Clean up Renderengine caching semantics

* Add unbindExternalTextureBuffer, so that callers such as
BufferLayerConsumer can help manage the cache directly, which improves
system utilization.
* Remove the CacheHint, as it's no longer needed.
* Remove the backing image cache in BufferLayerConsumer, as it has not
been used. We still need a shadow array to properly callback into
RenderEngine, but we no longer need to store EGLImages here.

Bug: 123107664
Test: systrace
Test: open and close apps with GL composition forced, check for buffer
leakage through dumpsys
Change-Id: Ie48f99868dd46a4e18b5d659eea520e97a9eb300
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 5d0aa1e..8069a1a 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -626,22 +626,13 @@
 }
 
 status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
-                                                     sp<Fence> bufferFence, bool readCache) {
-    return bindExternalTextureBuffer(texName, buffer, bufferFence, readCache,
-                                     /*persistCache=*/false);
-}
-
-status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
-                                                     sp<Fence> bufferFence, bool readCache,
-                                                     bool persistCache) {
+                                                     sp<Fence> bufferFence) {
     ATRACE_CALL();
-    if (readCache) {
-        auto cachedImage = mImageCache.find(buffer->getId());
+    auto cachedImage = mImageCache.find(buffer->getId());
 
-        if (cachedImage != mImageCache.end()) {
-            bindExternalTextureImage(texName, *cachedImage->second);
-            return NO_ERROR;
-        }
+    if (cachedImage != mImageCache.end()) {
+        bindExternalTextureImage(texName, *cachedImage->second);
+        return NO_ERROR;
     }
 
     std::unique_ptr<Image> newImage = createImage();
@@ -678,35 +669,19 @@
             }
         }
     }
-
-    // We don't always want to persist to the cache, e.g. on older devices we
-    // might bind for synchronization purposes, but that might leak if we never
-    // call drawLayers again, so it's just better to recreate the image again
-    // if needed when we draw.
-    if (persistCache) {
-        mImageCache.insert(std::make_pair(buffer->getId(), std::move(newImage)));
-    }
+    mImageCache.insert(std::make_pair(buffer->getId(), std::move(newImage)));
 
     return NO_ERROR;
 }
 
-void GLESRenderEngine::evictImages(const std::vector<LayerSettings>& layers) {
-    ATRACE_CALL();
-    // destroy old image references that we're not going to draw with.
-    std::unordered_set<uint64_t> bufIds;
-    for (auto layer : layers) {
-        if (layer.source.buffer.buffer != nullptr) {
-            bufIds.emplace(layer.source.buffer.buffer->getId());
-        }
+void GLESRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
+    const auto& cachedImage = mImageCache.find(bufferId);
+    if (cachedImage != mImageCache.end()) {
+        ALOGV("Destroying image for buffer: %" PRIu64, bufferId);
+        mImageCache.erase(bufferId);
+        return;
     }
-
-    for (auto it = mImageCache.begin(); it != mImageCache.end();) {
-        if (bufIds.count(it->first) == 0) {
-            it = mImageCache.erase(it);
-        } else {
-            it++;
-        }
-    }
+    ALOGV("Failed to find image for buffer: %" PRIu64, bufferId);
 }
 
 FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) {
@@ -844,8 +819,6 @@
         return fbo.getStatus();
     }
 
-    evictImages(layers);
-
     // clear the entire buffer, sometimes when we reuse buffers we'd persist
     // ghost images otherwise.
     // we also require a full transparent framebuffer for overlays. This is
@@ -888,10 +861,8 @@
             isOpaque = layer.source.buffer.isOpaque;
 
             sp<GraphicBuffer> gBuf = layer.source.buffer.buffer;
-
-            bool readCache = layer.source.buffer.cacheHint == Buffer::CachingHint::USE_CACHE;
             bindExternalTextureBuffer(layer.source.buffer.textureName, gBuf,
-                                      layer.source.buffer.fence, readCache, /*persistCache=*/true);
+                                      layer.source.buffer.fence);
 
             usePremultipliedAlpha = layer.source.buffer.usePremultipliedAlpha;
             Texture texture(Texture::TEXTURE_EXTERNAL, layer.source.buffer.textureName);
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index e37c91d..728882a 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -74,8 +74,8 @@
     void genTextures(size_t count, uint32_t* names) override;
     void deleteTextures(size_t count, uint32_t const* names) override;
     void bindExternalTextureImage(uint32_t texName, const Image& image) override;
-    status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence,
-                                       bool readCache);
+    status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence);
+    void unbindExternalTextureBuffer(uint64_t bufferId);
     status_t bindFrameBuffer(Framebuffer* framebuffer) override;
     void unbindFrameBuffer(Framebuffer* framebuffer) override;
     void checkErrors() const override;
@@ -143,8 +143,6 @@
     // Defines the viewport, and sets the projection matrix to the projection
     // defined by the clip.
     void setViewportAndProjection(Rect viewport, Rect clip);
-    status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence,
-                                       bool readCache, bool persistCache);
     // Evicts stale images from the buffer cache.
     void evictImages(const std::vector<LayerSettings>& layers);
     // Computes the cropping window for the layer and sets up cropping
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index aa45ed8..b8bf801 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -32,16 +32,6 @@
 
 // Metadata describing the input buffer to render from.
 struct Buffer {
-    // Hint for whether to use the Image cache or not.
-    // If NO_CACHE is specified, then upload the contents of the GraphicBuffer
-    // to the GPU, without checking against any implementation defined cache.
-    // If USE_CACHE is specified, then check against an implementation defined
-    // cache first. If there is an Image cached for the given GraphicBuffer id,
-    // then use that instead of the provided buffer contents. If there is no
-    // cached image or the RenderEngine implementation does not support caching,
-    // then use the GraphicBuffer contents.
-    enum class CachingHint { NO_CACHE, USE_CACHE };
-
     // Buffer containing the image that we will render.
     // If buffer == nullptr, then the rest of the fields in this struct will be
     // ignored.
@@ -50,9 +40,6 @@
     // Fence that will fire when the buffer is ready to be bound.
     sp<Fence> fence = nullptr;
 
-    // Caching hint to use when uploading buffer contents.
-    CachingHint cacheHint = CachingHint::NO_CACHE;
-
     // Texture identifier to bind the external texture to.
     // TODO(alecmouri): This is GL-specific...make the type backend-agnostic.
     uint32_t textureName = 0;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 2a2b48f..ab34274 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -110,7 +110,11 @@
     virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
     virtual void bindExternalTextureImage(uint32_t texName, const Image& image) = 0;
     virtual status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
-                                               sp<Fence> fence, bool cleanCache) = 0;
+                                               sp<Fence> fence) = 0;
+    // Removes internal resources referenced by the bufferId. This method should be
+    // invoked when the caller will no longer hold a reference to a GraphicBuffer
+    // and needs to clean up its resources.
+    virtual void unbindExternalTextureBuffer(uint64_t bufferId) = 0;
     // When binding a native buffer, it must be done before setViewportAndProjection
     // Returns NO_ERROR when binds successfully, NO_MEMORY when there's no memory for allocation.
     virtual status_t bindFrameBuffer(Framebuffer* framebuffer) = 0;
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 5956c46..ddf7420 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -53,7 +53,8 @@
     MOCK_METHOD2(genTextures, void(size_t, uint32_t*));
     MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*));
     MOCK_METHOD2(bindExternalTextureImage, void(uint32_t, const renderengine::Image&));
-    MOCK_METHOD4(bindExternalTextureBuffer, status_t(uint32_t, sp<GraphicBuffer>, sp<Fence>, bool));
+    MOCK_METHOD3(bindExternalTextureBuffer, status_t(uint32_t, sp<GraphicBuffer>, sp<Fence>));
+    MOCK_METHOD1(unbindExternalTextureBuffer, void(uint64_t));
     MOCK_CONST_METHOD0(checkErrors, void());
     MOCK_METHOD4(setViewportAndProjection,
                  void(size_t, size_t, Rect, ui::Transform::orientation_flags));