2 * Copyright 2015 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 #include "sk_tool_utils.h"
11 #include "GrContext.h"
12 #include "GrRenderTargetContextPriv.h"
14 #include "effects/GrRRectEffect.h"
15 #include "ops/GrDrawOp.h"
16 #include "ops/GrNonAAFillRectOp.h"
20 ///////////////////////////////////////////////////////////////////////////////
22 class BigRRectAAEffectGM : public GM {
24 BigRRectAAEffectGM(const SkRRect& rrect, const char* name)
27 this->setBGColor(sk_tool_utils::color_to_565(SK_ColorBLUE));
28 // Each test case draws the rrect with gaps around it.
29 fTestWidth = SkScalarCeilToInt(rrect.width()) + 2 * kGap;
30 fTestHeight = SkScalarCeilToInt(rrect.height()) + 2 * kGap;
32 // Add a pad between test cases.
33 fTestOffsetX = fTestWidth + kPad;
34 fTestOffsetY = fTestHeight + kPad;
36 // We draw two tests in x (fill and inv-fill) and pad around
37 // all four sides of the image.
38 fWidth = 2 * fTestOffsetX + kPad;
39 fHeight = fTestOffsetY + kPad;
43 SkString onShortName() override {
45 name.printf("big_rrect_%s_aa_effect", fName);
49 SkISize onISize() override { return SkISize::Make(fWidth, fHeight); }
51 void onDraw(SkCanvas* canvas) override {
52 GrRenderTargetContext* renderTargetContext =
53 canvas->internal_private_accessTopLayerRenderTargetContext();
54 if (!renderTargetContext) {
55 skiagm::GM::DrawGpuOnlyMessage(canvas);
63 constexpr GrPrimitiveEdgeType kEdgeTypes[] = {
64 kFillAA_GrProcessorEdgeType,
65 kInverseFillAA_GrProcessorEdgeType,
67 SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight);
68 for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) {
69 GrPrimitiveEdgeType edgeType = kEdgeTypes[et];
71 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
73 // Draw a background for the test case
75 paint.setColor(SK_ColorWHITE);
76 canvas->drawRect(testBounds, paint);
78 SkRRect rrect = fRRect;
79 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
80 sk_sp<GrFragmentProcessor> fp(GrRRectEffect::Make(edgeType, rrect));
84 grPaint.setColor4f(GrColor4f(0, 0, 0, 1.f));
85 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
86 grPaint.addCoverageFragmentProcessor(std::move(fp));
88 SkRect bounds = testBounds;
89 bounds.offset(SkIntToScalar(x), SkIntToScalar(y));
91 renderTargetContext->priv().testingOnly_addDrawOp(
92 GrNonAAFillRectOp::Make(std::move(grPaint), SkMatrix::I(), bounds,
93 nullptr, nullptr, GrAAType::kNone));
101 // pad between test cases
102 static constexpr int kPad = 7;
103 // gap between rect for each case that is rendered and exterior of rrect
104 static constexpr int kGap = 3;
114 typedef GM INHERITED;
117 ///////////////////////////////////////////////////////////////////////////////
118 // This value is motivated by bug chromium:477684. It has to be large to cause overflow in
120 constexpr int kSize = 700;
122 DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); )
123 DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); )
124 DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); )
125 // The next two have small linear segments between the corners
126 DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); )
127 DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 15.f), "elliptical_corner"); )