mDirtyRegion is single threaded, but could be accessed from a hwc thread
We now have mInvalidateRegion which holds the region to invalidate, it
can be set from any thread as long as mInvalidateLock is held. We use
fine-grained locking here because mInvalidateRegion can be set from anywhere,
in particular frmo HWC callbacks.
Bug: 5466774
Change-Id: Iafca20aa3f5b25a87755e65bde7b769aa8f997bc
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4b2866c..ba8f630 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -788,6 +788,8 @@
}
unlockPageFlip(currentLayers);
+
+ mDirtyRegion.orSelf(getAndClearInvalidateRegion());
mDirtyRegion.andSelf(screenRegion);
}
@@ -1798,12 +1800,24 @@
}
void SurfaceFlinger::repaintEverything() {
- Mutex::Autolock _l(mStateLock);
const DisplayHardware& hw(graphicPlane(0).displayHardware());
- mDirtyRegion.set(hw.bounds());
+ const Rect bounds(hw.getBounds());
+ setInvalidateRegion(Region(bounds));
signalEvent();
}
+void SurfaceFlinger::setInvalidateRegion(const Region& reg) {
+ Mutex::Autolock _l(mInvalidateLock);
+ mInvalidateRegion = reg;
+}
+
+Region SurfaceFlinger::getAndClearInvalidateRegion() {
+ Mutex::Autolock _l(mInvalidateLock);
+ Region reg(mInvalidateRegion);
+ mInvalidateRegion.clear();
+ return reg;
+}
+
// ---------------------------------------------------------------------------
status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3c8f4e5..3284fdb 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -308,6 +308,9 @@
void composeSurfaces(const Region& dirty);
+ void setInvalidateRegion(const Region& reg);
+ Region getAndClearInvalidateRegion();
+
ssize_t addClientLayer(const sp<Client>& client,
const sp<LayerBaseClient>& lbc);
status_t addLayer_l(const sp<LayerBase>& layer);
@@ -367,6 +370,10 @@
bool mLayersRemoved;
DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayerMap;
+ // access must be protected by mInvalidateLock
+ mutable Mutex mInvalidateLock;
+ Region mInvalidateRegion;
+
// constant members (no synchronization needed for access)
sp<IMemoryHeap> mServerHeap;
surface_flinger_cblk_t* mServerCblk;