* commit '488986f4ad7a92b04fdfd761ae07785019d2a9d3': libgui: Fix handling of rotated surface damage
This commit is contained in:
commit
c08e7cb7b1
@ -344,20 +344,61 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
|
|||||||
if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
|
if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
|
||||||
input.setSurfaceDamage(Region::INVALID_REGION);
|
input.setSurfaceDamage(Region::INVALID_REGION);
|
||||||
} else {
|
} else {
|
||||||
// The surface damage was specified using the OpenGL ES convention of
|
// Here we do two things:
|
||||||
|
// 1) The surface damage was specified using the OpenGL ES convention of
|
||||||
// the origin being in the bottom-left corner. Here we flip to the
|
// the origin being in the bottom-left corner. Here we flip to the
|
||||||
// convention that the rest of the system uses (top-left corner) by
|
// convention that the rest of the system uses (top-left corner) by
|
||||||
// subtracting all top/bottom coordinates from the buffer height.
|
// subtracting all top/bottom coordinates from the buffer height.
|
||||||
|
// 2) If the buffer is coming in rotated (for example, because the EGL
|
||||||
|
// implementation is reacting to the transform hint coming back from
|
||||||
|
// SurfaceFlinger), the surface damage needs to be rotated the
|
||||||
|
// opposite direction, since it was generated assuming an unrotated
|
||||||
|
// buffer (the app doesn't know that the EGL implementation is
|
||||||
|
// reacting to the transform hint behind its back). The
|
||||||
|
// transformations in the switch statement below apply those
|
||||||
|
// complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
|
||||||
|
|
||||||
|
int width = buffer->width;
|
||||||
int height = buffer->height;
|
int height = buffer->height;
|
||||||
if ((mTransform ^ mStickyTransform) & NATIVE_WINDOW_TRANSFORM_ROT_90) {
|
bool rotated90 = (mTransform ^ mStickyTransform) &
|
||||||
height = buffer->width;
|
NATIVE_WINDOW_TRANSFORM_ROT_90;
|
||||||
|
if (rotated90) {
|
||||||
|
std::swap(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Region flippedRegion;
|
Region flippedRegion;
|
||||||
for (auto rect : mDirtyRegion) {
|
for (auto rect : mDirtyRegion) {
|
||||||
auto top = height - rect.bottom;
|
int left = rect.left;
|
||||||
auto bottom = height - rect.top;
|
int right = rect.right;
|
||||||
Rect flippedRect{rect.left, top, rect.right, bottom};
|
int top = height - rect.bottom; // Flip from OpenGL convention
|
||||||
|
int bottom = height - rect.top; // Flip from OpenGL convention
|
||||||
|
switch (mTransform ^ mStickyTransform) {
|
||||||
|
case NATIVE_WINDOW_TRANSFORM_ROT_90: {
|
||||||
|
// Rotate 270 degrees
|
||||||
|
Rect flippedRect{top, width - right, bottom, width - left};
|
||||||
flippedRegion.orSelf(flippedRect);
|
flippedRegion.orSelf(flippedRect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NATIVE_WINDOW_TRANSFORM_ROT_180: {
|
||||||
|
// Rotate 180 degrees
|
||||||
|
Rect flippedRect{width - right, height - bottom,
|
||||||
|
width - left, height - top};
|
||||||
|
flippedRegion.orSelf(flippedRect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NATIVE_WINDOW_TRANSFORM_ROT_270: {
|
||||||
|
// Rotate 90 degrees
|
||||||
|
Rect flippedRect{height - bottom, left,
|
||||||
|
height - top, right};
|
||||||
|
flippedRegion.orSelf(flippedRect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
Rect flippedRect{left, top, right, bottom};
|
||||||
|
flippedRegion.orSelf(flippedRect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input.setSurfaceDamage(flippedRegion);
|
input.setSurfaceDamage(flippedRegion);
|
||||||
|
@ -551,14 +551,7 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
|
|||||||
const Transform& tr = hw->getTransform();
|
const Transform& tr = hw->getTransform();
|
||||||
Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
|
Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
|
||||||
layer.setVisibleRegionScreen(visible);
|
layer.setVisibleRegionScreen(visible);
|
||||||
|
|
||||||
// Pass full-surface damage down untouched
|
|
||||||
if (surfaceDamageRegion.isRect() &&
|
|
||||||
surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
|
|
||||||
layer.setSurfaceDamage(surfaceDamageRegion);
|
layer.setSurfaceDamage(surfaceDamageRegion);
|
||||||
} else {
|
|
||||||
layer.setSurfaceDamage(tr.transform(surfaceDamageRegion));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSidebandStream.get()) {
|
if (mSidebandStream.get()) {
|
||||||
layer.setSidebandStream(mSidebandStream);
|
layer.setSidebandStream(mSidebandStream);
|
||||||
|
Loading…
Reference in New Issue
Block a user