Cleanup DeferredLayerUpdater

Bug: 17765082

DeferredLayerUpdater had fallen behind RT updates. Re-snap to
latest expectations, ensuring to call requireGlContext() prior
to detachSurfaceTexture to avoid leaking SurfaceTextures

Change-Id: Ic65fb9831e5284f658866da8da9ad5af1d227699
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 836de45..a6d7e78 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -18,38 +18,52 @@
 #include "OpenGLRenderer.h"
 
 #include "LayerRenderer.h"
+#include "renderthread/EglManager.h"
+#include "renderthread/RenderTask.h"
 
 namespace android {
 namespace uirenderer {
 
-static void defaultLayerDestroyer(Layer* layer) {
-    Caches::getInstance().resourceCache.decrementRefcount(layer);
-}
+class DeleteLayerTask : public renderthread::RenderTask {
+public:
+    DeleteLayerTask(renderthread::EglManager& eglManager, Layer* layer)
+        : mEglManager(eglManager)
+        , mLayer(layer)
+    {}
 
-DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, LayerDestroyer destroyer)
+    virtual void run() {
+        mEglManager.requireGlContext();
+        LayerRenderer::destroyLayer(mLayer);
+        mLayer = 0;
+        delete this;
+    }
+
+private:
+    renderthread::EglManager& mEglManager;
+    Layer* mLayer;
+};
+
+DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer)
         : mSurfaceTexture(0)
         , mTransform(0)
         , mNeedsGLContextAttach(false)
         , mUpdateTexImage(false)
         , mLayer(layer)
         , mCaches(Caches::getInstance())
-        , mDestroyer(destroyer) {
+        , mRenderThread(thread) {
     mWidth = mLayer->layer.getWidth();
     mHeight = mLayer->layer.getHeight();
     mBlend = mLayer->isBlend();
     mColorFilter = SkSafeRef(mLayer->getColorFilter());
     mAlpha = mLayer->getAlpha();
     mMode = mLayer->getMode();
-
-    if (!mDestroyer) {
-        mDestroyer = defaultLayerDestroyer;
-    }
 }
 
 DeferredLayerUpdater::~DeferredLayerUpdater() {
     SkSafeUnref(mColorFilter);
     setTransform(0);
-    mDestroyer(mLayer);
+    mRenderThread.queue(new DeleteLayerTask(mRenderThread.eglManager(), mLayer));
+    mLayer = 0;
 }
 
 void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
@@ -121,7 +135,12 @@
 
 void DeferredLayerUpdater::detachSurfaceTexture() {
     if (mSurfaceTexture.get()) {
-        mSurfaceTexture->detachFromContext();
+        mRenderThread.eglManager().requireGlContext();
+        status_t err = mSurfaceTexture->detachFromContext();
+        if (err != 0) {
+            // TODO: Elevate to fatal exception
+            ALOGE("Failed to detach SurfaceTexture from context %d", err);
+        }
         mSurfaceTexture = 0;
         mLayer->clearTexture();
     }
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index c838c32..dda3e89 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -25,19 +25,18 @@
 #include "Layer.h"
 #include "Rect.h"
 #include "RenderNode.h"
+#include "renderthread/RenderThread.h"
 
 namespace android {
 namespace uirenderer {
 
-typedef void (*LayerDestroyer)(Layer* layer);
-
 // Container to hold the properties a layer should be set to at the start
 // of a render pass
 class DeferredLayerUpdater : public VirtualLightRefBase {
 public:
     // Note that DeferredLayerUpdater assumes it is taking ownership of the layer
     // and will not call incrementRef on it as a result.
-    ANDROID_API DeferredLayerUpdater(Layer* layer, LayerDestroyer = 0);
+    ANDROID_API DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer);
     ANDROID_API ~DeferredLayerUpdater();
 
     ANDROID_API bool setSize(uint32_t width, uint32_t height) {
@@ -99,8 +98,7 @@
 
     Layer* mLayer;
     Caches& mCaches;
-
-    LayerDestroyer mDestroyer;
+    renderthread::RenderThread& mRenderThread;
 
     void doUpdateTexImage();
 };
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 1c416a7..b50a433 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -344,11 +344,6 @@
     task->run();
 }
 
-Layer* CanvasContext::createRenderLayer(int width, int height) {
-    requireSurface();
-    return LayerRenderer::createRenderLayer(mRenderThread.renderState(), width, height);
-}
-
 Layer* CanvasContext::createTextureLayer() {
     requireSurface();
     return LayerRenderer::createTextureLayer(mRenderThread.renderState());
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 2460f6b8..d4282fa 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -83,7 +83,6 @@
 
     void runWithGlContext(RenderTask* task);
 
-    Layer* createRenderLayer(int width, int height);
     Layer* createTextureLayer();
 
     ANDROID_API static void setTextureAtlas(RenderThread& thread,
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 9528874..047819d 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -257,31 +257,16 @@
     RenderThread::getInstance().queue(task);
 }
 
-CREATE_BRIDGE3(createDisplayListLayer, CanvasContext* context, int width, int height) {
-    Layer* layer = args->context->createRenderLayer(args->width, args->height);
-    if (!layer) return 0;
-    return new DeferredLayerUpdater(layer, RenderProxy::enqueueDestroyLayer);
-}
-
-DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) {
-    SETUP_TASK(createDisplayListLayer);
-    args->width = width;
-    args->height = height;
-    args->context = mContext;
-    void* retval = postAndWait(task);
-    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
-    return layer;
-}
-
-CREATE_BRIDGE1(createTextureLayer, CanvasContext* context) {
+CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) {
     Layer* layer = args->context->createTextureLayer();
     if (!layer) return 0;
-    return new DeferredLayerUpdater(layer, RenderProxy::enqueueDestroyLayer);
+    return new DeferredLayerUpdater(*args->thread, layer);
 }
 
 DeferredLayerUpdater* RenderProxy::createTextureLayer() {
     SETUP_TASK(createTextureLayer);
     args->context = mContext;
+    args->thread = &mRenderThread;
     void* retval = postAndWait(task);
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
     return layer;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 8b8d99c..678e7e2 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -80,7 +80,6 @@
     ANDROID_API void runWithGlContext(RenderTask* task);
 
     static void enqueueDestroyLayer(Layer* layer);
-    ANDROID_API DeferredLayerUpdater* createDisplayListLayer(int width, int height);
     ANDROID_API DeferredLayerUpdater* createTextureLayer();
     ANDROID_API void buildLayer(RenderNode* node);
     ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);