summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2013-05-10 18:01:12 -0700
committerMathias Agopian <mathias@google.com>2013-05-10 18:35:43 -0700
commitf3e85d432749ca77ad707bec523b67d741d43e6e (patch)
tree4955c1f1bb5c9600b2c276c26b82efac7ddc776a
parent6c7f25afb75ac155bad0b3bc17c0089d0337d060 (diff)
downloadframeworks_native-f3e85d432749ca77ad707bec523b67d741d43e6e.zip
frameworks_native-f3e85d432749ca77ad707bec523b67d741d43e6e.tar.gz
frameworks_native-f3e85d432749ca77ad707bec523b67d741d43e6e.tar.bz2
take the "transparent region" into account for blending
until now it was only used to discard a layer entirely. we're now reducing the size of the layer if it is still visible, if possible. this works for instance when a surfaceView is used and only the menu bar is displayed over it. Change-Id: I3f5527c5cd1e69ecc968272c8948f1513ada8c55
-rw-r--r--include/ui/Rect.h4
-rw-r--r--libs/ui/Rect.cpp31
-rw-r--r--services/surfaceflinger/Layer.cpp18
3 files changed, 50 insertions, 3 deletions
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index 9169287..6cf64eb 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -160,6 +160,10 @@ public:
// the input.
Rect transform(uint32_t xform, int32_t width, int32_t height) const;
+ // this calculates (Region(*this) - exclude).bounds() efficiently
+ Rect reduce(const Rect& exclude) const;
+
+
// for backward compatibility
inline int32_t width() const { return getWidth(); }
inline int32_t height() const { return getHeight(); }
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
index 365ea13..b480f3a 100644
--- a/libs/ui/Rect.cpp
+++ b/libs/ui/Rect.cpp
@@ -107,4 +107,35 @@ Rect Rect::transform(uint32_t xform, int32_t width, int32_t height) const {
return result;
}
+Rect Rect::reduce(const Rect& exclude) const {
+ Rect result;
+
+ uint32_t mask = 0;
+ mask |= (exclude.left > left) ? 1 : 0;
+ mask |= (exclude.top > top) ? 2 : 0;
+ mask |= (exclude.right < right) ? 4 : 0;
+ mask |= (exclude.bottom < bottom) ? 8 : 0;
+
+ if (mask == 0) {
+ // crop entirely covers us
+ result.clear();
+ } else {
+ result = *this;
+ if (!(mask & (mask - 1))) {
+ // power-of-2, i.e.: just one bit is set
+ if (mask & 1) {
+ result.right = exclude.left;
+ } else if (mask & 2) {
+ result.bottom = exclude.top;
+ } else if (mask & 4) {
+ result.left = exclude.right;
+ } else if (mask & 8) {
+ result.top = exclude.bottom;
+ }
+ }
+ }
+
+ return result;
+}
+
}; // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 07f9b8b..c15dfd5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -270,6 +270,16 @@ uint32_t Layer::getContentTransform() const {
return mCurrentTransform;
}
+static Rect reduce(const Rect& win, const Region& exclude) {
+ if (CC_LIKELY(exclude.isEmpty())) {
+ return win;
+ }
+ if (exclude.isRect()) {
+ return win.reduce(exclude.getBounds());
+ }
+ return Region(win).subtract(exclude).getBounds();
+}
+
Rect Layer::computeBounds() const {
const Layer::State& s(drawingState());
Rect win(s.active.w, s.active.h);
@@ -277,8 +287,7 @@ Rect Layer::computeBounds() const {
win.intersect(s.active.crop, &win);
}
// subtract the transparent region and snap to the bounds
- win = Region(win).subtract(s.activeTransparentRegion).getBounds();
- return win;
+ return reduce(win, s.activeTransparentRegion);
}
Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
@@ -312,6 +321,9 @@ Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
// window's bounds
activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
+ // subtract the transparent region and snap to the bounds
+ activeCrop = reduce(activeCrop, s.activeTransparentRegion);
+
if (!activeCrop.isEmpty()) {
// Transform the window crop to match the buffer coordinate system,
// which means using the inverse of the current transform set on the
@@ -669,7 +681,7 @@ void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh)
win.intersect(s.active.crop, &win);
}
// subtract the transparent region and snap to the bounds
- win = Region(win).subtract(s.activeTransparentRegion).getBounds();
+ win = reduce(win, s.activeTransparentRegion);
if (mesh) {
tr.transform(mesh->mVertices[0], win.left, win.top);
tr.transform(mesh->mVertices[1], win.left, win.bottom);