Moved all the rendering code to the new shader generator.

The generator supports features that are not yet implement in the
renderer: color matrix, lighting, porterduff color blending and
composite shaders.

This change also adds support for repeated/mirrored non-power of 2
bitmap shaders.

Change-Id: I903a11a070c0eb9cc8850a60ef305751e5b47234
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 5a89eb6..c9e2d2e 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -40,6 +40,9 @@
         "uniform vec2 gradient;\n"
         "uniform vec2 gradientStart;\n"
         "uniform mat4 screenSpace;\n";
+const char* gVS_Header_Uniforms_HasBitmap =
+        "uniform mat4 textureTransform;\n"
+        "uniform vec2 textureDimension;\n";
 const char* gVS_Header_Varyings_HasTexture =
         "varying vec2 outTexCoords;\n";
 const char* gVS_Header_Varyings_HasBitmap =
@@ -53,6 +56,9 @@
 const char* gVS_Main_OutGradientIndex =
         "    vec4 location = screenSpace * position;\n"
         "    index = dot(location.xy - gradientStart, gradient) * gradientLength;\n";
+const char* gVS_Main_OutBitmapTexCoords =
+        "    vec4 bitmapCoords = textureTransform * position;\n"
+        "    outBitmapTexCoords = bitmapCoords.xy * textureDimension;\n";
 const char* gVS_Main_Position =
         "    gl_Position = transform * position;\n";
 const char* gVS_Footer =
@@ -97,12 +103,18 @@
         "    vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n";
 const char* gFS_Main_FetchBitmap =
         "    vec4 bitmapColor = texture2D(bitmapSampler, outBitmapTexCoords);\n";
+const char* gFS_Main_FetchBitmapNpot =
+        "    vec4 bitmapColor = texture2D(bitmapSampler, wrap(outBitmapTexCoords));\n";
 const char* gFS_Main_BlendShadersBG =
         "    fragColor = blendShaders(bitmapColor, gradientColor)";
 const char* gFS_Main_BlendShadersGB =
         "    fragColor = blendShaders(gradientColor, bitmapColor)";
 const char* gFS_Main_BlendShaders_Modulate =
         " * fragColor.a;\n";
+const char* gFS_Main_GradientShader_Modulate =
+        "    fragColor = gradientColor * fragColor.a;\n";
+const char* gFS_Main_BitmapShader_Modulate =
+        "    fragColor = bitmapColor * fragColor.a;\n";
 const char* gFS_Main_FragColor =
         "    gl_FragColor = fragColor;\n";
 const char* gFS_Main_ApplyColorOp[4] = {
@@ -204,7 +216,7 @@
 String8 ProgramCache::generateVertexShader(const ProgramDescription& description) {
     // Add attributes
     String8 shader(gVS_Header_Attributes);
-    if (description.hasTexture || description.hasBitmap) {
+    if (description.hasTexture) {
         shader.append(gVS_Header_Attributes_TexCoords);
     }
     // Uniforms
@@ -212,6 +224,9 @@
     if (description.hasGradient) {
         shader.append(gVS_Header_Uniforms_HasGradient);
     }
+    if (description.hasBitmap) {
+        shader.append(gVS_Header_Uniforms_HasBitmap);
+    }
     // Varyings
     if (description.hasTexture) {
         shader.append(gVS_Header_Varyings_HasTexture);
@@ -231,6 +246,9 @@
         if (description.hasGradient) {
             shader.append(gVS_Main_OutGradientIndex);
         }
+        if (description.hasBitmap) {
+            shader.append(gVS_Main_OutBitmapTexCoords);
+        }
         // Output transformed position
         shader.append(gVS_Main_Position);
     }
@@ -278,6 +296,9 @@
     if (description.colorOp == ProgramDescription::kColorBlend) {
         generatePorterDuffBlend(shader, "blendColors", description.colorMode);
     }
+    if (description.isBitmapNpot) {
+        generateTextureWrap(shader, description.bitmapWrapS, description.bitmapWrapT);
+    }
 
     // Begin the shader
     shader.append(gFS_Main); {
@@ -295,7 +316,11 @@
             shader.append(gFS_Main_FetchGradient);
         }
         if (description.hasBitmap) {
-            shader.append(gFS_Main_FetchBitmap);
+            if (!description.isBitmapNpot) {
+                shader.append(gFS_Main_FetchBitmap);
+            } else {
+                shader.append(gFS_Main_FetchBitmapNpot);
+            }
         }
         // Case when we have two shaders set
         if (description.hasGradient && description.hasBitmap) {
@@ -305,6 +330,12 @@
                 shader.append(gFS_Main_BlendShadersGB);
             }
             shader.append(gFS_Main_BlendShaders_Modulate);
+        } else {
+            if (description.hasGradient) {
+                shader.append(gFS_Main_GradientShader_Modulate);
+            } else if (description.hasBitmap) {
+                shader.append(gFS_Main_BitmapShader_Modulate);
+            }
         }
         // Apply the color op if needed
         shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
@@ -328,5 +359,37 @@
     shader.append("}\n");
 }
 
+void ProgramCache::generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT) {
+    shader.append("\nvec2 wrap(vec2 texCoords) {\n");
+    if (wrapS == GL_MIRRORED_REPEAT) {
+        shader.append("    float xMod2 = mod(texCoords.x, 2.0);\n");
+        shader.append("    if (xMod2 > 1.0) xMod2 = 2.0 - xMod2;\n");
+    }
+    if (wrapT == GL_MIRRORED_REPEAT) {
+        shader.append("    float yMod2 = mod(texCoords.y, 2.0);\n");
+        shader.append("    if (yMod2 > 1.0) yMod2 = 2.0 - yMod2;\n");
+    }
+    shader.append("    return vec2(");
+    switch (wrapS) {
+        case GL_REPEAT:
+            shader.append("mod(texCoords.x, 1.0)");
+            break;
+        case GL_MIRRORED_REPEAT:
+            shader.append("xMod2");
+            break;
+    }
+    shader.append(", ");
+    switch (wrapT) {
+        case GL_REPEAT:
+            shader.append("mod(texCoords.y, 1.0)");
+            break;
+        case GL_MIRRORED_REPEAT:
+            shader.append("yMod2");
+            break;
+    }
+    shader.append(");\n");
+    shader.append("}\n");
+}
+
 }; // namespace uirenderer
 }; // namespace android