Flutter Engine
The Flutter Engine
GrDataUtils.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 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
9
14#include "include/core/SkSize.h"
20#include "modules/skcms/skcms.h"
23#include "src/base/SkTLazy.h"
29#include "src/gpu/Swizzle.h"
32
33#include <algorithm>
34#include <cstdint>
35#include <cstring>
36#include <functional>
37
38using namespace skia_private;
39
40#if defined(GR_TEST_UTILS)
41
42// The following four helpers are copied from src/gpu/DataUtils.cpp to support the test only
43// GrTwoColorBC1Compress function. Ideally we would copy the test function into DataUtils.cpp
44// instead, but we're currently trying to avoid using the GR_TEST_UTILS define in src/gpu.
45
46static int num_4x4_blocks(int size) {
47 return ((size + 3) & ~3) >> 2;
48}
49
50struct BC1Block {
51 uint16_t fColor0;
52 uint16_t fColor1;
53 uint32_t fIndices;
54};
55
56static uint16_t to565(SkColor col) {
57 int r5 = SkMulDiv255Round(31, SkColorGetR(col));
58 int g6 = SkMulDiv255Round(63, SkColorGetG(col));
59 int b5 = SkMulDiv255Round(31, SkColorGetB(col));
60
61 return (r5 << 11) | (g6 << 5) | b5;
62}
63
64// Create a BC1 compressed block that has two colors but is initialized to 'col0'
65static void create_BC1_block(SkColor col0, SkColor col1, BC1Block* block) {
66 block->fColor0 = to565(col0);
67 block->fColor1 = to565(col1);
68 SkASSERT(block->fColor0 <= block->fColor1); // we always assume transparent blocks
69
70 if (col0 == SK_ColorTRANSPARENT) {
71 // This sets all 16 pixels to just use color3 (under the assumption
72 // that this is a kBC1_RGBA8_UNORM texture. Note that in this case
73 // fColor0 will be opaque black.
74 block->fIndices = 0xFFFFFFFF;
75 } else {
76 // This sets all 16 pixels to just use 'fColor0'
77 block->fIndices = 0;
78 }
79}
80
81// Fill in 'dstPixels' with BC1 blocks derived from the 'pixmap'.
82void GrTwoColorBC1Compress(const SkPixmap& pixmap, SkColor otherColor, char* dstPixels) {
83 BC1Block* dstBlocks = reinterpret_cast<BC1Block*>(dstPixels);
85
86 BC1Block block;
87
88 // black -> fColor0, otherColor -> fColor1
89 create_BC1_block(SK_ColorBLACK, otherColor, &block);
90
91 int numXBlocks = num_4x4_blocks(pixmap.width());
92 int numYBlocks = num_4x4_blocks(pixmap.height());
93
94 for (int y = 0; y < numYBlocks; ++y) {
95 for (int x = 0; x < numXBlocks; ++x) {
96 int shift = 0;
97 int offsetX = 4 * x, offsetY = 4 * y;
98 block.fIndices = 0; // init all the pixels to color0 (i.e., opaque black)
99 for (int i = 0; i < 4; ++i) {
100 for (int j = 0; j < 4; ++j, shift += 2) {
101 if (offsetX + j >= pixmap.width() || offsetY + i >= pixmap.height()) {
102 // This can happen for the topmost levels of a mipmap and for
103 // non-multiple of 4 textures
104 continue;
105 }
106
107 SkColor tmp = pixmap.getColor(offsetX + j, offsetY + i);
108 if (tmp == SK_ColorTRANSPARENT) {
109 // For RGBA BC1 images color3 is set to transparent black
110 block.fIndices |= 3 << shift;
111 } else if (tmp != SK_ColorBLACK) {
112 block.fIndices |= 1 << shift; // color1
113 }
114 }
115 }
116
117 dstBlocks[y*numXBlocks + x] = block;
118 }
119 }
120}
121
122#endif
123
124size_t GrComputeTightCombinedBufferSize(size_t bytesPerPixel, SkISize baseDimensions,
125 TArray<size_t>* individualMipOffsets, int mipLevelCount) {
126 SkASSERT(individualMipOffsets && individualMipOffsets->empty());
127 SkASSERT(mipLevelCount >= 1);
128
129 individualMipOffsets->push_back(0);
130
131 size_t combinedBufferSize = baseDimensions.width() * bytesPerPixel * baseDimensions.height();
132 SkISize levelDimensions = baseDimensions;
133
134 // The Vulkan spec for copying a buffer to an image requires that the alignment must be at
135 // least 4 bytes and a multiple of the bytes per pixel of the image config.
136 SkASSERT(bytesPerPixel == 1 || bytesPerPixel == 2 || bytesPerPixel == 3 ||
137 bytesPerPixel == 4 || bytesPerPixel == 8 || bytesPerPixel == 16);
138 int desiredAlignment = (bytesPerPixel == 3) ? 12 : (bytesPerPixel > 4 ? bytesPerPixel : 4);
139
140 for (int currentMipLevel = 1; currentMipLevel < mipLevelCount; ++currentMipLevel) {
141 levelDimensions = {std::max(1, levelDimensions.width() /2),
142 std::max(1, levelDimensions.height()/2)};
143
144 size_t trimmedSize = levelDimensions.area() * bytesPerPixel;
145 const size_t alignmentDiff = combinedBufferSize % desiredAlignment;
146 if (alignmentDiff != 0) {
147 combinedBufferSize += desiredAlignment - alignmentDiff;
148 }
149 SkASSERT((0 == combinedBufferSize % 4) && (0 == combinedBufferSize % bytesPerPixel));
150
151 individualMipOffsets->push_back(combinedBufferSize);
152 combinedBufferSize += trimmedSize;
153 }
154
155 SkASSERT(individualMipOffsets->size() == mipLevelCount);
156 return combinedBufferSize;
157}
158
160 bool* isNormalized, bool* isSRGB) {
161 skgpu::Swizzle swizzle("rgba");
162 *isNormalized = true;
163 *isSRGB = false;
164 switch (ct) {
165 case GrColorType::kAlpha_8: *load = SkRasterPipelineOp::load_a8; break;
166 case GrColorType::kAlpha_16: *load = SkRasterPipelineOp::load_a16; break;
167 case GrColorType::kBGR_565: *load = SkRasterPipelineOp::load_565; break;
168 case GrColorType::kRGB_565: swizzle = skgpu::Swizzle("bgr1");
169 *load = SkRasterPipelineOp::load_565; break;
170 case GrColorType::kABGR_4444: *load = SkRasterPipelineOp::load_4444; break;
171 case GrColorType::kARGB_4444: swizzle = skgpu::Swizzle("bgra");
172 *load = SkRasterPipelineOp::load_4444; break;
173 case GrColorType::kBGRA_4444: swizzle = skgpu::Swizzle("gbar");
174 *load = SkRasterPipelineOp::load_4444; break;
175 case GrColorType::kRGBA_8888: *load = SkRasterPipelineOp::load_8888; break;
176 case GrColorType::kRG_88: *load = SkRasterPipelineOp::load_rg88; break;
177 case GrColorType::kRGBA_1010102: *load = SkRasterPipelineOp::load_1010102; break;
178 case GrColorType::kBGRA_1010102: *load = SkRasterPipelineOp::load_1010102;
179 swizzle = skgpu::Swizzle("bgra");
180 break;
181 case GrColorType::kRGBA_10x6: *load = SkRasterPipelineOp::load_10x6; break;
182 case GrColorType::kAlpha_F16: *load = SkRasterPipelineOp::load_af16; break;
183 case GrColorType::kRGBA_F16_Clamped: *load = SkRasterPipelineOp::load_f16; break;
184 case GrColorType::kRG_1616: *load = SkRasterPipelineOp::load_rg1616; break;
185 case GrColorType::kRGBA_16161616: *load = SkRasterPipelineOp::load_16161616; break;
186
187 case GrColorType::kRGBA_8888_SRGB: *load = SkRasterPipelineOp::load_8888;
188 *isSRGB = true;
189 break;
190 case GrColorType::kRG_F16: *load = SkRasterPipelineOp::load_rgf16;
191 *isNormalized = false;
192 break;
193 case GrColorType::kRGBA_F16: *load = SkRasterPipelineOp::load_f16;
194 *isNormalized = false;
195 break;
196 case GrColorType::kRGBA_F32: *load = SkRasterPipelineOp::load_f32;
197 *isNormalized = false;
198 break;
199 case GrColorType::kAlpha_8xxx: *load = SkRasterPipelineOp::load_8888;
200 swizzle = skgpu::Swizzle("000r");
201 break;
202 case GrColorType::kAlpha_F32xxx: *load = SkRasterPipelineOp::load_f32;
203 swizzle = skgpu::Swizzle("000r");
204 break;
205 case GrColorType::kGray_8xxx: *load = SkRasterPipelineOp::load_8888;
206 swizzle = skgpu::Swizzle("rrr1");
207 break;
208 case GrColorType::kGray_8: *load = SkRasterPipelineOp::load_a8;
209 swizzle = skgpu::Swizzle("aaa1");
210 break;
211 case GrColorType::kR_8xxx: *load = SkRasterPipelineOp::load_8888;
212 swizzle = skgpu::Swizzle("r001");
213 break;
214 case GrColorType::kR_8: *load = SkRasterPipelineOp::load_a8;
215 swizzle = skgpu::Swizzle("a001");
216 break;
217 case GrColorType::kGrayAlpha_88: *load = SkRasterPipelineOp::load_rg88;
218 swizzle = skgpu::Swizzle("rrrg");
219 break;
220 case GrColorType::kBGRA_8888: *load = SkRasterPipelineOp::load_8888;
221 swizzle = skgpu::Swizzle("bgra");
222 break;
223 case GrColorType::kRGB_888x: *load = SkRasterPipelineOp::load_8888;
224 swizzle = skgpu::Swizzle("rgb1");
225 break;
226
227 // These are color types we don't expect to ever have to load.
233 SK_ABORT("unexpected CT");
234 }
235 return swizzle;
236}
237
238enum class LumMode {
239 kNone,
240 kToRGB,
242};
243
245 LumMode* lumMode, bool* isNormalized,
246 bool* isSRGB) {
247 skgpu::Swizzle swizzle("rgba");
248 *isNormalized = true;
249 *isSRGB = false;
250 *lumMode = LumMode::kNone;
251 switch (ct) {
252 case GrColorType::kAlpha_8: *store = SkRasterPipelineOp::store_a8; break;
253 case GrColorType::kAlpha_16: *store = SkRasterPipelineOp::store_a16; break;
254 case GrColorType::kBGR_565: *store = SkRasterPipelineOp::store_565; break;
255 case GrColorType::kRGB_565: swizzle = skgpu::Swizzle("bgr1");
256 *store = SkRasterPipelineOp::store_565; break;
257 case GrColorType::kABGR_4444: *store = SkRasterPipelineOp::store_4444; break;
258 case GrColorType::kARGB_4444: swizzle = skgpu::Swizzle("bgra");
259 *store = SkRasterPipelineOp::store_4444; break;
260 case GrColorType::kBGRA_4444: swizzle = skgpu::Swizzle("argb");
261 *store = SkRasterPipelineOp::store_4444; break;
262 case GrColorType::kRGBA_8888: *store = SkRasterPipelineOp::store_8888; break;
263 case GrColorType::kRG_88: *store = SkRasterPipelineOp::store_rg88; break;
264 case GrColorType::kRGBA_1010102: *store = SkRasterPipelineOp::store_1010102; break;
265 case GrColorType::kBGRA_1010102: swizzle = skgpu::Swizzle("bgra");
266 *store = SkRasterPipelineOp::store_1010102;
267 break;
268 case GrColorType::kRGBA_10x6: *store = SkRasterPipelineOp::store_10x6; break;
269 case GrColorType::kRGBA_F16_Clamped: *store = SkRasterPipelineOp::store_f16; break;
270 case GrColorType::kRG_1616: *store = SkRasterPipelineOp::store_rg1616; break;
271 case GrColorType::kRGBA_16161616: *store = SkRasterPipelineOp::store_16161616; break;
272
273 case GrColorType::kRGBA_8888_SRGB: *store = SkRasterPipelineOp::store_8888;
274 *isSRGB = true;
275 break;
276 case GrColorType::kRG_F16: *store = SkRasterPipelineOp::store_rgf16;
277 *isNormalized = false;
278 break;
279 case GrColorType::kAlpha_F16: *store = SkRasterPipelineOp::store_af16;
280 *isNormalized = false;
281 break;
282 case GrColorType::kRGBA_F16: *store = SkRasterPipelineOp::store_f16;
283 *isNormalized = false;
284 break;
285 case GrColorType::kRGBA_F32: *store = SkRasterPipelineOp::store_f32;
286 *isNormalized = false;
287 break;
288 case GrColorType::kAlpha_8xxx: *store = SkRasterPipelineOp::store_8888;
289 swizzle = skgpu::Swizzle("a000");
290 break;
291 case GrColorType::kAlpha_F32xxx: *store = SkRasterPipelineOp::store_f32;
292 swizzle = skgpu::Swizzle("a000");
293 break;
294 case GrColorType::kBGRA_8888: swizzle = skgpu::Swizzle("bgra");
295 *store = SkRasterPipelineOp::store_8888;
296 break;
297 case GrColorType::kRGB_888x: swizzle = skgpu::Swizzle("rgb1");
298 *store = SkRasterPipelineOp::store_8888;
299 break;
300 case GrColorType::kR_8xxx: swizzle = skgpu::Swizzle("r001");
301 *store = SkRasterPipelineOp::store_8888;
302 break;
303 case GrColorType::kR_8: swizzle = skgpu::Swizzle("agbr");
304 *store = SkRasterPipelineOp::store_a8;
305 break;
306 case GrColorType::kR_16: swizzle = skgpu::Swizzle("agbr");
307 *store = SkRasterPipelineOp::store_a16;
308 break;
309 case GrColorType::kR_F16: swizzle = skgpu::Swizzle("agbr");
310 *store = SkRasterPipelineOp::store_af16;
311 break;
313 *store = SkRasterPipelineOp::store_af16;
314 break;
316 *store = SkRasterPipelineOp::store_a8;
317 break;
319 swizzle = skgpu::Swizzle("ragb");
320 *store = SkRasterPipelineOp::store_rg88;
321 break;
323 *store = SkRasterPipelineOp::store_8888;
324 swizzle = skgpu::Swizzle("r000");
325 break;
326
327 // These are color types we don't expect to ever have to store.
328 case GrColorType::kRGB_888: // This is handled specially in GrConvertPixels.
330 SK_ABORT("unexpected CT");
331 }
332 return swizzle;
333}
334
335bool GrConvertPixels(const GrPixmap& dst, const GrCPixmap& src, bool flipY) {
336 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
337 if (src.dimensions().isEmpty() || dst.dimensions().isEmpty()) {
338 return false;
339 }
340 if (src.colorType() == GrColorType::kUnknown || dst.colorType() == GrColorType::kUnknown) {
341 return false;
342 }
343 if (!src.hasPixels() || !dst.hasPixels()) {
344 return false;
345 }
346 if (dst.dimensions() != src.dimensions()) {
347 return false;
348 }
349 if (dst.colorType() == GrColorType::kRGB_888) {
350 // SkRasterPipeline doesn't handle writing to RGB_888. So we have it write to RGB_888x and
351 // then do another conversion that does the 24bit packing. We could be cleverer and skip the
352 // temp pixmap if this is the only conversion but this is rare so keeping it simple.
353 GrPixmap temp = GrPixmap::Allocate(dst.info().makeColorType(GrColorType::kRGB_888x));
354 if (!GrConvertPixels(temp, src, flipY)) {
355 return false;
356 }
357 auto* tRow = reinterpret_cast<const char*>(temp.addr());
358 auto* dRow = reinterpret_cast<char*>(dst.addr());
359 for (int y = 0; y < dst.height(); ++y, tRow += temp.rowBytes(), dRow += dst.rowBytes()) {
360 for (int x = 0; x < dst.width(); ++x) {
361 auto t = tRow + x*sizeof(uint32_t);
362 auto d = dRow + x*3;
363 memcpy(d, t, 3);
364 }
365 }
366 return true;
367 } else if (src.colorType() == GrColorType::kRGB_888) {
368 // SkRasterPipeline doesn't handle reading from RGB_888. So convert it to RGB_888x and then
369 // do a recursive call if there is any remaining conversion.
370 GrPixmap temp = GrPixmap::Allocate(src.info().makeColorType(GrColorType::kRGB_888x));
371 auto* sRow = reinterpret_cast<const char*>(src.addr());
372 auto* tRow = reinterpret_cast<char*>(temp.addr());
373 for (int y = 0; y < src.height(); ++y, sRow += src.rowBytes(), tRow += temp.rowBytes()) {
374 for (int x = 0; x < src.width(); ++x) {
375 auto s = sRow + x*3;
376 auto t = tRow + x*sizeof(uint32_t);
377 memcpy(t, s, 3);
378 t[3] = static_cast<char>(0xFF);
379 }
380 }
381 return GrConvertPixels(dst, temp, flipY);
382 }
383
384 size_t srcBpp = src.info().bpp();
385 size_t dstBpp = dst.info().bpp();
386
387 // SkRasterPipeline operates on row-pixels not row-bytes.
388 SkASSERT(dst.rowBytes() % dstBpp == 0);
389 SkASSERT(src.rowBytes() % srcBpp == 0);
390
391 bool premul = src.alphaType() == kUnpremul_SkAlphaType &&
392 dst.alphaType() == kPremul_SkAlphaType;
393 bool unpremul = src.alphaType() == kPremul_SkAlphaType &&
394 dst.alphaType() == kUnpremul_SkAlphaType;
395 bool alphaOrCSConversion =
396 premul || unpremul || !SkColorSpace::Equals(src.colorSpace(), dst.colorSpace());
397
398 if (src.colorType() == dst.colorType() && !alphaOrCSConversion) {
399 size_t tightRB = dstBpp * dst.width();
400 if (flipY) {
401 auto s = static_cast<const char*>(src.addr());
402 auto d = SkTAddOffset<char>(dst.addr(), dst.rowBytes()*(dst.height() - 1));
403 for (int y = 0; y < dst.height(); ++y, d -= dst.rowBytes(), s += src.rowBytes()) {
404 memcpy(d, s, tightRB);
405 }
406 } else {
407 SkRectMemcpy(dst.addr(), dst.rowBytes(),
408 src.addr(), src.rowBytes(),
409 tightRB, src.height());
410 }
411 return true;
412 }
413
415 bool srcIsNormalized;
416 bool srcIsSRGB;
417 auto loadSwizzle = get_load_and_src_swizzle(src.colorType(),
418 &load,
419 &srcIsNormalized,
420 &srcIsSRGB);
421
423 LumMode lumMode;
424 bool dstIsNormalized;
425 bool dstIsSRGB;
426 auto storeSwizzle = get_dst_swizzle_and_store(dst.colorType(),
427 &store,
428 &lumMode,
429 &dstIsNormalized,
430 &dstIsSRGB);
431
433 skgpu::Swizzle loadStoreSwizzle;
434 if (alphaOrCSConversion) {
435 steps.init(src.colorSpace(), src.alphaType(), dst.colorSpace(), dst.alphaType());
436 } else {
437 loadStoreSwizzle = skgpu::Swizzle::Concat(loadSwizzle, storeSwizzle);
438 }
439 int cnt = 1;
440 int height = src.height();
442 srcCtx{const_cast<void*>(src.addr()), SkToInt(src.rowBytes()/srcBpp)},
443 dstCtx{ dst.addr(), SkToInt(dst.rowBytes()/dstBpp)};
444
445 if (flipY) {
446 // It *almost* works to point the src at the last row and negate the stride and run the
447 // whole rectangle. However, SkRasterPipeline::run()'s control loop uses size_t loop
448 // variables so it winds up relying on unsigned overflow math. It works out in practice
449 // but UBSAN says "no!" as it's technically undefined and in theory a compiler could emit
450 // code that didn't do what is intended. So we go one row at a time. :(
451 srcCtx.pixels = static_cast<char*>(srcCtx.pixels) + src.rowBytes()*(height - 1);
452 std::swap(cnt, height);
453 }
454
455 bool hasConversion = alphaOrCSConversion || lumMode != LumMode::kNone;
456
457 if (srcIsSRGB && dstIsSRGB && !hasConversion) {
458 // No need to convert from srgb if we are just going to immediately convert it back.
459 srcIsSRGB = dstIsSRGB = false;
460 }
461
462 hasConversion = hasConversion || srcIsSRGB || dstIsSRGB;
463
464 SkRasterPipeline_<256> pipeline;
465 pipeline.append(load, &srcCtx);
466 if (hasConversion) {
467 loadSwizzle.apply(&pipeline);
468 if (srcIsSRGB) {
470 }
471 if (alphaOrCSConversion) {
472 steps->apply(&pipeline);
473 }
474 switch (lumMode) {
475 case LumMode::kNone:
476 break;
477 case LumMode::kToRGB:
478 pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_rgb);
479 break;
481 pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_alpha);
482 // If we ever need to store srgb-encoded gray (e.g. GL_SLUMINANCE8) then we
483 // should use ToRGB and then a swizzle stage rather than ToAlpha. The subsequent
484 // transfer function stage ignores the alpha channel (where we just stashed the
485 // gray).
486 SkASSERT(!dstIsSRGB);
487 break;
488 }
489 if (dstIsSRGB) {
491 }
492 storeSwizzle.apply(&pipeline);
493 } else {
494 loadStoreSwizzle.apply(&pipeline);
495 }
496 pipeline.append(store, &dstCtx);
497 auto pipelineFn = pipeline.compile();
498 for (int i = 0; i < cnt; ++i) {
499 pipelineFn(0, 0, src.width(), height);
500 srcCtx.pixels = static_cast<char*>(srcCtx.pixels) - src.rowBytes();
501 dstCtx.pixels = static_cast<char*>(dstCtx.pixels) + dst.rowBytes();
502 }
503
504 return true;
505}
506
507bool GrClearImage(const GrImageInfo& dstInfo, void* dst, size_t dstRB, std::array<float, 4> color) {
508 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
509
510 if (!dstInfo.isValid()) {
511 return false;
512 }
513 if (!dst) {
514 return false;
515 }
516 if (dstRB < dstInfo.minRowBytes()) {
517 return false;
518 }
519 if (dstInfo.colorType() == GrColorType::kRGB_888) {
520 // SkRasterPipeline doesn't handle writing to RGB_888. So we handle that specially here.
521 uint32_t rgba = SkColor4f{color[0], color[1], color[2], color[3]}.toBytes_RGBA();
522 for (int y = 0; y < dstInfo.height(); ++y) {
523 char* d = static_cast<char*>(dst) + y * dstRB;
524 for (int x = 0; x < dstInfo.width(); ++x, d += 3) {
525 memcpy(d, &rgba, 3);
526 }
527 }
528 return true;
529 }
530
531 LumMode lumMode;
532 bool isNormalized;
533 bool dstIsSRGB;
535 skgpu::Swizzle storeSwizzle = get_dst_swizzle_and_store(dstInfo.colorType(), &store, &lumMode,
536 &isNormalized, &dstIsSRGB);
537 char block[64];
538 SkArenaAlloc alloc(block, sizeof(block), 1024);
539 SkRasterPipeline_<256> pipeline;
540 pipeline.appendConstantColor(&alloc, color.data());
541 switch (lumMode) {
542 case LumMode::kNone:
543 break;
544 case LumMode::kToRGB:
545 pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_rgb);
546 break;
548 pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_alpha);
549 // If we ever need to store srgb-encoded gray (e.g. GL_SLUMINANCE8) then we should use
550 // ToRGB and then a swizzle stage rather than ToAlpha. The subsequent transfer function
551 // stage ignores the alpha channel (where we just stashed the gray).
552 SkASSERT(!dstIsSRGB);
553 break;
554 }
555 if (dstIsSRGB) {
557 }
558 storeSwizzle.apply(&pipeline);
559 SkRasterPipeline_MemoryCtx dstCtx{dst, SkToInt(dstRB/dstInfo.bpp())};
560 pipeline.append(store, &dstCtx);
561 pipeline.run(0, 0, dstInfo.width(), dstInfo.height());
562
563 return true;
564}
bool GrConvertPixels(const GrPixmap &dst, const GrCPixmap &src, bool flipY)
LumMode
size_t GrComputeTightCombinedBufferSize(size_t bytesPerPixel, SkISize baseDimensions, TArray< size_t > *individualMipOffsets, int mipLevelCount)
bool GrClearImage(const GrImageInfo &dstInfo, void *dst, size_t dstRB, std::array< float, 4 > color)
static skgpu::Swizzle get_dst_swizzle_and_store(GrColorType ct, SkRasterPipelineOp *store, LumMode *lumMode, bool *isNormalized, bool *isSRGB)
static skgpu::Swizzle get_load_and_src_swizzle(GrColorType ct, SkRasterPipelineOp *load, bool *isNormalized, bool *isSRGB)
GrColorType
Definition: GrTypesPriv.h:540
kUnpremul_SkAlphaType
static const uint32_t rgba[kNumPixels]
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#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
#define SkColorGetR(color)
Definition: SkColor.h:65
#define SkColorGetG(color)
Definition: SkColor.h:69
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
#define SkColorGetB(color)
Definition: SkColor.h:73
static U8CPU SkMulDiv255Round(U16CPU a, U16CPU b)
Definition: SkMath.h:73
static void SkRectMemcpy(void *dst, size_t dstRB, const void *src, size_t srcRB, size_t trimRowBytes, int rowCount)
Definition: SkRectMemcpy.h:16
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
constexpr int SkToInt(S x)
Definition: SkTo.h:29
#define TRACE_FUNC
Definition: SkTraceEvent.h:30
SI void store(P *ptr, const T &val)
SI T load(const P *ptr)
Definition: Transform_inl.h:98
static uint32_t premul(uint32_t color)
static uint16_t to565(SkColor col)
static int num_4x4_blocks(int size)
static void create_BC1_block(BC1Block *block, bool transparent)
int width() const
Definition: GrImageInfo.h:54
GrColorType colorType() const
Definition: GrImageInfo.h:44
size_t bpp() const
Definition: GrImageInfo.h:58
int height() const
Definition: GrImageInfo.h:56
bool isValid() const
Definition: GrImageInfo.h:62
size_t minRowBytes() const
Definition: GrImageInfo.h:60
size_t rowBytes() const
Definition: GrPixmap.h:21
T * addr() const
Definition: GrPixmap.h:20
static GrPixmap Allocate(const GrImageInfo &info)
Definition: GrPixmap.h:101
static bool Equals(const SkColorSpace *, const SkColorSpace *)
SkColor getColor(int x, int y) const
Definition: SkPixmap.cpp:187
int width() const
Definition: SkPixmap.h:160
SkColorType colorType() const
Definition: SkPixmap.h:173
int height() const
Definition: SkPixmap.h:166
void run(size_t x, size_t y, size_t w, size_t h) const
void appendTransferFunction(const skcms_TransferFunction &)
void append(SkRasterPipelineOp, void *=nullptr)
std::function< void(size_t, size_t, size_t, size_t)> compile() const
void appendConstantColor(SkArenaAlloc *, const float rgba[4])
T * init(Args &&... args)
Definition: SkTLazy.h:45
static constexpr Swizzle Concat(const Swizzle &a, const Swizzle &b)
Definition: Swizzle.h:156
void apply(SkRasterPipeline *) const
Definition: Swizzle.cpp:17
bool empty() const
Definition: SkTArray.h:199
int size() const
Definition: SkTArray.h:421
DlColor color
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
struct MyStruct s
static float max(float r, float g, float b)
Definition: hsl.cpp:49
double y
double x
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
dst
Definition: cp.py:12
SkScalar offsetX
SkScalar offsetY
int32_t height
const skcms_TransferFunction * skcms_sRGB_Inverse_TransferFunction()
Definition: skcms.cc:1591
const skcms_TransferFunction * skcms_sRGB_TransferFunction()
Definition: skcms.cc:1587
uint16_t fColor0
uint32_t fIndices
uint16_t fColor1
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
constexpr int64_t area() const
Definition: SkSize.h:39
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131