Fix crash when EGLSurface is no longer valid.
The EGLSurface stored in the pipeline can become obsolete if the
EglManager/RenderThread has to destroy the context. This CL enables the
RenderThread to notify all active pipelines that their surface is invalid.
Bug: 115290937
Test: hwui_unit_tests
Change-Id: Ib3054822273bc35406630b7442229a81b39a2c91
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index b524bcb..b595ab8 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -41,8 +41,15 @@
GpuMemoryTracker::onGpuContextCreated();
}
+static void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) {
+ layerUpdater->destroyLayer();
+}
+
void RenderState::onContextDestroyed() {
- destroyLayersInUpdater();
+ std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater);
+ for(auto callback : mContextCallbacks) {
+ callback->onContextDestroyed();
+ }
GpuMemoryTracker::onGpuContextDestroyed();
}
@@ -91,14 +98,6 @@
// DEAD CODE
}
-static void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) {
- layerUpdater->destroyLayer();
-}
-
-void RenderState::destroyLayersInUpdater() {
- std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater);
-}
-
void RenderState::postDecStrong(VirtualLightRefBase* object) {
if (pthread_equal(mThreadId, pthread_self())) {
object->decStrong(nullptr);
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index f39aa4b..dee02e9 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -41,6 +41,13 @@
class RenderThread;
}
+class IGpuContextCallback {
+public:
+ virtual void onContextDestroyed() = 0;
+protected:
+ virtual ~IGpuContextCallback() {}
+};
+
// wrapper of Caches for users to migrate to.
class RenderState {
PREVENT_COPY_AND_ASSIGN(RenderState);
@@ -48,9 +55,6 @@
friend class renderthread::CacheManager;
public:
- void onContextCreated();
- void onContextDestroyed();
-
void onBitmapDestroyed(uint32_t pixelRefId);
void setViewport(GLsizei width, GLsizei height);
@@ -63,6 +67,9 @@
void debugOverdraw(bool enable, bool clear);
+ void registerContextCallback(IGpuContextCallback* cb) { mContextCallbacks.insert(cb); }
+ void removeContextCallback(IGpuContextCallback* cb) { mContextCallbacks.erase(cb); }
+
void registerLayer(Layer* layer) { mActiveLayers.insert(layer); }
void unregisterLayer(Layer* layer) { mActiveLayers.erase(layer); }
@@ -93,13 +100,16 @@
renderthread::RenderThread& getRenderThread();
private:
- void destroyLayersInUpdater();
-
explicit RenderState(renderthread::RenderThread& thread);
~RenderState();
+ // Context notifications are only to be triggered by renderthread::RenderThread
+ void onContextCreated();
+ void onContextDestroyed();
+
renderthread::RenderThread& mRenderThread;
+ std::set<IGpuContextCallback*> mContextCallbacks;
std::set<Layer*> mActiveLayers;
std::set<DeferredLayerUpdater*> mActiveLayerUpdaters;
std::set<renderthread::CanvasContext*> mRegisteredContexts;