Merge "lshal: debug checks fqname"
diff --git a/libs/math/tests/mat_test.cpp b/libs/math/tests/mat_test.cpp
index 3217a1a..a14c7ea 100644
--- a/libs/math/tests/mat_test.cpp
+++ b/libs/math/tests/mat_test.cpp
@@ -35,7 +35,7 @@
 
 TEST_F(MatTest, Basics) {
     mat4 m0;
-    EXPECT_EQ(sizeof(mat4), sizeof(float)*16);
+    EXPECT_EQ(sizeof(m0), sizeof(float)*16);
 }
 
 TEST_F(MatTest, ComparisonOps) {
@@ -76,6 +76,7 @@
     EXPECT_EQ(m3, m1);
 
     mat4 m4(vec4(1), vec4(2), vec4(3), vec4(4));
+    EXPECT_NE(m4, m1);
 }
 
 TEST_F(MatTest, ArithmeticOps) {
@@ -172,7 +173,7 @@
 
 TEST_F(Mat3Test, Basics) {
     mat3 m0;
-    EXPECT_EQ(sizeof(mat3), sizeof(float)*9);
+    EXPECT_EQ(sizeof(m0), sizeof(float)*9);
 }
 
 TEST_F(Mat3Test, ComparisonOps) {
@@ -279,7 +280,7 @@
 
 TEST_F(Mat2Test, Basics) {
     mat2 m0;
-    EXPECT_EQ(sizeof(mat2), sizeof(float)*4);
+    EXPECT_EQ(sizeof(m0), sizeof(float)*4);
 }
 
 TEST_F(Mat2Test, ComparisonOps) {
diff --git a/libs/ui/include/ui/FloatRect.h b/libs/ui/include/ui/FloatRect.h
index 270675c..6a7479a 100644
--- a/libs/ui/include/ui/FloatRect.h
+++ b/libs/ui/include/ui/FloatRect.h
@@ -27,6 +27,17 @@
     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 b50e4ec..c099a02 100644
--- a/libs/ui/include/ui/Rect.h
+++ b/libs/ui/include/ui/Rect.h
@@ -69,6 +69,15 @@
         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() {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 70c702b..97c56b3 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -447,6 +447,14 @@
     return Region(win).subtract(exclude).getBounds();
 }
 
+static FloatRect reduce(const FloatRect& win, const Region& exclude) {
+    if (CC_LIKELY(exclude.isEmpty())) {
+        return win;
+    }
+    // Convert through Rect (by rounding) for lack of FloatRegion
+    return Region(Rect{win}).subtract(exclude).getBounds().toFloatRect();
+}
+
 Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
     const Layer::State& s(getDrawingState());
     Rect win(s.active.w, s.active.h);
@@ -485,12 +493,12 @@
     return win;
 }
 
-Rect Layer::computeBounds() const {
+FloatRect Layer::computeBounds() const {
     const Layer::State& s(getDrawingState());
     return computeBounds(s.activeTransparentRegion);
 }
 
-Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
+FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
     const Layer::State& s(getDrawingState());
     Rect win(s.active.w, s.active.h);
 
@@ -507,14 +515,16 @@
     }
 
     Transform t = getTransform();
+
+    FloatRect floatWin = win.toFloatRect();
     if (p != nullptr) {
-        win = t.transform(win);
-        win.intersect(bounds, &win);
-        win = t.inverse().transform(win);
+        floatWin = t.transform(floatWin);
+        floatWin = floatWin.intersect(bounds.toFloatRect());
+        floatWin = t.inverse().transform(floatWin);
     }
 
     // subtract the transparent region and snap to the bounds
-    return reduce(win, activeTransparentRegion);
+    return reduce(floatWin, activeTransparentRegion);
 }
 
 Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& hw) const {
@@ -723,7 +733,9 @@
                 s.active.w, activeCrop.bottom));
     }
 
-    Rect frame(t.transform(computeBounds(activeTransparentRegion)));
+    // computeBounds returns a FloatRect to provide more accuracy during the
+    // transformation. We then round upon constructing 'frame'.
+    Rect frame{t.transform(computeBounds(activeTransparentRegion))};
     if (!s.finalCrop.isEmpty()) {
         if(!frame.intersect(s.finalCrop, &frame)) {
             frame.clear();
@@ -1225,16 +1237,17 @@
      * minimal value)? Or, we could make GL behave like HWC -- but this feel
      * like more of a hack.
      */
-    Rect win(computeBounds());
+    const Rect bounds{computeBounds()}; // Rounds from FloatRect
 
     Transform t = getTransform();
+    Rect win = bounds;
     if (!s.finalCrop.isEmpty()) {
         win = t.transform(win);
         if (!win.intersect(s.finalCrop, &win)) {
             win.clear();
         }
         win = t.inverse().transform(win);
-        if (!win.intersect(computeBounds(), &win)) {
+        if (!win.intersect(bounds, &win)) {
             win.clear();
         }
     }
@@ -1440,7 +1453,7 @@
     const Layer::State& s(getDrawingState());
     const Transform hwTransform(hw->getTransform());
     const uint32_t hw_h = hw->getHeight();
-    Rect win = computeBounds();
+    FloatRect win = computeBounds();
 
     vec2 lt = vec2(win.left, win.top);
     vec2 lb = vec2(win.left, win.bottom);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f7501a3..56f508b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -27,6 +27,7 @@
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
+#include <ui/FloatRect.h>
 #include <ui/FrameStats.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
@@ -258,8 +259,8 @@
 
     void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
             bool useIdentityTransform) const;
-    Rect computeBounds(const Region& activeTransparentRegion) const;
-    Rect computeBounds() const;
+    FloatRect computeBounds(const Region& activeTransparentRegion) const;
+    FloatRect computeBounds() const;
 
     int32_t getSequence() const { return sequence; }
 
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index effd319..d44288d 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -32,6 +32,7 @@
     mOpaque = true;
     mTextureEnabled = false;
     mColorMatrixEnabled = false;
+    mIsWideGamut = false;
 
     memset(mColor, 0, sizeof(mColor));
 }
diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
index 6be9ae2..073acca 100644
--- a/services/surfaceflinger/Transform.cpp
+++ b/services/surfaceflinger/Transform.cpp
@@ -224,6 +224,27 @@
     return r;
 }
 
+FloatRect Transform::transform(const FloatRect& bounds) const
+{
+    vec2 lt(bounds.left, bounds.top);
+    vec2 rt(bounds.right, bounds.top);
+    vec2 lb(bounds.left, bounds.bottom);
+    vec2 rb(bounds.right, bounds.bottom);
+
+    lt = transform(lt);
+    rt = transform(rt);
+    lb = transform(lb);
+    rb = transform(rb);
+
+    FloatRect r;
+    r.left = min(lt[0], rt[0], lb[0], rb[0]);
+    r.top = min(lt[1], rt[1], lb[1], rb[1]);
+    r.right = max(lt[0], rt[0], lb[0], rb[0]);
+    r.bottom = max(lt[1], rt[1], lb[1], rb[1]);
+
+    return r;
+}
+
 Region Transform::transform(const Region& reg) const
 {
     Region out;
diff --git a/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h
index 6640a13..2b47887 100644
--- a/services/surfaceflinger/Transform.h
+++ b/services/surfaceflinger/Transform.h
@@ -80,6 +80,7 @@
             Region  transform(const Region& reg) const;
             Rect    transform(const Rect& bounds,
                     bool roundOutwards = false) const;
+            FloatRect transform(const FloatRect& bounds) const;
             Transform operator * (const Transform& rhs) const;
             // assumes the last row is < 0 , 0 , 1 >
             vec2 transform(const vec2& v) const;