surfaceflinger: remove support for context detaching
BufferLayerConsumer::detachFromContext and
BufferLayerConsumer::attachToContext are unused.
BufferLayerConsumer::bindTextureImageLocked used to support a
special case (see libgui_test's
SurfaceTextureMultiContextGLTest.AttachAfterDisplayTerminatedSucceeds)
because of context detaching, the support can be removed as well.
Test: builds
Change-Id: I169a57ebd1b99770ce5c1cc68aa5eb097c6f1b26
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index b9930d1..8519a70 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -124,35 +124,7 @@
mTexTarget(texTarget),
mEglDisplay(EGL_NO_DISPLAY),
mEglContext(EGL_NO_CONTEXT),
- mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
- mAttached(true) {
- BLC_LOGV("BufferLayerConsumer");
-
- memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix));
-
- mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
-}
-
-BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget,
- bool useFenceSync, bool isControlledByApp)
- : ConsumerBase(bq, isControlledByApp),
- mCurrentCrop(Rect::EMPTY_RECT),
- mCurrentTransform(0),
- mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
- mCurrentFence(Fence::NO_FENCE),
- mCurrentTimestamp(0),
- mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
- mCurrentFrameNumber(0),
- mDefaultWidth(1),
- mDefaultHeight(1),
- mFilteringEnabled(true),
- mTexName(0),
- mUseFenceSync(useFenceSync),
- mTexTarget(texTarget),
- mEglDisplay(EGL_NO_DISPLAY),
- mEglContext(EGL_NO_CONTEXT),
- mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
- mAttached(false) {
+ mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT) {
BLC_LOGV("BufferLayerConsumer");
memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix));
@@ -252,13 +224,6 @@
int slot = item.mSlot;
- if (!mAttached) {
- BLC_LOGE("updateAndRelease: BufferLayerConsumer is not attached to an OpenGL "
- "ES context");
- releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR);
- return INVALID_OPERATION;
- }
-
// Confirm state.
err = checkAndUpdateEglStateLocked();
if (err != NO_ERROR) {
@@ -364,42 +329,21 @@
}
mCurrentTextureImage->bindToTextureTarget(mTexTarget);
- // In the rare case that the display is terminated and then initialized
- // again, we can't detect that the display changed (it didn't), but the
- // image is invalid. In this case, repeat the exact same steps while
- // forcing the creation of a new image.
- if ((error = glGetError()) != GL_NO_ERROR) {
- glBindTexture(mTexTarget, mTexName);
- status_t result = mCurrentTextureImage->createIfNeeded(mEglDisplay, mCurrentCrop, true);
- if (result != NO_ERROR) {
- BLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", mEglDisplay,
- mCurrentTexture);
- return UNKNOWN_ERROR;
- }
- mCurrentTextureImage->bindToTextureTarget(mTexTarget);
- if ((error = glGetError()) != GL_NO_ERROR) {
- BLC_LOGE("bindTextureImage: error binding external image: %#04x", error);
- return UNKNOWN_ERROR;
- }
- }
-
// Wait for the new buffer to be ready.
return doGLFenceWaitLocked();
}
-status_t BufferLayerConsumer::checkAndUpdateEglStateLocked(bool contextCheck) {
+status_t BufferLayerConsumer::checkAndUpdateEglStateLocked() {
EGLDisplay dpy = eglGetCurrentDisplay();
EGLContext ctx = eglGetCurrentContext();
- if (!contextCheck) {
- // 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_CONTEXT) {
- mEglContext = ctx;
- }
+ // 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_CONTEXT) {
+ mEglContext = ctx;
}
if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) {
@@ -412,8 +356,6 @@
return INVALID_OPERATION;
}
- mEglDisplay = dpy;
- mEglContext = ctx;
return NO_ERROR;
}
@@ -427,103 +369,6 @@
}
}
-status_t BufferLayerConsumer::detachFromContext() {
- ATRACE_CALL();
- BLC_LOGV("detachFromContext");
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- BLC_LOGE("detachFromContext: abandoned BufferLayerConsumer");
- return NO_INIT;
- }
-
- if (!mAttached) {
- BLC_LOGE("detachFromContext: BufferLayerConsumer is not attached to a "
- "context");
- return INVALID_OPERATION;
- }
-
- EGLDisplay dpy = eglGetCurrentDisplay();
- EGLContext ctx = eglGetCurrentContext();
-
- if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) {
- BLC_LOGE("detachFromContext: invalid current EGLDisplay");
- return INVALID_OPERATION;
- }
-
- if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) {
- BLC_LOGE("detachFromContext: invalid current EGLContext");
- return INVALID_OPERATION;
- }
-
- if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) {
- status_t err = syncForReleaseLocked(dpy);
- if (err != OK) {
- return err;
- }
-
- glDeleteTextures(1, &mTexName);
- }
-
- mEglDisplay = EGL_NO_DISPLAY;
- mEglContext = EGL_NO_CONTEXT;
- mAttached = false;
-
- return OK;
-}
-
-status_t BufferLayerConsumer::attachToContext(uint32_t tex) {
- ATRACE_CALL();
- BLC_LOGV("attachToContext");
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- BLC_LOGE("attachToContext: abandoned BufferLayerConsumer");
- return NO_INIT;
- }
-
- if (mAttached) {
- BLC_LOGE("attachToContext: BufferLayerConsumer is already attached to a "
- "context");
- return INVALID_OPERATION;
- }
-
- EGLDisplay dpy = eglGetCurrentDisplay();
- EGLContext ctx = eglGetCurrentContext();
-
- if (dpy == EGL_NO_DISPLAY) {
- BLC_LOGE("attachToContext: invalid current EGLDisplay");
- return INVALID_OPERATION;
- }
-
- if (ctx == EGL_NO_CONTEXT) {
- BLC_LOGE("attachToContext: invalid current EGLContext");
- return INVALID_OPERATION;
- }
-
- // We need to bind the texture regardless of whether there's a current
- // buffer.
- glBindTexture(mTexTarget, GLuint(tex));
-
- mEglDisplay = dpy;
- mEglContext = ctx;
- mTexName = tex;
- mAttached = true;
-
- if (mCurrentTextureImage != NULL) {
- // This may wait for a buffer a second time. This is likely required if
- // this is a different context, since otherwise the wait could be skipped
- // by bouncing through another context. For the same context the extra
- // wait is redundant.
- status_t err = bindTextureImageLocked();
- if (err != NO_ERROR) {
- return err;
- }
- }
-
- return OK;
-}
-
status_t BufferLayerConsumer::syncForReleaseLocked(EGLDisplay dpy) {
BLC_LOGV("syncForReleaseLocked");
@@ -894,13 +739,13 @@
}
}
-status_t BufferLayerConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay, const Rect& cropRect,
- bool forceCreation) {
+status_t BufferLayerConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay,
+ const Rect& cropRect) {
// If there's an image and it's no longer valid, destroy it.
bool haveImage = mEglImage != EGL_NO_IMAGE_KHR;
bool displayInvalid = mEglDisplay != eglDisplay;
bool cropInvalid = hasEglAndroidImageCrop() && mCropRect != cropRect;
- if (haveImage && (displayInvalid || cropInvalid || forceCreation)) {
+ if (haveImage && (displayInvalid || cropInvalid)) {
if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
ALOGE("createIfNeeded: eglDestroyImageKHR failed");
}
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index 931b84c..84a94e7 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -44,9 +44,10 @@
* If a new frame is available, the texture will be updated. If not,
* the previous contents are retained.
*
- * By default, the texture is attached to the GL_TEXTURE_EXTERNAL_OES
- * texture target, in the EGL context of the first thread that calls
- * updateTexImage().
+ * The texture is attached to the GL_TEXTURE_EXTERNAL_OES texture target, in
+ * the EGL context of the first thread that calls updateTexImage(). After that
+ * point, all calls to updateTexImage must be made with the same OpenGL ES
+ * context current.
*
* This class was previously called SurfaceTexture.
*/
@@ -55,38 +56,16 @@
enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES
typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
- // BufferLayerConsumer constructs a new BufferLayerConsumer object. If the constructor with
- // the tex parameter is used, tex indicates the name of the OpenGL ES
+ // BufferLayerConsumer constructs a new BufferLayerConsumer object.
+ // The tex parameter indicates the name of the OpenGL ES
// texture to which images are to be streamed. texTarget specifies the
// OpenGL ES texture target to which the texture will be bound in
// updateTexImage. useFenceSync specifies whether fences should be used to
// synchronize access to buffers if that behavior is enabled at
// compile-time.
- //
- // A BufferLayerConsumer may be detached from one OpenGL ES context and then
- // attached to a different context using the detachFromContext and
- // attachToContext methods, respectively. The intention of these methods is
- // purely to allow a BufferLayerConsumer to be transferred from one consumer
- // context to another. If such a transfer is not needed there is no
- // requirement that either of these methods be called.
- //
- // If the constructor with the tex parameter is used, the BufferLayerConsumer is
- // created in a state where it is considered attached to an OpenGL ES
- // context for the purposes of the attachToContext and detachFromContext
- // methods. However, despite being considered "attached" to a context, the
- // specific OpenGL ES context doesn't get latched until the first call to
- // updateTexImage. After that point, all calls to updateTexImage must be
- // made with the same OpenGL ES context current.
- //
- // If the constructor without the tex parameter is used, the BufferLayerConsumer is
- // created in a detached state, and attachToContext must be called before
- // calls to updateTexImage.
BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, uint32_t texureTarget,
bool useFenceSync, bool isControlledByApp);
- BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texureTarget,
- bool useFenceSync, bool isControlledByApp);
-
// updateTexImage acquires the most recently queued buffer, and sets the
// image contents of the target texture to it.
//
@@ -195,33 +174,6 @@
// DEFAULT_USAGE_FLAGS to usage.
status_t setConsumerUsageBits(uint64_t usage);
- // detachFromContext detaches the BufferLayerConsumer from the calling thread's
- // current OpenGL ES context. This context must be the same as the context
- // that was current for previous calls to updateTexImage.
- //
- // Detaching a BufferLayerConsumer from an OpenGL ES context will result in the
- // deletion of the OpenGL ES texture object into which the images were being
- // streamed. After a BufferLayerConsumer has been detached from the OpenGL ES
- // context calls to updateTexImage will fail returning INVALID_OPERATION
- // until the BufferLayerConsumer is attached to a new OpenGL ES context using the
- // attachToContext method.
- status_t detachFromContext();
-
- // attachToContext attaches a BufferLayerConsumer that is currently in the
- // 'detached' state to the current OpenGL ES context. A BufferLayerConsumer is
- // in the 'detached' state iff detachFromContext has successfully been
- // called and no calls to attachToContext have succeeded since the last
- // detachFromContext call. Calls to attachToContext made on a
- // BufferLayerConsumer that is not in the 'detached' state will result in an
- // INVALID_OPERATION error.
- //
- // The tex argument specifies the OpenGL ES texture object name in the
- // new context into which the image contents will be streamed. A successful
- // call to attachToContext will result in this texture object being bound to
- // the texture target and populated with the image contents that were
- // current at the time of the last call to detachFromContext.
- status_t attachToContext(uint32_t tex);
-
protected:
// abandonLocked overrides the ConsumerBase method to clear
// mCurrentTextureImage in addition to the ConsumerBase behavior.
@@ -279,9 +231,7 @@
// to mEglDisplay and mEglContext. If the fields have been previously
// set, the values must match; if not, the fields are set to the current
// values.
- // 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);
+ status_t checkAndUpdateEglStateLocked();
private:
// EglImage is a utility class for tracking and creating EGLImageKHRs. There
@@ -295,7 +245,7 @@
// createIfNeeded creates an EGLImage if required (we haven't created
// one yet, or the EGLDisplay or crop-rect has changed).
- status_t createIfNeeded(EGLDisplay display, const Rect& cropRect, bool forceCreate = false);
+ status_t createIfNeeded(EGLDisplay display, const Rect& cropRect);
// This calls glEGLImageTargetTexture2DOES to bind the image to the
// texture in the specified texture target.
@@ -411,9 +361,8 @@
bool mFilteringEnabled;
// mTexName is the name of the OpenGL texture to which streamed images will
- // be bound when updateTexImage is called. It is set at construction time
- // and can be changed with a call to attachToContext.
- uint32_t mTexName;
+ // be bound when updateTexImage is called. It is set at construction time.
+ const uint32_t mTexName;
// mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync
// extension should be used to prevent buffers from being dequeued before
@@ -447,14 +396,13 @@
// mEglDisplay is the EGLDisplay with which this BufferLayerConsumer is currently
// associated. It is intialized to EGL_NO_DISPLAY and gets set to the
- // current display when updateTexImage is called for the first time and when
- // attachToContext is called.
+ // current display when updateTexImage is called for the first time.
EGLDisplay mEglDisplay;
// mEglContext is the OpenGL ES context with which this BufferLayerConsumer is
// currently associated. It is initialized to EGL_NO_CONTEXT and gets set
// to the current GL context when updateTexImage is called for the first
- // time and when attachToContext is called.
+ // time.
EGLContext mEglContext;
// mEGLSlots stores the buffers that have been allocated by the BufferQueue
@@ -473,14 +421,6 @@
// that no buffer is bound to the texture. A call to setBufferCount will
// reset mCurrentTexture to INVALID_BUFFER_SLOT.
int mCurrentTexture;
-
- // mAttached indicates whether the ConsumerBase is currently attached to
- // an OpenGL ES context. For legacy reasons, this is initialized to true,
- // indicating that the ConsumerBase is considered to be attached to
- // whatever context is current at the time of the first updateTexImage call.
- // It is set to false by detachFromContext, and then set to true again by
- // attachToContext.
- bool mAttached;
};
// ----------------------------------------------------------------------------