summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/renderengine/gl/GLESRenderEngine.cpp22
-rw-r--r--libs/renderengine/gl/GLESRenderEngine.h1
-rw-r--r--libs/renderengine/include/renderengine/RenderEngine.h1
-rw-r--r--libs/renderengine/include/renderengine/mock/RenderEngine.h1
-rw-r--r--libs/renderengine/threaded/RenderEngineThreaded.cpp15
-rw-r--r--libs/renderengine/threaded/RenderEngineThreaded.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp1
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();
}