blob: 5ea95a47b3d15d80f0d65d6af669c08b09d2c78c [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/GrTypesPriv.h"
Robert Phillips7a0d3c32021-07-21 15:39:51 -040021#include "src/core/SkCanvasPriv.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"
Ben Wagner6a34f3a2019-05-01 10:59:30 -040025#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/effects/GrRRectEffect.h"
Robert Phillipsfbf02142021-09-01 16:31:34 -040027#include "src/gpu/ops/FillRectOp.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "src/gpu/ops/GrDrawOp.h"
Robert Phillips4dca8312021-07-28 15:13:20 -040029#include "src/gpu/v1/SurfaceDrawContext_v1.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "tools/ToolUtils.h"
bsalomonc41f4d62015-08-03 14:23:03 -070031
Ben Wagner6a34f3a2019-05-01 10:59:30 -040032#include <memory>
33#include <utility>
34
bsalomonc41f4d62015-08-03 14:23:03 -070035namespace skiagm {
36
37///////////////////////////////////////////////////////////////////////////////
38
Chris Dalton3a778372019-02-07 15:23:36 -070039class BigRRectAAEffectGM : public GpuGM {
bsalomonc41f4d62015-08-03 14:23:03 -070040public:
bsalomon4a4f14b2015-12-09 10:17:35 -080041 BigRRectAAEffectGM(const SkRRect& rrect, const char* name)
42 : fRRect(rrect)
43 , fName(name) {
Mike Kleinea3f0142019-03-20 11:12:10 -050044 this->setBGColor(ToolUtils::color_to_565(SK_ColorBLUE));
bsalomon4a4f14b2015-12-09 10:17:35 -080045 // Each test case draws the rrect with gaps around it.
46 fTestWidth = SkScalarCeilToInt(rrect.width()) + 2 * kGap;
47 fTestHeight = SkScalarCeilToInt(rrect.height()) + 2 * kGap;
48
49 // Add a pad between test cases.
50 fTestOffsetX = fTestWidth + kPad;
51 fTestOffsetY = fTestHeight + kPad;
52
53 // We draw two tests in x (fill and inv-fill) and pad around
54 // all four sides of the image.
55 fWidth = 2 * fTestOffsetX + kPad;
56 fHeight = fTestOffsetY + kPad;
bsalomonc41f4d62015-08-03 14:23:03 -070057 }
58
59protected:
60 SkString onShortName() override {
bsalomon4a4f14b2015-12-09 10:17:35 -080061 SkString name;
62 name.printf("big_rrect_%s_aa_effect", fName);
63 return name;
bsalomonc41f4d62015-08-03 14:23:03 -070064 }
65
bsalomon4a4f14b2015-12-09 10:17:35 -080066 SkISize onISize() override { return SkISize::Make(fWidth, fHeight); }
bsalomonc41f4d62015-08-03 14:23:03 -070067
Robert Phillips7a0d3c32021-07-21 15:39:51 -040068 DrawResult onDraw(GrRecordingContext* rContext, SkCanvas* canvas, SkString* errorMsg) override {
Robert Phillips7a0d3c32021-07-21 15:39:51 -040069 auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(canvas);
70 if (!sdc) {
71 *errorMsg = kErrorMsg_DrawSkippedGpuOnly;
72 return DrawResult::kSkip;
73 }
74
bsalomonc41f4d62015-08-03 14:23:03 -070075 int y = kPad;
76 int x = kPad;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050077 constexpr GrClipEdgeType kEdgeTypes[] = {
Ethan Nicholas1706f842017-11-10 11:58:19 -050078 GrClipEdgeType::kFillAA,
79 GrClipEdgeType::kInverseFillAA,
bsalomonc41f4d62015-08-03 14:23:03 -070080 };
bsalomon4a4f14b2015-12-09 10:17:35 -080081 SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight);
bsalomonc41f4d62015-08-03 14:23:03 -070082 for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) {
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050083 GrClipEdgeType edgeType = kEdgeTypes[et];
bsalomon4a4f14b2015-12-09 10:17:35 -080084 canvas->save();
halcanary9d524f22016-03-29 09:03:52 -070085 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
bsalomonc41f4d62015-08-03 14:23:03 -070086
bsalomon4a4f14b2015-12-09 10:17:35 -080087 // Draw a background for the test case
88 SkPaint paint;
89 paint.setColor(SK_ColorWHITE);
90 canvas->drawRect(testBounds, paint);
bsalomonc41f4d62015-08-03 14:23:03 -070091
bsalomon4a4f14b2015-12-09 10:17:35 -080092 SkRRect rrect = fRRect;
93 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
Robert Phillips7a0d3c32021-07-21 15:39:51 -040094 const auto& caps = *rContext->priv().caps()->shaderCaps();
John Stiles851b90e2020-06-17 13:53:37 -040095 auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, edgeType, rrect,
96 caps);
97 SkASSERT(success);
98 if (success) {
99 SkASSERT(fp);
Brian Salomon82f44312017-01-11 13:42:54 -0500100 GrPaint grPaint;
Brian Osmancb3d0872018-10-16 15:19:28 -0400101 grPaint.setColor4f({ 0, 0, 0, 1.f });
Brian Salomon82f44312017-01-11 13:42:54 -0500102 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
John Stiles41d91b62020-07-21 14:39:40 -0400103 grPaint.setCoverageFragmentProcessor(std::move(fp));
bsalomon4a4f14b2015-12-09 10:17:35 -0800104
105 SkRect bounds = testBounds;
106 bounds.offset(SkIntToScalar(x), SkIntToScalar(y));
107
Robert Phillipsfbf02142021-09-01 16:31:34 -0400108 sdc->addDrawOp(skgpu::v1::FillRectOp::MakeNonAARect(
Robert Phillips7a0d3c32021-07-21 15:39:51 -0400109 rContext, std::move(grPaint), SkMatrix::I(), bounds));
bsalomon4a4f14b2015-12-09 10:17:35 -0800110 }
111 canvas->restore();
112 x = x + fTestOffsetX;
bsalomonc41f4d62015-08-03 14:23:03 -0700113 }
Robert Phillips7a0d3c32021-07-21 15:39:51 -0400114
115 return DrawResult::kOk;
bsalomonc41f4d62015-08-03 14:23:03 -0700116 }
117
bsalomonc41f4d62015-08-03 14:23:03 -0700118private:
bsalomon4a4f14b2015-12-09 10:17:35 -0800119 // pad between test cases
mtkleindbfd7ab2016-09-01 11:24:54 -0700120 static constexpr int kPad = 7;
bsalomon4a4f14b2015-12-09 10:17:35 -0800121 // gap between rect for each case that is rendered and exterior of rrect
mtkleindbfd7ab2016-09-01 11:24:54 -0700122 static constexpr int kGap = 3;
bsalomonc41f4d62015-08-03 14:23:03 -0700123
bsalomon4a4f14b2015-12-09 10:17:35 -0800124 SkRRect fRRect;
125 int fWidth;
126 int fHeight;
127 int fTestWidth;
128 int fTestHeight;
129 int fTestOffsetX;
130 int fTestOffsetY;
131 const char* fName;
John Stiles7571f9e2020-09-02 22:42:33 -0400132 using INHERITED = GM;
bsalomonc41f4d62015-08-03 14:23:03 -0700133};
134
135///////////////////////////////////////////////////////////////////////////////
bsalomon4a4f14b2015-12-09 10:17:35 -0800136// This value is motivated by bug chromium:477684. It has to be large to cause overflow in
137// the shader
mtkleindbfd7ab2016-09-01 11:24:54 -0700138constexpr int kSize = 700;
bsalomonc41f4d62015-08-03 14:23:03 -0700139
bsalomon4a4f14b2015-12-09 10:17:35 -0800140DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); )
141DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); )
142DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); )
143// The next two have small linear segments between the corners
144DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); )
145DEF_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 -0700146
John Stilesa6841be2020-08-06 14:11:56 -0400147} // namespace skiagm