Cleanup AutoBackendTexture to make it more difficult to leak resources

Also add some addtional logging to make it easier to debug why a surface
or image fails to be created.

Test: librenderengine_test
Bug: 183391755
Bug: 182142615
Change-Id: Ib1f07f08d60cdb2ce1c773f7fc66cadedd020a8d
diff --git a/libs/renderengine/skia/AutoBackendTexture.cpp b/libs/renderengine/skia/AutoBackendTexture.cpp
index c535597..9ed759f 100644
--- a/libs/renderengine/skia/AutoBackendTexture.cpp
+++ b/libs/renderengine/skia/AutoBackendTexture.cpp
@@ -29,7 +29,8 @@
 namespace skia {
 
 AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer,
-                                       bool isRender) {
+                                       bool isOutputBuffer)
+      : mIsOutputBuffer(isOutputBuffer) {
     ATRACE_CALL();
     AHardwareBuffer_Desc desc;
     AHardwareBuffer_describe(buffer, &desc);
@@ -40,8 +41,12 @@
             GrAHardwareBufferUtils::MakeBackendTexture(context, buffer, desc.width, desc.height,
                                                        &mDeleteProc, &mUpdateProc, &mImageCtx,
                                                        createProtectedImage, backendFormat,
-                                                       isRender);
+                                                       isOutputBuffer);
     mColorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format);
+    ALOGE_IF(!mBackendTexture.isValid(),
+             "Failed to create a valid texture. [%p]:[%d,%d] isProtected:%d isWriteable:%d "
+             "format:%d",
+             this, desc.width, desc.height, isOutputBuffer, createProtectedImage, desc.format);
 }
 
 void AutoBackendTexture::unref(bool releaseLocalResources) {
@@ -92,13 +97,16 @@
 
     mImage = image;
     mDataspace = dataspace;
-    LOG_ALWAYS_FATAL_IF(mImage == nullptr, "Unable to generate SkImage from buffer");
+    LOG_ALWAYS_FATAL_IF(mImage == nullptr,
+                        "Unable to generate SkImage. isTextureValid:%d dataspace:%d",
+                        mBackendTexture.isValid(), dataspace);
     return mImage;
 }
 
 sk_sp<SkSurface> AutoBackendTexture::getOrCreateSurface(ui::Dataspace dataspace,
                                                         GrDirectContext* context) {
     ATRACE_CALL();
+    LOG_ALWAYS_FATAL_IF(!mIsOutputBuffer, "You can't generate a SkSurface for a read-only texture");
     if (!mSurface.get() || mDataspace != dataspace) {
         sk_sp<SkSurface> surface =
                 SkSurface::MakeFromBackendTexture(context, mBackendTexture,
@@ -113,7 +121,9 @@
     }
 
     mDataspace = dataspace;
-    LOG_ALWAYS_FATAL_IF(mSurface == nullptr, "Unable to generate SkSurface");
+    LOG_ALWAYS_FATAL_IF(mSurface == nullptr,
+                        "Unable to generate SkSurface. isTextureValid:%d dataspace:%d",
+                        mBackendTexture.isValid(), dataspace);
     return mSurface;
 }
 
diff --git a/libs/renderengine/skia/AutoBackendTexture.h b/libs/renderengine/skia/AutoBackendTexture.h
index 2d61cf8..3133de6 100644
--- a/libs/renderengine/skia/AutoBackendTexture.h
+++ b/libs/renderengine/skia/AutoBackendTexture.h
@@ -41,34 +41,42 @@
     // of shared ownership with Skia objects, so we wrap it here instead.
     class LocalRef {
     public:
-        LocalRef(AutoBackendTexture* texture) { setTexture(texture); }
-
-        ~LocalRef() {
-            // Destroying the texture is the same as setting it to null
-            setTexture(nullptr);
+        LocalRef(GrDirectContext* context, AHardwareBuffer* buffer, bool isOutputBuffer) {
+            mTexture = new AutoBackendTexture(context, buffer, isOutputBuffer);
+            mTexture->ref();
         }
 
-        AutoBackendTexture* getTexture() const { return mTexture; }
+        ~LocalRef() {
+            if (mTexture != nullptr) {
+                mTexture->unref(true);
+            }
+        }
+
+        // Makes a new SkImage from the texture content.
+        // As SkImages are immutable but buffer content is not, we create
+        // a new SkImage every time.
+        sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType,
+                                 GrDirectContext* context) {
+            return mTexture->makeImage(dataspace, alphaType, context);
+        }
+
+        // Makes a new SkSurface from the texture content, if needed.
+        sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context) {
+            return mTexture->getOrCreateSurface(dataspace, context);
+        }
 
         DISALLOW_COPY_AND_ASSIGN(LocalRef);
 
     private:
-        // Sets the texture to locally ref-track.
-        void setTexture(AutoBackendTexture* texture) {
-            if (mTexture != nullptr) {
-                mTexture->unref(true);
-            }
-
-            mTexture = texture;
-            if (mTexture != nullptr) {
-                mTexture->ref();
-            }
-        }
         AutoBackendTexture* mTexture = nullptr;
     };
 
+private:
     // Creates a GrBackendTexture whose contents come from the provided buffer.
-    AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isRender);
+    AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isOutputBuffer);
+
+    // The only way to invoke dtor is with unref, when mUsageCount is 0.
+    ~AutoBackendTexture() {}
 
     void ref() { mUsageCount++; }
 
@@ -85,10 +93,6 @@
     // Makes a new SkSurface from the texture content, if needed.
     sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context);
 
-private:
-    // The only way to invoke dtor is with unref, when mUsageCount is 0.
-    ~AutoBackendTexture() {}
-
     GrBackendTexture mBackendTexture;
     GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
     GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
@@ -99,6 +103,7 @@
 
     int mUsageCount = 0;
 
+    const bool mIsOutputBuffer;
     sk_sp<SkImage> mImage = nullptr;
     sk_sp<SkSurface> mSurface = nullptr;
     ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 37d98a3..0a84754 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -508,9 +508,9 @@
 
     if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
         std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
-                std::make_shared<AutoBackendTexture::LocalRef>(
-                        new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(),
-                                               isRenderable));
+                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
+                                                               buffer->toAHardwareBuffer(),
+                                                               isRenderable);
         cache.insert({buffer->getId(), imageTextureRef});
     }
     // restore the original state of the protected context if necessary
@@ -669,15 +669,17 @@
     if (const auto& it = cache.find(buffer->getBuffer()->getId()); it != cache.end()) {
         surfaceTextureRef = it->second;
     } else {
-        surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
-                new AutoBackendTexture(grContext.get(), buffer->getBuffer()->toAHardwareBuffer(),
-                                       true));
+        surfaceTextureRef =
+                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
+                                                               buffer->getBuffer()
+                                                                       ->toAHardwareBuffer(),
+                                                               true);
     }
 
     const ui::Dataspace dstDataspace =
             mUseColorManagement ? display.outputDataspace : ui::Dataspace::UNKNOWN;
     sk_sp<SkSurface> dstSurface =
-            surfaceTextureRef->getTexture()->getOrCreateSurface(dstDataspace, grContext.get());
+            surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext.get());
 
     SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
     if (dstCanvas == nullptr) {
@@ -889,18 +891,17 @@
                 // it. If we're using skia, we're guaranteed to run on a dedicated GPU thread so if
                 // we didn't find anything in the cache then we intentionally did not cache this
                 // buffer's resources.
-                imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
-                        new AutoBackendTexture(grContext.get(),
-                                               item.buffer->getBuffer()->toAHardwareBuffer(),
-                                               false));
+                imageTextureRef = std::make_shared<
+                        AutoBackendTexture::LocalRef>(grContext.get(),
+                                                      item.buffer->getBuffer()->toAHardwareBuffer(),
+                                                      false);
             }
 
             sk_sp<SkImage> image =
-                    imageTextureRef->getTexture()->makeImage(layerDataspace,
-                                                             item.usePremultipliedAlpha
-                                                                     ? kPremul_SkAlphaType
-                                                                     : kUnpremul_SkAlphaType,
-                                                             grContext.get());
+                    imageTextureRef->makeImage(layerDataspace,
+                                               item.usePremultipliedAlpha ? kPremul_SkAlphaType
+                                                                          : kUnpremul_SkAlphaType,
+                                               grContext.get());
 
             auto texMatrix = getSkM44(item.textureTransform).asM33();
             // textureTansform was intended to be passed directly into a shader, so when