Glop Bitmap and RoundRect clipping support

Change-Id: I4577546a5d2e5f084cc03f39a89db9231b8111ee
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 61cd16f..0841124 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -57,16 +57,11 @@
     #define EVENT_LOGD(...)
 #endif
 
+#define USE_GLOPS true
+
 namespace android {
 namespace uirenderer {
 
-static GLenum getFilter(const SkPaint* paint) {
-    if (!paint || paint->getFilterLevel() != SkPaint::kNone_FilterLevel) {
-        return GL_LINEAR;
-    }
-    return GL_NEAREST;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Globals
 ///////////////////////////////////////////////////////////////////////////////
@@ -1586,6 +1581,7 @@
         // TODO: specify more clearly when a draw should dirty the layer.
         // is writing to the stencil the only time we should ignore this?
         dirtyLayer(glop.bounds.left, glop.bounds.top, glop.bounds.right, glop.bounds.bottom);
+        mDirty = true;
     }
 }
 
@@ -1611,7 +1607,7 @@
 
     mSetShaderColor = false;
     mColorSet = false;
-    mColorA = mColorR = mColorG = mColorB = 0.0f;
+    mColor.a = mColor.r = mColor.g = mColor.b = 0.0f;
     mTextureUnit = 0;
     mTrackDirtyRegions = true;
 
@@ -1647,21 +1643,21 @@
 }
 
 void OpenGLRenderer::setupDrawColor(int color, int alpha) {
-    mColorA = alpha / 255.0f;
-    mColorR = mColorA * ((color >> 16) & 0xFF) / 255.0f;
-    mColorG = mColorA * ((color >>  8) & 0xFF) / 255.0f;
-    mColorB = mColorA * ((color      ) & 0xFF) / 255.0f;
+    mColor.a = alpha / 255.0f;
+    mColor.r = mColor.a * ((color >> 16) & 0xFF) / 255.0f;
+    mColor.g = mColor.a * ((color >>  8) & 0xFF) / 255.0f;
+    mColor.b = mColor.a * ((color      ) & 0xFF) / 255.0f;
     mColorSet = true;
-    mSetShaderColor = mDescription.setColorModulate(mColorA);
+    mSetShaderColor = mDescription.setColorModulate(mColor.a);
 }
 
 void OpenGLRenderer::setupDrawAlpha8Color(int color, int alpha) {
-    mColorA = alpha / 255.0f;
-    mColorR = mColorA * ((color >> 16) & 0xFF) / 255.0f;
-    mColorG = mColorA * ((color >>  8) & 0xFF) / 255.0f;
-    mColorB = mColorA * ((color      ) & 0xFF) / 255.0f;
+    mColor.a = alpha / 255.0f;
+    mColor.r = mColor.a * ((color >> 16) & 0xFF) / 255.0f;
+    mColor.g = mColor.a * ((color >>  8) & 0xFF) / 255.0f;
+    mColor.b = mColor.a * ((color      ) & 0xFF) / 255.0f;
     mColorSet = true;
-    mSetShaderColor = mDescription.setAlpha8ColorModulate(mColorR, mColorG, mColorB, mColorA);
+    mSetShaderColor = mDescription.setAlpha8ColorModulate(mColor.r, mColor.g, mColor.b, mColor.a);
 }
 
 void OpenGLRenderer::setupDrawTextGamma(const SkPaint* paint) {
@@ -1669,10 +1665,10 @@
 }
 
 void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) {
-    mColorA = a;
-    mColorR = r;
-    mColorG = g;
-    mColorB = b;
+    mColor.a = a;
+    mColor.r = r;
+    mColor.g = g;
+    mColor.b = b;
     mColorSet = true;
     mSetShaderColor = mDescription.setColorModulate(a);
 }
@@ -1699,8 +1695,8 @@
 
 void OpenGLRenderer::accountForClear(SkXfermode::Mode mode) {
     if (mColorSet && mode == SkXfermode::kClear_Mode) {
-        mColorA = 1.0f;
-        mColorR = mColorG = mColorB = 0.0f;
+        mColor.a = 1.0f;
+        mColor.r = mColor.g = mColor.b = 0.0f;
         mSetShaderColor = mDescription.modulate = true;
     }
 }
@@ -1713,7 +1709,7 @@
     // TODO: check shader blending, once we have shader drawing support for layers.
     bool blend = layer->isBlend()
             || getLayerAlpha(layer) < 1.0f
-            || (mColorSet && mColorA < 1.0f)
+            || (mColorSet && mColor.a < 1.0f)
             || PaintUtils::isBlendedColorFilter(layer->getColorFilter());
     chooseBlending(blend, mode, mDescription, swapSrcDst);
 }
@@ -1723,7 +1719,7 @@
     // When the blending mode is kClear_Mode, we need to use a modulate color
     // argb=1,0,0,0
     accountForClear(mode);
-    blend |= (mColorSet && mColorA < 1.0f)
+    blend |= (mColorSet && mColor.a < 1.0f)
             || (getShader(paint) && !getShader(paint)->isOpaque())
             || PaintUtils::isBlendedColorFilter(getColorFilter(paint));
     chooseBlending(blend, mode, mDescription, swapSrcDst);
@@ -1775,13 +1771,13 @@
 
 void OpenGLRenderer::setupDrawColorUniforms(bool hasShader) {
     if ((mColorSet && !hasShader) || (hasShader && mSetShaderColor)) {
-        mCaches.program().setColor(mColorR, mColorG, mColorB, mColorA);
+        mCaches.program().setColor(mColor);
     }
 }
 
 void OpenGLRenderer::setupDrawPureColorUniforms() {
     if (mSetShaderColor) {
-        mCaches.program().setColor(mColorR, mColorG, mColorB, mColorA);
+        mCaches.program().setColor(mColor);
     }
 }
 
@@ -1973,22 +1969,34 @@
     }
 }
 
-void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top,
-        const SkPaint* paint) {
-    float x = left;
-    float y = top;
+void OpenGLRenderer::drawAlphaBitmap(Texture* texture, const SkPaint* paint) {
+    if (USE_GLOPS && (!paint || !paint->getShader())) {
+        Glop glop;
+        GlopBuilder aBuilder(mRenderState, mCaches, &glop);
+        aBuilder.setMeshTexturedUnitQuad(texture->uvMapper, true)
+                .setFillTexturePaint(*texture, true, paint, currentSnapshot()->alpha)
+                .setTransformClip(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false)
+                .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height))
+                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
+                .build();
+        renderGlop(glop);
+        return;
+    }
+
+    float x = 0;
+    float y = 0;
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
 
     bool ignoreTransform = false;
     if (currentTransform()->isPureTranslate()) {
-        x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
-        y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
+        x = (int) floorf(currentTransform()->getTranslateX() + 0.5f);
+        y = (int) floorf(currentTransform()->getTranslateY() + 0.5f);
         ignoreTransform = true;
 
         texture->setFilter(GL_NEAREST, true);
     } else {
-        texture->setFilter(getFilter(paint), true);
+        texture->setFilter(PaintUtils::getFilter(paint), true);
     }
 
     // No need to check for a UV mapper on the texture object, only ARGB_8888
@@ -2013,7 +2021,7 @@
     const AutoTexture autoCleanup(texture);
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(pureTranslate ? GL_NEAREST : getFilter(paint), true);
+    texture->setFilter(pureTranslate ? GL_NEAREST : PaintUtils::getFilter(paint), true);
 
     const float x = (int) floorf(bounds.left + 0.5f);
     const float y = (int) floorf(bounds.top + 0.5f);
@@ -2043,9 +2051,9 @@
     const AutoTexture autoCleanup(texture);
 
     if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
-        drawAlphaBitmap(texture, 0, 0, paint);
+        drawAlphaBitmap(texture, paint);
     } else {
-        drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
+        drawTextureRect(texture, paint);
     }
 
     mDirty = true;
@@ -2130,7 +2138,7 @@
     const AutoTexture autoCleanup(texture);
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(getFilter(paint), true);
+    texture->setFilter(PaintUtils::getFilter(paint), true);
 
     int alpha;
     SkXfermode::Mode mode;
@@ -2213,10 +2221,10 @@
         dstLeft = x;
         dstTop = y;
 
-        texture->setFilter(scaled ? getFilter(paint) : GL_NEAREST, true);
+        texture->setFilter(scaled ? PaintUtils::getFilter(paint) : GL_NEAREST, true);
         ignoreTransform = true;
     } else {
-        texture->setFilter(getFilter(paint), true);
+        texture->setFilter(PaintUtils::getFilter(paint), true);
     }
 
     if (CC_UNLIKELY(useScaleTransform)) {
@@ -2350,15 +2358,16 @@
         return;
     }
 
-    if (!paint->getShader() && !currentSnapshot()->roundRectClipState) {
+    if (USE_GLOPS && !paint->getShader()) {
         Glop glop;
         GlopBuilder aBuilder(mRenderState, mCaches, &glop);
         bool fudgeOffset = displayFlags & kVertexBuffer_Offset;
         bool shadowInterp = displayFlags & kVertexBuffer_ShadowInterp;
         aBuilder.setMeshVertexBuffer(vertexBuffer, shadowInterp)
-                .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), fudgeOffset)
+                .setFillPaint(*paint, currentSnapshot()->alpha)
+                .setTransformClip(currentSnapshot()->getOrthoMatrix(), *currentTransform(), fudgeOffset)
                 .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds())
-                .setPaint(*paint, currentSnapshot()->alpha)
+                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
                 .build();
         renderGlop(glop);
         return;
@@ -3251,14 +3260,15 @@
         return;
     }
 
-    if (!paint->getShader() && !currentSnapshot()->roundRectClipState) {
+    if (USE_GLOPS && !paint->getShader()) {
         const Matrix4& transform = ignoreTransform ? Matrix4::identity() : *currentTransform();
         Glop glop;
         GlopBuilder aBuilder(mRenderState, mCaches, &glop);
         aBuilder.setMeshIndexedQuads(&mesh[0], count / 4)
-                .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false)
+                .setFillPaint(*paint, currentSnapshot()->alpha)
+                .setTransformClip(currentSnapshot()->getOrthoMatrix(), transform, false)
                 .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom))
-                .setPaint(*paint, currentSnapshot()->alpha)
+                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
                 .build();
         renderGlop(glop);
         return;
@@ -3296,14 +3306,15 @@
 void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
         const SkPaint* paint, bool ignoreTransform) {
 
-    if (!paint->getShader() && !currentSnapshot()->roundRectClipState) {
+    if (USE_GLOPS && !paint->getShader()) {
         const Matrix4& transform = ignoreTransform ? Matrix4::identity() : *currentTransform();
         Glop glop;
         GlopBuilder aBuilder(mRenderState, mCaches, &glop);
         aBuilder.setMeshUnitQuad()
-                .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false)
+                .setFillPaint(*paint, currentSnapshot()->alpha)
+                .setTransformClip(currentSnapshot()->getOrthoMatrix(), transform, false)
                 .setModelViewMapUnitToRect(Rect(left, top, right, bottom))
-                .setPaint(*paint, currentSnapshot()->alpha)
+                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
                 .build();
         renderGlop(glop);
         return;
@@ -3332,8 +3343,20 @@
     glDrawArrays(GL_TRIANGLE_STRIP, 0, kUnitQuadCount);
 }
 
-void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
-        Texture* texture, const SkPaint* paint) {
+void OpenGLRenderer::drawTextureRect(Texture* texture, const SkPaint* paint) {
+    if (USE_GLOPS) {
+        Glop glop;
+        GlopBuilder aBuilder(mRenderState, mCaches, &glop);
+        aBuilder.setMeshTexturedUnitQuad(texture->uvMapper, false)
+                .setFillTexturePaint(*texture, false, paint, currentSnapshot()->alpha)
+                .setTransformClip(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false)
+                .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height))
+                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
+                .build();
+        renderGlop(glop);
+        return;
+    }
+
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
 
     GLvoid* vertices = (GLvoid*) nullptr;
@@ -3350,16 +3373,16 @@
     }
 
     if (CC_LIKELY(currentTransform()->isPureTranslate())) {
-        const float x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
-        const float y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
+        const float x = (int) floorf(currentTransform()->getTranslateX() + 0.5f);
+        const float y = (int) floorf(currentTransform()->getTranslateY() + 0.5f);
 
         texture->setFilter(GL_NEAREST, true);
         drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
                 paint, texture->blend, vertices, texCoords,
                 GL_TRIANGLE_STRIP, kUnitQuadCount, false, true);
     } else {
-        texture->setFilter(getFilter(paint), true);
-        drawTextureMesh(left, top, right, bottom, texture->id, paint,
+        texture->setFilter(PaintUtils::getFilter(paint), true);
+        drawTextureMesh(0, 0, texture->width, texture->height, texture->id, paint,
                 texture->blend, vertices, texCoords, GL_TRIANGLE_STRIP, kUnitQuadCount);
     }