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;
 };
 
 // ----------------------------------------------------------------------------