Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ExtendedSkColorTypeTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 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
21#include "include/gpu/GrTypes.h"
29#include "tests/Test.h"
30#include "tests/TestUtils.h"
31#include "tools/ToolUtils.h"
32
33#include <array>
34#include <cstddef>
35#include <cstdint>
36#include <functional>
37#include <initializer_list>
38
39class SkPixmap;
40struct GrContextOptions;
41
42static constexpr int kSize = 32;
43
45 float a = 0;
46 if (!(channels & kAlpha_SkColorChannelFlag)) {
47 a = 1;
48 }
49
50 return { 0, 0, 0, a };
51}
52
54 if (channels & kGray_SkColorChannelFlag) {
55 return { 1, 1, 1, 1 };
56 }
57
58 float r = 1, g = 1, b = 1;
59 if (!(channels & kRed_SkColorChannelFlag)) {
60 r = 0;
61 }
62 if (!(channels & kGreen_SkColorChannelFlag)) {
63 g = 0;
64 }
65 if (!(channels & kBlue_SkColorChannelFlag)) {
66 b = 0;
67 }
68
69 return { r, g, b, 1.0f };
70}
71
78
79static const TestCase gTests[] = {
98};
99
101
102 const SkImageInfo nativeII = SkImageInfo::Make(kSize, kSize, test.fColorType, test.fAlphaType);
105
106 uint32_t actualChannels = SkColorTypeChannelFlags(test.fColorType);
107 REPORTER_ASSERT(reporter, test.fChannels == actualChannels);
108
109 // all colorTypes can be drawn to
110 {
111 auto s = SkSurfaces::Raster(nativeII);
113 }
114
115 // opaque formats should make transparent black become opaque
116 {
118 pm.alloc(nativeII);
120 SkColor actual = pm.getColor(0, 0);
121 SkColor4f expected = get_trans_black_expected_color(test.fChannels);
122 REPORTER_ASSERT(reporter, expected.toSkColor() == actual);
123 }
124
125 // unused channels should drop out
126 {
128 pm.alloc(nativeII);
130 SkColor actual = pm.getColor(0, 0);
131 SkColor4f expected = get_opaque_white_expected_color(test.fChannels);
132 REPORTER_ASSERT(reporter, expected.toSkColor() == actual);
133 }
134
135 // Reading back from an image to the same colorType should always work
136 {
138 srcPM.alloc(nativeII);
139 srcPM.erase(SkColors::kWhite);
140 auto i = SkImages::RasterFromPixmap(srcPM, nullptr, nullptr);
142
143 SkAutoPixmapStorage readbackPM;
144 readbackPM.alloc(nativeII);
145 readbackPM.erase(SkColors::kTransparent);
146
147 REPORTER_ASSERT(reporter, i->readPixels(nullptr, readbackPM, 0, 0));
148
149 SkColor expected = srcPM.getColor(0, 0);
150 SkColor actual = readbackPM.getColor(0, 0);
151 REPORTER_ASSERT(reporter, expected == actual);
152 }
153
154 // Rendering to an F32 surface should always work
155 {
157 srcPM.alloc(nativeII);
158 srcPM.erase(SkColors::kWhite);
159 auto i = SkImages::RasterFromPixmap(srcPM, nullptr, nullptr);
161
162 auto s = SkSurfaces::Raster(f32Unpremul);
164
165 {
166 auto c = s->getCanvas();
167 c->drawImage(i, 0, 0);
168 }
169
170 SkAutoPixmapStorage readbackPM;
171 readbackPM.alloc(f32Unpremul);
172 readbackPM.erase(SkColors::kTransparent);
173
174 REPORTER_ASSERT(reporter, i->readPixels(nullptr, readbackPM, 0, 0));
175
176 SkColor expected = srcPM.getColor(0, 0);
177 SkColor actual = readbackPM.getColor(0, 0);
178 REPORTER_ASSERT(reporter, expected == actual);
179 }
180}
181
183 const SkPixmap& expected, const SkPixmap& actual,
184 SkColorType ct, const char* label) {
185 const float tols[4] = {0.0f, 0.0f, 0.0f, 0};
186
187 auto error = std::function<ComparePixmapsErrorReporter>(
188 [reporter, ct, label](int x, int y, const float diffs[4]) {
189 SkASSERT(x >= 0 && y >= 0);
190 ERRORF(reporter, "%s %s - mismatch at %d, %d (%f, %f, %f %f)",
191 ToolUtils::colortype_name(ct), label, x, y,
192 diffs[0], diffs[1], diffs[2], diffs[3]);
193 });
194
195 ComparePixels(expected, actual, tols, error);
196}
197
198static void gpu_tests(GrDirectContext* dContext,
200 const TestCase& test) {
201 using namespace skgpu;
202
203 const SkImageInfo nativeII = SkImageInfo::Make(kSize, kSize, test.fColorType, test.fAlphaType);
206
207 // We had better not be able to render to prohibited colorTypes
208 if (!test.fGpuCanMakeSurfaces) {
209 auto s = SkSurfaces::RenderTarget(dContext, Budgeted::kNo, nativeII);
211 }
212
213 if (!dContext->colorTypeSupportedAsImage(test.fColorType)) {
214 return;
215 }
216
217 Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
218
219 SkAutoPixmapStorage nativeExpected;
220 nativeExpected.alloc(nativeII);
221 nativeExpected.erase(SkColors::kWhite);
222
223 for (bool fullInit : { false, true }) {
224 GrBackendTexture backendTex;
225
226 bool finishedBECreate = false;
227 auto markFinished = [](void* context) {
228 *(bool*)context = true;
229 };
230 if (fullInit) {
231 backendTex = dContext->createBackendTexture(nativeExpected, kTopLeft_GrSurfaceOrigin,
232 GrRenderable::kNo, isProtected,
233 markFinished, &finishedBECreate);
234 } else {
235 backendTex = dContext->createBackendTexture(kSize,
236 kSize,
237 test.fColorType,
239 Mipmapped::kNo,
240 GrRenderable::kNo,
241 isProtected,
242 markFinished,
243 &finishedBECreate);
244 }
245 REPORTER_ASSERT(reporter, backendTex.isValid());
246 dContext->submit();
247 while (backendTex.isValid() && !finishedBECreate) {
248 dContext->checkAsyncWorkCompletion();
249 }
250
251 auto img = SkImages::BorrowTextureFrom(dContext,
252 backendTex,
254 test.fColorType,
255 test.fAlphaType,
256 nullptr);
258
259 {
260 SkAutoPixmapStorage nativeActual;
261 nativeActual.alloc(nativeII);
262 nativeActual.erase(SkColors::kTransparent);
263
264 if (img->readPixels(dContext, nativeActual, 0, 0)) {
265 compare_pixmaps(reporter, nativeExpected, nativeActual,
266 test.fColorType, "SkImage::readPixels to native CT");
267 }
268
269 // SkSurface::readPixels with the same colorType as the source pixels round trips
270 // (when allowed)
271 if (dContext->colorTypeSupportedAsSurface(test.fColorType)) {
272 auto s = SkSurfaces::RenderTarget(dContext, Budgeted::kNo, nativeII);
274
275 {
276 SkCanvas* c = s->getCanvas();
277 c->drawImage(img, 0, 0);
278 }
279
280 nativeActual.erase(SkColors::kTransparent);
281 REPORTER_ASSERT(reporter, s->readPixels(nativeActual, 0, 0));
282
283 compare_pixmaps(reporter, nativeExpected, nativeActual,
284 test.fColorType, "SkSurface::readPixels to native CT");
285 }
286 }
287
288 {
289 SkAutoPixmapStorage f32Expected;
290 f32Expected.alloc(f32Unpremul);
291 f32Expected.erase(get_opaque_white_expected_color(test.fChannels));
292
293 // read back to F32 if possible
294 {
295 SkAutoPixmapStorage f32Actual;
296 f32Actual.alloc(f32Unpremul);
297 f32Actual.erase(SkColors::kTransparent);
298 if (img->readPixels(dContext, f32Actual, 0, 0)) {
299 compare_pixmaps(reporter, f32Expected, f32Actual,
300 test.fColorType, "SkImage::readPixels to F32");
301 }
302 }
303
304 // drawing a native SkImage works appropriately (as assessed by reading back from an
305 // RGBA8 surface to an F32 pixmap)
306 {
307 const SkImageInfo rgba8888Premul = SkImageInfo::Make(kSize, kSize,
310
311 auto s = SkSurfaces::RenderTarget(dContext, Budgeted::kNo, rgba8888Premul);
313
314 {
315 SkCanvas* c = s->getCanvas();
316 c->drawImage(img, 0, 0);
317 }
318
319 SkAutoPixmapStorage f32Actual;
320 f32Actual.alloc(f32Unpremul);
321 f32Actual.erase(SkColors::kTransparent);
322 REPORTER_ASSERT(reporter, s->readPixels(f32Actual, 0, 0));
323
324 compare_pixmaps(reporter, f32Expected, f32Actual,
325 test.fColorType, "SkSurface::drawn to RGBA8888");
326 }
327 }
328
329 img.reset();
330 dContext->flushAndSubmit();
331 dContext->deleteBackendTexture(backendTex);
332 }
333}
334
335DEF_TEST(ExtendedSkColorTypeTests_raster, reporter) {
336 for (size_t i = 0; i < std::size(gTests); ++i) {
338 }
339}
340
341DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(ExtendedSkColorTypeTests_gpu,
342 reporter,
343 ctxInfo,
345 auto context = ctxInfo.directContext();
346
347 for (size_t i = 0; i < std::size(gTests); ++i) {
348 gpu_tests(context, reporter, gTests[i]);
349 }
350}
static void raster_tests(skiatest::Reporter *reporter, const TestCase &test)
static constexpr int kSize
static SkColor4f get_trans_black_expected_color(SkColorChannelFlag channels)
static SkColor4f get_opaque_white_expected_color(SkColorChannelFlag channels)
static const TestCase gTests[]
static void gpu_tests(GrDirectContext *dContext, skiatest::Reporter *reporter, const TestCase &test)
static void compare_pixmaps(skiatest::Reporter *reporter, const SkPixmap &expected, const SkPixmap &actual, SkColorType ct, const char *label)
reporter
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
skgpu::Protected Protected
kUnpremul_SkAlphaType
SkAlphaType
Definition SkAlphaType.h:26
@ 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
SkColorType
Definition SkColorType.h:19
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
Definition SkColorType.h:50
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition SkColorType.h:23
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
Definition SkColorType.h:43
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition SkColorType.h:26
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
Definition SkColorType.h:48
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition SkColorType.h:38
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition SkColorType.h:21
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
Definition SkColorType.h:29
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition SkColorType.h:25
@ kA16_float_SkColorType
pixel with a half float for alpha
Definition SkColorType.h:45
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition SkColorType.h:40
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition SkColorType.h:27
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
Definition SkColorType.h:49
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition SkColorType.h:36
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition SkColorType.h:46
uint32_t SkColor
Definition SkColor.h:37
SkColorChannelFlag
Definition SkColor.h:238
@ kRGB_SkColorChannelFlags
Definition SkColor.h:247
@ kRGBA_SkColorChannelFlags
Definition SkColor.h:248
@ kRed_SkColorChannelFlag
Definition SkColor.h:239
@ kRG_SkColorChannelFlags
Definition SkColor.h:246
@ kGreen_SkColorChannelFlag
Definition SkColor.h:240
@ kAlpha_SkColorChannelFlag
Definition SkColor.h:242
@ kGray_SkColorChannelFlag
Definition SkColor.h:243
@ kBlue_SkColorChannelFlag
Definition SkColor.h:241
static uint32_t SkColorTypeChannelFlags(SkColorType ct)
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
bool ComparePixels(const GrCPixmap &a, const GrCPixmap &b, const float tolRGBA[4], std::function< ComparePixmapsErrorReporter > &error)
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define ERRORF(r,...)
Definition Test.h:293
#define DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info, ctsEnforcement)
Definition Test.h:434
const GrCaps * caps() const
bool supportsProtectedContent() const
Definition GrCaps.h:422
SK_API bool colorTypeSupportedAsSurface(SkColorType colorType) const
SK_API bool colorTypeSupportedAsImage(SkColorType) const
bool submit(GrSyncCpu sync=GrSyncCpu::kNo)
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
void deleteBackendTexture(const GrBackendTexture &)
GrBackendTexture createBackendTexture(int width, int height, const GrBackendFormat &, skgpu::Mipmapped, GrRenderable, GrProtected=GrProtected::kNo, std::string_view label={})
GrDirectContextPriv priv()
void alloc(const SkImageInfo &)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
SkColor getColor(int x, int y) const
Definition SkPixmap.cpp:187
bool erase(SkColor color, const SkIRect &subset) const
Definition SkPixmap.cpp:742
static bool b
struct MyStruct s
struct MyStruct a[10]
const uint8_t uint32_t uint32_t GError ** error
double y
double x
constexpr SkColor4f kWhite
Definition SkColor.h:439
constexpr SkColor4f kTransparent
Definition SkColor.h:434
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
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)
const char * colortype_name(SkColorType ct)
Definition ToolUtils.cpp:65
Protected
Definition GpuTypes.h:61
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkColorChannelFlag fChannels