Flutter Engine
The Flutter Engine
UpdateBackendTextureTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
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 "tests/Test.h"
9
20#include "tests/TestUtils.h"
21#include "tools/ToolUtils.h"
22
23using namespace skgpu;
24using namespace skgpu::graphite;
25
26namespace {
27const SkISize kSize = { 32, 32 };
28constexpr int kNumMipLevels = 6;
29
31 const SkColor4f& expected,
32 const SkPixmap& actual,
33 SkColorType ct,
34 const char* label) {
35 const float kTols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
36
37 auto error = std::function<ComparePixmapsErrorReporter>(
38 [reporter, ct, label, expected](int x, int y, const float diffs[4]) {
39 SkASSERT(x >= 0 && y >= 0);
40 ERRORF(reporter, "%s %s - mismatch at %d, %d "
41 "expected: (%.2f, %.2f, %.2f, %.2f) "
42 "- diffs: (%.2f, %.2f, %.2f, %.2f)",
43 ToolUtils::colortype_name(ct), label, x, y,
44 expected.fR, expected.fG, expected.fB, expected.fA,
45 diffs[0], diffs[1], diffs[2], diffs[3]);
46 });
47
48 CheckSolidPixels(expected, actual, kTols, error);
49}
50
51void update_backend_texture(Recorder* recorder,
52 const BackendTexture& backendTex,
53 SkColorType ct,
54 bool withMips,
55 const SkColor4f colors[6]) {
56 SkPixmap pixmaps[6];
57 std::unique_ptr<char[]> memForPixmaps;
58
59 int numMipLevels = ToolUtils::make_pixmaps(ct, kPremul_SkAlphaType, withMips, colors, pixmaps,
60 &memForPixmaps);
61 SkASSERT(numMipLevels == 1 || numMipLevels == kNumMipLevels);
62 SkASSERT(kSize == pixmaps[0].dimensions());
63
64 recorder->updateBackendTexture(backendTex, pixmaps, numMipLevels);
65
66}
67
68BackendTexture create_backend_texture(skiatest::Reporter* reporter,
69 const Caps* caps,
70 Recorder* recorder,
71 SkColorType ct,
72 bool withMips,
73 Renderable renderable,
74 const SkColor4f colors[6]) {
75 Mipmapped mipmapped = withMips ? Mipmapped::kYes : Mipmapped::kNo;
77 mipmapped,
79 renderable);
80
81 BackendTexture backendTex = recorder->createBackendTexture(kSize, info);
82 REPORTER_ASSERT(reporter, backendTex.isValid());
83
84 update_backend_texture(recorder, backendTex, ct, withMips, colors);
85
86 return backendTex;
87}
88
89sk_sp<SkImage> wrap_backend_texture(skiatest::Reporter* reporter,
90 Recorder* recorder,
91 const skgpu::graphite::BackendTexture& backendTex,
92 SkColorType ct,
93 bool withMips) {
95 backendTex,
96 ct,
98 /* colorSpace= */ nullptr);
100 REPORTER_ASSERT(reporter, image->hasMipmaps() == withMips);
101
102 return image;
103}
104
105void check_levels(skiatest::Reporter* reporter,
106 Context* context,
107 Recorder* recorder,
108 SkImage* image,
109 bool withMips,
110 const SkColor4f colors[6]) {
111 int numLevels = withMips ? kNumMipLevels : 1;
112
113 SkSamplingOptions sampling = withMips
116
118 sk_sp<SkSurface> surf = SkSurfaces::RenderTarget(recorder, surfaceII, Mipmapped::kNo);
119 SkCanvas* canvas = surf->getCanvas();
120
121 for (int i = 0, drawSize = kSize.width(); i < numLevels; ++i, drawSize /= 2) {
122 if (i == 5) {
123 // TODO: Metal currently never draws the top-most mip-level (skbug.com/13792)
124 continue;
125 }
126
127 SkImageInfo readbackII = SkImageInfo::Make({drawSize, drawSize}, kRGBA_8888_SkColorType,
129 SkAutoPixmapStorage actual;
130 SkAssertResult(actual.tryAlloc(readbackII));
131 actual.erase(SkColors::kTransparent);
132
134 paint.setBlendMode(SkBlendMode::kSrc);
135
137
138#if 0
139 // This option gives greater control over the tilemodes and texture scaling
140 SkMatrix lm;
141 lm.setScale(1.0f / (1 << i), 1.0f / (1 << i));
142
144 canvas->drawRect(SkRect::MakeWH(drawSize, drawSize), paint);
145#else
146 canvas->drawImageRect(image, SkRect::MakeWH(drawSize, drawSize), sampling, &paint);
147#endif
148
149 if (!surf->readPixels(actual, 0, 0)) {
150 ERRORF(reporter, "readPixels failed");
151 return;
152 }
153
154 SkString str;
155 str.appendf("mip-level %d", i);
156
158 }
159}
160
161} // anonymous namespace
162
163DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(UpdateImageBackendTextureTest, reporter, context,
165 // TODO: Remove this check once Vulkan supports creating default TexutreInfo from caps and we
166 // implement createBackendTexture.
167 if (context->backend() == BackendApi::kVulkan) {
168 return;
169 }
170
171 const Caps* caps = context->priv().caps();
172 std::unique_ptr<Recorder> recorder = context->makeRecorder();
173
174 constexpr SkColor4f kColors[6] = {
175 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
176 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
177 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
178 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
179 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
180 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
181 };
182
183 constexpr SkColor4f kColorsNew[6] = {
184 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
185 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
186 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
187 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
188 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
189 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
190 };
191
192 // TODO: test more than just RGBA8
193 for (SkColorType ct : { kRGBA_8888_SkColorType }) {
194 for (bool withMips : { true, false }) {
195 for (Renderable renderable : { Renderable::kYes, Renderable::kNo }) {
196
197 BackendTexture backendTex = create_backend_texture(reporter, caps, recorder.get(),
198 ct, withMips, renderable,
199 kColors);
200
201 sk_sp<SkImage> image = wrap_backend_texture(reporter, recorder.get(), backendTex,
202 ct, withMips);
203 if (!image) {
204 continue;
205 }
206
207 check_levels(reporter, context, recorder.get(), image.get(), withMips, kColors);
208
209 image.reset();
210
211 update_backend_texture(recorder.get(), backendTex, ct, withMips, kColorsNew);
212
213 image = wrap_backend_texture(reporter, recorder.get(), backendTex, ct, withMips);
214 if (!image) {
215 continue;
216 }
217
218 check_levels(reporter, context, recorder.get(), image.get(), withMips, kColorsNew);
219
220 image.reset();
221
222 recorder->deleteBackendTexture(backendTex);
223 }
224 }
225 }
226}
static void check_solid_pixmap(skiatest::Reporter *reporter, const SkColor4f &expected, const SkPixmap &actual, GrColorType ct, const char *label1, const char *label2)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
reporter
Definition: FontMgrTest.cpp:39
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
kUnpremul_SkAlphaType
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorType
Definition: SkColorType.h:19
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
SkFilterMode
bool CheckSolidPixels(const SkColor4f &col, const SkPixmap &pixmap, const float tolRGBA[4], std::function< ComparePixmapsErrorReporter > &error)
Definition: TestUtils.cpp:191
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define ERRORF(r,...)
Definition: Test.h:293
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(UpdateImageBackendTextureTest, reporter, context, CtsEnforcement::kNextRelease)
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void clear(SkColor color)
Definition: SkCanvas.h:1199
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
Definition: SkCanvas.cpp:2333
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkImage.cpp:179
SkColorType colorType() const
Definition: SkImage.cpp:152
bool hasMipmaps() const
Definition: SkImage.cpp:292
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:296
const char * c_str() const
Definition: SkString.h:133
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:550
SkCanvas * getCanvas()
Definition: SkSurface.cpp:82
bool readPixels(const SkPixmap &dst, int srcX, int srcY)
Definition: SkSurface.cpp:125
T * get() const
Definition: SkRefCnt.h:303
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
virtual TextureInfo getDefaultSampledTextureInfo(SkColorType, Mipmapped mipmapped, Protected, Renderable) const =0
const Caps * caps() const
Definition: ContextPriv.h:32
BackendApi backend() const
Definition: Context.cpp:130
std::unique_ptr< Recorder > makeRecorder(const RecorderOptions &={})
Definition: Context.cpp:132
BackendTexture createBackendTexture(SkISize dimensions, const TextureInfo &)
Definition: Recorder.cpp:284
bool updateBackendTexture(const BackendTexture &, const SkPixmap srcData[], int numLevels)
Definition: Recorder.cpp:314
const Paint & paint
Definition: color_source.cc:38
@ kVulkan
Definition: embedder.h:86
const uint8_t uint32_t uint32_t GError ** error
constexpr int kSize
double y
double x
constexpr SkColor4f kTransparent
Definition: SkColor.h:434
SK_API sk_sp< SkImage > WrapTexture(skgpu::graphite::Recorder *, const skgpu::graphite::BackendTexture &, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, skgpu::Origin origin, GenerateMipmapsFromBase generateMipmapsFromBase, TextureReleaseProc=nullptr, ReleaseContext=nullptr, std::string_view label={})
sk_sp< const SkImage > image
Definition: SkRecords.h:269
PODArray< SkColor > colors
Definition: SkRecords.h:276
SkSamplingOptions sampling
Definition: SkRecords.h:337
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)
int make_pixmaps(SkColorType ct, SkAlphaType at, bool withMips, const SkColor4f colors[6], SkPixmap pixmaps[6], std::unique_ptr< char[]> *mem)
Definition: ToolUtils.cpp:181
const char * colortype_name(SkColorType ct)
Definition: ToolUtils.cpp:65
const DlColor kColors[]
Definition: GpuTools.h:21
Renderable
Definition: GpuTypes.h:69
Mipmapped
Definition: GpuTypes.h:53
SkSamplingOptions(SkFilterMode::kLinear))
Definition: SkSize.h:16
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609