diff options
| -rw-r--r-- | libs/renderengine/gl/GLESRenderEngine.cpp | 22 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLESRenderEngine.h | 1 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/RenderEngine.h | 1 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/mock/RenderEngine.h | 1 | ||||
| -rw-r--r-- | libs/renderengine/threaded/RenderEngineThreaded.cpp | 15 | ||||
| -rw-r--r-- | libs/renderengine/threaded/RenderEngineThreaded.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 1 |
7 files changed, 37 insertions, 6 deletions
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp index 3090d193d1..42e74df901 100644 --- a/libs/renderengine/gl/GLESRenderEngine.cpp +++ b/libs/renderengine/gl/GLESRenderEngine.cpp @@ -451,15 +451,10 @@ GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisp GLESRenderEngine::~GLESRenderEngine() { // Destroy the image manager first. mImageManager = nullptr; + cleanFramebufferCache(); std::lock_guard<std::mutex> lock(mRenderingMutex); unbindFrameBuffer(mDrawingBuffer.get()); mDrawingBuffer = nullptr; - while (!mFramebufferImageCache.empty()) { - EGLImageKHR expired = mFramebufferImageCache.front().second; - mFramebufferImageCache.pop_front(); - eglDestroyImageKHR(mEGLDisplay, expired); - DEBUG_EGL_IMAGE_TRACKER_DESTROY(); - } eglDestroyImageKHR(mEGLDisplay, mPlaceholderImage); mImageCache.clear(); eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -965,6 +960,7 @@ bool GLESRenderEngine::cleanupPostRender(CleanupMode mode) { // Bind the texture to placeholder so that backing image data can be freed. GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(getFramebufferForDrawing()); glFramebuffer->allocateBuffers(1, 1, mPlaceholderDrawBuffer); + // Release the cached fence here, so that we don't churn reallocations when // we could no-op repeated calls of this method instead. mLastDrawFence = nullptr; @@ -972,6 +968,20 @@ bool GLESRenderEngine::cleanupPostRender(CleanupMode mode) { return true; } +void GLESRenderEngine::cleanFramebufferCache() { + std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex); + // Bind the texture to placeholder so that backing image data can be freed. + GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(getFramebufferForDrawing()); + glFramebuffer->allocateBuffers(1, 1, mPlaceholderDrawBuffer); + + while (!mFramebufferImageCache.empty()) { + EGLImageKHR expired = mFramebufferImageCache.front().second; + mFramebufferImageCache.pop_front(); + eglDestroyImageKHR(mEGLDisplay, expired); + DEBUG_EGL_IMAGE_TRACKER_DESTROY(); + } +} + void GLESRenderEngine::checkErrors() const { checkErrors(nullptr); } diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h index 2a98bd88a6..8f0df2c32a 100644 --- a/libs/renderengine/gl/GLESRenderEngine.h +++ b/libs/renderengine/gl/GLESRenderEngine.h @@ -135,6 +135,7 @@ private: status_t bindFrameBuffer(Framebuffer* framebuffer); void unbindFrameBuffer(Framebuffer* framebuffer); void bindExternalTextureImage(uint32_t texName, const Image& image); + void cleanFramebufferCache() EXCLUDES(mFramebufferImageCacheMutex) override; // A data space is considered HDR data space if it has BT2020 color space // with PQ or HLG transfer function. diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h index 6db2af8612..a0e7ab7a43 100644 --- a/libs/renderengine/include/renderengine/RenderEngine.h +++ b/libs/renderengine/include/renderengine/RenderEngine.h @@ -178,6 +178,7 @@ public: const std::vector<const LayerSettings*>& layers, const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0; + virtual void cleanFramebufferCache() = 0; protected: friend class threaded::RenderEngineThreaded; diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h index 3fd125ec74..0b80d885b8 100644 --- a/libs/renderengine/include/renderengine/mock/RenderEngine.h +++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h @@ -60,6 +60,7 @@ public: status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&, const sp<GraphicBuffer>&, const bool, base::unique_fd&&, base::unique_fd*)); + MOCK_METHOD0(cleanFramebufferCache, void()); }; } // namespace mock diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp index dc47070460..9b79943235 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.cpp +++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp @@ -322,6 +322,21 @@ status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display, return resultFuture.get(); } +void RenderEngineThreaded::cleanFramebufferCache() { + std::promise<void> resultPromise; + std::future<void> resultFuture = resultPromise.get_future(); + { + std::lock_guard lock(mThreadMutex); + mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) { + ATRACE_NAME("REThreaded::cleanFramebufferCache"); + instance.cleanFramebufferCache(); + resultPromise.set_value(); + }); + } + mCondition.notify_one(); + resultFuture.wait(); +} + } // namespace threaded } // namespace renderengine } // namespace android diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h index 96a49b3a0b..b02cdd9e46 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.h +++ b/libs/renderengine/threaded/RenderEngineThreaded.h @@ -65,6 +65,8 @@ public: const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) override; + void cleanFramebufferCache() override; + private: void threadMain(CreateInstanceFactory factory); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 6478497b8f..9d35a3fca6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2684,6 +2684,7 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, const sp<IBinder> drawingBinder = IInterface::asBinder(drawingState.surface); if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) { // changing the surface is like destroying and recreating the DisplayDevice + getRenderEngine().cleanFramebufferCache(); if (const auto display = getDisplayDeviceLocked(displayToken)) { display->disconnect(); } |