Don't call hwc set() if there is nothing new to do

there was situations where SF's main loop would run (as if there was
an invalidate), but the dirty region was empty (so no new buffers
were retired). In this case we return early and don't swap, which
would cause drawing artifacts.

Bug: 5476838
Change-Id: Id3b7bf4b7aabec7919c50d9278eb2165973a4c3d
This commit is contained in:
Mathias Agopian 2011-10-18 17:36:28 -07:00
parent c492e67810
commit 3a3cad30c4

View File

@ -445,6 +445,11 @@ bool SurfaceFlinger::threadLoop()
// post surfaces (if needed) // post surfaces (if needed)
handlePageFlip(); handlePageFlip();
if (mDirtyRegion.isEmpty()) {
// nothing new to do.
return true;
}
if (UNLIKELY(mHwWorkListDirty)) { if (UNLIKELY(mHwWorkListDirty)) {
// build the h/w work list // build the h/w work list
handleWorkList(); handleWorkList();
@ -478,6 +483,9 @@ bool SurfaceFlinger::threadLoop()
void SurfaceFlinger::postFramebuffer() void SurfaceFlinger::postFramebuffer()
{ {
// this should never happen. we do the flip anyways so we don't
// risk to cause a deadlock with hwc
LOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty");
const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware());
const nsecs_t now = systemTime(); const nsecs_t now = systemTime();
mDebugInSwapBuffers = now; mDebugInSwapBuffers = now;
@ -938,7 +946,7 @@ void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
// data. // data.
// //
// Also we want to make sure to not clear areas that belong to // Also we want to make sure to not clear areas that belong to
// layers above that won't redraw (we would just erasing them), // layers above that won't redraw (we would just be erasing them),
// that is, we can't erase anything outside the dirty region. // that is, we can't erase anything outside the dirty region.
Region transparent; Region transparent;
@ -1769,7 +1777,7 @@ status_t SurfaceFlinger::onTransact(
void SurfaceFlinger::repaintEverything() { void SurfaceFlinger::repaintEverything() {
Mutex::Autolock _l(mStateLock); Mutex::Autolock _l(mStateLock);
const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware());
mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe mDirtyRegion.set(hw.bounds());
signalEvent(); signalEvent();
} }