Don't copy paints for 9patches

Change-Id: I863100a0dc53fec1a3a1b2acbdeb76e6049ffe58
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index d376e3a..841a35b 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -486,7 +486,8 @@
                 float top = getFloat();
                 float right = getFloat();
                 float bottom = getFloat();
-                SkPaint* paint = getPaint(renderer);
+                int alpha = getInt();
+                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
                 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
                         left, top, right, bottom);
             }
@@ -1089,11 +1090,14 @@
                 float top = getFloat();
                 float right = getFloat();
                 float bottom = getFloat();
-                SkPaint* paint = getPaint(renderer);
+
+                int alpha = getInt();
+                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
 
                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
                 drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
-                        xDivsCount, yDivsCount, numColors, left, top, right, bottom, paint);
+                        xDivsCount, yDivsCount, numColors, left, top, right, bottom,
+                        alpha, mode);
             }
             break;
             case DrawColor: {
@@ -1570,6 +1574,10 @@
 status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
         const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
         int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
+    int alpha;
+    SkXfermode::Mode mode;
+    OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
+
     const bool reject = quickReject(left, top, right, bottom);
     uint32_t* location = addOp(DisplayList::DrawPatch, reject);
     addBitmap(bitmap);
@@ -1577,7 +1585,8 @@
     addInts(yDivs, height);
     addUInts(colors, numColors);
     addBounds(left, top, right, bottom);
-    addPaint(paint);
+    addInt(alpha);
+    addInt(mode);
     addSkip(location);
     return DrawGlInfo::kStatusDone;
 }
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index ca798db..99016d6 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1677,10 +1677,23 @@
 status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
         const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
         float left, float top, float right, float bottom, SkPaint* paint) {
+    int alpha;
+    SkXfermode::Mode mode;
+    getAlphaAndModeDirect(paint, &alpha, &mode);
+
+    return drawPatch(bitmap, xDivs, yDivs, colors, width, height, numColors,
+            left, top, right, bottom, alpha, mode);
+}
+
+status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
+        float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode) {
     if (quickReject(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
+    alpha *= mSnapshot->alpha;
+
     mCaches.activeTexture(0);
     Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
@@ -1688,10 +1701,6 @@
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
     texture->setFilter(GL_LINEAR, true);
 
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-
     const Patch* mesh = mCaches.patchCache.get(bitmap->width(), bitmap->height(),
             right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);
 
@@ -2921,30 +2930,9 @@
 }
 
 void OpenGLRenderer::getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
-    if (paint) {
-        *mode = getXfermode(paint->getXfermode());
-
-        // Skia draws using the color's alpha channel if < 255
-        // Otherwise, it uses the paint's alpha
-        int color = paint->getColor();
-        *alpha = (color >> 24) & 0xFF;
-        if (*alpha == 255) {
-            *alpha = paint->getAlpha();
-        }
-    } else {
-        *mode = SkXfermode::kSrcOver_Mode;
-        *alpha = 255;
-    }
+    getAlphaAndModeDirect(paint, alpha,  mode);
     *alpha *= mSnapshot->alpha;
 }
 
-SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) {
-    SkXfermode::Mode resultMode;
-    if (!SkXfermode::AsMode(mode, &resultMode)) {
-        resultMode = SkXfermode::kSrcOver_Mode;
-    }
-    return resultMode;
-}
-
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 7aac87c..8bdc450 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -123,6 +123,9 @@
     virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
             const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
             float left, float top, float right, float bottom, SkPaint* paint);
+    status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
+            float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode);
     virtual status_t drawColor(int color, SkXfermode::Mode mode);
     virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
@@ -213,6 +216,54 @@
      */
     void drawTextureLayer(Layer* layer, const Rect& rect);
 
+    /**
+     * Gets the alpha and xfermode out of a paint object. If the paint is null
+     * alpha will be 255 and the xfermode will be SRC_OVER.
+     *
+     * @param paint The paint to extract values from
+     * @param alpha Where to store the resulting alpha
+     * @param mode Where to store the resulting xfermode
+     */
+    inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
+
+    /**
+     * Gets the alpha and xfermode out of a paint object. If the paint is null
+     * alpha will be 255 and the xfermode will be SRC_OVER. This method does
+     * not multiply the paint's alpha by the current snapshot's alpha.
+     *
+     * @param paint The paint to extract values from
+     * @param alpha Where to store the resulting alpha
+     * @param mode Where to store the resulting xfermode
+     */
+    static inline void getAlphaAndModeDirect(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
+        if (paint) {
+            *mode = getXfermode(paint->getXfermode());
+
+            // Skia draws using the color's alpha channel if < 255
+            // Otherwise, it uses the paint's alpha
+            int color = paint->getColor();
+            *alpha = (color >> 24) & 0xFF;
+            if (*alpha == 255) {
+                *alpha = paint->getAlpha();
+            }
+        } else {
+            *mode = SkXfermode::kSrcOver_Mode;
+            *alpha = 255;
+        }
+    }
+
+    /**
+     * Safely retrieves the mode from the specified xfermode. If the specified
+     * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
+     */
+    static inline SkXfermode::Mode getXfermode(SkXfermode* mode) {
+        SkXfermode::Mode resultMode;
+        if (!SkXfermode::AsMode(mode, &resultMode)) {
+            resultMode = SkXfermode::kSrcOver_Mode;
+        }
+        return resultMode;
+    }
+
 private:
     /**
      * Ensures the state of the renderer is the same as the state of
@@ -471,16 +522,6 @@
     void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2);
 
     /**
-     * Gets the alpha and xfermode out of a paint object. If the paint is null
-     * alpha will be 255 and the xfermode will be SRC_OVER.
-     *
-     * @param paint The paint to extract values from
-     * @param alpha Where to store the resulting alpha
-     * @param mode Where to store the resulting xfermode
-     */
-    inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
-
-    /**
      * Binds the specified texture. The texture unit must have been selected
      * prior to calling this method.
      */
@@ -504,12 +545,6 @@
             bool swapSrcDst = false);
 
     /**
-     * Safely retrieves the mode from the specified xfermode. If the specified
-     * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
-     */
-    inline SkXfermode::Mode getXfermode(SkXfermode* mode);
-
-    /**
      * Use the specified program with the current GL context. If the program is already
      * in use, it will not be bound again. If it is not in use, the current program is
      * marked unused and the specified program becomes used and becomes the new