blob: 492836f5ba0f41c9332a65251d714d4776a6033b [file] [log] [blame]
bsalomonc41f4d62015-08-03 14:23:03 -07001/*
2 * Copyright 2015 Google Inc.
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -04009#include "include/core/SkBlendMode.h"
10#include "include/core/SkCanvas.h"
11#include "include/core/SkColor.h"
12#include "include/core/SkMatrix.h"
13#include "include/core/SkPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkRRect.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040015#include "include/core/SkRect.h"
16#include "include/core/SkScalar.h"
17#include "include/core/SkSize.h"
18#include "include/core/SkString.h"
19#include "include/core/SkTypes.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040020#include "include/private/GrSharedEnums.h"
21#include "include/private/GrTypesPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050022#include "src/gpu/GrCaps.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040023#include "src/gpu/GrFragmentProcessor.h"
24#include "src/gpu/GrPaint.h"
25#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/GrRenderTargetContextPriv.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040027#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "src/gpu/effects/GrRRectEffect.h"
29#include "src/gpu/ops/GrDrawOp.h"
30#include "src/gpu/ops/GrFillRectOp.h"
31#include "tools/ToolUtils.h"
bsalomonc41f4d62015-08-03 14:23:03 -070032
Ben Wagner6a34f3a2019-05-01 10:59:30 -040033#include <memory>
34#include <utility>
35
bsalomonc41f4d62015-08-03 14:23:03 -070036namespace skiagm {
37
38///////////////////////////////////////////////////////////////////////////////
39
Chris Dalton3a778372019-02-07 15:23:36 -070040class BigRRectAAEffectGM : public GpuGM {
bsalomonc41f4d62015-08-03 14:23:03 -070041public:
bsalomon4a4f14b2015-12-09 10:17:35 -080042 BigRRectAAEffectGM(const SkRRect& rrect, const char* name)
43 : fRRect(rrect)
44 , fName(name) {
Mike Kleinea3f0142019-03-20 11:12:10 -050045 this->setBGColor(ToolUtils::color_to_565(SK_ColorBLUE));
bsalomon4a4f14b2015-12-09 10:17:35 -080046 // Each test case draws the rrect with gaps around it.
47 fTestWidth = SkScalarCeilToInt(rrect.width()) + 2 * kGap;
48 fTestHeight = SkScalarCeilToInt(rrect.height()) + 2 * kGap;
49
50 // Add a pad between test cases.
51 fTestOffsetX = fTestWidth + kPad;
52 fTestOffsetY = fTestHeight + kPad;
53
54 // We draw two tests in x (fill and inv-fill) and pad around
55 // all four sides of the image.
56 fWidth = 2 * fTestOffsetX + kPad;
57 fHeight = fTestOffsetY + kPad;
bsalomonc41f4d62015-08-03 14:23:03 -070058 }
59
60protected:
61 SkString onShortName() override {
bsalomon4a4f14b2015-12-09 10:17:35 -080062 SkString name;
63 name.printf("big_rrect_%s_aa_effect", fName);
64 return name;
bsalomonc41f4d62015-08-03 14:23:03 -070065 }
66
bsalomon4a4f14b2015-12-09 10:17:35 -080067 SkISize onISize() override { return SkISize::Make(fWidth, fHeight); }
bsalomonc41f4d62015-08-03 14:23:03 -070068
Robert Phillips95c250c2020-06-29 15:36:12 -040069 void onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Chris Dalton3a778372019-02-07 15:23:36 -070070 SkCanvas* canvas) override {
bsalomonc41f4d62015-08-03 14:23:03 -070071 SkPaint paint;
72
bsalomonc41f4d62015-08-03 14:23:03 -070073 int y = kPad;
74 int x = kPad;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050075 constexpr GrClipEdgeType kEdgeTypes[] = {
Ethan Nicholas1706f842017-11-10 11:58:19 -050076 GrClipEdgeType::kFillAA,
77 GrClipEdgeType::kInverseFillAA,
bsalomonc41f4d62015-08-03 14:23:03 -070078 };
bsalomon4a4f14b2015-12-09 10:17:35 -080079 SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight);
bsalomonc41f4d62015-08-03 14:23:03 -070080 for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) {
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050081 GrClipEdgeType edgeType = kEdgeTypes[et];
bsalomon4a4f14b2015-12-09 10:17:35 -080082 canvas->save();
halcanary9d524f22016-03-29 09:03:52 -070083 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
bsalomonc41f4d62015-08-03 14:23:03 -070084
bsalomon4a4f14b2015-12-09 10:17:35 -080085 // Draw a background for the test case
86 SkPaint paint;
87 paint.setColor(SK_ColorWHITE);
88 canvas->drawRect(testBounds, paint);
bsalomonc41f4d62015-08-03 14:23:03 -070089
bsalomon4a4f14b2015-12-09 10:17:35 -080090 SkRRect rrect = fRRect;
91 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
Ethan Nicholaseace9352018-10-15 20:09:54 +000092 const auto& caps = *renderTargetContext->caps()->shaderCaps();
John Stiles851b90e2020-06-17 13:53:37 -040093 auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, edgeType, rrect,
94 caps);
95 SkASSERT(success);
96 if (success) {
97 SkASSERT(fp);
Brian Salomon82f44312017-01-11 13:42:54 -050098 GrPaint grPaint;
Brian Osmancb3d0872018-10-16 15:19:28 -040099 grPaint.setColor4f({ 0, 0, 0, 1.f });
Brian Salomon82f44312017-01-11 13:42:54 -0500100 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
John Stiles41d91b62020-07-21 14:39:40 -0400101 grPaint.setCoverageFragmentProcessor(std::move(fp));
bsalomon4a4f14b2015-12-09 10:17:35 -0800102
103 SkRect bounds = testBounds;
104 bounds.offset(SkIntToScalar(x), SkIntToScalar(y));
105
Brian Salomonac70f842017-05-08 10:43:33 -0400106 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400107 GrFillRectOp::MakeNonAARect(context, std::move(grPaint),
108 SkMatrix::I(), bounds));
bsalomon4a4f14b2015-12-09 10:17:35 -0800109 }
110 canvas->restore();
111 x = x + fTestOffsetX;
bsalomonc41f4d62015-08-03 14:23:03 -0700112 }
113 }
114
bsalomonc41f4d62015-08-03 14:23:03 -0700115private:
bsalomon4a4f14b2015-12-09 10:17:35 -0800116 // pad between test cases
mtkleindbfd7ab2016-09-01 11:24:54 -0700117 static constexpr int kPad = 7;
bsalomon4a4f14b2015-12-09 10:17:35 -0800118 // gap between rect for each case that is rendered and exterior of rrect
mtkleindbfd7ab2016-09-01 11:24:54 -0700119 static constexpr int kGap = 3;
bsalomonc41f4d62015-08-03 14:23:03 -0700120
bsalomon4a4f14b2015-12-09 10:17:35 -0800121 SkRRect fRRect;
122 int fWidth;
123 int fHeight;
124 int fTestWidth;
125 int fTestHeight;
126 int fTestOffsetX;
127 int fTestOffsetY;
128 const char* fName;
John Stiles7571f9e2020-09-02 22:42:33 -0400129 using INHERITED = GM;
bsalomonc41f4d62015-08-03 14:23:03 -0700130};
131
132///////////////////////////////////////////////////////////////////////////////
bsalomon4a4f14b2015-12-09 10:17:35 -0800133// This value is motivated by bug chromium:477684. It has to be large to cause overflow in
134// the shader
mtkleindbfd7ab2016-09-01 11:24:54 -0700135constexpr int kSize = 700;
bsalomonc41f4d62015-08-03 14:23:03 -0700136
bsalomon4a4f14b2015-12-09 10:17:35 -0800137DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); )
138DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); )
139DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); )
140// The next two have small linear segments between the corners
141DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); )
142DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 15.f), "elliptical_corner"); )
bsalomonc41f4d62015-08-03 14:23:03 -0700143
John Stilesa6841be2020-08-06 14:11:56 -0400144} // namespace skiagm