Flutter Engine
The Flutter Engine
AtlasSlide.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
10#include "include/core/SkFont.h"
11#include "include/core/SkPath.h"
15#include "src/base/SkRandom.h"
18#include "tools/viewer/Slide.h"
19
20typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
21 const SkColor[], int, const SkRect*, const SkSamplingOptions&,
22 const SkPaint*);
23
24static void draw_atlas(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
25 const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
26 const SkSamplingOptions& sampling, const SkPaint* paint) {
27 canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate,
28 sampling, cull, paint);
29}
30
31static void draw_atlas_sim(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
32 const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
33 const SkSamplingOptions& sampling, const SkPaint* paint) {
34 for (int i = 0; i < count; ++i) {
36 matrix.setRSXform(xform[i]);
37
38 canvas->save();
39 canvas->concat(matrix);
40 canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()),
42 canvas->restore();
43 }
44}
45
46static sk_sp<SkImage> make_atlas(int atlasSize, int cellSize) {
47 SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
49 SkCanvas* canvas = surface->getCanvas();
50
52 SkRandom rand;
53
54 const SkScalar half = cellSize * SK_ScalarHalf;
55 const char* s = "01234567890!@#$%^&*=+<>?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
57
58 int i = 0;
59 for (int y = 0; y < atlasSize; y += cellSize) {
60 for (int x = 0; x < atlasSize; x += cellSize) {
61 paint.setColor(rand.nextU());
62 paint.setAlpha(0xFF);
63 int index = i % strlen(s);
64 SkTextUtils::Draw(canvas, &s[index], 1, SkTextEncoding::kUTF8,
65 x + half, y + half + half/2, font, paint,
67 i += 1;
68 }
69 }
70 return surface->makeImageSnapshot();
71}
72
74 static constexpr int kMaxScale = 2;
75 static constexpr int kCellSize = 32;
76 static constexpr int kAtlasSize = 512;
77
78 struct Rec {
79 SkPoint fCenter;
80 SkVector fVelocity;
81 SkScalar fScale;
82 SkScalar fDScale;
83 SkScalar fRadian;
84 SkScalar fDRadian;
85 SkScalar fAlpha;
86 SkScalar fDAlpha;
87
88 void advance(const SkRect& bounds) {
89 fCenter += fVelocity;
90 if (fCenter.fX > bounds.right()) {
91 SkASSERT(fVelocity.fX > 0);
92 fVelocity.fX = -fVelocity.fX;
93 } else if (fCenter.fX < bounds.left()) {
94 SkASSERT(fVelocity.fX < 0);
95 fVelocity.fX = -fVelocity.fX;
96 }
97 if (fCenter.fY > bounds.bottom()) {
98 if (fVelocity.fY > 0) {
99 fVelocity.fY = -fVelocity.fY;
100 }
101 } else if (fCenter.fY < bounds.top()) {
102 if (fVelocity.fY < 0) {
103 fVelocity.fY = -fVelocity.fY;
104 }
105 }
106
107 fScale += fDScale;
108 if (fScale > 2 || fScale < SK_Scalar1/2) {
109 fDScale = -fDScale;
110 }
111
112 fRadian += fDRadian;
113 fRadian = SkScalarMod(fRadian, 2 * SK_ScalarPI);
114
115 fAlpha += fDAlpha;
116 if (fAlpha > 1) {
117 fAlpha = 1;
118 fDAlpha = -fDAlpha;
119 } else if (fAlpha < 0) {
120 fAlpha = 0;
121 fDAlpha = -fDAlpha;
122 }
123 }
124
125 SkRSXform asRSXform() const {
126 return SkRSXform::MakeFromRadians(fScale, fRadian, fCenter.x(), fCenter.y(),
128 }
129 };
130
131 DrawAtlasProc fProc;
132
133 enum {
134 N = 256,
135 };
136
137 sk_sp<SkImage> fAtlas;
138 Rec fRec[N];
139 SkRect fTex[N];
140 SkRect fBounds;
141 bool fUseColors;
142
143public:
145 : fProc(proc), fBounds(r), fUseColors(false)
146 {
147 SkRandom rand;
148 fAtlas = make_atlas(kAtlasSize, kCellSize);
149 const SkScalar kMaxSpeed = 5;
150 const SkScalar cell = SkIntToScalar(kCellSize);
151 int i = 0;
152 for (int y = 0; y < kAtlasSize; y += kCellSize) {
153 for (int x = 0; x < kAtlasSize; x += kCellSize) {
154 const SkScalar sx = SkIntToScalar(x);
155 const SkScalar sy = SkIntToScalar(y);
156 fTex[i].setXYWH(sx, sy, cell, cell);
157
158 fRec[i].fCenter.set(sx + cell/2, sy + 3*cell/4);
159 fRec[i].fVelocity.fX = rand.nextSScalar1() * kMaxSpeed;
160 fRec[i].fVelocity.fY = rand.nextSScalar1() * kMaxSpeed;
161 fRec[i].fScale = 1;
162 fRec[i].fDScale = rand.nextSScalar1() / 16;
163 fRec[i].fRadian = 0;
164 fRec[i].fDRadian = rand.nextSScalar1() / 8;
165 fRec[i].fAlpha = rand.nextUScalar1();
166 fRec[i].fDAlpha = rand.nextSScalar1() / 10;
167 i += 1;
168 }
169 }
170 }
171
173 fUseColors = !fUseColors;
174 }
175
176protected:
177 void onDraw(SkCanvas* canvas) override {
178 SkRSXform xform[N];
179 SkColor colors[N];
180
181 for (int i = 0; i < N; ++i) {
182 fRec[i].advance(fBounds);
183 xform[i] = fRec[i].asRSXform();
184 if (fUseColors) {
185 colors[i] = SkColorSetARGB((int)(fRec[i].fAlpha * 0xFF), 0xFF, 0xFF, 0xFF);
186 }
187 }
190
191 const SkRect cull = this->getBounds();
192 const SkColor* colorsPtr = fUseColors ? colors : nullptr;
193 fProc(canvas, fAtlas.get(), xform, fTex, colorsPtr, N, &cull, sampling, &paint);
194 }
195
196 SkRect onGetBounds() override {
197 const SkScalar border = kMaxScale * kCellSize;
198 SkRect r = fBounds;
199 r.outset(border, border);
200 return r;
201 }
202};
203
204class DrawAtlasSlide : public Slide {
205 DrawAtlasProc fProc;
206 sk_sp<DrawAtlasDrawable> fDrawable;
207
208public:
209 DrawAtlasSlide(const char name[], DrawAtlasProc proc) : fProc(proc) { fName = name; }
210
211 bool onChar(SkUnichar uni) override {
212 switch (uni) {
213 case 'C': fDrawable->toggleUseColors(); return true;
214 default: break;
215 }
216 return false;
217 }
218
219 void draw(SkCanvas* canvas) override {
220 canvas->drawDrawable(fDrawable.get());
221 }
222
223 bool animate(double /*nanos*/) override { return true; }
224#if 0
225 // TODO: switch over to use this for our animation
226 bool animate(double nanos) override {
227 SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
228 fAnimatingDrawable->setSweep(angle);
229 return true;
230 }
231#endif
232
233 void load(SkScalar winWidth, SkScalar winHeight) override {
234 fDrawable = sk_make_sp<DrawAtlasDrawable>(fProc, SkRect::Make(this->getDimensions()));
235 }
236
237 SkISize getDimensions() const override { return {640, 480}; }
238};
239
240//////////////////////////////////////////////////////////////////////////////
241
242DEF_SLIDE( return new DrawAtlasSlide("DrawAtlas", draw_atlas); )
243DEF_SLIDE( return new DrawAtlasSlide("DrawAtlasSim", draw_atlas_sim); )
void(* DrawAtlasProc)(SkCanvas *, SkImage *, const SkRSXform[], const SkRect[], const SkColor[], int, const SkRect *, const SkSamplingOptions &, const SkPaint *)
Definition: AtlasSlide.cpp:20
static void draw_atlas(SkCanvas *canvas, SkImage *atlas, const SkRSXform xform[], const SkRect tex[], const SkColor colors[], int count, const SkRect *cull, const SkSamplingOptions &sampling, const SkPaint *paint)
Definition: AtlasSlide.cpp:24
static sk_sp< SkImage > make_atlas(int atlasSize, int cellSize)
Definition: AtlasSlide.cpp:46
static void draw_atlas_sim(SkCanvas *canvas, SkImage *atlas, const SkRSXform xform[], const SkRect tex[], const SkColor colors[], int count, const SkRect *cull, const SkSamplingOptions &sampling, const SkPaint *paint)
Definition: AtlasSlide.cpp:31
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
IsFiniteProc fProc
Definition: MathBench.cpp:219
const SkRect fBounds
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kModulate
r = s*d
uint32_t SkColor
Definition: SkColor.h:37
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
@ kUTF8
uses bytes to represent UTF-8 or ASCII
#define SkScalarMod(x, y)
Definition: SkScalar.h:41
#define SK_Scalar1
Definition: SkScalar.h:18
#define SkScalarHalf(a)
Definition: SkScalar.h:75
#define SK_ScalarHalf
Definition: SkScalar.h:19
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SK_ScalarPI
Definition: SkScalar.h:21
int32_t SkUnichar
Definition: SkTypes.h:175
#define DEF_SLIDE(code)
Definition: Slide.h:25
#define N
Definition: beziers.cpp:19
SkRect onGetBounds() override
Definition: AtlasSlide.cpp:196
void onDraw(SkCanvas *canvas) override
Definition: AtlasSlide.cpp:177
DrawAtlasDrawable(DrawAtlasProc proc, const SkRect &r)
Definition: AtlasSlide.cpp:144
DrawAtlasSlide(const char name[], DrawAtlasProc proc)
Definition: AtlasSlide.cpp:209
bool onChar(SkUnichar uni) override
Definition: AtlasSlide.cpp:211
SkISize getDimensions() const override
Definition: AtlasSlide.cpp:237
void load(SkScalar winWidth, SkScalar winHeight) override
Definition: AtlasSlide.cpp:233
bool animate(double) override
Definition: AtlasSlide.cpp:223
void draw(SkCanvas *canvas) override
Definition: AtlasSlide.cpp:219
void restore()
Definition: SkCanvas.cpp:461
void drawDrawable(SkDrawable *drawable, const SkMatrix *matrix=nullptr)
Definition: SkCanvas.cpp:2574
@ kFast_SrcRectConstraint
sample outside bounds; faster
Definition: SkCanvas.h:1543
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
Definition: SkCanvas.cpp:2333
int save()
Definition: SkCanvas.cpp:447
void drawAtlas(const SkImage *atlas, const SkRSXform xform[], const SkRect tex[], const SkColor colors[], int count, SkBlendMode mode, const SkSamplingOptions &sampling, const SkRect *cullRect, const SkPaint *paint)
Definition: SkCanvas.cpp:1810
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
SkRect getBounds()
Definition: SkDrawable.cpp:71
Definition: SkFont.h:35
uint32_t nextU()
Definition: SkRandom.h:42
SkScalar nextUScalar1()
Definition: SkRandom.h:101
SkScalar nextSScalar1()
Definition: SkRandom.h:113
static void Draw(SkCanvas *, const void *text, size_t size, SkTextEncoding, SkScalar x, SkScalar y, const SkFont &, const SkPaint &, Align=kLeft_Align)
Definition: SkTextUtils.cpp:24
Definition: Slide.h:29
SkString fName
Definition: Slide.h:54
T * get() const
Definition: SkRefCnt.h:303
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
struct MyStruct s
const int kCellSize
double y
double x
sk_sp< const SkImage > atlas
Definition: SkRecords.h:331
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
PODArray< SkColor > colors
Definition: SkRecords.h:276
SkSamplingOptions sampling
Definition: SkRecords.h:337
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
sk_sp< SkTypeface > DefaultTypeface()
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
font
Font Metadata and Metrics.
Definition: SkSize.h:16
static SkImageInfo MakeN32Premul(int width, int height)
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
static SkRSXform MakeFromRadians(SkScalar scale, SkScalar radians, SkScalar tx, SkScalar ty, SkScalar ax, SkScalar ay)
Definition: SkRSXform.h:35
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
void setXYWH(float x, float y, float width, float height)
Definition: SkRect.h:931
void outset(float dx, float dy)
Definition: SkRect.h:1077