DeferredLayerUpdater: clean up Layer lifecycle

Test: refactoring CL, all existent tests should pass
bug:34919311
Change-Id: Ib2889667a5ab8a2aaba443458782bc163467f0ea
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 41c44f1b..7af1020 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -132,7 +132,7 @@
     }
 
     public void setSurfaceTexture(SurfaceTexture surface) {
-        nSetSurfaceTexture(mFinalizer.get(), surface, false);
+        nSetSurfaceTexture(mFinalizer.get(), surface);
         mRenderer.pushLayerUpdate(this);
     }
 
@@ -148,7 +148,6 @@
     private static native boolean nPrepare(long layerUpdater, int width, int height, boolean isOpaque);
     private static native void nSetLayerPaint(long layerUpdater, long paint);
     private static native void nSetTransform(long layerUpdater, long matrix);
-    private static native void nSetSurfaceTexture(long layerUpdater,
-            SurfaceTexture surface, boolean isAlreadyAttached);
+    private static native void nSetSurfaceTexture(long layerUpdater, SurfaceTexture surface);
     private static native void nUpdateSurfaceTexture(long layerUpdater);
 }
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 65c1590..d934870 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -66,10 +66,10 @@
 }
 
 static void android_view_HardwareLayer_setSurfaceTexture(JNIEnv* env, jobject clazz,
-        jlong layerUpdaterPtr, jobject surface, jboolean isAlreadyAttached) {
+        jlong layerUpdaterPtr, jobject surface) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
     sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
-    layer->setSurfaceTexture(surfaceTexture, !isAlreadyAttached);
+    layer->setSurfaceTexture(surfaceTexture);
 }
 
 static void android_view_HardwareLayer_updateSurfaceTexture(JNIEnv* env, jobject clazz,
@@ -88,7 +88,7 @@
     { "nPrepare",                "(JIIZ)Z",    (void*) android_view_HardwareLayer_prepare },
     { "nSetLayerPaint",          "(JJ)V",      (void*) android_view_HardwareLayer_setLayerPaint },
     { "nSetTransform",           "(JJ)V",      (void*) android_view_HardwareLayer_setTransform },
-    { "nSetSurfaceTexture",      "(JLandroid/graphics/SurfaceTexture;Z)V",
+    { "nSetSurfaceTexture",      "(JLandroid/graphics/SurfaceTexture;)V",
             (void*) android_view_HardwareLayer_setSurfaceTexture },
     { "nUpdateSurfaceTexture",   "(J)V",       (void*) android_view_HardwareLayer_updateSurfaceTexture },
 };
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 415e850..00e8c05 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -31,7 +31,7 @@
         , mBlend(false)
         , mSurfaceTexture(nullptr)
         , mTransform(nullptr)
-        , mNeedsGLContextAttach(false)
+        , mGLContextAttached(false)
         , mUpdateTexImage(false)
         , mLayer(nullptr)
         , mLayerApi(layerApi)
@@ -47,10 +47,21 @@
 }
 
 void DeferredLayerUpdater::destroyLayer() {
-    if (mLayer) {
-        mLayer->postDecStrong();
-        mLayer = nullptr;
+    if (!mLayer) {
+        return;
     }
+
+    if (mSurfaceTexture.get() && mLayerApi == Layer::Api::OpenGL && mGLContextAttached) {
+        status_t err = mSurfaceTexture->detachFromContext();
+        mGLContextAttached = false;
+        if (err != 0) {
+            // TODO: Elevate to fatal exception
+            ALOGE("Failed to detach SurfaceTexture from context %d", err);
+        }
+    }
+
+    mLayer->postDecStrong();
+    mLayer = nullptr;
 }
 
 void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
@@ -78,8 +89,9 @@
             LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
                                 "apply surfaceTexture with non GL backend %x, GL %x, VK %x",
                                 mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
-            if (mNeedsGLContextAttach) {
-                mNeedsGLContextAttach = false;
+            if (!mGLContextAttached) {
+                mGLContextAttached = true;
+                mUpdateTexImage = true;
                 mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId());
             }
             if (mUpdateTexImage) {
@@ -169,16 +181,7 @@
 
 void DeferredLayerUpdater::detachSurfaceTexture() {
     if (mSurfaceTexture.get()) {
-        if (mLayerApi == Layer::Api::OpenGL) {
-            status_t err = mSurfaceTexture->detachFromContext();
-            if (err != 0) {
-                // TODO: Elevate to fatal exception
-                ALOGE("Failed to detach SurfaceTexture from context %d", err);
-            }
-            if (mLayer) {
-                static_cast<GlLayer*>(mLayer)->clearTexture();
-            }
-        }
+        destroyLayer();
         mSurfaceTexture = nullptr;
     }
 }
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 064b724..6717361 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -68,9 +68,8 @@
         return false;
     }
 
-    ANDROID_API void setSurfaceTexture(const sp<GLConsumer>& texture, bool needsAttach) {
+    ANDROID_API void setSurfaceTexture(const sp<GLConsumer>& texture) {
         if (texture.get() != mSurfaceTexture.get()) {
-            mNeedsGLContextAttach = needsAttach;
             mSurfaceTexture = texture;
 
             GLenum target = texture->getCurrentTextureTarget();
@@ -122,7 +121,7 @@
     SkBlendMode mMode = SkBlendMode::kSrcOver;
     sp<GLConsumer> mSurfaceTexture;
     SkMatrix* mTransform;
-    bool mNeedsGLContextAttach;
+    bool mGLContextAttached;
     bool mUpdateTexImage;
 
     Layer* mLayer;
diff --git a/libs/hwui/GlLayer.cpp b/libs/hwui/GlLayer.cpp
index 8174bcc..aacad54 100644
--- a/libs/hwui/GlLayer.cpp
+++ b/libs/hwui/GlLayer.cpp
@@ -43,7 +43,10 @@
 }
 
 GlLayer::~GlLayer() {
-    if (texture.mId) {
+    // There's a rare possibility that Caches could have been destroyed already
+    // since this method is queued up as a task.
+    // Since this is a reset method, treat this as non-fatal.
+    if (caches.isInitialized() && texture.mId) {
         texture.deleteTexture();
     }
 }
@@ -64,15 +67,5 @@
     }
 }
 
-void GlLayer::clearTexture() {
-    // There's a rare possibility that Caches could have been destroyed already
-    // since this method is queued up as a task.
-    // Since this is a reset method, treat this as non-fatal.
-    if (caches.isInitialized()) {
-        caches.textureState().unbindTexture(texture.mId);
-    }
-    texture.mId = 0;
-}
-
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h
index 23dfd9d..85ddaff 100644
--- a/libs/hwui/GlLayer.h
+++ b/libs/hwui/GlLayer.h
@@ -88,13 +88,6 @@
     void generateTexture();
 
     /**
-     * When the caller frees the texture itself, the caller
-     * must call this method to tell this layer that it lost
-     * the texture.
-     */
-    void clearTexture();
-
-    /**
      * Lost the GL context but the layer is still around, mark it invalid internally
      * so the dtor knows not to do any GL work
      */