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

Change-Id: I27e0bc57e927d47b2b98113ee37b5396bcc72019
This commit is contained in:
Mathias Agopian 2013-08-08 18:16:21 -07:00
parent 96a7dc08f2
commit 45155969dc
2 changed files with 46 additions and 20 deletions

View File

@ -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.

View File

@ -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 (err != NO_ERROR) {
return err; if (mAttached) {
err = checkAndUpdateEglStateLocked(true);
if (err != NO_ERROR) {
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);
// Do whatever sync ops we need to do before releasing the slot. if (mAttached) {
err = syncForReleaseLocked(mEglDisplay); // Do whatever sync ops we need to do before releasing the slot.
if (err != NO_ERROR) { err = syncForReleaseLocked(mEglDisplay);
ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err); if (err != NO_ERROR) {
return err; ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, 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;
// bind a dummy texture if (mAttached) {
glBindTexture(mTexTarget, mTexName); // bind a dummy texture
bindUnslottedBufferLocked(mEglDisplay); glBindTexture(mTexTarget, mTexName);
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;
} }