add shaderprocs for all-in-one special blits (matrix+sampler)



git-svn-id: http://skia.googlecode.com/svn/trunk@267 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleCircle.cpp b/samplecode/SampleCircle.cpp
index 3f39dbd..b250f29 100644
--- a/samplecode/SampleCircle.cpp
+++ b/samplecode/SampleCircle.cpp
@@ -26,6 +26,7 @@
 
     CircleView() {
         fDX = fDY = fRAD = 0;
+        fN = 3;
     }
     
 protected:
@@ -71,56 +72,75 @@
         const SkBitmap& bm = device->accessBitmap(false);
         canvas->drawBitmapRect(bm, &src, dst, NULL);
     }
+    
+    static void make_poly(SkPath* path, int n) {
+        if (n <= 0) {
+            return;
+        }
+        path->incReserve(n + 1);
+        path->moveTo(SK_Scalar1, 0);
+        SkScalar step = SK_ScalarPI * 2 / n;
+        SkScalar angle = 0;
+        for (int i = 1; i < n; i++) {
+            angle += step;
+            SkScalar c, s = SkScalarSinCos(angle, &c);
+            path->lineTo(c, s);
+        }
+        path->close();
+    }
+    
+    static void rotate(SkCanvas* canvas, SkScalar angle, SkScalar px, SkScalar py) {
+        canvas->translate(-px, -py);
+        canvas->rotate(angle);
+        canvas->translate(px, py);
+    }
 
     virtual void onDraw(SkCanvas* canvas) {
         this->drawBG(canvas);
         
-        test_circlebounds(canvas);
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setStyle(SkPaint::kStroke_Style);
+//        canvas->drawCircle(250, 250, 220, paint);
+        SkMatrix matrix;
+        matrix.setScale(SkIntToScalar(100), SkIntToScalar(100));
+        matrix.postTranslate(SkIntToScalar(200), SkIntToScalar(200));
+        canvas->concat(matrix);
+        for (int n = 3; n < 20; n++) {
+            SkPath path;
+            make_poly(&path, n);
+            SkAutoCanvasRestore acr(canvas, true);
+            canvas->rotate(SkIntToScalar(10) * (n - 3));
+            canvas->translate(-SK_Scalar1, 0);
+            canvas->drawPath(path, paint);
+        }
         
         if (false) {
-          //  canvas->translate(SK_ScalarHalf, SK_ScalarHalf);
-
-            SkPaint paint;
-            paint.setAntiAlias(true);
-            paint.setStyle(SkPaint::kStroke_Style);
-            canvas->drawCircle(SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(2), paint);
+            test_circlebounds(canvas);
             
-            SkIRect r;
-            r.set(7, 7, 13, 13);
-            SkRect dst;
-            dst.set(SkIntToScalar(100), SkIntToScalar(10), SkIntToScalar(200), SkIntToScalar(110));
-            blowup(canvas, r, dst);
-            return;
-        }
-        
-        // test that degenerate rects do nothing
-        if (true) {
-            SkScalar x = SkIntToScalar(30);
-            SkRect  r;
-            r.set(x, x, x, x);
-            SkPaint p;
-            canvas->drawRect(r, p);
-            p.setAntiAlias(true);
-            canvas->drawRect(r, p);
-        }
+            SkScalar dx = SkIntToScalar(32);
+            SkScalar dy = SkIntToScalar(32);
+            
+            canvas->translate(dx + fDX, dy + fDY);
+            drawSix(canvas, dx, dy);
 
-        SkScalar dx = SkIntToScalar(32);
-        SkScalar dy = SkIntToScalar(32);
-        
-        canvas->translate(dx + fDX, dy + fDY);
-        drawSix(canvas, dx, dy);
-
-        canvas->translate(dx, 0);
-        canvas->translate(SK_ScalarHalf, SK_ScalarHalf);
-        drawSix(canvas, dx, dy);
+            canvas->translate(dx, 0);
+            canvas->translate(SK_ScalarHalf, SK_ScalarHalf);
+            drawSix(canvas, dx, dy);
+        }
         
         fDX += ANIM_DX;
         fDY += ANIM_DY;
         fRAD += ANIM_RAD;
+        fN += 1;
+        if (fN > 40) {
+            fN = 3;
+        }
         this->inval(NULL);
     }
     
 private:
+    int fN;
     typedef SkView INHERITED;
 };
 
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 2302e0f..b396c68 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -134,9 +134,13 @@
 #define BUF_MAX     128
 
 void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
-    uint32_t buffer[BUF_MAX];
+    const SkBitmapProcState& state = fState;
+    if (state.fShaderProc32) {
+        state.fShaderProc32(state, x, y, dstC, count);
+        return;
+    }
 
-    const SkBitmapProcState&        state = fState;
+    uint32_t buffer[BUF_MAX];
     SkBitmapProcState::MatrixProc   mproc = state.fMatrixProc;
     SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32;
     int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX;
@@ -162,9 +166,13 @@
 }
 
 void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
-    uint32_t buffer[BUF_MAX];
+    const SkBitmapProcState& state = fState;
+    if (state.fShaderProc16) {
+        state.fShaderProc16(state, x, y, dstC, count);
+        return;
+    }
     
-    const SkBitmapProcState&        state = fState;
+    uint32_t buffer[BUF_MAX];
     SkBitmapProcState::MatrixProc   mproc = state.fMatrixProc;
     SkBitmapProcState::SampleProc16 sproc = state.fSampleProc16;
     int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX;
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index 3558573..7dc9324 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -345,6 +345,11 @@
                 (inv.getType() > SkMatrix::kTranslate_Mask &&
                  valid_for_filtering(fBitmap->width() | fBitmap->height()));
 
+    fShaderProc32 = NULL;
+    fShaderProc16 = NULL;
+    fSampleProc32 = NULL;
+    fSampleProc16 = NULL;
+    
     fMatrixProc = this->chooseMatrixProc();
     if (NULL == fMatrixProc) {
         return false;
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 561bdb7..553b952 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -24,6 +24,12 @@
 
 struct SkBitmapProcState {
 
+    typedef void (*ShaderProc32)(const SkBitmapProcState&, int x, int y,
+                                 SkPMColor[], int count);
+
+    typedef void (*ShaderProc16)(const SkBitmapProcState&, int x, int y,
+                                 uint16_t[], int count);
+
     typedef void (*MatrixProc)(const SkBitmapProcState&,
                                uint32_t bitmapXY[],
                                int count,
@@ -40,7 +46,12 @@
                                  uint16_t colors[]);
     
     typedef U16CPU (*FixedTileProc)(SkFixed);   // returns 0..0xFFFF
-    
+
+    // If a shader proc is present, then the corresponding matrix/sample procs
+    // are ignored
+    ShaderProc32        fShaderProc32;      // chooseProcs
+    ShaderProc16        fShaderProc16;      // chooseProcs
+    // These are used if the shaderproc is NULL
     MatrixProc          fMatrixProc;        // chooseProcs
     SampleProc32        fSampleProc32;      // chooseProcs
     SampleProc16        fSampleProc16;      // chooseProcs
diff --git a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
index 813db06..654f361 100644
--- a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
+++ b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
@@ -32,7 +32,6 @@
 		0041CDFA0F009F0700695E8C /* SkImageRefPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CDF90F009F0700695E8C /* SkImageRefPool.cpp */; };
 		0041CE350F00A12400695E8C /* SampleBitmapRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE1E0F00A12400695E8C /* SampleBitmapRect.cpp */; };
 		0041CE360F00A12400695E8C /* SampleCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE1F0F00A12400695E8C /* SampleCamera.cpp */; };
-		0041CE370F00A12400695E8C /* SampleCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE200F00A12400695E8C /* SampleCircle.cpp */; };
 		0041CE380F00A12400695E8C /* SampleCull.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE220F00A12400695E8C /* SampleCull.cpp */; };
 		0041CE390F00A12400695E8C /* SampleDither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE230F00A12400695E8C /* SampleDither.cpp */; };
 		0041CE3A0F00A12400695E8C /* SampleDrawLooper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE240F00A12400695E8C /* SampleDrawLooper.cpp */; };
@@ -41,7 +40,6 @@
 		0041CE400F00A12400695E8C /* SampleFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2A0F00A12400695E8C /* SampleFontCache.cpp */; };
 		0041CE420F00A12400695E8C /* SampleImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2C0F00A12400695E8C /* SampleImage.cpp */; };
 		0041CE430F00A12400695E8C /* SampleLayers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2D0F00A12400695E8C /* SampleLayers.cpp */; };
-		0041CE440F00A12400695E8C /* SampleLines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2E0F00A12400695E8C /* SampleLines.cpp */; };
 		0041CE450F00A12400695E8C /* SampleMeasure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2F0F00A12400695E8C /* SampleMeasure.cpp */; };
 		0041CE470F00A12400695E8C /* SampleNinePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE310F00A12400695E8C /* SampleNinePatch.cpp */; };
 		0041CE480F00A12400695E8C /* SampleOverflow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE320F00A12400695E8C /* SampleOverflow.cpp */; };
@@ -77,6 +75,8 @@
 		00FF39140FC6ED2C00915187 /* SampleEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00FF39130FC6ED2C00915187 /* SampleEffects.cpp */; };
 		0156F80407C56A3000C6122B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0156F80307C56A3000C6122B /* Foundation.framework */; };
 		01FC44D507BD3BB800D228F4 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01FC44D407BD3BB800D228F4 /* Quartz.framework */; };
+		27005D16100903C100E275B6 /* SampleLines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2E0F00A12400695E8C /* SampleLines.cpp */; };
+		27005D5F10095B2B00E275B6 /* SampleCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE200F00A12400695E8C /* SampleCircle.cpp */; };
 		2762F66D0FCCCABE002BD8B4 /* SkFlipPixelRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F66B0FCCCABE002BD8B4 /* SkFlipPixelRef.cpp */; };
 		2762F66E0FCCCABE002BD8B4 /* SkPageFlipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F66C0FCCCABE002BD8B4 /* SkPageFlipper.cpp */; };
 		2762F67D0FCCCB01002BD8B4 /* SamplePageFlip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F6770FCCCB01002BD8B4 /* SamplePageFlip.cpp */; };
@@ -528,7 +528,6 @@
 				0041CDFA0F009F0700695E8C /* SkImageRefPool.cpp in Sources */,
 				0041CE350F00A12400695E8C /* SampleBitmapRect.cpp in Sources */,
 				0041CE360F00A12400695E8C /* SampleCamera.cpp in Sources */,
-				0041CE370F00A12400695E8C /* SampleCircle.cpp in Sources */,
 				0041CE380F00A12400695E8C /* SampleCull.cpp in Sources */,
 				0041CE390F00A12400695E8C /* SampleDither.cpp in Sources */,
 				0041CE3A0F00A12400695E8C /* SampleDrawLooper.cpp in Sources */,
@@ -554,7 +553,6 @@
 				007C785E0F3B4C230004B142 /* SamplePathClip.cpp in Sources */,
 				009CC9190F65918A002185BE /* SampleFontScalerTest.cpp in Sources */,
 				007A7CB30F01658C00A2D6EE /* SamplePicture.cpp in Sources */,
-				0041CE440F00A12400695E8C /* SampleLines.cpp in Sources */,
 				008C4D980F77DAEE0056981C /* SampleHairline.cpp in Sources */,
 				009490320FB0A5B90063C792 /* SampleLayerMask.cpp in Sources */,
 				007A7CB60F01658C00A2D6EE /* SampleRegion.cpp in Sources */,
@@ -575,6 +573,8 @@
 				0057785F0FF17CCC00582CD9 /* SampleMipMap.cpp in Sources */,
 				005778B40FF5616F00582CD9 /* SampleShapes.cpp in Sources */,
 				00F53F480FFCFC4D003FA70A /* SampleGradients.cpp in Sources */,
+				27005D16100903C100E275B6 /* SampleLines.cpp in Sources */,
+				27005D5F10095B2B00E275B6 /* SampleCircle.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};