From 2ca79399b933935eb1b6c0ec1f746f8c4475369c Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 2 Apr 2013 18:30:32 -0700 Subject: [PATCH] latch transparent region hint only when we get a new frame since the transparent region hint really depends on the content of the window containing the SurfaceView (it's calculated by the view hierarchy based on overlapping views), it makes sense to latch it only when the content of the window (the app) changes. This should help fixing drawing artifacts when changing the layout of a window containing a SurfaceView. Bug: 8511430 Change-Id: Ic3aa668495293cb4d82a2cd7dcf3b6a337287678 --- include/ui/Region.h | 4 ++++ libs/ui/Region.cpp | 4 ++++ services/surfaceflinger/Layer.cpp | 17 +++++++++++++---- services/surfaceflinger/Layer.h | 6 +++++- services/surfaceflinger/SurfaceFlinger.cpp | 4 ++-- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/ui/Region.h b/include/ui/Region.h index ffcd429ae..ce91f3b69 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -108,6 +108,10 @@ public: inline Region& operator += (const Point& pt); + // returns true if the regions share the same underlying storage + bool isTriviallyEqual(const Region& region) const; + + /* various ways to access the rectangle list */ diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 488fba32c..bf01488ca 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -239,6 +239,10 @@ void Region::set(uint32_t w, uint32_t h) mStorage.add(Rect(w,h)); } +bool Region::isTriviallyEqual(const Region& region) const { + return begin() == region.begin(); +} + // ---------------------------------------------------------------------------- void Region::addRectUnchecked(int l, int t, int r, int b) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index a4c613cb8..2302367bb 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -881,8 +881,7 @@ bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { return true; } bool Layer::setTransparentRegionHint(const Region& transparent) { - mCurrentState.sequence++; - mCurrentState.transparentRegion = transparent; + mCurrentState.requestedTransparentRegion = transparent; setTransactionFlags(eTransactionNeeded); return true; } @@ -1008,7 +1007,6 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) swap(bufWidth, bufHeight); } - bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; if (front.active != front.requested) { @@ -1061,6 +1059,17 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) return true; } } + + // if the transparent region has changed (this test is + // conservative, but that's fine, worst case we're doing + // a bit of extra work), we latch the new one and we + // trigger a visible-region recompute. + if (!front.activeTransparentRegion.isTriviallyEqual( + front.requestedTransparentRegion)) { + front.activeTransparentRegion = front.requestedTransparentRegion; + recomputeVisibleRegions = true; + } + return false; } }; @@ -1168,7 +1177,7 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const getTypeId(), this, getName().string()); result.append(buffer); - s.transparentRegion.dump(result, "transparentRegion"); + s.activeTransparentRegion.dump(result, "transparentRegion"); visibleRegion.dump(result, "visibleRegion"); sp client(mClientRef.promote()); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 6bca9413a..2765db1be 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -103,7 +103,11 @@ public: uint8_t reserved[2]; int32_t sequence; // changes when visible regions can change Transform transform; - Region transparentRegion; + // the transparentRegion hint is a bit special, it's latched only + // when we receive a buffer -- this is because it's "content" + // dependent. + Region activeTransparentRegion; + Region requestedTransparentRegion; }; class LayerMesh { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3ed8b1b2e..5c7cf0758 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1360,14 +1360,14 @@ void SurfaceFlinger::computeVisibleRegions( if (tr.transformed()) { if (tr.preserveRects()) { // transform the transparent region - transparentRegion = tr.transform(s.transparentRegion); + transparentRegion = tr.transform(s.activeTransparentRegion); } else { // transformation too complex, can't do the // transparent region optimization. transparentRegion.clear(); } } else { - transparentRegion = s.transparentRegion; + transparentRegion = s.activeTransparentRegion; } }