Fixing deferred canvas bug caused by SkTwoPointConicalGradient declaring itself as...
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 20 Mar 2013 00:49:57 +0000 (00:49 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 20 Mar 2013 00:49:57 +0000 (00:49 +0000)
BUG=https://code.google.com/p/chromium/issues/detail?id=222140
TEST=DeferredCanvas unit test + DRT with --enable-deferred-2d-canvas

Author: junov@chromium.org

Reviewed By: bsalomon@chromium.org

Review URL: https://chromiumcodereview.appspot.com/12879005

git-svn-id: http://skia.googlecode.com/svn/trunk@8247 2bbb7eff-a529-9590-31e7-b0007b416f81

src/effects/gradients/SkTwoPointConicalGradient.cpp
src/effects/gradients/SkTwoPointConicalGradient.h
tests/DeferredCanvasTest.cpp

index d3fb4dd..38aa60c 100644 (file)
@@ -190,6 +190,12 @@ SkTwoPointConicalGradient::SkTwoPointConicalGradient(
     this->init();
 }
 
+bool SkTwoPointConicalGradient::isOpaque() const {
+    // Because areas outside the cone are left untouched, we cannot treat the
+    // shader as opaque even if the gradient itself is opaque.
+    return false;
+}
+
 void SkTwoPointConicalGradient::shadeSpan(int x, int y, SkPMColor* dstCParam,
                                           int count) {
     int toggle = init_dither_toggle(x, y);
index e02c390..0807ae3 100644 (file)
@@ -62,6 +62,7 @@ public:
                                  TileMode* xy) const;
     virtual SkShader::GradientType asAGradient(GradientInfo* info) const  SK_OVERRIDE;
     virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const SK_OVERRIDE;
+    virtual bool isOpaque() const SK_OVERRIDE;
 
     SkScalar getCenterX1() const { return SkPoint::Distance(fCenter1, fCenter2); }
     SkScalar getStartRadius() const { return fRadius1; }
index a752c83..a95e09c 100644 (file)
@@ -10,6 +10,7 @@
 #include "SkBitmapProcShader.h"
 #include "SkDeferredCanvas.h"
 #include "SkDevice.h"
+#include "SkGradientShader.h"
 #include "SkShader.h"
 
 static const int gWidth = 2;
@@ -97,22 +98,22 @@ static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
     // trigger frames to be marked as fresh
     {
         SkPaint paint;
-        paint.setStyle( SkPaint::kFill_Style );
-        paint.setAlpha( 255 );
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setAlpha(255);
         canvas.drawRect(fullRect, paint);
         REPORTER_ASSERT(reporter, canvas.isFreshFrame());
     }
     {
         SkPaint paint;
-        paint.setStyle( SkPaint::kFill_Style );
-        paint.setAlpha( 255 );
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setAlpha(255);
         paint.setXfermodeMode(SkXfermode::kSrcIn_Mode);
         canvas.drawRect(fullRect, paint);
         REPORTER_ASSERT(reporter, !canvas.isFreshFrame());
     }
     {
         SkPaint paint;
-        paint.setStyle( SkPaint::kFill_Style );
+        paint.setStyle(SkPaint::kFill_Style);
         SkBitmap bmp;
         create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
         bmp.setIsOpaque(true);
@@ -127,14 +128,30 @@ static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
     // do not trigger frames to be marked as fresh
     {
         SkPaint paint;
-        paint.setStyle( SkPaint::kFill_Style );
-        paint.setAlpha( 254 );
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setAlpha(254);
+        canvas.drawRect(fullRect, paint);
+        REPORTER_ASSERT(reporter, !canvas.isFreshFrame());
+    }
+    {
+        SkPaint paint;
+        paint.setStyle(SkPaint::kFill_Style);
+        // Defining a cone that partially overlaps the canvas
+        const SkPoint pt1 = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0));
+        const SkScalar r1 = SkIntToScalar(1);
+        const SkPoint pt2 = SkPoint::Make(SkIntToScalar(10), SkIntToScalar(0));
+        const SkScalar r2 = SkIntToScalar(5);
+        const SkColor colors[2] = {SK_ColorWHITE, SK_ColorWHITE};
+        const SkScalar pos[2] = {0, SK_Scalar1};
+        SkShader* shader = SkGradientShader::CreateTwoPointConical(
+            pt1, r1, pt2, r2, colors, pos, 2, SkShader::kClamp_TileMode, NULL);
+        paint.setShader(shader)->unref();
         canvas.drawRect(fullRect, paint);
         REPORTER_ASSERT(reporter, !canvas.isFreshFrame());
     }
     {
         SkPaint paint;
-        paint.setStyle( SkPaint::kFill_Style );
+        paint.setStyle(SkPaint::kFill_Style);
         SkBitmap bmp;
         create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
         bmp.setIsOpaque(false);
@@ -169,8 +186,8 @@ static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
     {
         canvas.save(SkCanvas::kMatrixClip_SaveFlag);
         SkPaint paint;
-        paint.setStyle( SkPaint::kFill_Style );
-        paint.setAlpha( 255 );
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setAlpha(255);
         SkPath path;
         path.addCircle(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(2));
         canvas.clipPath(path, SkRegion::kIntersect_Op, false);
@@ -182,8 +199,8 @@ static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
     // Verify that stroked rect does not trigger a fresh frame
     {
         SkPaint paint;
-        paint.setStyle( SkPaint::kStroke_Style );
-        paint.setAlpha( 255 );
+        paint.setStyle(SkPaint::kStroke_Style);
+        paint.setAlpha(255);
         canvas.drawRect(fullRect, paint);
         REPORTER_ASSERT(reporter, !canvas.isFreshFrame());
     }
@@ -191,8 +208,8 @@ static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
     // Verify kSrcMode triggers a fresh frame even with transparent color
     {
         SkPaint paint;
-        paint.setStyle( SkPaint::kFill_Style );
-        paint.setAlpha( 100 );
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setAlpha(100);
         paint.setXfermodeMode(SkXfermode::kSrc_Mode);
         canvas.drawRect(fullRect, paint);
         REPORTER_ASSERT(reporter, canvas.isFreshFrame());