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

Commit 90ed8508 authored by Jesse Hall's avatar Jesse Hall
Browse files

Recreate EGLImage for previously used slots

SurfaceTexture would only create an EGLImage for a buffer slot when
BufferQueue returns a GraphicBuffer, i.e. either the slot was acquired
for the first time ever, or the buffer for the slot was reallocated.
But the EGLImage may also need to be re-created for a
previously-acquired buffer if the slot's EGLImage was destroyed during
detachFromContext(); in this case BufferQueue won't return a
GraphicBuffer since SurfaceTexture already has a reference to the
correct buffer.

Bug: 6461693
Change-Id: Ib95d0d757192efe336c5fda0866f857481a6617d
parent e804aa48
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -228,14 +228,16 @@ status_t SurfaceTexture::updateTexImage() {
            mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
        }

        // Update the GL texture object.
        // Update the GL texture object. We may have to do this even when
        // item.mGraphicBuffer == NULL, if we destroyed the EGLImage when
        // detaching from a context but the buffer has not been re-allocated.
        EGLImageKHR image = mEGLSlots[buf].mEglImage;
        if (image == EGL_NO_IMAGE_KHR) {
            if (item.mGraphicBuffer == 0) {
            if (mEGLSlots[buf].mGraphicBuffer == NULL) {
                ST_LOGE("updateTexImage: buffer at slot %d is null", buf);
                return BAD_VALUE;
            }
            image = createImage(dpy, item.mGraphicBuffer);
            image = createImage(dpy, mEGLSlots[buf].mGraphicBuffer);
            mEGLSlots[buf].mEglImage = image;
            if (image == EGL_NO_IMAGE_KHR) {
                // NOTE: if dpy was invalid, createImage() is guaranteed to
+28 −0
Original line number Diff line number Diff line
@@ -2577,4 +2577,32 @@ TEST_F(SurfaceTextureMultiContextGLTest,
    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
}

TEST_F(SurfaceTextureMultiContextGLTest,
        UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
    ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true));
    ASSERT_EQ(NO_ERROR, mST->setBufferCountServer(2));

    // produce two frames and consume them both on the primary context
    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    mFW->waitForFrame();
    ASSERT_EQ(OK, mST->updateTexImage());

    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
    mFW->waitForFrame();
    ASSERT_EQ(OK, mST->updateTexImage());

    // produce one more frame
    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));

    // Detach from the primary context and attach to the secondary context
    ASSERT_EQ(OK, mST->detachFromContext());
    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
            mSecondEglContext));
    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));

    // Consume final frame on secondary context
    mFW->waitForFrame();
    ASSERT_EQ(OK, mST->updateTexImage());
}

} // namespace android