Flutter Engine
The Flutter Engine
BitmapCopyTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 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
16#include "include/core/SkRect.h"
18#include "include/core/SkSize.h"
20#include "src/core/SkMemset.h"
21#include "tests/Test.h"
22#include "tools/ToolUtils.h"
23
24#include <array>
25#include <cstddef>
26
27static void init_src(const SkBitmap& bitmap) {
28 if (bitmap.getPixels()) {
29 bitmap.eraseColor(SK_ColorWHITE);
30 }
31}
32
33struct Pair {
35 const char* fValid;
36};
37
38// Utility functions for copyPixelsTo()/copyPixelsFrom() tests.
39// getPixel()
40// setPixel()
41// getSkConfigName()
42// struct Coordinates
43// reportCopyVerification()
44// writeCoordPixels()
45
46// Helper struct to contain pixel locations, while avoiding need for STL.
48
49 const int length;
50 SkIPoint* const data;
51
52 explicit Coordinates(int _length): length(_length)
53 , data(new SkIPoint[length]) { }
54
56 delete [] data;
57 }
58
59 SkIPoint* operator[](int i) const {
60 // Use with care, no bounds checking.
61 return data + i;
62 }
63};
64
65static const Pair gPairs[] = {
66 { kUnknown_SkColorType, "0000000" },
67 { kAlpha_8_SkColorType, "0100000" },
68 { kRGB_565_SkColorType, "0101011" },
69 { kARGB_4444_SkColorType, "0101111" },
70 { kN32_SkColorType, "0101111" },
71 { kRGBA_F16_SkColorType, "0101011" },
72};
73
74static void setup_src_bitmaps(SkBitmap* srcOpaque, SkBitmap* srcPremul,
75 SkColorType ct) {
76 const int W = 20;
77 const int H = 33;
78 sk_sp<SkColorSpace> colorSpace = nullptr;
79 if (kRGBA_F16_SkColorType == ct) {
80 colorSpace = SkColorSpace::MakeSRGB();
81 }
82
83 srcOpaque->allocPixels(SkImageInfo::Make(W, H, ct, kOpaque_SkAlphaType, colorSpace));
84 srcPremul->allocPixels(SkImageInfo::Make(W, H, ct, kPremul_SkAlphaType, colorSpace));
85 init_src(*srcOpaque);
86 init_src(*srcPremul);
87}
88
89DEF_TEST(BitmapCopy_extractSubset, reporter) {
90 const int W = 20;
91 for (size_t i = 0; i < std::size(gPairs); i++) {
92 SkBitmap srcOpaque, srcPremul;
93 setup_src_bitmaps(&srcOpaque, &srcPremul, gPairs[i].fColorType);
94
95 SkBitmap bitmap(srcOpaque);
96 SkBitmap subset;
97 SkIRect r;
98 // Extract a subset which has the same width as the original. This
99 // catches a bug where we cloned the genID incorrectly.
100 r.setLTRB(0, 1, W, 3);
101 // Relies on old behavior of extractSubset failing if colortype is unknown
102 if (kUnknown_SkColorType != bitmap.colorType() && bitmap.extractSubset(&subset, r)) {
103 REPORTER_ASSERT(reporter, subset.width() == W);
104 REPORTER_ASSERT(reporter, subset.height() == 2);
105 REPORTER_ASSERT(reporter, subset.alphaType() == bitmap.alphaType());
106
107 // Test copying an extracted subset.
108 for (size_t j = 0; j < std::size(gPairs); j++) {
110 bool success = ToolUtils::copy_to(&copy, gPairs[j].fColorType, subset);
111 if (!success) {
112 // Skip checking that success matches fValid, which is redundant
113 // with the code below.
115 continue;
116 }
117
118 // When performing a copy of an extracted subset, the gen id should
119 // change.
120 REPORTER_ASSERT(reporter, copy.getGenerationID() != subset.getGenerationID());
121
122 REPORTER_ASSERT(reporter, copy.width() == W);
123 REPORTER_ASSERT(reporter, copy.height() == 2);
124 }
125 }
126
127 bitmap = srcPremul;
128 if (bitmap.extractSubset(&subset, r)) {
129 REPORTER_ASSERT(reporter, subset.alphaType() == bitmap.alphaType());
130 }
131 }
132}
133
134/**
135 * Construct 4x4 pixels where we can look at a color and determine where it should be in the grid.
136 * alpha = 0xFF, blue = 0x80, red = x, green = y
137 */
139 for (int y = 0; y < 4; ++y) {
140 for (int x = 0; x < 4; ++x) {
141 colors[y*4+x] = SkPackARGB32(0xFF, x, y, 0x80);
142 }
143 }
144}
145
146static bool check_4x4_pixel(SkPMColor color, unsigned x, unsigned y) {
147 SkASSERT(x < 4 && y < 4);
148 return 0xFF == SkGetPackedA32(color) &&
149 x == SkGetPackedR32(color) &&
150 y == SkGetPackedG32(color) &&
151 0x80 == SkGetPackedB32(color);
152}
153
154/**
155 * Fill with all zeros, which will never match any value from fill_4x4_pixels
156 */
158 SkOpts::memset32(colors, 0, 16);
159}
160
161// Much of readPixels is exercised by copyTo testing, since readPixels is the backend for that
162// method. Here we explicitly test subset copies.
163//
164DEF_TEST(BitmapReadPixels, reporter) {
165 const int W = 4;
166 const int H = 4;
167 const size_t rowBytes = W * sizeof(SkPMColor);
168 const SkImageInfo srcInfo = SkImageInfo::MakeN32Premul(W, H);
169 SkPMColor srcPixels[16];
170 fill_4x4_pixels(srcPixels);
171 SkBitmap srcBM;
172 srcBM.installPixels(srcInfo, srcPixels, rowBytes);
173
175 SkPMColor dstPixels[16];
176
177 const struct {
178 bool fExpectedSuccess;
179 SkIPoint fRequestedSrcLoc;
180 SkISize fRequestedDstSize;
181 // If fExpectedSuccess, check these, otherwise ignore
182 SkIPoint fExpectedDstLoc;
183 SkIRect fExpectedSrcR;
184 } gRec[] = {
185 { true, { 0, 0 }, { 4, 4 }, { 0, 0 }, { 0, 0, 4, 4 } },
186 { true, { 1, 1 }, { 2, 2 }, { 0, 0 }, { 1, 1, 3, 3 } },
187 { true, { 2, 2 }, { 4, 4 }, { 0, 0 }, { 2, 2, 4, 4 } },
188 { true, {-1,-1 }, { 2, 2 }, { 1, 1 }, { 0, 0, 1, 1 } },
189 { false, {-1,-1 }, { 1, 1 }, { 0, 0 }, { 0, 0, 0, 0 } },
190 };
191
192 for (size_t i = 0; i < std::size(gRec); ++i) {
193 clear_4x4_pixels(dstPixels);
194
195 dstInfo = dstInfo.makeDimensions(gRec[i].fRequestedDstSize);
196 bool success = srcBM.readPixels(dstInfo, dstPixels, rowBytes,
197 gRec[i].fRequestedSrcLoc.x(), gRec[i].fRequestedSrcLoc.y());
198
199 REPORTER_ASSERT(reporter, gRec[i].fExpectedSuccess == success);
200 if (success) {
201 const SkIRect srcR = gRec[i].fExpectedSrcR;
202 const int dstX = gRec[i].fExpectedDstLoc.x();
203 const int dstY = gRec[i].fExpectedDstLoc.y();
204 // Walk the dst pixels, and check if we got what we expected
205 for (int y = 0; y < H; ++y) {
206 for (int x = 0; x < W; ++x) {
207 SkPMColor dstC = dstPixels[y*4+x];
208 // get into src coordinates
209 int sx = x - dstX + srcR.x();
210 int sy = y - dstY + srcR.y();
211 if (srcR.contains(sx, sy)) {
213 } else {
214 REPORTER_ASSERT(reporter, 0 == dstC);
215 }
216 }
217 }
218 }
219 }
220}
static bool check_4x4_pixel(SkPMColor color, unsigned x, unsigned y)
DEF_TEST(BitmapCopy_extractSubset, reporter)
static void fill_4x4_pixels(SkPMColor colors[16])
static void setup_src_bitmaps(SkBitmap *srcOpaque, SkBitmap *srcPremul, SkColorType ct)
static void init_src(const SkBitmap &bitmap)
static void clear_4x4_pixels(SkPMColor colors[16])
static const Pair gPairs[]
static const struct @223 gRec[]
reporter
Definition: FontMgrTest.cpp:39
SkColorType fColorType
@ 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
#define SkGetPackedB32(packed)
Definition: SkColorPriv.h:95
#define SkGetPackedR32(packed)
Definition: SkColorPriv.h:93
#define SkGetPackedA32(packed)
Definition: SkColorPriv.h:92
#define SkGetPackedG32(packed)
Definition: SkColorPriv.h:94
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColorPriv.h:106
SkColorType
Definition: SkColorType.h:19
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition: SkColorType.h:23
@ 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_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
uint32_t SkPMColor
Definition: SkColor.h:205
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static void copy(void *dst, const uint8_t *src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[])
Definition: SkSwizzler.cpp:31
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define W
Definition: aaa.cpp:17
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
Definition: SkBitmap.cpp:323
SkAlphaType alphaType() const
Definition: SkBitmap.h:162
int width() const
Definition: SkBitmap.h:149
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY) const
Definition: SkBitmap.cpp:488
uint32_t getGenerationID() const
Definition: SkBitmap.cpp:361
int height() const
Definition: SkBitmap.h:158
static sk_sp< SkColorSpace > MakeSRGB()
#define H
DlColor color
SkColorType fColorType
const char * fValid
double y
double x
void(* memset32)(uint32_t[], uint32_t, int)
PODArray< SkColor > colors
Definition: SkRecords.h:276
bool copy_to(SkBitmap *dst, SkColorType dstColorType, const SkBitmap &src)
Definition: ToolUtils.cpp:394
Definition: bitmap.py:1
Definition: copy.py:1
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
const int length
SkIPoint *const data
Coordinates(int _length)
SkIPoint * operator[](int i) const
Definition: SkMD5.cpp:130
Definition: SkRect.h:32
constexpr int32_t x() const
Definition: SkRect.h:141
constexpr int32_t y() const
Definition: SkRect.h:148
void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom)
Definition: SkRect.h:253
bool contains(int32_t x, int32_t y) const
Definition: SkRect.h:463
Definition: SkSize.h:16
static SkImageInfo MakeN32Premul(int width, int height)
SkImageInfo makeDimensions(SkISize newSize) const
Definition: SkImageInfo.h:454
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)