1 /* 2 * Copyright 2019 Google LLC. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "gm/gm.h" 9 10 #include "include/core/SkPath.h" 11 #include "include/gpu/GrContextOptions.h" 12 #include "include/gpu/GrRecordingContext.h" 13 #include "src/gpu/GrDirectContextPriv.h" 14 #include "src/gpu/GrDrawingManager.h" 15 #include "src/gpu/GrRecordingContextPriv.h" 16 #include "src/gpu/GrSurfaceDrawContext.h" 17 #include "tools/ToolUtils.h" 18 19 namespace skiagm { 20 21 #define ERR_MSG_ASSERT(COND) \ 22 do { \ 23 if (!(COND)) { \ 24 errorMsg->printf("preservefillrule.cpp(%i): assert(%s)", \ 25 __LINE__, #COND); \ 26 return DrawResult::kFail; \ 27 } \ 28 } while (false) 29 30 31 /** 32 * This test originally ensured that the ccpr path cache preserved fill rules properly. CCRP is gone 33 * now, but we decided to keep the test. 34 */ 35 class PreserveFillRuleGM : public GpuGM { 36 public: PreserveFillRuleGM(bool big)37 PreserveFillRuleGM(bool big) : fBig(big) , fStarSize((big) ? 200 : 20) {} 38 39 private: onShortName()40 SkString onShortName() override { 41 SkString name("preservefillrule"); 42 name += (fBig) ? "_big" : "_little"; 43 return name; 44 } onISize()45 SkISize onISize() override { return SkISize::Make(fStarSize * 2, fStarSize * 2); } 46 modifyGrContextOptions(GrContextOptions * ctxOptions)47 void modifyGrContextOptions(GrContextOptions* ctxOptions) override { 48 ctxOptions->fGpuPathRenderers = GpuPathRenderers::kCoverageCounting; 49 ctxOptions->fAllowPathMaskCaching = true; 50 } 51 onDraw(GrRecordingContext * rContext,GrSurfaceDrawContext * rtc,SkCanvas * canvas,SkString * errorMsg)52 DrawResult onDraw(GrRecordingContext* rContext, GrSurfaceDrawContext* rtc, SkCanvas* canvas, 53 SkString* errorMsg) override { 54 if (rtc->numSamples() > 1) { 55 errorMsg->set("ccpr is currently only used for coverage AA"); 56 return DrawResult::kSkip; 57 } 58 59 auto* ccpr = rContext->priv().drawingManager()->getCoverageCountingPathRenderer(); 60 if (!ccpr) { 61 errorMsg->set("ccpr only"); 62 return DrawResult::kSkip; 63 } 64 65 auto dContext = GrAsDirectContext(rContext); 66 if (!dContext) { 67 *errorMsg = "Requires a direct context."; 68 return skiagm::DrawResult::kSkip; 69 } 70 71 auto starRect = SkRect::MakeWH(fStarSize, fStarSize); 72 SkPath star7_winding = ToolUtils::make_star(starRect, 7); 73 star7_winding.setFillType(SkPathFillType::kWinding); 74 75 SkPath star7_evenOdd = star7_winding; 76 star7_evenOdd.transform(SkMatrix::Translate(0, fStarSize)); 77 star7_evenOdd.setFillType(SkPathFillType::kEvenOdd); 78 79 SkPath star5_winding = ToolUtils::make_star(starRect, 5); 80 star5_winding.transform(SkMatrix::Translate(fStarSize, 0)); 81 star5_winding.setFillType(SkPathFillType::kWinding); 82 83 SkPath star5_evenOdd = star5_winding; 84 star5_evenOdd.transform(SkMatrix::Translate(0, fStarSize)); 85 star5_evenOdd.setFillType(SkPathFillType::kEvenOdd); 86 87 SkPaint paint; 88 paint.setColor(SK_ColorGREEN); 89 paint.setAntiAlias(true); 90 91 canvas->clear(SK_ColorWHITE); 92 canvas->drawPath(star7_winding, paint); 93 canvas->drawPath(star7_evenOdd, paint); 94 canvas->drawPath(star5_winding, paint); 95 canvas->drawPath(star5_evenOdd, paint); 96 dContext->priv().flushSurface(rtc->asSurfaceProxy()); 97 98 return DrawResult::kOk; 99 } 100 101 private: 102 const bool fBig; 103 const int fStarSize; 104 }; 105 106 DEF_GM( return new PreserveFillRuleGM(true); ) 107 DEF_GM( return new PreserveFillRuleGM(false); ) 108 109 } // namespace skiagm 110