Increase performance for screenshots by pre-loading the buffer

When running with a threaded renderer the output buffer will now be
added to the cache when it is created to avoid any stalls putting
the buffer into an SkSurface.

Test: perfetto tracing and librenderengine_test
Bug: 181028875
Change-Id: Ie5f3f61b9cab2411a86841ca87010b3b78853690
diff --git a/libs/renderengine/skia/AutoBackendTexture.cpp b/libs/renderengine/skia/AutoBackendTexture.cpp
index c535597..ae3d88a 100644
--- a/libs/renderengine/skia/AutoBackendTexture.cpp
+++ b/libs/renderengine/skia/AutoBackendTexture.cpp
@@ -28,19 +28,19 @@
 namespace renderengine {
 namespace skia {
 
-AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer,
-                                       bool isRender) {
+AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer) {
     ATRACE_CALL();
     AHardwareBuffer_Desc desc;
     AHardwareBuffer_describe(buffer, &desc);
-    bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
+    const bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
+    const bool isRenderable = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER);
     GrBackendFormat backendFormat =
             GrAHardwareBufferUtils::GetBackendFormat(context, buffer, desc.format, false);
     mBackendTexture =
             GrAHardwareBufferUtils::MakeBackendTexture(context, buffer, desc.width, desc.height,
                                                        &mDeleteProc, &mUpdateProc, &mImageCtx,
                                                        createProtectedImage, backendFormat,
-                                                       isRender);
+                                                       isRenderable);
     mColorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format);
 }
 
diff --git a/libs/renderengine/skia/AutoBackendTexture.h b/libs/renderengine/skia/AutoBackendTexture.h
index bb75878..a6f73db 100644
--- a/libs/renderengine/skia/AutoBackendTexture.h
+++ b/libs/renderengine/skia/AutoBackendTexture.h
@@ -69,7 +69,7 @@
     };
 
     // Creates a GrBackendTexture whose contents come from the provided buffer.
-    AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isRender);
+    AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer);
 
     void ref() { mUsageCount++; }
 
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index c5ee15d..c7001b9 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -499,7 +499,7 @@
         std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
                 std::make_shared<AutoBackendTexture::LocalRef>();
         imageTextureRef->setTexture(
-                new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), false));
+                new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer()));
         cache.insert({buffer->getId(), imageTextureRef});
     }
     // restore the original state of the protected context if necessary
@@ -653,7 +653,7 @@
         ATRACE_NAME("Cache miss");
         surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
         surfaceTextureRef->setTexture(
-                new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), true));
+                new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer()));
         if (useFramebufferCache) {
             ALOGD("Adding to cache");
             cache.insert({buffer->getId(), surfaceTextureRef});
@@ -860,9 +860,8 @@
                 imageTextureRef = iter->second;
             } else {
                 imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
-                imageTextureRef->setTexture(new AutoBackendTexture(grContext.get(),
-                                                                   item.buffer->toAHardwareBuffer(),
-                                                                   false));
+                imageTextureRef->setTexture(
+                        new AutoBackendTexture(grContext.get(), item.buffer->toAHardwareBuffer()));
                 cache.insert({item.buffer->getId(), imageTextureRef});
             }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 31097aa..f690d12 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5907,8 +5907,11 @@
     const status_t bufferStatus = buffer->initCheck();
     LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d",
                         bufferStatus);
-    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
-                               false /* regionSampling */, grayscale, captureListener);
+    getRenderEngine().cacheExternalTextureBuffer(buffer);
+    status_t result = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
+                                          false /* regionSampling */, grayscale, captureListener);
+    getRenderEngine().unbindExternalTextureBuffer(buffer->getId());
+    return result;
 }
 
 status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
@@ -5948,15 +5951,6 @@
                                             regionSampling, grayscale, captureResults);
         });
 
-        // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine
-        // Only do this when we're not doing region sampling, to allow the region sampling thread to
-        // manage buffer lifecycle itself.
-        if (!regionSampling &&
-            getRenderEngine().getRenderEngineType() ==
-                    renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) {
-            getRenderEngine().unbindExternalTextureBuffer(buffer->getId());
-        }
-
         captureResults.result = result;
         captureListener->onScreenCaptureCompleted(captureResults);
     }));