blob: 5c36c548155e46451f91d20f805dd48500e1a12d [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/*
19 * The purpose of this test is to exercise all three codepaths in GrDrawContext (drawFilledRect,
20 * fillRectToRect, fillRectWithLocalMatrix) that pre-crop filled rects based on the clip.
21 *
22 * The test creates an image of a green square surrounded by red background, then draws this image
23 * in various ways with the red clipped out. The test is successful if there is no visible red
24 * background, scissor is never used, and ideally, all the rectangles draw in one batch.
25 */
26class CroppedRectsGM : public GM {
27private:
28 SkString onShortName() override final { return SkString("croppedrects"); }
29 SkISize onISize() override { return SkISize::Make(500, 500); }
30
31 void onOnceBeforeDraw() override {
32 sk_sp<SkSurface> srcSurface = SkSurface::MakeRasterN32Premul(500, 500);
33 SkCanvas* srcCanvas = srcSurface->getCanvas();
34
35 srcCanvas->clear(SK_ColorRED);
36
37 SkPaint paint;
38 paint.setColor(0xff00ff00);
39 srcCanvas->drawRect(kSrcImageClip, paint);
40
41 constexpr SkScalar kStrokeWidth = 10;
42 SkPaint stroke;
43 stroke.setStyle(SkPaint::kStroke_Style);
44 stroke.setStrokeWidth(kStrokeWidth);
45 stroke.setColor(0xff008800);
46 srcCanvas->drawRect(kSrcImageClip.makeInset(kStrokeWidth / 2, kStrokeWidth / 2), stroke);
47
48 fSrcImage = srcSurface->makeImageSnapshot(SkBudgeted::kYes, SkSurface::kNo_ForceUnique);
49 fSrcImageShader = fSrcImage->makeShader(SkShader::kClamp_TileMode,
50 SkShader::kClamp_TileMode);
51 }
52
53 void onDraw(SkCanvas* canvas) override {
54 canvas->clear(SK_ColorWHITE);
55
56 {
57 // GrDrawContext::drawFilledRect.
58 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 {
67 // GrDrawContext::fillRectToRect.
68 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 {
81 // GrDrawContext::fillRectWithLocalMatrix.
82 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);
91 canvas->translate(-90, 263);
92 canvas->scale(300 / kSrcImageClip.width(), 100 / kSrcImageClip.height());
93 canvas->clipRect(kSrcImageClip);
94 canvas->drawPath(path, paint);
95 }
96
97 // TODO: assert the draw target only has one batch in the post-MDB world.
98 }
99
100 sk_sp<SkImage> fSrcImage;
101 sk_sp<SkShader> fSrcImageShader;
102
103 typedef GM INHERITED;
104};
105
106DEF_GM( return new CroppedRectsGM(); )
107
108}