• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkImage.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPath.h"
14 #include "include/core/SkRect.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkScalar.h"
17 #include "include/core/SkShader.h"
18 #include "include/core/SkSize.h"
19 #include "include/core/SkString.h"
20 #include "include/core/SkSurface.h"
21 
22 namespace skiagm {
23 
24 constexpr SkRect kSrcImageClip{75, 75, 275, 275};
25 
26 /*
27  * The purpose of this test is to exercise all three codepaths in skgpu::v1::SurfaceDrawContext
28  * (drawFilledRect, fillRectToRect, fillRectWithLocalMatrix) that pre-crop filled rects based on the
29  * clip.
30  *
31  * The test creates an image of a green square surrounded by red background, then draws this image
32  * in various ways with the red clipped out. The test is successful if there is no visible red
33  * background, scissor is never used, and ideally, all the rectangles draw in one GrDrawOp.
34  */
35 class CroppedRectsGM : public GM {
36 private:
onShortName()37     SkString onShortName() final { return SkString("croppedrects"); }
onISize()38     SkISize onISize() override { return SkISize::Make(500, 500); }
39 
onOnceBeforeDraw()40     void onOnceBeforeDraw() override {
41         sk_sp<SkSurface> srcSurface = SkSurface::MakeRasterN32Premul(500, 500);
42         SkCanvas* srcCanvas = srcSurface->getCanvas();
43 
44         srcCanvas->clear(SK_ColorRED);
45 
46         SkPaint paint;
47         paint.setColor(0xff00ff00);
48         srcCanvas->drawRect(kSrcImageClip, paint);
49 
50         constexpr SkScalar kStrokeWidth = 10;
51         SkPaint stroke;
52         stroke.setStyle(SkPaint::kStroke_Style);
53         stroke.setStrokeWidth(kStrokeWidth);
54         stroke.setColor(0xff008800);
55         srcCanvas->drawRect(kSrcImageClip.makeInset(kStrokeWidth / 2, kStrokeWidth / 2), stroke);
56 
57         fSrcImage = srcSurface->makeImageSnapshot();
58         fSrcImageShader = fSrcImage->makeShader(SkSamplingOptions());
59     }
60 
onDraw(SkCanvas * canvas)61     void onDraw(SkCanvas* canvas) override {
62         canvas->clear(SK_ColorWHITE);
63 
64         {
65             // skgpu::v1::SurfaceDrawContext::drawFilledRect.
66             SkAutoCanvasRestore acr(canvas, true);
67             SkPaint paint;
68             paint.setShader(fSrcImageShader);
69             canvas->clipRect(kSrcImageClip);
70             canvas->drawPaint(paint);
71         }
72 
73         {
74             // skgpu::v1::SurfaceDrawContext::fillRectToRect.
75             SkAutoCanvasRestore acr(canvas, true);
76             SkRect drawRect = SkRect::MakeXYWH(350, 100, 100, 300);
77             canvas->clipRect(drawRect);
78             canvas->drawImageRect(fSrcImage.get(),
79                                   kSrcImageClip.makeOutset(0.5f * kSrcImageClip.width(),
80                                                            kSrcImageClip.height()),
81                                   drawRect.makeOutset(0.5f * drawRect.width(), drawRect.height()),
82                                   SkSamplingOptions(), nullptr,
83                                   SkCanvas::kStrict_SrcRectConstraint);
84         }
85 
86         {
87             // skgpu::v1::SurfaceDrawContext::fillRectWithLocalMatrix.
88             SkAutoCanvasRestore acr(canvas, true);
89             SkPath path = SkPath::Line(
90                    {kSrcImageClip.fLeft - kSrcImageClip.width(), kSrcImageClip.centerY()},
91                    {kSrcImageClip.fRight + 3 * kSrcImageClip.width(), kSrcImageClip.centerY()});
92             SkPaint paint;
93             paint.setStyle(SkPaint::kStroke_Style);
94             paint.setStrokeWidth(2 * kSrcImageClip.height());
95             paint.setShader(fSrcImageShader);
96             canvas->translate(23, 301);
97             canvas->scale(300 / kSrcImageClip.width(), 100 / kSrcImageClip.height());
98             canvas->translate(-kSrcImageClip.left(), -kSrcImageClip.top());
99             canvas->clipRect(kSrcImageClip);
100             canvas->drawPath(path, paint);
101         }
102 
103         // TODO: assert the draw target only has one op in the post-MDB world.
104     }
105 
106     sk_sp<SkImage> fSrcImage;
107     sk_sp<SkShader> fSrcImageShader;
108 
109     using INHERITED = GM;
110 };
111 
112 DEF_GM( return new CroppedRectsGM(); )
113 
114 }  // namespace skiagm
115