summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2017-12-20 15:57:52 -0800
committerDan Stoza <stoza@google.com>2018-01-04 16:06:28 -0800
commit74a5e172c44f3b6b4b72706188cc0e33de4d8736 (patch)
tree3b3e24e295517d327d7a3da3fa13b6f30e95d0f1 /libs
parent3aa6c9820b3368f982959f59988fd4d8d9ef4947 (diff)
downloadnative-74a5e172c44f3b6b4b72706188cc0e33de4d8736.tar.gz
SF: Switch computeBounds to return FloatRect
Switches Layer::computeBounds to return a FloatRect instead of a Rect. During the computation of the bounds, we apply the layer transformation to its nominal dimensions, clip it against its bounds (which are either its parents bounds or the screen bounds), and apply the inverse of the layer transformation. Previously, the intermediate position (after transformation/clip, but before inverse transformation) was stored as Rect, which is to say that it was truncated to integer coordinates. After applying the inverse transformation, this loss of precision can cause glitches where a layer that should be clipped against, e.g., the side of the screen no longer creates a watertight seal against that side. In order to fix this, we now store the intermediate value as a FloatRect and propagate float precision back through computeBounds. The callers of computeBounds tend to then immediately apply the transform again, at which point it is safe to round back to integer. Bug: 64070729 Bug: 66431327 Bug: 69935057 Test: Modified android.view.cts.SurfaceViewSyncTest# testSurfaceViewBigScale no longer produces bogus display frames Change-Id: If5987ca4ad76657f9670a5f59258f896180352e2 (cherry picked from commit 80d611613ef1a9c05a31cd3f47badfd4de9b1418) Merged-In: If5987ca4ad76657f9670a5f59258f896180352e2
Diffstat (limited to 'libs')
-rw-r--r--libs/ui/include/ui/FloatRect.h11
-rw-r--r--libs/ui/include/ui/Rect.h9
2 files changed, 20 insertions, 0 deletions
diff --git a/libs/ui/include/ui/FloatRect.h b/libs/ui/include/ui/FloatRect.h
index 270675cba2..6a7479a68a 100644
--- a/libs/ui/include/ui/FloatRect.h
+++ b/libs/ui/include/ui/FloatRect.h
@@ -27,6 +27,17 @@ public:
float getWidth() const { return right - left; }
float getHeight() const { return bottom - top; }
+ FloatRect intersect(const FloatRect& other) const {
+ return {
+ // Inline to avoid tromping on other min/max defines or adding a
+ // dependency on STL
+ (left > other.left) ? left : other.left,
+ (top > other.top) ? top : other.top,
+ (right < other.right) ? right : other.right,
+ (bottom < other.bottom) ? bottom : other.bottom
+ };
+ }
+
float left = 0.0f;
float top = 0.0f;
float right = 0.0f;
diff --git a/libs/ui/include/ui/Rect.h b/libs/ui/include/ui/Rect.h
index b50e4ec656..c099a026aa 100644
--- a/libs/ui/include/ui/Rect.h
+++ b/libs/ui/include/ui/Rect.h
@@ -69,6 +69,15 @@ public:
bottom = rb.y;
}
+ inline explicit Rect(const FloatRect& floatRect) {
+ // Ideally we would use std::round, but we don't want to add an STL
+ // dependency here, so we use an approximation
+ left = static_cast<int32_t>(floatRect.left + 0.5f);
+ top = static_cast<int32_t>(floatRect.top + 0.5f);
+ right = static_cast<int32_t>(floatRect.right + 0.5f);
+ bottom = static_cast<int32_t>(floatRect.bottom + 0.5f);
+ }
+
void makeInvalid();
inline void clear() {