fix [2420565] Surface.lockCanvas() updates the dirty region too often
There was a bug where we were we could be reallocating buffers for no reason.
Change-Id: Ieb8a81a289da9339ab7faf987cd3a73428943c1a
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 5dd75c3..3c7a4d2 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -495,9 +495,12 @@
// below we make sure we AT LEAST have the usage flags we want
const uint32_t usage(getUsage());
const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
+
+ // Always call needNewBuffer(), since it clears the needed buffers flags
+ bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
if (backBuffer == 0 ||
((uint32_t(backBuffer->usage) & usage) != usage) ||
- mSharedBufferClient->needNewBuffer(bufIdx))
+ needNewBuffer)
{
err = getBufferLocked(bufIdx, usage);
LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)",
@@ -717,25 +720,25 @@
Region scratch(bounds);
Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
+ const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
if (mNeedFullUpdate) {
- // reset newDirtyRegion to bounds when a buffer is reallocated
- // it would be better if this information was associated with
- // the buffer and made available to outside of Surface.
- // This will do for now though.
mNeedFullUpdate = false;
- newDirtyRegion.set(bounds);
- } else {
- newDirtyRegion.andSelf(bounds);
+ Region uninitialized(bounds);
+ uninitialized.subtractSelf(copyback | newDirtyRegion);
+ // reset newDirtyRegion to bounds when a buffer is reallocated
+ // and we have nothing to copy back to it
+ if (!uninitialized.isEmpty())
+ newDirtyRegion.set(bounds);
}
+ newDirtyRegion.andSelf(bounds);
const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
- if (frontBuffer !=0 &&
+ if (frontBuffer != 0 &&
backBuffer->width == frontBuffer->width &&
backBuffer->height == frontBuffer->height &&
!(mFlags & ISurfaceComposer::eDestroyBackbuffer))
{
- const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
- if (!copyback.isEmpty() && frontBuffer!=0) {
+ if (!copyback.isEmpty()) {
// copy front to back
copyBlt(backBuffer, frontBuffer, copyback);
}