Remove confusing behavior of Rect::intersect() and rename

bug:24670525

Removes silly 'do nothing if rects do not intersect' behavior, and
changes the name to clarify the difference (contrasting against
SkRect::intersect())

bug:24670525

Change-Id: Id2ca1cfea1a9d720d4dc70b251f426d9916f8b53
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index 8e7efb4..a9d1e42 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -23,14 +23,6 @@
 namespace android {
 namespace uirenderer {
 
-static bool intersect(Rect& r, const Rect& r2) {
-    bool hasIntersection = r.intersect(r2);
-    if (!hasIntersection) {
-        r.setEmpty();
-    }
-    return hasIntersection;
-}
-
 static void handlePoint(Rect& transformedBounds, const Matrix4& transform, float x, float y) {
     Vertex v = {x, y};
     transform.mapPoint(v.x, v.y);
@@ -67,9 +59,8 @@
     return mTransform == other.mTransform;
 }
 
-bool TransformedRectangle::intersectWith(const TransformedRectangle& other) {
-    Rect translatedBounds(other.mBounds);
-    return intersect(mBounds, translatedBounds);
+void TransformedRectangle::intersectWith(const TransformedRectangle& other) {
+    mBounds.doIntersect(other.mBounds);
 }
 
 bool TransformedRectangle::isEmpty() const {
@@ -146,7 +137,7 @@
         if (index == 0) {
             bounds = tr.transformedBounds();
         } else {
-            bounds.intersect(tr.transformedBounds());
+            bounds.doIntersect(tr.transformedBounds());
         }
     }
     return bounds;
@@ -275,10 +266,7 @@
     if (transform->rectToRect()) {
         Rect transformed(r);
         transform->mapRect(transformed);
-        bool hasIntersection = mClipRect.intersect(transformed);
-        if (!hasIntersection) {
-            mClipRect.setEmpty();
-        }
+        mClipRect.doIntersect(transformed);
         return;
     }
 
diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h
index 38fefe5..f88fd92 100644
--- a/libs/hwui/ClipArea.h
+++ b/libs/hwui/ClipArea.h
@@ -33,7 +33,7 @@
     TransformedRectangle(const Rect& bounds, const Matrix4& transform);
 
     bool canSimplyIntersectWith(const TransformedRectangle& other) const;
-    bool intersectWith(const TransformedRectangle& other);
+    void intersectWith(const TransformedRectangle& other);
 
     bool isEmpty() const;
 
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index c63b559..227271d 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -58,7 +58,7 @@
         mLayer->region.clear();
         dirty.set(0.0f, 0.0f, width, height);
     } else {
-        dirty.intersect(0.0f, 0.0f, width, height);
+        dirty.doIntersect(0.0f, 0.0f, width, height);
         android::Rect r(dirty.left, dirty.top, dirty.right, dirty.bottom);
         mLayer->region.subtractSelf(r);
     }
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 9f24e37..cd03ac4 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -488,7 +488,8 @@
     currentTransform()->mapRect(bounds);
 
     // Layers only make sense if they are in the framebuffer's bounds
-    if (bounds.intersect(mState.currentClipRect())) {
+    bounds.doIntersect(mState.currentClipRect());
+    if (!bounds.isEmpty()) {
         // We cannot work with sub-pixels in this case
         bounds.snapToPixelBoundaries();
 
@@ -497,23 +498,20 @@
         // of the framebuffer
         const Snapshot& previous = *(currentSnapshot()->previous);
         Rect previousViewport(0, 0, previous.getViewportWidth(), previous.getViewportHeight());
-        if (!bounds.intersect(previousViewport)) {
-            bounds.setEmpty();
-        } else if (fboLayer) {
+
+        bounds.doIntersect(previousViewport);
+        if (!bounds.isEmpty() && fboLayer) {
             clip.set(bounds);
             mat4 inverse;
             inverse.loadInverse(*currentTransform());
             inverse.mapRect(clip);
             clip.snapToPixelBoundaries();
-            if (clip.intersect(untransformedBounds)) {
+            clip.doIntersect(untransformedBounds);
+            if (!clip.isEmpty()) {
                 clip.translate(-untransformedBounds.left, -untransformedBounds.top);
                 bounds.set(untransformedBounds);
-            } else {
-                clip.setEmpty();
             }
         }
-    } else {
-        bounds.setEmpty();
     }
 }
 
@@ -1038,7 +1036,8 @@
 }
 
 void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
-    if (CC_LIKELY(!bounds.isEmpty() && bounds.intersect(mState.currentClipRect()))) {
+    bounds.doIntersect(mState.currentClipRect());
+    if (!bounds.isEmpty()) {
         bounds.snapToPixelBoundaries();
         android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
         if (!dirty.isEmpty()) {
@@ -1112,7 +1111,8 @@
             // is used, it should more closely duplicate the quickReject logic (in how it uses
             // snapToPixelBoundaries)
 
-            if (!clippedBounds.intersect(currentClip)) {
+            clippedBounds.doIntersect(currentClip);
+            if (clippedBounds.isEmpty()) {
                 // quick rejected
                 return true;
             }
@@ -1242,9 +1242,8 @@
         Rect bounds = tr.getBounds();
         if (transform.rectToRect()) {
             transform.mapRect(bounds);
-            if (!bounds.intersect(scissorBox)) {
-                bounds.setEmpty();
-            } else {
+            bounds.doIntersect(scissorBox);
+            if (!bounds.isEmpty()) {
                 handlePointNoTransform(rectangleVertices, bounds.left, bounds.top);
                 handlePointNoTransform(rectangleVertices, bounds.right, bounds.top);
                 handlePointNoTransform(rectangleVertices, bounds.left, bounds.bottom);
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 4c4cd3d..50199db 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -125,25 +125,32 @@
     }
 
     bool intersects(float l, float t, float r, float b) const {
-        return !intersectWith(l, t, r, b).isEmpty();
+        float tempLeft = std::max(left, l);
+        float tempTop = std::max(top, t);
+        float tempRight = std::min(right, r);
+        float tempBottom = std::min(bottom, b);
+
+        return ((tempLeft < tempRight) && (tempTop < tempBottom)); // !isEmpty
     }
 
     bool intersects(const Rect& r) const {
         return intersects(r.left, r.top, r.right, r.bottom);
     }
 
-    bool intersect(float l, float t, float r, float b) {
-        Rect tmp(l, t, r, b);
-        intersectWith(tmp);
-        if (!tmp.isEmpty()) {
-            set(tmp);
-            return true;
-        }
-        return false;
+    /**
+     * This method is named 'doIntersect' instead of 'intersect' so as not to be confused with
+     * SkRect::intersect / android.graphics.Rect#intersect behavior, which do not modify the object
+     * if the intersection of the rects would be empty.
+     */
+    void doIntersect(float l, float t, float r, float b) {
+        left = std::max(left, l);
+        top = std::max(top, t);
+        right = std::min(right, r);
+        bottom = std::min(bottom, b);
     }
 
-    bool intersect(const Rect& r) {
-        return intersect(r.left, r.top, r.right, r.bottom);
+    void doIntersect(const Rect& r) {
+        doIntersect(r.left, r.top, r.right, r.bottom);
     }
 
     inline bool contains(float l, float t, float r, float b) const {
@@ -271,24 +278,6 @@
     void dump(const char* label = nullptr) const {
         ALOGD("%s[l=%f t=%f r=%f b=%f]", label ? label : "Rect", left, top, right, bottom);
     }
-
-private:
-    void intersectWith(Rect& tmp) const {
-        tmp.left = std::max(left, tmp.left);
-        tmp.top = std::max(top, tmp.top);
-        tmp.right = std::min(right, tmp.right);
-        tmp.bottom = std::min(bottom, tmp.bottom);
-    }
-
-    Rect intersectWith(float l, float t, float r, float b) const {
-        Rect tmp;
-        tmp.left = std::max(left, l);
-        tmp.top = std::max(top, t);
-        tmp.right = std::min(right, r);
-        tmp.bottom = std::min(bottom, b);
-        return tmp;
-    }
-
 }; // class Rect
 
 }; // namespace uirenderer
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 71589c8..f824cc0 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -549,7 +549,7 @@
         if (flags & CLIP_TO_BOUNDS) {
             outRect->set(0, 0, getWidth(), getHeight());
             if (flags & CLIP_TO_CLIP_BOUNDS) {
-                outRect->intersect(mPrimitiveFields.mClipBounds);
+                outRect->doIntersect(mPrimitiveFields.mClipBounds);
             }
         } else {
             outRect->set(mPrimitiveFields.mClipBounds);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index ddfd621..38f6e53 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -339,7 +339,7 @@
             // Remember the intersection of the target bounds and the intersection bounds against
             // which we have to crop the content.
             backdropBounds.set(x, y, x + backdropBounds.getWidth(), y + backdropBounds.getHeight());
-            backdropBounds.intersect(targetBounds);
+            backdropBounds.doIntersect(targetBounds);
             // Check if we have to draw something on the left side ...
             if (targetBounds.left < contentBounds.left) {
                 mCanvas->save(SkCanvas::kClip_SaveFlag);