[RenderEngine] Add cache contents to dumpsys

We've had some high EGL utilization attributed to SurfaceFlinger
recently, so adding info to dumpsys to hopefully catch a leak.

Bug: 137514000
Test: dumpsys
Change-Id: I38ccebda5db9847c6c526d4df5a97bc6394325a9
Merged-In: I22cf9eb01162d341c44dbe1440f74865dbf960fb
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 46a8e9e..2129a52 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -842,6 +842,7 @@
                                                              bool useFramebufferCache) {
     sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(nativeBuffer);
     if (useFramebufferCache) {
+        std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex);
         for (const auto& image : mFramebufferImageCache) {
             if (image.first == graphicBuffer->getId()) {
                 return image.second;
@@ -857,6 +858,7 @@
                                           nativeBuffer, attributes);
     if (useFramebufferCache) {
         if (image != EGL_NO_IMAGE_KHR) {
+            std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex);
             if (mFramebufferImageCache.size() >= mFramebufferImageCacheSize) {
                 EGLImageKHR expired = mFramebufferImageCache.front().second;
                 mFramebufferImageCache.pop_front();
@@ -1306,6 +1308,23 @@
     StringAppendF(&result, "RenderEngine last dataspace conversion: (%s) to (%s)\n",
                   dataspaceDetails(static_cast<android_dataspace>(mDataSpace)).c_str(),
                   dataspaceDetails(static_cast<android_dataspace>(mOutputDataSpace)).c_str());
+    {
+        std::lock_guard<std::mutex> lock(mRenderingMutex);
+        StringAppendF(&result, "RenderEngine image cache size: %zu\n", mImageCache.size());
+        StringAppendF(&result, "Dumping buffer ids...\n");
+        for (const auto& [id, unused] : mImageCache) {
+            StringAppendF(&result, "0x%" PRIx64 "\n", id);
+        }
+    }
+    {
+        std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex);
+        StringAppendF(&result, "RenderEngine framebuffer image cache size: %zu\n",
+                      mFramebufferImageCache.size());
+        StringAppendF(&result, "Dumping buffer ids...\n");
+        for (const auto& [id, unused] : mFramebufferImageCache) {
+            StringAppendF(&result, "0x%" PRIx64 "\n", id);
+        }
+    }
 }
 
 GLESRenderEngine::GlesVersion GLESRenderEngine::parseGlesVersion(const char* str) {
@@ -1432,7 +1451,7 @@
 }
 
 bool GLESRenderEngine::isFramebufferImageCachedForTesting(uint64_t bufferId) {
-    std::lock_guard<std::mutex> lock(mRenderingMutex);
+    std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex);
     return std::any_of(mFramebufferImageCache.cbegin(), mFramebufferImageCache.cend(),
                        [=](std::pair<uint64_t, EGLImageKHR> image) {
                            return image.first == bufferId;
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index de793c2..acc0c71 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -93,17 +93,20 @@
     EGLConfig getEGLConfig() const { return mEGLConfig; }
     // Creates an output image for rendering to
     EGLImageKHR createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer, bool isProtected,
-                                               bool useFramebufferCache);
+                                               bool useFramebufferCache)
+            EXCLUDES(mFramebufferImageCacheMutex);
 
     // Test-only methods
     // Returns true iff mImageCache contains an image keyed by bufferId
     bool isImageCachedForTesting(uint64_t bufferId) EXCLUDES(mRenderingMutex);
     // Returns true iff mFramebufferImageCache contains an image keyed by bufferId
-    bool isFramebufferImageCachedForTesting(uint64_t bufferId) EXCLUDES(mRenderingMutex);
+    bool isFramebufferImageCachedForTesting(uint64_t bufferId)
+            EXCLUDES(mFramebufferImageCacheMutex);
 
 protected:
     Framebuffer* getFramebufferForDrawing() override;
-    void dump(std::string& result) override;
+    void dump(std::string& result) override EXCLUDES(mRenderingMutex)
+            EXCLUDES(mFramebufferImageCacheMutex);
     void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
                                   ui::Transform::orientation_flags rotation) override;
     void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
@@ -200,7 +203,11 @@
     uint32_t mFramebufferImageCacheSize = 0;
 
     // Cache of output images, keyed by corresponding GraphicBuffer ID.
-    std::deque<std::pair<uint64_t, EGLImageKHR>> mFramebufferImageCache;
+    std::deque<std::pair<uint64_t, EGLImageKHR>> mFramebufferImageCache
+            GUARDED_BY(mFramebufferImageCacheMutex);
+    // The only reason why we have this mutex is so that we don't segfault when
+    // dumping info.
+    std::mutex mFramebufferImageCacheMutex;
 
     // Current dataspace of layer being rendered
     ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN;