Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54ba51df authored by Mathias Agopian's avatar Mathias Agopian
Browse files

fix [2143798] Need to figure out how to do video

    Use EGLImageKHR instead of copybit directly.
    We now have the basis to use streaming YUV textures (well, in fact
    we already are). When/if we use the GPU instead of the MDP we'll
    need to make sure it supports the appropriate YUV format.

    Also make sure we compile if EGL_ANDROID_image_native_buffer is not supported
parent 36bc9417
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -66,7 +66,11 @@ public:
    GraphicBuffer();

    // creates w * h buffer
    GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t ssage);
    GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage);

    // create a buffer from an existing handle
    GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
            uint32_t stride, native_handle_t* handle, bool keepOwnership);

    // return status
    status_t initCheck() const;
@@ -94,9 +98,15 @@ protected:
    GraphicBuffer(const Parcel& reply);
    virtual ~GraphicBuffer();

    enum {
        ownNone   = 0,
        ownHandle = 1,
        ownData   = 2,
    };

    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
    bool mOwner;
    uint8_t mOwner;

private:
    friend class Surface;
+4 −0
Original line number Diff line number Diff line
@@ -256,12 +256,16 @@ void DisplayHardware::init(uint32_t dpy)
    if (strstr(gl_extensions, "GL_OES_draw_texture")) {
        mFlags |= DRAW_TEXTURE_EXTENSION;
    }
#ifdef EGL_ANDROID_image_native_buffer
    if (strstr( gl_extensions, "GL_OES_EGL_image") &&
        (strstr(egl_extensions, "EGL_KHR_image_base") || 
                strstr(egl_extensions, "EGL_KHR_image")) &&
        strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) {
        mFlags |= DIRECT_TEXTURE;
    }
#else
#warning "EGL_ANDROID_image_native_buffer not supported"
#endif

    // Unbind the context from this thread
    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+6 −59
Original line number Diff line number Diff line
@@ -130,62 +130,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
    return NO_ERROR;
}

status_t Layer::initializeEglImageLocked(
        const sp<GraphicBuffer>& buffer, Texture* texture)
{
    status_t err = NO_ERROR;

    // we need to recreate the texture
    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());

    // free the previous image
    if (texture->image != EGL_NO_IMAGE_KHR) {
        eglDestroyImageKHR(dpy, texture->image);
        texture->image = EGL_NO_IMAGE_KHR;
    }

    // construct an EGL_NATIVE_BUFFER_ANDROID
    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();

    // create the new EGLImageKHR
    const EGLint attrs[] = {
            EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
            EGL_NONE,                   EGL_NONE
    };
    texture->image = eglCreateImageKHR(
            dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
            (EGLClientBuffer)clientBuf, attrs);

    LOGE_IF(texture->image == EGL_NO_IMAGE_KHR,
            "eglCreateImageKHR() failed. err=0x%4x",
            eglGetError());

    if (texture->image != EGL_NO_IMAGE_KHR) {
        glBindTexture(GL_TEXTURE_2D, texture->name);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
                (GLeglImageOES)texture->image);
        GLint error = glGetError();
        if (UNLIKELY(error != GL_NO_ERROR)) {
            // this failed, for instance, because we don't support NPOT.
            // FIXME: do something!
            LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
                 "failed err=0x%04x",
                 this, texture->image, error);
            mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
            err = INVALID_OPERATION;
        } else {
            // Everything went okay!
            texture->NPOTAdjust = false;
            texture->dirty  = false;
            texture->width  = clientBuf->width;
            texture->height = clientBuf->height;
        }
    } else {
        err = INVALID_OPERATION;
    }
    return err;
}

void Layer::reloadTexture(const Region& dirty)
{
    Mutex::Autolock _l(mLock);
@@ -199,10 +143,11 @@ void Layer::reloadTexture(const Region& dirty)
        mTextures[index].height = 0;
    }

#ifdef EGL_ANDROID_image_native_buffer
    if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
        if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
            if (mTextures[index].dirty) {
                initializeEglImageLocked(buffer, &mTextures[index]);
                initializeEglImage(buffer, &mTextures[index]);
            }
        } else {
            if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
@@ -212,7 +157,7 @@ void Layer::reloadTexture(const Region& dirty)
                        buffer->width, buffer->height, buffer->format,
                        GraphicBuffer::USAGE_SW_WRITE_OFTEN |
                        GraphicBuffer::USAGE_HW_TEXTURE);
                initializeEglImageLocked(
                initializeEglImage(
                        mHybridBuffer, &mTextures[0]);
            }

@@ -279,7 +224,9 @@ void Layer::reloadTexture(const Region& dirty)
                buffer->unlock();
            }
        }
    } else {
    } else
#endif
    {
        for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
            mTextures[i].image = EGL_NO_IMAGE_KHR;
        }
+0 −2
Original line number Diff line number Diff line
@@ -85,8 +85,6 @@ private:
    }
 
    void reloadTexture(const Region& dirty);
    status_t initializeEglImageLocked(
            const sp<GraphicBuffer>& buffer, Texture* texture);

    uint32_t getEffectiveUsage(uint32_t usage) const;

+57 −0
Original line number Diff line number Diff line
@@ -617,6 +617,63 @@ void LayerBase::loadTexture(Texture* texture,
    }
}

status_t LayerBase::initializeEglImage(
        const sp<GraphicBuffer>& buffer, Texture* texture)
{
    status_t err = NO_ERROR;

    // we need to recreate the texture
    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());

    // free the previous image
    if (texture->image != EGL_NO_IMAGE_KHR) {
        eglDestroyImageKHR(dpy, texture->image);
        texture->image = EGL_NO_IMAGE_KHR;
    }

    // construct an EGL_NATIVE_BUFFER_ANDROID
    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();

    // create the new EGLImageKHR
    const EGLint attrs[] = {
            EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
            EGL_NONE,                   EGL_NONE
    };
    texture->image = eglCreateImageKHR(
            dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
            (EGLClientBuffer)clientBuf, attrs);

    LOGE_IF(texture->image == EGL_NO_IMAGE_KHR,
            "eglCreateImageKHR() failed. err=0x%4x",
            eglGetError());

    if (texture->image != EGL_NO_IMAGE_KHR) {
        glBindTexture(GL_TEXTURE_2D, texture->name);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
                (GLeglImageOES)texture->image);
        GLint error = glGetError();
        if (UNLIKELY(error != GL_NO_ERROR)) {
            // this failed, for instance, because we don't support NPOT.
            // FIXME: do something!
            LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
                 "failed err=0x%04x",
                 this, texture->image, error);
            mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
            err = INVALID_OPERATION;
        } else {
            // Everything went okay!
            texture->NPOTAdjust = false;
            texture->dirty  = false;
            texture->width  = clientBuf->width;
            texture->height = clientBuf->height;
        }
    } else {
        err = INVALID_OPERATION;
    }
    return err;
}


// ---------------------------------------------------------------------------

int32_t LayerBaseClient::sIdentity = 0;
Loading