blob: d6002d39f5901817a12cdc92cfd70cbd539f7645 [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
8#include "gm.h"
9#include "SkPath.h"
10#include "SkRandom.h"
11#include "SkRRect.h"
12#include "SkSurface.h"
13
14namespace skiagm {
15
16constexpr SkRect kSrcImageClip{75, 75, 275, 275};
17
18/*
Brian Osman11052242016-10-27 14:47:55 -040019 * The purpose of this test is to exercise all three codepaths in GrRenderTargetContext
20 * (drawFilledRect, fillRectToRect, fillRectWithLocalMatrix) that pre-crop filled rects based on the
21 * clip.
csmartdalton97f6cd52016-07-13 13:37:08 -070022 *
23 * The test creates an image of a green square surrounded by red background, then draws this image
24 * 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 -050025 * background, scissor is never used, and ideally, all the rectangles draw in one GrDrawOp.
csmartdalton97f6cd52016-07-13 13:37:08 -070026 */
27class CroppedRectsGM : public GM {
28private:
29 SkString onShortName() override final { return SkString("croppedrects"); }
30 SkISize onISize() override { return SkISize::Make(500, 500); }
31
32 void onOnceBeforeDraw() override {
33 sk_sp<SkSurface> srcSurface = SkSurface::MakeRasterN32Premul(500, 500);
34 SkCanvas* srcCanvas = srcSurface->getCanvas();
35
36 srcCanvas->clear(SK_ColorRED);
37
38 SkPaint paint;
39 paint.setColor(0xff00ff00);
40 srcCanvas->drawRect(kSrcImageClip, paint);
41
42 constexpr SkScalar kStrokeWidth = 10;
43 SkPaint stroke;
44 stroke.setStyle(SkPaint::kStroke_Style);
45 stroke.setStrokeWidth(kStrokeWidth);
46 stroke.setColor(0xff008800);
47 srcCanvas->drawRect(kSrcImageClip.makeInset(kStrokeWidth / 2, kStrokeWidth / 2), stroke);
48
Robert Phillipsac6b1fa2017-03-20 08:38:50 -040049 fSrcImage = srcSurface->makeImageSnapshot();
Mike Reed0acd7952017-04-28 11:12:19 -040050 fSrcImageShader = fSrcImage->makeShader();
csmartdalton97f6cd52016-07-13 13:37:08 -070051 }
52
53 void onDraw(SkCanvas* canvas) override {
54 canvas->clear(SK_ColorWHITE);
55
56 {
Brian Osman11052242016-10-27 14:47:55 -040057 // GrRenderTargetContext::drawFilledRect.
csmartdalton97f6cd52016-07-13 13:37:08 -070058 SkAutoCanvasRestore acr(canvas, true);
59 SkPaint paint;
60 paint.setShader(fSrcImageShader);
61 paint.setFilterQuality(kNone_SkFilterQuality);
62 canvas->clipRect(kSrcImageClip);
63 canvas->drawPaint(paint);
64 }
65
66 {
Brian Osman11052242016-10-27 14:47:55 -040067 // GrRenderTargetContext::fillRectToRect.
csmartdalton97f6cd52016-07-13 13:37:08 -070068 SkAutoCanvasRestore acr(canvas, true);
69 SkPaint paint;
70 paint.setFilterQuality(kNone_SkFilterQuality);
71 SkRect drawRect = SkRect::MakeXYWH(350, 100, 100, 300);
72 canvas->clipRect(drawRect);
73 canvas->drawImageRect(fSrcImage.get(),
74 kSrcImageClip.makeOutset(0.5f * kSrcImageClip.width(),
75 kSrcImageClip.height()),
76 drawRect.makeOutset(0.5f * drawRect.width(), drawRect.height()),
77 &paint);
78 }
79
80 {
Brian Osman11052242016-10-27 14:47:55 -040081 // GrRenderTargetContext::fillRectWithLocalMatrix.
csmartdalton97f6cd52016-07-13 13:37:08 -070082 SkAutoCanvasRestore acr(canvas, true);
83 SkPath path;
84 path.moveTo(kSrcImageClip.fLeft - kSrcImageClip.width(), kSrcImageClip.centerY());
85 path.lineTo(kSrcImageClip.fRight + 3 * kSrcImageClip.width(), kSrcImageClip.centerY());
86 SkPaint paint;
87 paint.setStyle(SkPaint::kStroke_Style);
88 paint.setStrokeWidth(2 * kSrcImageClip.height());
89 paint.setShader(fSrcImageShader);
90 paint.setFilterQuality(kNone_SkFilterQuality);
Chris Daltonb246b942017-06-06 17:20:43 -060091 canvas->translate(23, 301);
csmartdalton97f6cd52016-07-13 13:37:08 -070092 canvas->scale(300 / kSrcImageClip.width(), 100 / kSrcImageClip.height());
Chris Daltonb246b942017-06-06 17:20:43 -060093 canvas->translate(-kSrcImageClip.left(), -kSrcImageClip.top());
csmartdalton97f6cd52016-07-13 13:37:08 -070094 canvas->clipRect(kSrcImageClip);
95 canvas->drawPath(path, paint);
96 }
97
Brian Salomon09d994e2016-12-21 11:14:46 -050098 // TODO: assert the draw target only has one op in the post-MDB world.
csmartdalton97f6cd52016-07-13 13:37:08 -070099 }
100
101 sk_sp<SkImage> fSrcImage;
102 sk_sp<SkShader> fSrcImageShader;
103
104 typedef GM INHERITED;
105};
106
107DEF_GM( return new CroppedRectsGM(); )
108
109}