Merge "libgui: Fix handling of rotated surface damage" into mnc-dev

This commit is contained in:
Dan Stoza 2015-06-26 19:37:23 +00:00 committed by Android (Google) Code Review
commit f413de05cf
2 changed files with 52 additions and 18 deletions

View File

@ -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:
// the origin being in the bottom-left corner. Here we flip to the // 1) The surface damage was specified using the OpenGL ES convention of
// convention that the rest of the system uses (top-left corner) by // the origin being in the bottom-left corner. Here we flip to the
// subtracting all top/bottom coordinates from the buffer height. // convention that the rest of the system uses (top-left corner) by
// 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
flippedRegion.orSelf(flippedRect); 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);
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);

View File

@ -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);
layer.setSurfaceDamage(surfaceDamageRegion);
// Pass full-surface damage down untouched
if (surfaceDamageRegion.isRect() &&
surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
layer.setSurfaceDamage(surfaceDamageRegion);
} else {
layer.setSurfaceDamage(tr.transform(surfaceDamageRegion));
}
if (mSidebandStream.get()) { if (mSidebandStream.get()) {
layer.setSidebandStream(mSidebandStream); layer.setSidebandStream(mSidebandStream);