blob: f3f10ae317b0664c60818df15d984b9898ffc8bd [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"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040010#include "GrCaps.h"
joshualitt04194f32016-01-13 10:08:27 -080011#include "GrContext.h"
Brian Osman11052242016-10-27 14:47:55 -040012#include "GrRenderTargetContextPriv.h"
bsalomonc41f4d62015-08-03 14:23:03 -070013#include "SkRRect.h"
joshualitt04194f32016-01-13 10:08:27 -080014#include "effects/GrRRectEffect.h"
Brian Salomon89527432016-12-16 09:52:16 -050015#include "ops/GrDrawOp.h"
Brian Salomonbaaf4392017-06-15 09:59:23 -040016#include "ops/GrRectOpFactory.h"
bsalomonc41f4d62015-08-03 14:23:03 -070017
18namespace skiagm {
19
20///////////////////////////////////////////////////////////////////////////////
21
22class BigRRectAAEffectGM : public GM {
23public:
bsalomon4a4f14b2015-12-09 10:17:35 -080024 BigRRectAAEffectGM(const SkRRect& rrect, const char* name)
25 : fRRect(rrect)
26 , fName(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;
31
32 // Add a pad between test cases.
33 fTestOffsetX = fTestWidth + kPad;
34 fTestOffsetY = fTestHeight + kPad;
35
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;
bsalomonc41f4d62015-08-03 14:23:03 -070040 }
41
42protected:
43 SkString onShortName() override {
bsalomon4a4f14b2015-12-09 10:17:35 -080044 SkString name;
45 name.printf("big_rrect_%s_aa_effect", fName);
46 return name;
bsalomonc41f4d62015-08-03 14:23:03 -070047 }
48
bsalomon4a4f14b2015-12-09 10:17:35 -080049 SkISize onISize() override { return SkISize::Make(fWidth, fHeight); }
bsalomonc41f4d62015-08-03 14:23:03 -070050
51 void onDraw(SkCanvas* canvas) override {
Brian Osman11052242016-10-27 14:47:55 -040052 GrRenderTargetContext* renderTargetContext =
53 canvas->internal_private_accessTopLayerRenderTargetContext();
54 if (!renderTargetContext) {
robertphillips175dd9b2016-04-28 14:32:04 -070055 skiagm::GM::DrawGpuOnlyMessage(canvas);
joshualitt04194f32016-01-13 10:08:27 -080056 return;
57 }
58
Robert Phillips7c525e62018-06-12 10:11:12 -040059 GrContext* context = canvas->getGrContext();
60 if (!context) {
61 return;
62 }
63
bsalomonc41f4d62015-08-03 14:23:03 -070064 SkPaint paint;
65
bsalomonc41f4d62015-08-03 14:23:03 -070066 int y = kPad;
67 int x = kPad;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050068 constexpr GrClipEdgeType kEdgeTypes[] = {
Ethan Nicholas1706f842017-11-10 11:58:19 -050069 GrClipEdgeType::kFillAA,
70 GrClipEdgeType::kInverseFillAA,
bsalomonc41f4d62015-08-03 14:23:03 -070071 };
bsalomon4a4f14b2015-12-09 10:17:35 -080072 SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight);
bsalomonc41f4d62015-08-03 14:23:03 -070073 for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) {
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050074 GrClipEdgeType edgeType = kEdgeTypes[et];
bsalomon4a4f14b2015-12-09 10:17:35 -080075 canvas->save();
halcanary9d524f22016-03-29 09:03:52 -070076 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
bsalomonc41f4d62015-08-03 14:23:03 -070077
bsalomon4a4f14b2015-12-09 10:17:35 -080078 // Draw a background for the test case
79 SkPaint paint;
80 paint.setColor(SK_ColorWHITE);
81 canvas->drawRect(testBounds, paint);
bsalomonc41f4d62015-08-03 14:23:03 -070082
bsalomon4a4f14b2015-12-09 10:17:35 -080083 SkRRect rrect = fRRect;
84 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
Brian Salomon14471772017-12-05 10:35:15 -050085 const auto& caps = *renderTargetContext->caps()->shaderCaps();
86 auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
bsalomon4a4f14b2015-12-09 10:17:35 -080087 SkASSERT(fp);
88 if (fp) {
Brian Salomon82f44312017-01-11 13:42:54 -050089 GrPaint grPaint;
Brian Salomonac70f842017-05-08 10:43:33 -040090 grPaint.setColor4f(GrColor4f(0, 0, 0, 1.f));
Brian Salomon82f44312017-01-11 13:42:54 -050091 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -070092 grPaint.addCoverageFragmentProcessor(std::move(fp));
bsalomon4a4f14b2015-12-09 10:17:35 -080093
94 SkRect bounds = testBounds;
95 bounds.offset(SkIntToScalar(x), SkIntToScalar(y));
96
Brian Salomonac70f842017-05-08 10:43:33 -040097 renderTargetContext->priv().testingOnly_addDrawOp(
Robert Phillips7c525e62018-06-12 10:11:12 -040098 GrRectOpFactory::MakeNonAAFill(context, std::move(grPaint),
99 SkMatrix::I(),
Brian Salomonbaaf4392017-06-15 09:59:23 -0400100 bounds, GrAAType::kNone));
bsalomon4a4f14b2015-12-09 10:17:35 -0800101 }
102 canvas->restore();
103 x = x + fTestOffsetX;
bsalomonc41f4d62015-08-03 14:23:03 -0700104 }
105 }
106
bsalomonc41f4d62015-08-03 14:23:03 -0700107private:
bsalomon4a4f14b2015-12-09 10:17:35 -0800108 // pad between test cases
mtkleindbfd7ab2016-09-01 11:24:54 -0700109 static constexpr int kPad = 7;
bsalomon4a4f14b2015-12-09 10:17:35 -0800110 // gap between rect for each case that is rendered and exterior of rrect
mtkleindbfd7ab2016-09-01 11:24:54 -0700111 static constexpr int kGap = 3;
bsalomonc41f4d62015-08-03 14:23:03 -0700112
bsalomon4a4f14b2015-12-09 10:17:35 -0800113 SkRRect fRRect;
114 int fWidth;
115 int fHeight;
116 int fTestWidth;
117 int fTestHeight;
118 int fTestOffsetX;
119 int fTestOffsetY;
120 const char* fName;
bsalomonc41f4d62015-08-03 14:23:03 -0700121 typedef GM INHERITED;
122};
123
124///////////////////////////////////////////////////////////////////////////////
bsalomon4a4f14b2015-12-09 10:17:35 -0800125// This value is motivated by bug chromium:477684. It has to be large to cause overflow in
126// the shader
mtkleindbfd7ab2016-09-01 11:24:54 -0700127constexpr int kSize = 700;
bsalomonc41f4d62015-08-03 14:23:03 -0700128
bsalomon4a4f14b2015-12-09 10:17:35 -0800129DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); )
130DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); )
131DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); )
132// The next two have small linear segments between the corners
133DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); )
134DEF_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 -0700135
136}