Apply shaders/filters to text drop shadows.
Bug #4318323

This change also fixes the fact that shaders were not modulated
by the paint's color when drawing paths.

Change-Id: Id88804143aea06c895d4cbcdbe106d660230aa5a
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 75f5a5f..dd0cca22 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1407,7 +1407,7 @@
     if (!isAA) {
         setupDrawVertices(vertices);
     } else {
-        void *alphaCoords = ((void*) aaVertices) + gVertexAlphaOffset;
+        AlphaVertex* alphaCoords = aaVertices + gVertexAlphaOffset;
         // innerProportion is the ratio of the inner (non-AA) port of the line to the total
         // AA stroke width (the base stroke width expanded by a half pixel on either side).
         // This value is used in the fragment shader to determine how to fill fragments.
@@ -1418,7 +1418,9 @@
     int generatedVerticesCount = 0;
     AlphaVertex *prevAAVertex = NULL;
     Vertex *prevVertex = NULL;
-    float inverseScaleX, inverseScaleY;
+    float inverseScaleX = 1.0f;
+    float inverseScaleY = 1.0f;
+
     if (isHairline) {
         // The quad that we use for AA hairlines needs to account for scaling because the line
         // should always be one pixel wide regardless of scale.
@@ -1438,6 +1440,7 @@
             inverseScaleY = (scaleY != 0) ? (inverseScaleY / scaleY) : 0;
         }
     }
+
     for (int i = 0; i < count; i += 4) {
         // a = start point, b = end point
         vec2 a(points[i], points[i + 1]);
@@ -1767,23 +1770,32 @@
                 count, mShadowRadius);
         const AutoTexture autoCleanup(shadow);
 
-        const float sx = x - shadow->left + mShadowDx;
-        const float sy = y - shadow->top + mShadowDy;
+        const float sx = oldX - shadow->left + mShadowDx;
+        const float sy = oldY - shadow->top + mShadowDy;
 
         const int shadowAlpha = ((mShadowColor >> 24) & 0xFF);
+        int shadowColor = mShadowColor;
+        if (mShader) {
+            shadowColor = 0xffffffff;
+        }
 
         glActiveTexture(gTextureUnits[0]);
         setupDraw();
         setupDrawWithTexture(true);
-        setupDrawAlpha8Color(mShadowColor, shadowAlpha < 255 ? shadowAlpha : alpha);
+        setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha);
+        setupDrawColorFilter();
+        setupDrawShader();
         setupDrawBlending(true, mode);
         setupDrawProgram();
-        setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height, pureTranslate);
+        setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height);
         setupDrawTexture(shadow->id);
         setupDrawPureColorUniforms();
+        setupDrawColorFilterUniforms();
+        setupDrawShaderUniforms();
         setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
 
         glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
         finishDrawTexture();
     }
 
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index b873bb8..80b1917 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -179,6 +179,8 @@
 // General case
 const char* gFS_Main_FetchColor =
         "    fragColor = color;\n";
+const char* gFS_Main_ModulateColor =
+        "    fragColor *= color.a;\n";
 const char* gFS_Main_AccountForWidth =
         "    if (distance < boundaryWidth) {\n"
         "        fragColor *= (distance * inverseBoundaryWidth);\n"
@@ -581,6 +583,7 @@
                 shader.append(gFS_Main_FetchBitmapNpot);
             }
         }
+        bool applyModulate = false;
         // Case when we have two shaders set
         if (description.hasGradient && description.hasBitmap) {
             int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
@@ -590,15 +593,21 @@
                 shader.append(gFS_Main_BlendShadersGB);
             }
             shader.append(gFS_Main_BlendShaders_Modulate[op]);
+            applyModulate = true;
         } else {
             if (description.hasGradient) {
                 int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
                 shader.append(gFS_Main_GradientShader_Modulate[op]);
+                applyModulate = true;
             } else if (description.hasBitmap) {
                 int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
                 shader.append(gFS_Main_BitmapShader_Modulate[op]);
+                applyModulate = true;
             }
         }
+        if (description.modulate && applyModulate) {
+            shader.append(gFS_Main_ModulateColor);
+        }
         // Apply the color op if needed
         shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
         // Output the fragment