Better error reporting for createOrUpdateLayer

Pass error handler down to the pipeline object, which allows
skia pipelines to print cache memory usage.
In case of an error, print arguments that were used to invoke
SkSurface::MakeRenderTarget.

Test: Ran android build on a device
Bug: 76115654
Change-Id: I5baddfa66debd505eddc3117cf94aa6ae69bedaa
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index fedcc10..d93a757 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -243,24 +243,11 @@
         return;
     }
 
-    if (info.canvasContext.createOrUpdateLayer(this, *info.damageAccumulator)) {
+    if (info.canvasContext.createOrUpdateLayer(this, *info.damageAccumulator, info.errorHandler)) {
         damageSelf(info);
     }
 
     if (!hasLayer()) {
-        Caches::getInstance().dumpMemoryUsage();
-        if (info.errorHandler) {
-            std::ostringstream err;
-            err << "Unable to create layer for " << getName();
-            const int maxTextureSize = Caches::getInstance().maxTextureSize;
-            if (getWidth() > maxTextureSize || getHeight() > maxTextureSize) {
-                err << ", size " << getWidth() << "x" << getHeight() << " exceeds max size "
-                    << maxTextureSize;
-            } else {
-                err << ", see logcat for more info";
-            }
-            info.errorHandler->onError(err.str());
-        }
         return;
     }
 
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 0cd1c15..07052cd 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -22,6 +22,7 @@
 #include <SkOverdrawColorFilter.h>
 #include <SkPicture.h>
 #include <SkPictureRecorder.h>
+#include "TreeInfo.h"
 #include "VectorDrawable.h"
 #include "utils/TraceUtils.h"
 
@@ -158,7 +159,7 @@
 }
 
 bool SkiaPipeline::createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
-                                       bool wideColorGamut) {
+                                       bool wideColorGamut, ErrorHandler* errorHandler) {
     // compute the size of the surface (i.e. texture) to be allocated for this layer
     const int surfaceWidth = ceilf(node->getWidth() / float(LAYER_SIZE)) * LAYER_SIZE;
     const int surfaceHeight = ceilf(node->getHeight() / float(LAYER_SIZE)) * LAYER_SIZE;
@@ -182,6 +183,20 @@
             Matrix4 windowTransform;
             damageAccumulator.computeCurrentTransform(&windowTransform);
             node->getSkiaLayer()->inverseTransformInWindow = windowTransform;
+        } else {
+            String8 cachesOutput;
+            mRenderThread.cacheManager().dumpMemoryUsage(cachesOutput,
+                    &mRenderThread.renderState());
+            ALOGE("%s", cachesOutput.string());
+            if (errorHandler) {
+                std::ostringstream err;
+                err << "Unable to create layer for " << node->getName();
+                const int maxTextureSize = DeviceInfo::get()->maxTextureSize();
+                err << ", size " << info.width() << "x" << info.height() << " max size "
+                    << maxTextureSize << " color type " << (int)info.colorType()
+                    << " has context " << (int)(mRenderThread.getGrContext() != nullptr);
+                errorHandler->onError(err.str());
+            }
         }
         return true;
     }
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 3800194..38ad9c0 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -47,7 +47,7 @@
                       const BakedOpRenderer::LightInfo& lightInfo) override;
 
     bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
-                             bool wideColorGamut) override;
+                             bool wideColorGamut, ErrorHandler* errorHandler) override;
 
     void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
                      const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut,
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index d80a247..c2cc72a 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -49,6 +49,7 @@
 
 class AnimationContext;
 class DeferredLayerUpdater;
+class ErrorHandler;
 class Layer;
 class Rect;
 class RenderState;
@@ -74,8 +75,10 @@
      *
      *  @return true if the layer has been created or updated
      */
-    bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator) {
-        return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut);
+    bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator,
+                             ErrorHandler* errorHandler) {
+        return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut,
+                errorHandler);
     }
 
     /**
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 246ab26..b1de497 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -31,6 +31,7 @@
 namespace uirenderer {
 
 class DeferredLayerUpdater;
+class ErrorHandler;
 
 namespace renderthread {
 
@@ -68,7 +69,7 @@
                               const BakedOpRenderer::LightInfo& lightInfo) = 0;
     virtual TaskManager* getTaskManager() = 0;
     virtual bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
-                                     bool wideColorGamut) = 0;
+                                     bool wideColorGamut, ErrorHandler* errorHandler) = 0;
     virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0;
     virtual bool pinImages(LsaVector<sk_sp<Bitmap>>& images) = 0;
     virtual void unpinImages() = 0;
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index f3103fd..876af47 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -23,6 +23,7 @@
 #include "OpenGLReadback.h"
 #include "ProfileRenderer.h"
 #include "renderstate/RenderState.h"
+#include "TreeInfo.h"
 
 #include <cutils/properties.h>
 #include <strings.h>
@@ -202,7 +203,8 @@
 
 bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node,
                                          const DamageAccumulator& damageAccumulator,
-                                         bool wideColorGamut) {
+                                         bool wideColorGamut,
+                                         ErrorHandler* errorHandler) {
     RenderState& renderState = mRenderThread.renderState();
     OffscreenBufferPool& layerPool = renderState.layerPool();
     bool transformUpdateNeeded = false;
@@ -228,6 +230,22 @@
         node->getLayer()->setWindowTransform(windowTransform);
     }
 
+    if (!node->hasLayer()) {
+        Caches::getInstance().dumpMemoryUsage();
+        if (errorHandler) {
+            std::ostringstream err;
+            err << "Unable to create layer for " << node->getName();
+            const int maxTextureSize = Caches::getInstance().maxTextureSize;
+            if (node->getWidth() > maxTextureSize || node->getHeight() > maxTextureSize) {
+                err << ", size " << node->getWidth() << "x" << node->getHeight()
+                    << " exceeds max size " << maxTextureSize;
+            } else {
+                err << ", see logcat for more info";
+            }
+            errorHandler->onError(err.str());
+        }
+    }
+
     return transformUpdateNeeded;
 }
 
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index 118007c..9859e93 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -53,7 +53,7 @@
                       const BakedOpRenderer::LightInfo& lightInfo) override;
     TaskManager* getTaskManager() override;
     bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
-                             bool wideColorGamut) override;
+                             bool wideColorGamut, ErrorHandler* errorHandler) override;
     bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
     bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override;
     void unpinImages() override;