Add support for ColorFilters.

Color filters are fully supported and can be used with shaders.

Change-Id: Id90ccf1c81cb462f2431f366f3f8f710d7971e04
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 23923f6..3205258 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -27,8 +27,6 @@
 // Vertex shaders snippets
 ///////////////////////////////////////////////////////////////////////////////
 
-// TODO: Implement BitmapShader, implement repeat/mirror for npot
-
 const char* gVS_Header_Attributes =
         "attribute vec4 position;\n";
 const char* gVS_Header_Attributes_TexCoords =
@@ -85,10 +83,10 @@
         "uniform mat4 colorMatrix;\n"
         "uniform vec4 colorMatrixVector;\n",
         // Lighting
-        "uniform float lightingMul;\n"
-        "uniform float lightingAdd;\n",
+        "uniform vec4 lightingMul;\n"
+        "uniform vec4 lightingAdd;\n",
         // PorterDuff
-        "uniform vec4 colorBLend;\n"
+        "uniform vec4 colorBlend;\n"
 };
 const char* gFS_Main =
         "\nvoid main(void) {\n"
@@ -121,11 +119,14 @@
         // None
         "",
         // Matrix
+        // TODO: Fix premultiplied alpha computations for color matrix
         "    fragColor *= colorMatrix;\n"
-        "    fragColor += colorMatrixVector;\n",
+        "    fragColor += colorMatrixVector;\n"
+        "    fragColor.rgb *= fragColor.a;\n",
         // Lighting
-        "    fragColor *= lightingMul;\n"
-        "    fragColor += lightingAdd;\n",
+        "    float lightingAlpha = fragColor.a;\n"
+        "    fragColor = min(fragColor * lightingMul + (lightingAdd * lightingAlpha), lightingAlpha);\n"
+        "    fragColor.a = lightingAlpha;\n",
         // PorterDuff
         "    fragColor = blendColors(colorBlend, fragColor);\n"
 };
@@ -345,7 +346,11 @@
     // End the shader
     shader.append(gFS_Footer);
 
-    PROGRAM_LOGD("*** Generated fragment shader:\n\n%s", shader.string());
+    if (DEBUG_PROGRAM_CACHE) {
+        PROGRAM_LOGD("*** Generated fragment shader:\n\n");
+        printLongString(shader);
+    }
+
     return shader;
 }
 
@@ -391,5 +396,19 @@
     shader.append("}\n");
 }
 
+void ProgramCache::printLongString(const String8& shader) const {
+    ssize_t index = 0;
+    ssize_t lastIndex = 0;
+    const char* str = shader.string();
+    while ((index = shader.find("\n", index)) > -1) {
+        String8 line(str, index - lastIndex);
+        if (line.length() == 0) line.append("\n");
+        PROGRAM_LOGD("%s", line.string());
+        index++;
+        str += (index - lastIndex);
+        lastIndex = index;
+    }
+}
+
 }; // namespace uirenderer
 }; // namespace android