Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
SkColor4f color
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)
constexpr int SkToInt(S x)
Definition SkTo.h:29
#define TRACE_FUNC
SI void store(P *ptr, const T &val)
SI T load(const P *ptr)
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:194
int size() const
Definition SkTArray.h:416
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
struct MyStruct s
double y
double x
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
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)