Add support for SweepGradient in the GL renderer.

Change-Id: I7aa397ed4e34655ead9ba1f5b4ce087665e0f022
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 946cc4b..c5d9767 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -164,6 +164,7 @@
 void SkiaLinearGradientShader::describe(ProgramDescription& description,
         const Extensions& extensions) {
     description.hasGradient = true;
+    description.gradientType = ProgramDescription::kGradientLinear;
 }
 
 void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView,
@@ -173,8 +174,7 @@
 
     Texture* texture = mGradientCache->get(mKey);
     if (!texture) {
-        texture = mGradientCache->addLinearGradient(mKey, mBounds, mColors, mPositions,
-                mCount, mTileX);
+        texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX);
     }
 
     Rect start(mBounds[0], mBounds[1], mBounds[2], mBounds[3]);
@@ -209,6 +209,64 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// Sweep gradient shader
+///////////////////////////////////////////////////////////////////////////////
+
+SkiaSweepGradientShader::SkiaSweepGradientShader(float x, float y, uint32_t* colors,
+        float* positions, int count, SkShader* key, SkMatrix* matrix, bool blend):
+        SkiaShader(kSweepGradient, key, SkShader::kClamp_TileMode,
+                SkShader::kClamp_TileMode, matrix, blend),
+        mX(x), mY(y), mColors(colors), mPositions(positions), mCount(count) {
+}
+
+SkiaSweepGradientShader::~SkiaSweepGradientShader() {
+    delete[] mColors;
+    delete[] mPositions;
+}
+
+void SkiaSweepGradientShader::describe(ProgramDescription& description,
+        const Extensions& extensions) {
+    description.hasGradient = true;
+    description.gradientType = ProgramDescription::kGradientSweep;
+}
+
+void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelView,
+        const Snapshot& snapshot, GLuint* textureUnit) {
+    GLuint textureSlot = (*textureUnit)++;
+    glActiveTexture(gTextureUnitsMap[textureSlot]);
+
+    Texture* texture = mGradientCache->get(mKey);
+    if (!texture) {
+        texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount);
+    }
+
+    float left = mX;
+    float top = mY;
+
+    if (mMatrix) {
+        mat4 shaderMatrix(*mMatrix);
+        shaderMatrix.mapPoint(left, top);
+    }
+    snapshot.transform->mapPoint(left, top);
+
+    mat4 screenSpace(*snapshot.transform);
+    screenSpace.multiply(modelView);
+
+    // Uniforms
+    bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
+    glUniform1i(program->getUniform("gradientSampler"), textureSlot);
+    glUniform2f(program->getUniform("gradientStart"), left, top);
+    glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
+}
+
+void SkiaSweepGradientShader::updateTransforms(Program* program, const mat4& modelView,
+        const Snapshot& snapshot) {
+    mat4 screenSpace(*snapshot.transform);
+    screenSpace.multiply(modelView);
+    glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // Compose shader
 ///////////////////////////////////////////////////////////////////////////////