From c62acbd12711ee6cff1ef94c146316dfe5169045 Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Tue, 21 Apr 2015 16:42:49 -0700 Subject: [PATCH] libgui: Fix CPU rendering on Surface When the surface damage code went in, it incorrectly assumed that if an application was doing CPU rendering, it would be using lock and unlockAndPost instead of dequeue and queue, so it repurposed the dirty region too aggressively. This change keeps it from clobbering the dirty region if a CPU producer is attached. Bug: 20431815 Change-Id: Id4dfd71378311ea822f0289f6de2d20a7bd84014 --- include/gui/Surface.h | 10 +++++----- libs/gui/Surface.cpp | 10 ++++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 8217652c3..a9f78cf02 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -298,12 +298,12 @@ private: sp mPostedBuffer; bool mConnectedToCpu; - // In the lock/unlock context, this reflects the region that the producer - // wished to update and whether the Surface was able to copy the previous - // buffer back to allow a partial update. + // When a CPU producer is attached, this reflects the region that the + // producer wished to update as well as whether the Surface was able to copy + // the previous buffer back to allow a partial update. // - // In the dequeue/queue context, this reflects the surface damage (the - // damage since the last frame) passed in by the producer. + // When a non-CPU producer is attached, this reflects the surface damage + // (the change since the previous frame) passed in by the producer. Region mDirtyRegion; }; diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 245f7a374..b8acad2a8 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -322,7 +322,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero, fence, mStickyTransform); - if (mDirtyRegion.bounds() == Rect::INVALID_RECT) { + if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) { input.setSurfaceDamage(Region::INVALID_REGION); } else { // The surface damage was specified using the OpenGL ES convention of @@ -356,8 +356,10 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mConsumerRunningBehind = (numPendingBuffers >= 2); - // Clear surface damage back to full-buffer - mDirtyRegion = Region::INVALID_REGION; + if (!mConnectedToCpu) { + // Clear surface damage back to full-buffer + mDirtyRegion = Region::INVALID_REGION; + } return err; } @@ -844,7 +846,7 @@ void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { ALOGV("Surface::setSurfaceDamage"); Mutex::Autolock lock(mMutex); - if (numRects == 0) { + if (mConnectedToCpu || numRects == 0) { mDirtyRegion = Region::INVALID_REGION; return; }