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

Commit 45155969 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

make sure GLConsumer::releaseTexImage() works after detachFromContext()

Change-Id: I27e0bc57e927d47b2b98113ee37b5396bcc72019
parent 96a7dc08
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -259,7 +259,9 @@ protected:
    // to mEglDisplay and mEglContext.  If the fields have been previously
    // to mEglDisplay and mEglContext.  If the fields have been previously
    // set, the values must match; if not, the fields are set to the current
    // set, the values must match; if not, the fields are set to the current
    // values.
    // values.
    status_t checkAndUpdateEglStateLocked();
    // The contextCheck argument is used to ensure that a GL context is
    // properly set; when set to false, the check is not performed.
    status_t checkAndUpdateEglStateLocked(bool contextCheck = false);


private:
private:
    // createImage creates a new EGLImage from a GraphicBuffer.
    // createImage creates a new EGLImage from a GraphicBuffer.
+43 −19
Original line number Original line Diff line number Diff line
@@ -188,26 +188,36 @@ status_t GLConsumer::releaseTexImage() {
    }
    }


    // Make sure the EGL state is the same as in previous calls.
    // Make sure the EGL state is the same as in previous calls.
    status_t err = checkAndUpdateEglStateLocked();
    status_t err = NO_ERROR;

    if (mAttached) {
        err = checkAndUpdateEglStateLocked(true);
        if (err != NO_ERROR) {
        if (err != NO_ERROR) {
            return err;
            return err;
        }
        }
    } else {
        // if we're detached, no need to validate EGL's state -- we won't use it.
    }


    // Update the GLConsumer state.
    // Update the GLConsumer state.
    int buf = mCurrentTexture;
    int buf = mCurrentTexture;
    if (buf != BufferQueue::INVALID_BUFFER_SLOT) {
    if (buf != BufferQueue::INVALID_BUFFER_SLOT) {


        ST_LOGV("releaseTexImage:(slot=%d", buf);
        ST_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached);


        if (mAttached) {
            // Do whatever sync ops we need to do before releasing the slot.
            // Do whatever sync ops we need to do before releasing the slot.
            err = syncForReleaseLocked(mEglDisplay);
            err = syncForReleaseLocked(mEglDisplay);
            if (err != NO_ERROR) {
            if (err != NO_ERROR) {
                ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err);
                ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err);
                return err;
                return err;
            }
            }
        } else {
            // if we're detached, we just use the fence that was created in detachFromContext()
            // so... basically, nothing more to do here.
        }


        err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
        err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR);
                mEglDisplay, EGL_NO_SYNC_KHR);
        if (err < NO_ERROR) {
        if (err < NO_ERROR) {
            ST_LOGE("releaseTexImage: failed to release buffer: %s (%d)",
            ST_LOGE("releaseTexImage: failed to release buffer: %s (%d)",
                    strerror(-err), err);
                    strerror(-err), err);
@@ -222,9 +232,14 @@ status_t GLConsumer::releaseTexImage() {
        mCurrentTimestamp = 0;
        mCurrentTimestamp = 0;
        mCurrentFence = Fence::NO_FENCE;
        mCurrentFence = Fence::NO_FENCE;


        if (mAttached) {
            // bind a dummy texture
            // bind a dummy texture
            glBindTexture(mTexTarget, mTexName);
            glBindTexture(mTexTarget, mTexName);
            bindUnslottedBufferLocked(mEglDisplay);
            bindUnslottedBufferLocked(mEglDisplay);
        } else {
            // detached, don't touch the texture (and we may not even have an
            // EGLDisplay here.
        }
    }
    }


    return NO_ERROR;
    return NO_ERROR;
@@ -409,18 +424,27 @@ status_t GLConsumer::bindTextureImageLocked() {


}
}


status_t GLConsumer::checkAndUpdateEglStateLocked() {
status_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) {
    EGLDisplay dpy = eglGetCurrentDisplay();
    EGLDisplay dpy = eglGetCurrentDisplay();
    EGLContext ctx = eglGetCurrentContext();
    EGLContext ctx = eglGetCurrentContext();


    if ((mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) ||
    if (!contextCheck) {
            dpy == EGL_NO_DISPLAY) {
        // if this is the first time we're called, mEglDisplay/mEglContext have
        // never been set, so don't error out (below).
        if (mEglDisplay == EGL_NO_DISPLAY) {
            mEglDisplay = dpy;
        }
        if (mEglContext == EGL_NO_DISPLAY) {
            mEglContext = ctx;
        }
    }

    if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) {
        ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
        ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }


    if ((mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) ||
    if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) {
            ctx == EGL_NO_CONTEXT) {
        ST_LOGE("checkAndUpdateEglState: invalid current EGLContext");
        ST_LOGE("checkAndUpdateEglState: invalid current EGLContext");
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }