blob: 5802eaf9e04ccb3e49f58a58b87c12cc69998db5 [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
8#include "gm.h"
Mike Klein33d20552017-03-22 13:47:51 -04009#include "sk_tool_utils.h"
joshualitt04194f32016-01-13 10:08:27 -080010#include "GrContext.h"
Brian Osman11052242016-10-27 14:47:55 -040011#include "GrRenderTargetContextPriv.h"
bsalomonc41f4d62015-08-03 14:23:03 -070012#include "SkRRect.h"
joshualitt04194f32016-01-13 10:08:27 -080013#include "effects/GrRRectEffect.h"
Brian Salomon89527432016-12-16 09:52:16 -050014#include "ops/GrDrawOp.h"
Brian Salomonbaaf4392017-06-15 09:59:23 -040015#include "ops/GrRectOpFactory.h"
bsalomonc41f4d62015-08-03 14:23:03 -070016
17namespace skiagm {
18
19///////////////////////////////////////////////////////////////////////////////
20
21class BigRRectAAEffectGM : public GM {
22public:
bsalomon4a4f14b2015-12-09 10:17:35 -080023 BigRRectAAEffectGM(const SkRRect& rrect, const char* name)
24 : fRRect(rrect)
25 , fName(name) {
26 this->setBGColor(sk_tool_utils::color_to_565(SK_ColorBLUE));
27 // Each test case draws the rrect with gaps around it.
28 fTestWidth = SkScalarCeilToInt(rrect.width()) + 2 * kGap;
29 fTestHeight = SkScalarCeilToInt(rrect.height()) + 2 * kGap;
30
31 // Add a pad between test cases.
32 fTestOffsetX = fTestWidth + kPad;
33 fTestOffsetY = fTestHeight + kPad;
34
35 // We draw two tests in x (fill and inv-fill) and pad around
36 // all four sides of the image.
37 fWidth = 2 * fTestOffsetX + kPad;
38 fHeight = fTestOffsetY + kPad;
bsalomonc41f4d62015-08-03 14:23:03 -070039 }
40
41protected:
42 SkString onShortName() override {
bsalomon4a4f14b2015-12-09 10:17:35 -080043 SkString name;
44 name.printf("big_rrect_%s_aa_effect", fName);
45 return name;
bsalomonc41f4d62015-08-03 14:23:03 -070046 }
47
bsalomon4a4f14b2015-12-09 10:17:35 -080048 SkISize onISize() override { return SkISize::Make(fWidth, fHeight); }
bsalomonc41f4d62015-08-03 14:23:03 -070049
50 void onDraw(SkCanvas* canvas) override {
Brian Osman11052242016-10-27 14:47:55 -040051 GrRenderTargetContext* renderTargetContext =
52 canvas->internal_private_accessTopLayerRenderTargetContext();
53 if (!renderTargetContext) {
robertphillips175dd9b2016-04-28 14:32:04 -070054 skiagm::GM::DrawGpuOnlyMessage(canvas);
joshualitt04194f32016-01-13 10:08:27 -080055 return;
56 }
57
Robert Phillips7c525e62018-06-12 10:11:12 -040058 GrContext* context = canvas->getGrContext();
59 if (!context) {
60 return;
61 }
62
bsalomonc41f4d62015-08-03 14:23:03 -070063 SkPaint paint;
64
bsalomonc41f4d62015-08-03 14:23:03 -070065 int y = kPad;
66 int x = kPad;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050067 constexpr GrClipEdgeType kEdgeTypes[] = {
Ethan Nicholas1706f842017-11-10 11:58:19 -050068 GrClipEdgeType::kFillAA,
69 GrClipEdgeType::kInverseFillAA,
bsalomonc41f4d62015-08-03 14:23:03 -070070 };
bsalomon4a4f14b2015-12-09 10:17:35 -080071 SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight);
bsalomonc41f4d62015-08-03 14:23:03 -070072 for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) {
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050073 GrClipEdgeType edgeType = kEdgeTypes[et];
bsalomon4a4f14b2015-12-09 10:17:35 -080074 canvas->save();
halcanary9d524f22016-03-29 09:03:52 -070075 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
bsalomonc41f4d62015-08-03 14:23:03 -070076
bsalomon4a4f14b2015-12-09 10:17:35 -080077 // Draw a background for the test case
78 SkPaint paint;
79 paint.setColor(SK_ColorWHITE);
80 canvas->drawRect(testBounds, paint);
bsalomonc41f4d62015-08-03 14:23:03 -070081
bsalomon4a4f14b2015-12-09 10:17:35 -080082 SkRRect rrect = fRRect;
83 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
Ethan Nicholas222e2752018-10-11 11:21:34 -040084 auto fp = GrRRectEffect::Make(edgeType, rrect, context);
bsalomon4a4f14b2015-12-09 10:17:35 -080085 SkASSERT(fp);
86 if (fp) {
Brian Salomon82f44312017-01-11 13:42:54 -050087 GrPaint grPaint;
Brian Salomonac70f842017-05-08 10:43:33 -040088 grPaint.setColor4f(GrColor4f(0, 0, 0, 1.f));
Brian Salomon82f44312017-01-11 13:42:54 -050089 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -070090 grPaint.addCoverageFragmentProcessor(std::move(fp));
bsalomon4a4f14b2015-12-09 10:17:35 -080091
92 SkRect bounds = testBounds;
93 bounds.offset(SkIntToScalar(x), SkIntToScalar(y));
94
Brian Salomonac70f842017-05-08 10:43:33 -040095 renderTargetContext->priv().testingOnly_addDrawOp(
Robert Phillips7c525e62018-06-12 10:11:12 -040096 GrRectOpFactory::MakeNonAAFill(context, std::move(grPaint),
97 SkMatrix::I(),
Brian Salomonbaaf4392017-06-15 09:59:23 -040098 bounds, GrAAType::kNone));
bsalomon4a4f14b2015-12-09 10:17:35 -080099 }
100 canvas->restore();
101 x = x + fTestOffsetX;
bsalomonc41f4d62015-08-03 14:23:03 -0700102 }
103 }
104
bsalomonc41f4d62015-08-03 14:23:03 -0700105private:
bsalomon4a4f14b2015-12-09 10:17:35 -0800106 // pad between test cases
mtkleindbfd7ab2016-09-01 11:24:54 -0700107 static constexpr int kPad = 7;
bsalomon4a4f14b2015-12-09 10:17:35 -0800108 // gap between rect for each case that is rendered and exterior of rrect
mtkleindbfd7ab2016-09-01 11:24:54 -0700109 static constexpr int kGap = 3;
bsalomonc41f4d62015-08-03 14:23:03 -0700110
bsalomon4a4f14b2015-12-09 10:17:35 -0800111 SkRRect fRRect;
112 int fWidth;
113 int fHeight;
114 int fTestWidth;
115 int fTestHeight;
116 int fTestOffsetX;
117 int fTestOffsetY;
118 const char* fName;
bsalomonc41f4d62015-08-03 14:23:03 -0700119 typedef GM INHERITED;
120};
121
122///////////////////////////////////////////////////////////////////////////////
bsalomon4a4f14b2015-12-09 10:17:35 -0800123// This value is motivated by bug chromium:477684. It has to be large to cause overflow in
124// the shader
mtkleindbfd7ab2016-09-01 11:24:54 -0700125constexpr int kSize = 700;
bsalomonc41f4d62015-08-03 14:23:03 -0700126
bsalomon4a4f14b2015-12-09 10:17:35 -0800127DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); )
128DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); )
129DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); )
130// The next two have small linear segments between the corners
131DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); )
132DEF_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 -0700133
134}