blob: 0ab125779631e2eb1422ee376c648843abb3ec46 [file] [log] [blame]
csmartdalton97f6cd52016-07-13 13:37:08 -07001/*
2 * Copyright 2016 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 Wagner7fde8e12019-05-01 17:28:53 -04009#include "include/core/SkCanvas.h"
10#include "include/core/SkColor.h"
11#include "include/core/SkFilterQuality.h"
12#include "include/core/SkImage.h"
13#include "include/core/SkPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkPath.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040015#include "include/core/SkRect.h"
16#include "include/core/SkRefCnt.h"
17#include "include/core/SkScalar.h"
18#include "include/core/SkShader.h"
19#include "include/core/SkSize.h"
20#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "include/core/SkSurface.h"
csmartdalton97f6cd52016-07-13 13:37:08 -070022
23namespace skiagm {
24
25constexpr SkRect kSrcImageClip{75, 75, 275, 275};
26
27/*
Brian Osman11052242016-10-27 14:47:55 -040028 * The purpose of this test is to exercise all three codepaths in GrRenderTargetContext
29 * (drawFilledRect, fillRectToRect, fillRectWithLocalMatrix) that pre-crop filled rects based on the
30 * clip.
csmartdalton97f6cd52016-07-13 13:37:08 -070031 *
32 * The test creates an image of a green square surrounded by red background, then draws this image
33 * in various ways with the red clipped out. The test is successful if there is no visible red
Brian Salomon09d994e2016-12-21 11:14:46 -050034 * background, scissor is never used, and ideally, all the rectangles draw in one GrDrawOp.
csmartdalton97f6cd52016-07-13 13:37:08 -070035 */
36class CroppedRectsGM : public GM {
37private:
38 SkString onShortName() override final { return SkString("croppedrects"); }
39 SkISize onISize() override { return SkISize::Make(500, 500); }
40
41 void onOnceBeforeDraw() override {
42 sk_sp<SkSurface> srcSurface = SkSurface::MakeRasterN32Premul(500, 500);
43 SkCanvas* srcCanvas = srcSurface->getCanvas();
44
45 srcCanvas->clear(SK_ColorRED);
46
47 SkPaint paint;
48 paint.setColor(0xff00ff00);
49 srcCanvas->drawRect(kSrcImageClip, paint);
50
51 constexpr SkScalar kStrokeWidth = 10;
52 SkPaint stroke;
53 stroke.setStyle(SkPaint::kStroke_Style);
54 stroke.setStrokeWidth(kStrokeWidth);
55 stroke.setColor(0xff008800);
56 srcCanvas->drawRect(kSrcImageClip.makeInset(kStrokeWidth / 2, kStrokeWidth / 2), stroke);
57
Robert Phillipsac6b1fa2017-03-20 08:38:50 -040058 fSrcImage = srcSurface->makeImageSnapshot();
Mike Reed0acd7952017-04-28 11:12:19 -040059 fSrcImageShader = fSrcImage->makeShader();
csmartdalton97f6cd52016-07-13 13:37:08 -070060 }
61
62 void onDraw(SkCanvas* canvas) override {
63 canvas->clear(SK_ColorWHITE);
64
65 {
Brian Osman11052242016-10-27 14:47:55 -040066 // GrRenderTargetContext::drawFilledRect.
csmartdalton97f6cd52016-07-13 13:37:08 -070067 SkAutoCanvasRestore acr(canvas, true);
68 SkPaint paint;
69 paint.setShader(fSrcImageShader);
70 paint.setFilterQuality(kNone_SkFilterQuality);
71 canvas->clipRect(kSrcImageClip);
72 canvas->drawPaint(paint);
73 }
74
75 {
Brian Osman11052242016-10-27 14:47:55 -040076 // GrRenderTargetContext::fillRectToRect.
csmartdalton97f6cd52016-07-13 13:37:08 -070077 SkAutoCanvasRestore acr(canvas, true);
78 SkPaint paint;
79 paint.setFilterQuality(kNone_SkFilterQuality);
80 SkRect drawRect = SkRect::MakeXYWH(350, 100, 100, 300);
81 canvas->clipRect(drawRect);
82 canvas->drawImageRect(fSrcImage.get(),
83 kSrcImageClip.makeOutset(0.5f * kSrcImageClip.width(),
84 kSrcImageClip.height()),
85 drawRect.makeOutset(0.5f * drawRect.width(), drawRect.height()),
86 &paint);
87 }
88
89 {
Brian Osman11052242016-10-27 14:47:55 -040090 // GrRenderTargetContext::fillRectWithLocalMatrix.
csmartdalton97f6cd52016-07-13 13:37:08 -070091 SkAutoCanvasRestore acr(canvas, true);
92 SkPath path;
93 path.moveTo(kSrcImageClip.fLeft - kSrcImageClip.width(), kSrcImageClip.centerY());
94 path.lineTo(kSrcImageClip.fRight + 3 * kSrcImageClip.width(), kSrcImageClip.centerY());
95 SkPaint paint;
96 paint.setStyle(SkPaint::kStroke_Style);
97 paint.setStrokeWidth(2 * kSrcImageClip.height());
98 paint.setShader(fSrcImageShader);
99 paint.setFilterQuality(kNone_SkFilterQuality);
Chris Daltonb246b942017-06-06 17:20:43 -0600100 canvas->translate(23, 301);
csmartdalton97f6cd52016-07-13 13:37:08 -0700101 canvas->scale(300 / kSrcImageClip.width(), 100 / kSrcImageClip.height());
Chris Daltonb246b942017-06-06 17:20:43 -0600102 canvas->translate(-kSrcImageClip.left(), -kSrcImageClip.top());
csmartdalton97f6cd52016-07-13 13:37:08 -0700103 canvas->clipRect(kSrcImageClip);
104 canvas->drawPath(path, paint);
105 }
106
Brian Salomon09d994e2016-12-21 11:14:46 -0500107 // TODO: assert the draw target only has one op in the post-MDB world.
csmartdalton97f6cd52016-07-13 13:37:08 -0700108 }
109
110 sk_sp<SkImage> fSrcImage;
111 sk_sp<SkShader> fSrcImageShader;
112
113 typedef GM INHERITED;
114};
115
116DEF_GM( return new CroppedRectsGM(); )
117
118}