Implement GPU path for matrix convolution.  Note that when not convolving alpha,
the premultiplying is done less efficiently than in the raster path:  it's
done on each texture access, rather than as a pre-processing pass.   This was
so I could do the filter as a single custom stage; will try the optimization
separately.

This implementation gives a ~30X speedup on the GPU results for the
matrixconvolution bench (~10X due to the GPU, and ~3X due to texture
uploads/readback removal).

Note:  this changes the matrixconvolution for the software path as well, so
it will likely break the bots until that test is rebaselined.

Review URL:  https://codereview.appspot.com/6585069/



git-svn-id: http://skia.googlecode.com/svn/trunk@5809 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/matrixconvolution.cpp b/gm/matrixconvolution.cpp
index 0a0afa4..6bb7d99 100644
--- a/gm/matrixconvolution.cpp
+++ b/gm/matrixconvolution.cpp
@@ -6,7 +6,9 @@
  */
 
 #include "gm.h"
+#include "SkColor.h"
 #include "SkMatrixConvolutionImageFilter.h"
+#include "SkGradientShader.h"
 
 namespace skiagm {
 
@@ -31,6 +33,12 @@
         paint.setAntiAlias(true);
         paint.setColor(0xFFFFFFFF);
         paint.setTextSize(SkIntToScalar(180));
+        SkPoint pts[2] = { SkPoint::Make(0, 0),
+                           SkPoint::Make(0, SkIntToScalar(80)) };
+        SkColor colors[2] = { 0xFFFFFFFF, 0x40404040 };
+        SkScalar pos[2] = { 0, SkIntToScalar(80) };
+        paint.setShader(SkGradientShader::CreateLinear(
+            pts, colors, pos, 2, SkShader::kClamp_TileMode))->unref();
         const char* str = "e";
         canvas.drawText(str, strlen(str), SkIntToScalar(-10), SkIntToScalar(80), paint);
     }
@@ -59,15 +67,17 @@
             fInitialized = true;
         }
         canvas->clear(0x00000000);
-        SkIPoint target = SkIPoint::Make(1, 1);
-        for (target.fY = 0; target.fY < 3; ++target.fY) {
-            int y = target.fY * 100 + 10;
-            draw(canvas, 10, y, target, SkMatrixConvolutionImageFilter::kClamp_TileMode, true);
-            draw(canvas, 110, y, target, SkMatrixConvolutionImageFilter::kClampToBlack_TileMode, true);
-            draw(canvas, 210, y, target, SkMatrixConvolutionImageFilter::kRepeat_TileMode, true);
+        SkIPoint target = SkIPoint::Make(1, 0);
+        for (int x = 10; x < 310; x += 100) {
+            draw(canvas, x, 10, target, SkMatrixConvolutionImageFilter::kClamp_TileMode, true);
+            draw(canvas, x, 110, target, SkMatrixConvolutionImageFilter::kClampToBlack_TileMode, true);
+            draw(canvas, x, 210, target, SkMatrixConvolutionImageFilter::kRepeat_TileMode, true);
+            target.fY++;
         }
         target.fY = 1;
         draw(canvas, 310, 10, target, SkMatrixConvolutionImageFilter::kClamp_TileMode, false);
+        draw(canvas, 310, 110, target, SkMatrixConvolutionImageFilter::kClampToBlack_TileMode, false);
+        draw(canvas, 310, 210, target, SkMatrixConvolutionImageFilter::kRepeat_TileMode, false);
     }
 
 private: