Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
perspshaders.cpp
Go to the documentation of this file.
1/*
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/gm.h"
16#include "include/core/SkPath.h"
18#include "include/core/SkRect.h"
22#include "include/core/SkSize.h"
28#include "tools/DecodeUtils.h"
29#include "tools/ToolUtils.h"
30
31static sk_sp<SkImage> make_image(SkCanvas* origCanvas, int w, int h) {
33 auto surface(ToolUtils::makeSurface(origCanvas, info));
34 SkCanvas* canvas = surface->getCanvas();
35
37 return surface->makeImageSnapshot();
38}
39
40namespace skiagm {
41
42class PerspShadersGM : public GM {
43public:
44 PerspShadersGM(bool doAA) : fDoAA(doAA) { }
45
46protected:
47 SkString getName() const override {
49 name.printf("persp_shaders_%s",
50 fDoAA ? "aa" : "bw");
51 return name;
52 }
53
54 SkISize getISize() override {
55 return SkISize::Make(kCellSize*kNumCols, kCellSize*kNumRows);
56 }
57
58 void onOnceBeforeDraw() override {
60 kCellSize, kCellSize, SK_ColorBLUE, SK_ColorYELLOW, kCellSize / 10);
61
62 SkPoint pts1[] = {
63 { 0, 0 },
64 { SkIntToScalar(kCellSize), SkIntToScalar(kCellSize) }
65 };
66 SkPoint pts2[] = {
67 { 0, 0 },
68 { 0, SkIntToScalar(kCellSize) }
69 };
70 constexpr SkColor colors[] = {
72 };
73 constexpr SkScalar pos[] = { 0, 0.25f, 0.5f, 0.75f, SK_Scalar1 };
74
75 fLinearGrad1 = SkGradientShader::MakeLinear(pts1, colors, pos, std::size(colors),
77 fLinearGrad2 = SkGradientShader::MakeLinear(pts2, colors, pos, std::size(colors),
79
80 fPerspMatrix.reset();
81 fPerspMatrix.setPerspY(SK_Scalar1 / 50);
82
83 fPath.moveTo(0, 0);
84 fPath.lineTo(0, SkIntToScalar(kCellSize));
85 fPath.lineTo(kCellSize/2.0f, kCellSize/2.0f);
86 fPath.lineTo(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize));
87 fPath.lineTo(SkIntToScalar(kCellSize), 0);
88 fPath.close();
89 }
90
91 void drawRow(SkCanvas* canvas, const SkSamplingOptions& sampling) {
92 SkPaint filterPaint;
93 filterPaint.setAntiAlias(fDoAA);
94
95 SkPaint pathPaint;
96 pathPaint.setShader(fBitmapImage->makeShader(sampling));
97 pathPaint.setAntiAlias(fDoAA);
98
99 SkPaint gradPaint1;
100 gradPaint1.setShader(fLinearGrad1);
101 gradPaint1.setAntiAlias(fDoAA);
102 SkPaint gradPaint2;
103 gradPaint2.setShader(fLinearGrad2);
104 gradPaint2.setAntiAlias(fDoAA);
105
106 SkRect r = SkRect::MakeWH(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize));
107
108 canvas->save();
109
110 canvas->save();
111 canvas->concat(fPerspMatrix);
112 canvas->drawImageRect(fBitmapImage, r, sampling, &filterPaint);
113 canvas->restore();
114
115 canvas->translate(SkIntToScalar(kCellSize), 0);
116 canvas->save();
117 canvas->concat(fPerspMatrix);
118 canvas->drawImage(fImage.get(), 0, 0, sampling, &filterPaint);
119 canvas->restore();
120
121 canvas->translate(SkIntToScalar(kCellSize), 0);
122 canvas->save();
123 canvas->concat(fPerspMatrix);
124 canvas->drawRect(r, pathPaint);
125 canvas->restore();
126
127 canvas->translate(SkIntToScalar(kCellSize), 0);
128 canvas->save();
129 canvas->concat(fPerspMatrix);
130 canvas->drawPath(fPath, pathPaint);
131 canvas->restore();
132
133 canvas->translate(SkIntToScalar(kCellSize), 0);
134 canvas->save();
135 canvas->concat(fPerspMatrix);
136 canvas->drawRect(r, gradPaint1);
137 canvas->restore();
138
139 canvas->translate(SkIntToScalar(kCellSize), 0);
140 canvas->save();
141 canvas->concat(fPerspMatrix);
142 canvas->drawPath(fPath, gradPaint2);
143 canvas->restore();
144
145 canvas->restore();
146 }
147
148 void onDraw(SkCanvas* canvas) override {
149 if (!fImage || !fImage->isValid(canvas->recordingContext())) {
150 fImage = make_image(canvas, kCellSize, kCellSize);
151 }
152
154 canvas->translate(0, SkIntToScalar(kCellSize));
156 canvas->translate(0, SkIntToScalar(kCellSize));
159 canvas->translate(0, SkIntToScalar(kCellSize));
161 canvas->translate(0, SkIntToScalar(kCellSize));
162 this->drawRow(canvas, SkSamplingOptions::Aniso(16));
163 canvas->translate(0, SkIntToScalar(kCellSize));
164 }
165private:
166 inline static constexpr int kCellSize = 50;
167 inline static constexpr int kNumRows = 5;
168 inline static constexpr int kNumCols = 6;
169
170 bool fDoAA;
171 SkPath fPath;
172 sk_sp<SkShader> fLinearGrad1;
173 sk_sp<SkShader> fLinearGrad2;
174 SkMatrix fPerspMatrix;
175 sk_sp<SkImage> fImage;
176 sk_sp<SkImage> fBitmapImage;
177
178 using INHERITED = GM;
179};
180DEF_GM(return new PerspShadersGM(true);)
181DEF_GM(return new PerspShadersGM(false);)
182} // namespace skiagm
183
184//////////////////////////////////////////////////////////////////////////////
185
186#include "tools/Resources.h"
187
189 SkRandom rand;
190 auto rand_pt = [&rand]() {
191 auto x = rand.nextF();
192 auto y = rand.nextF();
193 return SkPoint{x * 400, y * 400};
194 };
195
196 SkPath path;
197 for (int i = 0; i < 4; ++i) {
198 SkPoint pts[6];
199 for (auto& p : pts) {
200 p = rand_pt();
201 }
202 path.moveTo(pts[0]).quadTo(pts[1], pts[2]).quadTo(pts[3], pts[4]).lineTo(pts[5]);
203 }
204 return path;
205}
206
207DEF_SIMPLE_GM(perspective_clip, canvas, 800, 800) {
208 SkPath path = make_path();
209 auto shader = ToolUtils::GetResourceAsImage("images/mandrill_128.png")
211
213 paint.setColor({0.75, 0.75, 0.75, 1});
214 canvas->drawPath(path, paint);
215
216 // This is a crazy perspective matrix, derived from halfplanes3, to draw a shape where
217 // part of it is "behind" the viewer, hence showing the need for "half-plane" clipping
218 // when in perspective.
219 SkMatrix mx;
220 const SkScalar array[] = {
221 -1.7866f, 1.3357f, 273.0295f,
222 -1.0820f, 1.3186f, 135.5196f,
223 -0.0047f, -0.0015f, 2.1485f,
224 };
225 mx.set9(array);
226
227 paint.setShader(shader);
228 canvas->concat(mx);
229 canvas->drawPath(path, paint);
230}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
SkPoint pos
constexpr SkColor SK_ColorYELLOW
Definition SkColor.h:139
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
#define SK_Scalar1
Definition SkScalar.h:18
#define SkIntToScalar(x)
Definition SkScalar.h:57
static SkPoint rand_pt(SkRandom &rand)
void drawRect(const SkRect &rect, const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
virtual GrRecordingContext * recordingContext() const
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void concat(const SkMatrix &matrix)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition SkImage.cpp:179
virtual bool isValid(GrRecordingContext *context) const =0
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
SkMatrix & set9(const SkScalar buffer[9])
Definition SkMatrix.cpp:51
SkMatrix & setPerspY(SkScalar v)
Definition SkMatrix.h:544
SkMatrix & reset()
Definition SkMatrix.cpp:49
void setAntiAlias(bool aa)
Definition SkPaint.h:170
void setShader(sk_sp< SkShader > shader)
SkPath & moveTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:678
SkPath & lineTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:718
SkPath & close()
Definition SkPath.cpp:813
float nextF()
Definition SkRandom.h:55
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:534
T * get() const
Definition SkRefCnt.h:303
void onDraw(SkCanvas *canvas) override
void onOnceBeforeDraw() override
SkString getName() const override
void drawRow(SkCanvas *canvas, const SkSamplingOptions &sampling)
SkISize getISize() override
const Paint & paint
VkSurfaceKHR surface
Definition main.cc:49
float SkScalar
Definition extension.cpp:12
const char * name
Definition fuchsia.cc:50
#define DEF_GM(CODE)
Definition gm.h:40
#define DEF_SIMPLE_GM(NAME, CANVAS, W, H)
Definition gm.h:50
static sk_sp< SkImage > make_image()
Definition mipmap.cpp:21
double y
double x
void draw_checkerboard(SkCanvas *canvas, SkColor c1, SkColor c2, int size)
sk_sp< SkSurface > makeSurface(SkCanvas *canvas, const SkImageInfo &info, const SkSurfaceProps *props)
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition DecodeUtils.h:25
sk_sp< SkImage > create_checkerboard_image(int w, int h, SkColor c1, SkColor c2, int checkSize)
static SkPath make_path()
SkScalar w
SkScalar h
static constexpr SkCubicResampler Mitchell()
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static SkImageInfo MakeN32Premul(int width, int height)
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static constexpr SkSamplingOptions Aniso(int maxAniso)