blob: 93c13c4fcbed586485c6b1e7ed7fd034ba57599f [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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "include/gpu/GrContext.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040021#include "include/private/GrSharedEnums.h"
22#include "include/private/GrTypesPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/GrCaps.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040024#include "src/gpu/GrFragmentProcessor.h"
25#include "src/gpu/GrPaint.h"
26#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#include "src/gpu/GrRenderTargetContextPriv.h"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040028#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050029#include "src/gpu/effects/GrRRectEffect.h"
30#include "src/gpu/ops/GrDrawOp.h"
31#include "src/gpu/ops/GrFillRectOp.h"
32#include "tools/ToolUtils.h"
bsalomonc41f4d62015-08-03 14:23:03 -070033
Ben Wagner6a34f3a2019-05-01 10:59:30 -040034#include <memory>
35#include <utility>
36
bsalomonc41f4d62015-08-03 14:23:03 -070037namespace skiagm {
38
39///////////////////////////////////////////////////////////////////////////////
40
Chris Dalton3a778372019-02-07 15:23:36 -070041class BigRRectAAEffectGM : public GpuGM {
bsalomonc41f4d62015-08-03 14:23:03 -070042public:
bsalomon4a4f14b2015-12-09 10:17:35 -080043 BigRRectAAEffectGM(const SkRRect& rrect, const char* name)
44 : fRRect(rrect)
45 , fName(name) {
Mike Kleinea3f0142019-03-20 11:12:10 -050046 this->setBGColor(ToolUtils::color_to_565(SK_ColorBLUE));
bsalomon4a4f14b2015-12-09 10:17:35 -080047 // Each test case draws the rrect with gaps around it.
48 fTestWidth = SkScalarCeilToInt(rrect.width()) + 2 * kGap;
49 fTestHeight = SkScalarCeilToInt(rrect.height()) + 2 * kGap;
50
51 // Add a pad between test cases.
52 fTestOffsetX = fTestWidth + kPad;
53 fTestOffsetY = fTestHeight + kPad;
54
55 // We draw two tests in x (fill and inv-fill) and pad around
56 // all four sides of the image.
57 fWidth = 2 * fTestOffsetX + kPad;
58 fHeight = fTestOffsetY + kPad;
bsalomonc41f4d62015-08-03 14:23:03 -070059 }
60
61protected:
62 SkString onShortName() override {
bsalomon4a4f14b2015-12-09 10:17:35 -080063 SkString name;
64 name.printf("big_rrect_%s_aa_effect", fName);
65 return name;
bsalomonc41f4d62015-08-03 14:23:03 -070066 }
67
bsalomon4a4f14b2015-12-09 10:17:35 -080068 SkISize onISize() override { return SkISize::Make(fWidth, fHeight); }
bsalomonc41f4d62015-08-03 14:23:03 -070069
Chris Dalton3a778372019-02-07 15:23:36 -070070 void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
71 SkCanvas* canvas) override {
bsalomonc41f4d62015-08-03 14:23:03 -070072 SkPaint paint;
73
bsalomonc41f4d62015-08-03 14:23:03 -070074 int y = kPad;
75 int x = kPad;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050076 constexpr GrClipEdgeType kEdgeTypes[] = {
Ethan Nicholas1706f842017-11-10 11:58:19 -050077 GrClipEdgeType::kFillAA,
78 GrClipEdgeType::kInverseFillAA,
bsalomonc41f4d62015-08-03 14:23:03 -070079 };
bsalomon4a4f14b2015-12-09 10:17:35 -080080 SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight);
bsalomonc41f4d62015-08-03 14:23:03 -070081 for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) {
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050082 GrClipEdgeType edgeType = kEdgeTypes[et];
bsalomon4a4f14b2015-12-09 10:17:35 -080083 canvas->save();
halcanary9d524f22016-03-29 09:03:52 -070084 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
bsalomonc41f4d62015-08-03 14:23:03 -070085
bsalomon4a4f14b2015-12-09 10:17:35 -080086 // Draw a background for the test case
87 SkPaint paint;
88 paint.setColor(SK_ColorWHITE);
89 canvas->drawRect(testBounds, paint);
bsalomonc41f4d62015-08-03 14:23:03 -070090
bsalomon4a4f14b2015-12-09 10:17:35 -080091 SkRRect rrect = fRRect;
92 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
Ethan Nicholaseace9352018-10-15 20:09:54 +000093 const auto& caps = *renderTargetContext->caps()->shaderCaps();
94 auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
bsalomon4a4f14b2015-12-09 10:17:35 -080095 SkASSERT(fp);
96 if (fp) {
Brian Salomon82f44312017-01-11 13:42:54 -050097 GrPaint grPaint;
Brian Osmancb3d0872018-10-16 15:19:28 -040098 grPaint.setColor4f({ 0, 0, 0, 1.f });
Brian Salomon82f44312017-01-11 13:42:54 -050099 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -0700100 grPaint.addCoverageFragmentProcessor(std::move(fp));
bsalomon4a4f14b2015-12-09 10:17:35 -0800101
102 SkRect bounds = testBounds;
103 bounds.offset(SkIntToScalar(x), SkIntToScalar(y));
104
Brian Salomonac70f842017-05-08 10:43:33 -0400105 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400106 GrFillRectOp::MakeNonAARect(context, std::move(grPaint),
107 SkMatrix::I(), bounds));
bsalomon4a4f14b2015-12-09 10:17:35 -0800108 }
109 canvas->restore();
110 x = x + fTestOffsetX;
bsalomonc41f4d62015-08-03 14:23:03 -0700111 }
112 }
113
bsalomonc41f4d62015-08-03 14:23:03 -0700114private:
bsalomon4a4f14b2015-12-09 10:17:35 -0800115 // pad between test cases
mtkleindbfd7ab2016-09-01 11:24:54 -0700116 static constexpr int kPad = 7;
bsalomon4a4f14b2015-12-09 10:17:35 -0800117 // gap between rect for each case that is rendered and exterior of rrect
mtkleindbfd7ab2016-09-01 11:24:54 -0700118 static constexpr int kGap = 3;
bsalomonc41f4d62015-08-03 14:23:03 -0700119
bsalomon4a4f14b2015-12-09 10:17:35 -0800120 SkRRect fRRect;
121 int fWidth;
122 int fHeight;
123 int fTestWidth;
124 int fTestHeight;
125 int fTestOffsetX;
126 int fTestOffsetY;
127 const char* fName;
bsalomonc41f4d62015-08-03 14:23:03 -0700128 typedef GM INHERITED;
129};
130
131///////////////////////////////////////////////////////////////////////////////
bsalomon4a4f14b2015-12-09 10:17:35 -0800132// This value is motivated by bug chromium:477684. It has to be large to cause overflow in
133// the shader
mtkleindbfd7ab2016-09-01 11:24:54 -0700134constexpr int kSize = 700;
bsalomonc41f4d62015-08-03 14:23:03 -0700135
bsalomon4a4f14b2015-12-09 10:17:35 -0800136DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); )
137DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); )
138DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); )
139// The next two have small linear segments between the corners
140DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); )
141DEF_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 -0700142
143}