From: commit-bot@chromium.org Date: Wed, 20 Mar 2013 00:49:57 +0000 (+0000) Subject: Fixing deferred canvas bug caused by SkTwoPointConicalGradient declaring itself as... X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~13066 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3fbab82bd30158ccabc708a20419025923e08655;p=platform%2Fupstream%2FlibSkiaSharp.git Fixing deferred canvas bug caused by SkTwoPointConicalGradient declaring itself as opaque. 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 --- diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp index d3fb4dd..38aa60c 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.cpp +++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp @@ -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); diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h index e02c390..0807ae3 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.h +++ b/src/effects/gradients/SkTwoPointConicalGradient.h @@ -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; } diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp index a752c83..a95e09c 100644 --- a/tests/DeferredCanvasTest.cpp +++ b/tests/DeferredCanvasTest.cpp @@ -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());