Add locking within RenderEngine during rendering
Multiple threads are allowed to access RenderEngine, which poses several
issues:
1. The image cache needs to be synchronized
2. It's theoretically possible for a thread other than the SF
main-thread to call drawLayers, which can cause undesirable behavior.
Bug: 128306587
Test: manual tests
Change-Id: Ic18b71924aa3c4d72f02f95ebf928257fb9e50ed
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 728882a..dcf5acc 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -74,8 +74,9 @@
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);
- void unbindExternalTextureBuffer(uint64_t bufferId);
+ status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence)
+ EXCLUDES(mRenderingMutex);
+ void unbindExternalTextureBuffer(uint64_t bufferId) EXCLUDES(mRenderingMutex);
status_t bindFrameBuffer(Framebuffer* framebuffer) override;
void unbindFrameBuffer(Framebuffer* framebuffer) override;
void checkErrors() const override;
@@ -85,7 +86,7 @@
bool useProtectedContext(bool useProtectedContext) override;
status_t drawLayers(const DisplaySettings& display, const std::vector<LayerSettings>& layers,
ANativeWindowBuffer* buffer, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
+ base::unique_fd* drawFence) EXCLUDES(mRenderingMutex) override;
// internal to RenderEngine
EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
@@ -197,10 +198,17 @@
const bool mUseColorManagement = false;
// Cache of GL images that we'll store per GraphicBuffer ID
- // TODO: Layer should call back on destruction instead to clean this up,
- // as it has better system utilization at the potential expense of a
- // more complicated interface.
- std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache;
+ std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache GUARDED_BY(mRenderingMutex);
+ // Mutex guarding rendering operations, so that:
+ // 1. GL operations aren't interleaved, and
+ // 2. Internal state related to rendering that is potentially modified by
+ // multiple threads is guaranteed thread-safe.
+ std::mutex mRenderingMutex;
+
+ // See bindExternalTextureBuffer above, but requiring that mRenderingMutex
+ // is held.
+ status_t bindExternalTextureBufferLocked(uint32_t texName, sp<GraphicBuffer> buffer,
+ sp<Fence> fence) REQUIRES(mRenderingMutex);
std::unique_ptr<Framebuffer> mDrawingBuffer;