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
This commit is contained in:
parent
6c7f25afb7
commit
f3e85d4327
@ -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(); }
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user