Fix a couple of rendering issues
Bug #7253839

1. Make sure we don't make GL calls while recording display lists

2. Disable an early and trivial clip optimization in font renderer
   when a perspective transformation is used on the Canvas

Change-Id: I3f1052164239329346854f72d0a0d401fbfecf06
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 6ca70a4..f84c847 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -1573,7 +1573,8 @@
 }
 
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
-    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
+    const bool reject = quickRejectNoScissor(left, top,
+            left + bitmap->width(), top + bitmap->height());
     uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
     addBitmap(bitmap);
     addPoint(left, top);
@@ -1587,7 +1588,7 @@
     const mat4 transform(*matrix);
     transform.mapRect(r);
 
-    const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
+    const bool reject = quickRejectNoScissor(r.left, r.top, r.right, r.bottom);
     uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
     addBitmap(bitmap);
     addMatrix(matrix);
@@ -1599,7 +1600,7 @@
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
         float dstRight, float dstBottom, SkPaint* paint) {
-    const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
+    const bool reject = quickRejectNoScissor(dstLeft, dstTop, dstRight, dstBottom);
     uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
     addBitmap(bitmap);
     addBounds(srcLeft, srcTop, srcRight, srcBottom);
@@ -1611,7 +1612,8 @@
 
 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
         SkPaint* paint) {
-    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
+    const bool reject = quickRejectNoScissor(left, top,
+            left + bitmap->width(), top + bitmap->height());
     uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
     addBitmapData(bitmap);
     addPoint(left, top);
@@ -1644,7 +1646,7 @@
     SkXfermode::Mode mode;
     OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
 
-    const bool reject = quickReject(left, top, right, bottom);
+    const bool reject = quickRejectNoScissor(left, top, right, bottom);
     uint32_t* location = addOp(DisplayList::DrawPatch, reject);
     addBitmap(bitmap);
     addInts(xDivs, width);
@@ -1667,7 +1669,7 @@
 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
         SkPaint* paint) {
     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
-            quickReject(left, top, right, bottom);
+            quickRejectNoScissor(left, top, right, bottom);
     uint32_t* location = addOp(DisplayList::DrawRect, reject);
     addBounds(left, top, right, bottom);
     addPaint(paint);
@@ -1678,7 +1680,7 @@
 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, SkPaint* paint) {
     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
-            quickReject(left, top, right, bottom);
+            quickRejectNoScissor(left, top, right, bottom);
     uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
     addBounds(left, top, right, bottom);
     addPoint(rx, ry);
@@ -1721,7 +1723,7 @@
     left -= offset;
     top -= offset;
 
-    const bool reject = quickReject(left, top, left + width, top + height);
+    const bool reject = quickRejectNoScissor(left, top, left + width, top + height);
     uint32_t* location = addOp(DisplayList::DrawPath, reject);
     addPath(path);
     addPaint(paint);
@@ -1791,7 +1793,7 @@
     if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
         SkPaint::FontMetrics metrics;
         paint->getFontMetrics(&metrics, 0.0f);
-        reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
+        reject = quickRejectNoScissor(x, y + metrics.fTop, x + length, y + metrics.fBottom);
     }
 
     uint32_t* location = addOp(DisplayList::DrawText, reject);
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 87add17..a924362 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -73,6 +73,11 @@
     return mIsIdentity;
 }
 
+bool Matrix4::isPerspective() const {
+    return data[kPerspective0] != 0.0f || data[kPerspective1] != 0.0f ||
+            data[kPerspective2] != 1.0f;
+}
+
 void Matrix4::load(const float* v) {
     memcpy(data, v, sizeof(data));
     // TODO: Do something smarter here
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 02b781e..f86823d 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -115,6 +115,7 @@
     bool isPureTranslate() const;
     bool isSimple() const;
     bool isIdentity() const;
+    bool isPerspective() const;
 
     bool changesBounds() const;
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 684d5e1..c015077 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2647,20 +2647,21 @@
     setupDrawShaderUniforms(pureTranslate);
     setupDrawTextGammaUniforms();
 
-    const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
+    const Rect* clip = pureTranslate ? mSnapshot->clipRect :
+            (mSnapshot->hasPerspectiveTransform() ? NULL : &mSnapshot->getLocalClip());
     Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
 
     const bool hasActiveLayer = hasLayer();
 
     bool status;
-    if (paint->getTextAlign() != SkPaint::kLeft_Align) {
+    if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) {
         SkPaint paintCopy(*paint);
         paintCopy.setTextAlign(SkPaint::kLeft_Align);
         status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y,
-            positions, hasActiveLayer ? &bounds : NULL);
+                positions, hasActiveLayer ? &bounds : NULL);
     } else {
         status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
-            positions, hasActiveLayer ? &bounds : NULL);
+                positions, hasActiveLayer ? &bounds : NULL);
     }
 
     if (status && hasActiveLayer) {
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 4484676..fbc8455 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -178,6 +178,10 @@
     flags |= Snapshot::kFlagClipSet;
 }
 
+bool Snapshot::hasPerspectiveTransform() const {
+    return transform->isPerspective();
+}
+
 const Rect& Snapshot::getLocalClip() {
     mat4 inverse;
     inverse.loadInverse(*transform);
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index a89b740..9c612ff 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -121,6 +121,11 @@
     bool isIgnored() const;
 
     /**
+     * Indicates whether the current transform has perspective components.
+     */
+    bool hasPerspectiveTransform() const;
+
+    /**
      * Dirty flags.
      */
     int flags;
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 6e205b8..7bfa63d 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "OpenGLRenderer"
+
 #include <cutils/compiler.h>
 
 #include <SkUtils.h>