Flutter Engine
The Flutter Engine
rectangletexture.cpp
Go to the documentation of this file.
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// This test only works with the GL backend.
9
10#include "gm/gm.h"
11
12#ifdef SK_GL
20#include "include/core/SkRect.h"
24#include "include/core/SkSize.h"
31#include "include/gpu/GrTypes.h"
39
40#include <algorithm>
41#include <cstdint>
42#include <memory>
43
44namespace skiagm {
45class RectangleTexture : public GM {
46public:
47 RectangleTexture() {
48 this->setBGColor(0xFFFFFFFF);
49 }
50
51private:
52 enum class ImageType {
53 kGradientCircle,
54 k2x2
55 };
56
57 SkString getName() const override { return SkString("rectangle_texture"); }
58
59 SkISize getISize() override { return SkISize::Make(1180, 710); }
60
61 SkBitmap makeImagePixels(int size, ImageType type) {
63 switch (type) {
64 case ImageType::kGradientCircle: {
65 SkBitmap bmp;
66 bmp.allocPixels(ii);
68 SkCanvas canvas(bmp);
69 SkPoint pts[] = {{0, 0}, {0, SkIntToScalar(size)}};
70 SkColor colors0[] = {0xFF1060B0, 0xFF102030};
71 paint.setShader(
72 SkGradientShader::MakeLinear(pts, colors0, nullptr, 2, SkTileMode::kClamp));
73 canvas.drawPaint(paint);
74 SkColor colors1[] = {0xFFA07010, 0xFFA02080};
75 paint.setAntiAlias(true);
76 paint.setShader(
77 SkGradientShader::MakeLinear(pts, colors1, nullptr, 2, SkTileMode::kClamp));
78 canvas.drawCircle(size/2.f, size/2.f, 2.f*size/5, paint);
79 return bmp;
80 }
81 case ImageType::k2x2: {
82 SkBitmap bmp;
83 bmp.allocPixels(ii);
84 *bmp.getAddr32(0, 0) = 0xFF0000FF;
85 *bmp.getAddr32(1, 0) = 0xFF00FF00;
86 *bmp.getAddr32(0, 1) = 0xFFFF0000;
87 *bmp.getAddr32(1, 1) = 0xFFFFFFFF;
88 return bmp;
89 }
90 }
92 }
93
94 sk_sp<SkImage> createRectangleTextureImg(GrDirectContext* dContext, GrSurfaceOrigin origin,
95 const SkBitmap content) {
98 auto bet = dContext->createBackendTexture(content.width(),
99 content.height(),
100 format,
104 /*label=*/"CreateRectangleTextureImage");
105 if (!bet.isValid()) {
106 return nullptr;
107 }
108 if (!dContext->updateBackendTexture(bet, content.pixmap(), origin, nullptr, nullptr)) {
109 dContext->deleteBackendTexture(bet);
110 }
111 return SkImages::AdoptTextureFrom(dContext, bet, origin, kRGBA_8888_SkColorType);
112 }
113
114 DrawResult onGpuSetup(SkCanvas* canvas, SkString* errorMsg, GraphiteTestContext*) override {
115 auto context = GrAsDirectContext(canvas->recordingContext());
116 if (!context || context->abandoned()) {
117 return DrawResult::kSkip;
118 }
119
120 if (context->backend() != GrBackendApi::kOpenGL_GrBackend ||
121 !static_cast<const GrGLCaps*>(context->priv().caps())->rectangleTextureSupport()) {
122 *errorMsg = "This GM requires an OpenGL context that supports texture rectangles.";
123 return DrawResult::kSkip;
124 }
125
126 auto gradCircle = this->makeImagePixels(50, ImageType::kGradientCircle);
127
128 fGradImgs[0] = this->createRectangleTextureImg(context, kTopLeft_GrSurfaceOrigin,
129 gradCircle);
130 fGradImgs[1] = this->createRectangleTextureImg(context, kBottomLeft_GrSurfaceOrigin,
131 gradCircle);
132 SkASSERT(SkToBool(fGradImgs[0]) == SkToBool(fGradImgs[1]));
133 if (!fGradImgs[0]) {
134 *errorMsg = "Could not create gradient rectangle texture images.";
135 return DrawResult::kFail;
136 }
137
138 fSmallImg = this->createRectangleTextureImg(context, kTopLeft_GrSurfaceOrigin,
139 this->makeImagePixels(2, ImageType::k2x2));
140 if (!fSmallImg) {
141 *errorMsg = "Could not create 2x2 rectangle texture image.";
142 return DrawResult::kFail;
143 }
144
145 return DrawResult::kOk;
146 }
147
148 void onGpuTeardown() override {
149 fGradImgs[0] = fGradImgs[1] = nullptr;
150 fSmallImg = nullptr;
151 }
152
153 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
154 SkASSERT(fGradImgs[0] && fGradImgs[1] && fSmallImg);
155
156 static constexpr SkScalar kPad = 5.f;
157
158 const SkSamplingOptions kSamplings[] = {
163 };
164
165 constexpr SkScalar kScales[] = {1.0f, 1.2f, 0.75f};
166
167 canvas->translate(kPad, kPad);
168 for (size_t i = 0; i < kNumGradImages; ++i) {
169 auto img = fGradImgs[i];
170 int w = img->width();
171 int h = img->height();
172 for (auto scale : kScales) {
173 canvas->save();
174 canvas->scale(scale, scale);
175 for (auto s : kSamplings) {
176 // drawImage
177 canvas->drawImage(img, 0, 0, s);
178 canvas->translate(w + kPad, 0);
179
180 // clamp/clamp shader
181 SkPaint clampPaint;
182 clampPaint.setShader(fGradImgs[i]->makeShader(s));
183 canvas->drawRect(SkRect::MakeWH(1.5f*w, 1.5f*h), clampPaint);
184 canvas->translate(1.5f*w + kPad, 0);
185
186 // repeat/mirror shader
187 SkPaint repeatPaint;
188 repeatPaint.setShader(fGradImgs[i]->makeShader(SkTileMode::kRepeat,
190 s));
191 canvas->drawRect(SkRect::MakeWH(1.5f*w, 1.5f*h), repeatPaint);
192 canvas->translate(1.5f*w + kPad, 0);
193
194 // drawImageRect with kStrict
195 auto srcRect = SkRect::MakeXYWH(.25f*w, .25f*h, .50f*w, .50f*h);
196 auto dstRect = SkRect::MakeXYWH( 0, 0, .50f*w, .50f*h);
197 canvas->drawImageRect(fGradImgs[i], srcRect, dstRect, s, nullptr,
199 canvas->translate(.5f*w + kPad, 0);
200 }
201 canvas->restore();
202 canvas->translate(0, kPad + 1.5f*h*scale);
203 }
204 }
205
206 static constexpr SkScalar kOutset = 25.f;
207 canvas->translate(kOutset, kOutset);
208 auto dstRect = SkRect::Make(fSmallImg->dimensions()).makeOutset(kOutset, kOutset);
209
210 const SkSamplingOptions gSamplings[] = {
215 };
216
217 for (const auto& sampling : gSamplings) {
219 // Medium is the same as Low for upscaling.
220 continue;
221 }
222 canvas->save();
223 for (int ty = 0; ty < kSkTileModeCount; ++ty) {
224 canvas->save();
225 for (int tx = 0; tx < kSkTileModeCount; ++tx) {
226 SkMatrix lm;
227 lm.setRotate(45.f, 1, 1);
228 lm.postScale(6.5f, 6.5f);
230 paint.setShader(fSmallImg->makeShader(static_cast<SkTileMode>(tx),
231 static_cast<SkTileMode>(ty),
232 sampling,
233 lm));
234 canvas->drawRect(dstRect, paint);
235 canvas->translate(dstRect.width() + kPad, 0);
236 }
237 canvas->restore();
238 canvas->translate(0, dstRect.height() + kPad);
239 }
240 canvas->restore();
241 canvas->translate((dstRect.width() + kPad)*kSkTileModeCount, 0);
242 }
243
244 return DrawResult::kOk;
245 }
246
247private:
248 static const int kNumGradImages = 2;
249
250 sk_sp<SkImage> fGradImgs[kNumGradImages];
251 sk_sp<SkImage> fSmallImg;
252
253 using INHERITED = GM;
254};
255
256DEF_GM(return new RectangleTexture;)
257} // namespace skiagm
258#endif
#define GR_GL_RGBA8
Definition: GrGLDefines.h:524
#define GR_GL_TEXTURE_RECTANGLE
Definition: GrGLDefines.h:1056
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
GrSurfaceOrigin
Definition: GrTypes.h:147
@ kBottomLeft_GrSurfaceOrigin
Definition: GrTypes.h:149
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
#define SkUNREACHABLE
Definition: SkAssert.h:135
#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
uint32_t SkColor
Definition: SkColor.h:37
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
#define SkIntToScalar(x)
Definition: SkScalar.h:57
SkTileMode
Definition: SkTileMode.h:13
static constexpr int kSkTileModeCount
Definition: SkTileMode.h:39
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
constexpr int kPad
GLenum type
bool updateBackendTexture(const GrBackendTexture &, const SkColor4f &color, GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext)
void deleteBackendTexture(const GrBackendTexture &)
GrBackendTexture createBackendTexture(int width, int height, const GrBackendFormat &, skgpu::Mipmapped, GrRenderable, GrProtected=GrProtected::kNo, std::string_view label={})
bool rectangleTextureSupport() const
Are textures with GL_TEXTURE_RECTANGLE type supported.
Definition: GrGLCaps.h:384
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
uint32_t * getAddr32(int x, int y) const
Definition: SkBitmap.h:1260
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
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 scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
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)
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:360
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:452
void setShader(sk_sp< SkShader > shader)
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
struct MyStruct s
uint32_t uint32_t * format
union flutter::testing::@2836::KeyboardChange::@76 content
SK_API GrBackendFormat MakeGL(GrGLenum format, GrGLenum target)
SK_API sk_sp< SkImage > AdoptTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin textureOrigin, SkColorType colorType)
SkSamplingOptions sampling
Definition: SkRecords.h:337
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
static SkPath scale(const SkPath &path, SkScalar scale)
Definition: patheffects.cpp:68
SkSamplingOptions(SkFilterMode::kLinear))
DrawResult
Definition: gm.h:104
SkScalar w
SkScalar h
static constexpr SkCubicResampler Mitchell()
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
SkRect makeOutset(float dx, float dy) const
Definition: SkRect.h:1002
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
const SkMipmapMode mipmap
const SkSamplingOptions gSamplings[]
Definition: image.cpp:57