Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
anisotropic.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"
14#include "include/core/SkRect.h"
17#include "include/core/SkSize.h"
22
23namespace skiagm {
24
25// This GM exercises anisotropic image scaling.
26class AnisotropicGM : public GM {
27public:
28 enum class Mode { kLinear, kMip, kAniso };
29
30 AnisotropicGM(Mode mode) : fMode(mode) {
31 switch (fMode) {
32 case Mode::kLinear:
34 break;
35 case Mode::kMip:
37 break;
38 case Mode::kAniso:
39 fSampling = SkSamplingOptions::Aniso(16);
40 break;
41 }
42 this->setBGColor(0xFFCCCCCC);
43 }
44
45protected:
46 SkString getName() const override {
47 SkString name("anisotropic_image_scale_");
48 switch (fMode) {
49 case Mode::kLinear:
50 name += "linear";
51 break;
52 case Mode::kMip:
53 name += "mip";
54 break;
55 case Mode::kAniso:
56 name += "aniso";
57 break;
58 }
59 return name;
60 }
61
62 SkISize getISize() override {
63 return SkISize::Make(2*kImageSize + 3*kSpacer,
64 kNumVertImages*kImageSize + (kNumVertImages+1)*kSpacer);
65 }
66
67 // Create an image consisting of lines radiating from its center
68 void onOnceBeforeDraw() override {
69 constexpr int kNumLines = 100;
70 constexpr SkScalar kAngleStep = 360.0f / kNumLines;
71 constexpr int kInnerOffset = 10;
72
73 auto info = SkImageInfo::MakeN32(kImageSize, kImageSize, kOpaque_SkAlphaType);
74 auto surf = SkSurfaces::Raster(info);
75 auto canvas = surf->getCanvas();
76
77 canvas->clear(SK_ColorWHITE);
78
79 SkPaint p;
80 p.setAntiAlias(true);
81
82 SkScalar angle = 0.0f, sin, cos;
83
84 canvas->translate(kImageSize/2.0f, kImageSize/2.0f);
85 for (int i = 0; i < kNumLines; ++i, angle += kAngleStep) {
86 sin = SkScalarSin(angle);
87 cos = SkScalarCos(angle);
88 canvas->drawLine(cos * kInnerOffset, sin * kInnerOffset,
89 cos * kImageSize/2, sin * kImageSize/2, p);
90 }
91 fImage = surf->makeImageSnapshot();
92 }
93
94 void draw(SkCanvas* canvas, int x, int y, int xSize, int ySize) {
96 SkIntToScalar(xSize), SkIntToScalar(ySize));
97 canvas->drawImageRect(fImage, r, fSampling);
98 }
99
100 void onDraw(SkCanvas* canvas) override {
101 SkScalar gScales[] = { 0.9f, 0.8f, 0.75f, 0.6f, 0.5f, 0.4f, 0.25f, 0.2f, 0.1f };
102
103 SkASSERT(kNumVertImages-1 == (int)std::size(gScales)/2);
104
105 // Minimize vertically
106 for (int i = 0; i < (int)std::size(gScales); ++i) {
107 int height = SkScalarFloorToInt(fImage->height() * gScales[i]);
108
109 int yOff;
110 if (i <= (int)std::size(gScales)/2) {
111 yOff = kSpacer + i * (fImage->height() + kSpacer);
112 } else {
113 // Position the more highly squashed images with their less squashed counterparts
114 yOff = (std::size(gScales) - i) * (fImage->height() + kSpacer) - height;
115 }
116
117 this->draw(canvas, kSpacer, yOff, fImage->width(), height);
118 }
119
120 // Minimize horizontally
121 for (int i = 0; i < (int)std::size(gScales); ++i) {
122 int width = SkScalarFloorToInt(fImage->width() * gScales[i]);
123
124 int xOff, yOff;
125 if (i <= (int)std::size(gScales)/2) {
126 xOff = fImage->width() + 2*kSpacer;
127 yOff = kSpacer + i * (fImage->height() + kSpacer);
128 } else {
129 // Position the more highly squashed images with their less squashed counterparts
130 xOff = fImage->width() + 2*kSpacer + fImage->width() - width;
131 yOff = kSpacer + (std::size(gScales) - i - 1) * (fImage->height() + kSpacer);
132 }
133
134 this->draw(canvas, xOff, yOff, width, fImage->height());
135 }
136 }
137
138private:
139 inline static constexpr int kImageSize = 256;
140 inline static constexpr int kSpacer = 10;
141 inline static constexpr int kNumVertImages = 5;
142
143 sk_sp<SkImage> fImage;
144 SkSamplingOptions fSampling;
145 Mode fMode;
146
147 using INHERITED = GM;
148};
149
150//////////////////////////////////////////////////////////////////////////////
151
152DEF_GM(return new AnisotropicGM(AnisotropicGM::Mode::kLinear);)
153DEF_GM(return new AnisotropicGM(AnisotropicGM::Mode::kMip);)
154DEF_GM(return new AnisotropicGM(AnisotropicGM::Mode::kAniso);)
155
156//////////////////////////////////////////////////////////////////////////////
157
158class AnisoMipsGM : public GM {
159public:
160 AnisoMipsGM() = default;
161
162protected:
163 SkString getName() const override { return SkString("anisomips"); }
164
165 SkISize getISize() override { return SkISize::Make(520, 260); }
166
168 surf->getCanvas()->clear(color);
170 paint.setColor(~color | 0xFF000000);
171 surf->getCanvas()->drawRect(SkRect::MakeLTRB(surf->width() *2/5.f,
172 surf->height()*2/5.f,
173 surf->width() *3/5.f,
174 surf->height()*3/5.f),
175 paint);
176 return surf->makeImageSnapshot()->withDefaultMipmaps();
177 }
178
179 void onDraw(SkCanvas* canvas) override {
180 auto ct = canvas->imageInfo().colorType() == kUnknown_SkColorType
182 : canvas->imageInfo().colorType();
185 ct,
187 canvas->imageInfo().refColorSpace());
188 // In GPU mode we want a surface that is created with mipmaps to ensure that we exercise the
189 // case where the SkSurface and SkImage share a texture. If the surface texture isn't
190 // created with MIPs then asking for a mipmapped image will cause a copy to a mipped
191 // texture.
193 if (auto rc = canvas->recordingContext()) {
196 ii,
197 /* sampleCount= */ 1,
199 /*surfaceProps=*/nullptr,
200 /*shouldCreateWithMips=*/true);
201 if (!surface) {
202 // We could be in an abandoned context situation.
203 return;
204 }
205 } else {
206 surface = canvas->makeSurface(ii);
207 if (!surface) { // could be a recording canvas.
209 }
210 }
211
212 static constexpr float kScales[] = {1.f, 0.5f, 0.25f, 0.125f};
213 SkColor kColors[] = {0xFFF0F0F0, SK_ColorBLUE, SK_ColorGREEN, SK_ColorRED};
214 static const SkSamplingOptions kSampling = SkSamplingOptions::Aniso(16);
215
216 for (bool shader : {false, true}) {
217 int c = 0;
218 canvas->save();
219 for (float sy : kScales) {
220 canvas->save();
221 for (float sx : kScales) {
222 canvas->save();
223 canvas->scale(sx, sy);
224 auto image = this->updateImage(surface.get(), kColors[c]);
225 if (shader) {
227 paint.setShader(image->makeShader(kSampling));
229 } else {
230 canvas->drawImage(image, 0, 0, kSampling);
231 }
232 canvas->restore();
233 canvas->translate(ii.width() * sx + kPad, 0);
234 c = (c + 1) % std::size(kColors);
235 }
236 canvas->restore();
237 canvas->translate(0, ii.width() * sy + kPad);
238 }
239 canvas->restore();
240 for (float sx : kScales) {
241 canvas->translate(ii.width() * sx + kPad, 0);
242 }
243 }
244 }
245
246private:
247 inline static constexpr int kImageSize = 128;
248 inline static constexpr int kPad = 5;
249
250 using INHERITED = GM;
251};
252
253//////////////////////////////////////////////////////////////////////////////
254
255DEF_GM(return new AnisoMipsGM();)
256
257} // namespace skiagm
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
SkColor4f color
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
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
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
#define INHERITED(method,...)
#define SkScalarSin(radians)
Definition SkScalar.h:45
#define SkIntToScalar(x)
Definition SkScalar.h:57
#define SkScalarCos(radians)
Definition SkScalar.h:46
#define SkScalarFloorToInt(x)
Definition SkScalar.h:35
Type::kYUV Type::kRGBA() int(0.7 *637)
constexpr int kPad
void drawRect(const SkRect &rect, const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
sk_sp< SkSurface > makeSurface(const SkImageInfo &info, const SkSurfaceProps *props=nullptr)
virtual GrRecordingContext * recordingContext() const
void clear(SkColor color)
Definition SkCanvas.h:1199
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
int save()
Definition SkCanvas.cpp:451
void scale(SkScalar sx, SkScalar sy)
SkImageInfo imageInfo() const
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
SkISize dimensions() const
Definition SkImage.h:297
sk_sp< SkImage > withDefaultMipmaps() const
Definition SkImage.cpp:305
int width() const
Definition SkImage.h:285
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition SkImage.cpp:179
int height() const
Definition SkImage.h:291
SkCanvas * getCanvas()
Definition SkSurface.cpp:82
int width() const
Definition SkSurface.h:178
sk_sp< SkImage > makeImageSnapshot()
Definition SkSurface.cpp:90
int height() const
Definition SkSurface.h:184
SkISize getISize() override
void onDraw(SkCanvas *canvas) override
sk_sp< SkImage > updateImage(SkSurface *surf, SkColor color)
SkString getName() const override
SkString getName() const override
void onDraw(SkCanvas *canvas) override
void draw(SkCanvas *canvas, int x, int y, int xSize, int ySize)
void onOnceBeforeDraw() override
SkISize getISize() override
SkScalar width()
Definition gm.h:159
SkScalar height()
Definition gm.h:162
void setBGColor(SkColor)
Definition gm.cpp:159
const Paint & paint
VkSurfaceKHR surface
Definition main.cc:49
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
static const int kImageSize
Definition flippity.cpp:44
const char * name
Definition fuchsia.cc:50
#define DEF_GM(CODE)
Definition gm.h:40
double y
double x
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
sk_sp< SkColorSpace > refColorSpace() const
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkColorType colorType() const
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646
static constexpr SkSamplingOptions Aniso(int maxAniso)