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