Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
asyncrescaleandread.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
8#include "gm/gm.h"
12#include "include/core/SkRect.h"
22#include "tools/DecodeUtils.h"
23#include "tools/Resources.h"
24#include "tools/ToolUtils.h"
25#include "tools/gpu/YUVUtils.h"
26
27#if defined(SK_GRAPHITE)
32#endif
33
34#include <variant>
35
36namespace {
37/// We test reading from images and surfaces
38enum class ReadSource {
39 kImage,
41};
42
43// We test reading to RGBA, YUV, and YUVA
44enum class Type {
45 kRGBA,
46 kYUV,
47 kYUVA
48};
49
50template <ReadSource> struct SourceS;
51template <> struct SourceS<ReadSource::kImage> { using Type = SkImage; };
52template <> struct SourceS<ReadSource::kSurface> { using Type = SkSurface; };
53
54template <ReadSource RS> using Source = typename SourceS<RS>::Type;
55
56// Converts a source image to either an SkImage or SkSurface, backed by GPU if canvas is. Returns
57// kSkip or kFail if the image cannot be converted.
58template <ReadSource RS>
59std::variant<sk_sp<Source<RS>>, skiagm::DrawResult> convert_image_to_source(SkCanvas* canvas,
61 SkString* errorMsg);
62
63template <>
64std::variant<sk_sp<SkImage>, skiagm::DrawResult> convert_image_to_source<ReadSource::kImage>(
65 SkCanvas* canvas,
67 SkString* errorMsg) {
68#if defined(SK_GRAPHITE)
69 if (auto recorder = canvas->recorder()) {
71 if (image) {
72 return image;
73 }
74 *errorMsg = "Could not create Graphite image";
76 }
77#endif
78 auto dContext = GrAsDirectContext(canvas->recordingContext());
79 if (!dContext && canvas->recordingContext()) {
80 *errorMsg = "Not supported in DDL mode";
82 }
83 if (dContext) {
85 if (image) {
86 return image;
87 }
88 // When testing abandoned GrContext we expect surface creation to fail.
89 if (dContext && dContext->abandoned()) {
91 }
92 *errorMsg = "Could not create Ganesh image";
94 }
95 return image;
96}
97
98template <>
99std::variant<sk_sp<SkSurface>, skiagm::DrawResult> convert_image_to_source<ReadSource::kSurface>(
100 SkCanvas* canvas,
102 SkString* errorMsg) {
103 // Turn the image into a surface in order to call the read and rescale API
104 auto surfInfo = image->imageInfo().makeDimensions(image->dimensions());
105 auto surface = canvas->makeSurface(surfInfo);
106 if (!surface && surfInfo.colorType() == kBGRA_8888_SkColorType) {
107 surfInfo = surfInfo.makeColorType(kRGBA_8888_SkColorType);
108 surface = canvas->makeSurface(surfInfo);
109 }
110 if (!surface) {
111 *errorMsg = "Could not create surface for image.";
112 // When testing abandoned GrContext we expect surface creation to fail.
113 if (canvas->recordingContext() && canvas->recordingContext()->abandoned()) {
115 }
117 }
119 paint.setBlendMode(SkBlendMode::kSrc);
120 surface->getCanvas()->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
121 return surface;
122}
123
124class AsyncReadGMBase : public skiagm::GM {
125public:
126 AsyncReadGMBase(const char* name) : fName(name) {}
127
128 SkString getName() const override { return fName; }
129
130protected:
131 // Does a rescale and read using Graphite, Ganesh, or CPU and returns the result as a pixmap
132 // image.
133 template <ReadSource ReadSource>
134 sk_sp<SkImage> readAndScaleRGBA(Source<ReadSource>* src,
135 SkIRect srcRect,
136 GrDirectContext* direct,
138 const SkImageInfo& ii,
139 SkImage::RescaleGamma rescaleGamma,
140 SkImage::RescaleMode rescaleMode) {
141 auto* asyncContext = new AsyncContext();
142 if (recorder) {
143#if defined(SK_GRAPHITE)
144 skgpu::graphite::Context* graphiteContext = recorder->priv().context();
145 if (!graphiteContext) {
146 return nullptr;
147 }
148 // We need to flush the existing drawing commands before we try to read
149 std::unique_ptr<skgpu::graphite::Recording> recording = recorder->snap();
150 if (!recording) {
151 return nullptr;
152 }
154 recordingInfo.fRecording = recording.get();
155 if (!graphiteContext->insertRecording(recordingInfo)) {
156 return nullptr;
157 }
158
159 graphiteContext->asyncRescaleAndReadPixels(src,
160 ii,
161 srcRect,
162 rescaleGamma,
163 rescaleMode,
164 AsyncCallback,
165 asyncContext);
166 graphiteContext->submit();
167 while (!asyncContext->fCalled) {
168 graphiteContext->checkAsyncWorkCompletion();
169 if (this->graphiteTestContext()) {
170 this->graphiteTestContext()->tick();
171 }
172 }
173#endif
174 } else {
175 src->asyncRescaleAndReadPixels(ii,
176 srcRect,
177 rescaleGamma,
178 rescaleMode,
179 AsyncCallback,
180 asyncContext);
181 if (direct) {
182 direct->submit();
183 }
184 while (!asyncContext->fCalled) {
185 // Only GPU should actually be asynchronous.
186 SkASSERT(direct);
187 direct->checkAsyncWorkCompletion();
188 }
189 }
190 if (!asyncContext->fResult) {
191 return nullptr;
192 }
193 SkPixmap pixmap(ii, asyncContext->fResult->data(0), asyncContext->fResult->rowBytes(0));
194 auto releasePixels = [](const void*, void* c) { delete static_cast<AsyncContext*>(c); };
195 return SkImages::RasterFromPixmap(pixmap, releasePixels, asyncContext);
196 }
197
198 // Does a YUV[A] rescale and read using Graphite or Ganesh (no CPU support) and returns the
199 // result as a YUVA planar texture image.
200 template <ReadSource ReadSource>
201 sk_sp<SkImage> readAndScaleYUVA(Source<ReadSource>* src,
202 SkIRect srcRect,
203 SkISize resultSize,
204 bool readAlpha,
205 GrDirectContext* direct,
207 SkYUVColorSpace yuvCS,
208 SkImage::RescaleGamma rescaleGamma,
209 SkImage::RescaleMode rescaleMode,
210 SkScopeExit* cleanup) {
211 SkASSERT(!(resultSize.width() & 0b1) && !(resultSize.height() & 0b1));
212
213 SkISize uvSize = {resultSize.width() / 2, resultSize.height() / 2};
216
217 AsyncContext asyncContext;
218 if (recorder) {
219#if defined(SK_GRAPHITE)
220 skgpu::graphite::Context* graphiteContext = recorder->priv().context();
221 if (!graphiteContext) {
222 return nullptr;
223 }
224 // We need to flush the existing drawing commands before we try to read
225 std::unique_ptr<skgpu::graphite::Recording> recording = recorder->snap();
226 if (!recording) {
227 return nullptr;
228 }
230 recordingInfo.fRecording = recording.get();
231 if (!graphiteContext->insertRecording(recordingInfo)) {
232 return nullptr;
233 }
234
235 if (readAlpha) {
236 graphiteContext->asyncRescaleAndReadPixelsYUVA420(src,
237 yuvCS,
239 srcRect,
240 resultSize,
241 rescaleGamma,
242 rescaleMode,
243 AsyncCallback,
244 &asyncContext);
245 } else {
246 graphiteContext->asyncRescaleAndReadPixelsYUV420(src,
247 yuvCS,
249 srcRect,
250 resultSize,
251 rescaleGamma,
252 rescaleMode,
253 AsyncCallback,
254 &asyncContext);
255 }
256 graphiteContext->submit();
257 while (!asyncContext.fCalled) {
258 graphiteContext->checkAsyncWorkCompletion();
259 if (this->graphiteTestContext()) {
260 this->graphiteTestContext()->tick();
261 }
262 }
263#endif
264 } else {
265 if (readAlpha) {
266 src->asyncRescaleAndReadPixelsYUVA420(yuvCS,
268 srcRect,
269 resultSize,
270 rescaleGamma,
271 rescaleMode,
272 AsyncCallback,
273 &asyncContext);
274 } else {
275 src->asyncRescaleAndReadPixelsYUV420(yuvCS,
277 srcRect,
278 resultSize,
279 rescaleGamma,
280 rescaleMode,
281 AsyncCallback,
282 &asyncContext);
283 }
284 if (direct) {
285 direct->submit();
286 }
287 while (!asyncContext.fCalled) {
288 // Only GPU should actually be asynchronous.
289 SkASSERT(direct);
290 direct->checkAsyncWorkCompletion();
291 }
292 }
293 if (!asyncContext.fResult) {
294 return nullptr;
295 }
296 auto planeConfig = readAlpha ? SkYUVAInfo::PlaneConfig::kY_U_V_A :
298 SkYUVAInfo yuvaInfo(resultSize,
299 planeConfig,
301 yuvCS);
302 SkPixmap yuvPMs[4] = {
303 {yaII, asyncContext.fResult->data(0), asyncContext.fResult->rowBytes(0)},
304 {uvII, asyncContext.fResult->data(1), asyncContext.fResult->rowBytes(1)},
305 {uvII, asyncContext.fResult->data(2), asyncContext.fResult->rowBytes(2)},
306 {},
307 };
308 if (readAlpha) {
309 yuvPMs[3] = {yaII, asyncContext.fResult->data(3), asyncContext.fResult->rowBytes(3)};
310 }
311 auto pixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, yuvPMs);
312 SkASSERT(pixmaps.isValid());
313 auto lazyYUVImage = sk_gpu_test::LazyYUVImage::Make(pixmaps);
314 SkASSERT(lazyYUVImage);
315#if defined(SK_GRAPHITE)
316 if (recorder) {
317 return lazyYUVImage->refImage(recorder, sk_gpu_test::LazyYUVImage::Type::kFromTextures);
318 } else
319#endif
320 {
321 return lazyYUVImage->refImage(direct, sk_gpu_test::LazyYUVImage::Type::kFromTextures);
322 }
323 }
324
325 // Draws a 3x2 grid of rescales. The columns are none, low, and high filter quality. The rows
326 // are rescale in src gamma and rescale in linear gamma.
327 template <ReadSource ReadSource>
328 skiagm::DrawResult drawRescaleGrid(SkCanvas* canvas,
329 Source<ReadSource>* src,
330 SkIRect srcRect,
331 SkISize readSize,
332 Type type,
333 SkString* errorMsg,
334 int pad = 0) {
336
337 auto direct = GrAsDirectContext(canvas->recordingContext());
338 auto recorder = canvas->recorder();
339 SkASSERT(direct || !canvas->recordingContext());
340
342 canvas->save();
343 for (auto gamma : {SkImage::RescaleGamma::kSrc, SkImage::RescaleGamma::kLinear}) {
344 canvas->save();
345 for (auto mode : {SkImage::RescaleMode::kNearest,
346 SkImage::RescaleMode::kRepeatedLinear,
347 SkImage::RescaleMode::kRepeatedCubic}) {
348 SkScopeExit cleanup;
350 switch (type) {
351 case Type::kRGBA: {
352 const auto ii = canvas->imageInfo().makeDimensions(readSize);
353 result = readAndScaleRGBA<ReadSource>(src,
354 srcRect,
355 direct,
356 recorder,
357 ii,
358 gamma,
359 mode);
360 if (!result) {
361 errorMsg->printf("async read call failed.");
363 }
364 break;
365 }
366 case Type::kYUV:
367 case Type::kYUVA:
368 result = readAndScaleYUVA<ReadSource>(src,
369 srcRect,
370 readSize,
371 /*readAlpha=*/type == Type::kYUVA,
372 direct,
373 recorder,
374 yuvColorSpace,
375 gamma,
376 mode,
377 &cleanup);
378 if (!result) {
379 errorMsg->printf("YUV[A]420 async call failed. Allowed for now.");
381 }
382 int nextCS = static_cast<int>(yuvColorSpace + 1) %
384 yuvColorSpace = static_cast<SkYUVColorSpace>(nextCS);
385 break;
386 }
387 canvas->drawImage(result, 0, 0);
388 canvas->translate(readSize.width() + pad, 0);
389 }
390 canvas->restore();
391 canvas->translate(0, readSize.height() + pad);
392 }
393 canvas->restore();
395 }
396
397private:
398 struct AsyncContext {
399 bool fCalled = false;
400 std::unique_ptr<const SkImage::AsyncReadResult> fResult;
401 };
402
403 // Making this a lambda in the test functions caused:
404 // "error: cannot compile this forwarded non-trivially copyable parameter yet"
405 // on x86/Win/Clang bot, referring to 'result'.
406 static void AsyncCallback(void* c, std::unique_ptr<const SkImage::AsyncReadResult> result) {
407 auto context = static_cast<AsyncContext*>(c);
408 context->fResult = std::move(result);
409 context->fCalled = true;
410 }
411
413};
414
415template <ReadSource ReadSource, Type Type>
416class AsyncRescaleAndReadGridGM : public AsyncReadGMBase {
417public:
418 AsyncRescaleAndReadGridGM(const char* name,
419 const char* imageFile,
420 SkIRect srcRect,
421 SkISize readSize)
422 : AsyncReadGMBase(name)
423 , fImageFile(imageFile)
424 , fSrcRect(srcRect)
425 , fReadSize(readSize) {}
426
427 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
429 auto image = ToolUtils::GetResourceAsImage(fImageFile.c_str());
430 if (!image) {
431 errorMsg->printf("Could not load image file %s.", fImageFile.c_str());
433 }
434 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) {
435 *errorMsg = "Not supported on recording/vector backends.";
437 }
438
439 auto sourceOrResult = convert_image_to_source<ReadSource>(canvas, image, errorMsg);
440 if (auto dr = std::get_if<skiagm::DrawResult>(&sourceOrResult)) {
441 return *dr;
442 }
443
444 using Src = sk_sp<Source<ReadSource>>;
445 return drawRescaleGrid<ReadSource>(canvas,
446 std::get<Src>(sourceOrResult).get(),
447 fSrcRect,
448 fReadSize,
449 Type,
450 errorMsg);
451 }
452
453 SkISize getISize() override { return {3 * fReadSize.width(), 2 * fReadSize.height()}; }
454
455private:
456 SkString fImageFile;
457 SkIRect fSrcRect;
458 SkISize fReadSize;
459};
460} // anonymous namespace
461
462#define DEF_RESCALE_AND_READ_GRID_GM(IMAGE_FILE, TAG, SRC_RECT, W, H, SOURCE, TYPE) \
463 DEF_GM(return new (AsyncRescaleAndReadGridGM<SOURCE, TYPE>)( \
464 "async_rescale_and_read_" #TAG, #IMAGE_FILE, SRC_RECT, SkISize{W, H});)
465
466DEF_RESCALE_AND_READ_GRID_GM(images/yellow_rose.webp,
467 yuv420_rose,
468 SkIRect::MakeXYWH(50, 5, 200, 150),
469 410,
470 376,
471 ReadSource::kSurface,
472 Type::kYUVA)
473
474DEF_RESCALE_AND_READ_GRID_GM(images/yellow_rose.webp,
476 SkIRect::MakeXYWH(50, 5, 200, 150),
477 106,
478 60,
479 ReadSource::kImage,
480 Type::kYUV)
481
482DEF_RESCALE_AND_READ_GRID_GM(images/yellow_rose.webp,
483 rose,
484 SkIRect::MakeXYWH(100, 20, 100, 100),
485 410,
486 410,
487 ReadSource::kSurface,
488 Type::kRGBA)
489
490DEF_RESCALE_AND_READ_GRID_GM(images/dog.jpg,
492 SkIRect::MakeXYWH(0, 10, 180, 150),
493 45,
494 45,
495 ReadSource::kSurface,
496 Type::kRGBA)
497
499 dog_up,
500 SkIRect::MakeWH(180, 180),
501 800,
502 400,
503 ReadSource::kImage,
504 Type::kRGBA)
505
508 SkIRect::MakeWH(637, 105),
509 (int)(0.7 * 637),
510 (int)(0.7 * 105),
511 ReadSource::kImage,
512 Type::kRGBA)
513
515 text_up,
516 SkIRect::MakeWH(637, 105),
517 (int)(1.2 * 637),
518 (int)(1.2 * 105),
519 ReadSource::kSurface,
520 Type::kRGBA)
521
524 SkIRect::MakeXYWH(300, 0, 300, 105),
525 (int)(2.4 * 300),
526 (int)(2.4 * 105),
527 ReadSource::kImage,
528 Type::kRGBA)
529
530namespace {
531class AyncYUVNoScaleGM : public AsyncReadGMBase {
532public:
533 AyncYUVNoScaleGM() : AsyncReadGMBase("async_yuv_no_scale") {}
534 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
535 auto surface = canvas->getSurface();
536 if (!surface) {
537 *errorMsg = "Not supported on recording/vector backends.";
539 }
540
541 auto dContext = GrAsDirectContext(surface->recordingContext());
542 if (!dContext && surface->recordingContext()) {
543 *errorMsg = "Not supported in DDL mode";
545 }
546
547 auto image = ToolUtils::GetResourceAsImage("images/yellow_rose.webp");
548 if (!image) {
550 }
552 canvas->drawImage(image.get(), 0, 0);
553
554 skgpu::graphite::Recorder* recorder = canvas->recorder();
555 SkScopeExit scopeExit;
556 auto yuvImage = readAndScaleYUVA<ReadSource::kSurface>(surface,
557 SkIRect::MakeWH(400, 300),
558 SkISize{400, 300},
559 /*readAlpha=*/false,
560 dContext,
561 recorder,
563 SkImage::RescaleGamma::kSrc,
564 SkImage::RescaleMode::kNearest,
565 &scopeExit);
566
567 canvas->clear(SK_ColorWHITE);
568 canvas->drawImage(yuvImage.get(), 0, 0);
569
571 }
572 SkISize getISize() override { return {400, 300}; }
573};
574} // namespace
575
576DEF_GM(return new AyncYUVNoScaleGM();)
577
578namespace {
579class AsyncRescaleAndReadNoBleedGM : public AsyncReadGMBase {
580public:
581 AsyncRescaleAndReadNoBleedGM() : AsyncReadGMBase("async_rescale_and_read_no_bleed") {}
582
583 SkISize getISize() override { return {60, 60}; }
584
585 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
586 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) {
587 *errorMsg = "Not supported on recording/vector backends.";
589 }
590
591 auto dContext = GrAsDirectContext(canvas->recordingContext());
592 if (!dContext && canvas->recordingContext()) {
593 *errorMsg = "Not supported in DDL mode";
595 }
596
597 static constexpr int kBorder = 5;
598 static constexpr int kInner = 5;
599 const auto srcRect = SkIRect::MakeXYWH(kBorder, kBorder, kInner, kInner);
600 auto surfaceII = SkImageInfo::Make(kInner + 2 * kBorder,
601 kInner + 2 * kBorder,
605 auto surface = canvas->makeSurface(surfaceII);
606 if (!surface) {
607 *errorMsg = "Could not create surface for image.";
608 // When testing abandoned GrContext we expect surface creation to fail.
609 if (canvas->recordingContext() && canvas->recordingContext()->abandoned()) {
611 }
613 }
614 surface->getCanvas()->clear(SK_ColorRED);
615 surface->getCanvas()->save();
616 surface->getCanvas()->clipRect(SkRect::Make(srcRect), SkClipOp::kIntersect, false);
617 surface->getCanvas()->clear(SK_ColorBLUE);
618 surface->getCanvas()->restore();
619 static constexpr int kPad = 2;
620 canvas->translate(kPad, kPad);
622 SkISize downSize = {static_cast<int>(kInner / 2), static_cast<int>(kInner / 2)};
623 result = drawRescaleGrid<ReadSource::kSurface>(canvas,
624 surface.get(),
625 srcRect,
626 downSize,
628 errorMsg,
629 kPad);
631 return result;
632 }
633 canvas->translate(0, 4 * downSize.height());
634 SkISize upSize = {static_cast<int>(kInner * 3.5), static_cast<int>(kInner * 4.6)};
635 result = drawRescaleGrid<ReadSource::kSurface>(canvas,
636 surface.get(),
637 srcRect,
638 upSize,
640 errorMsg,
641 kPad);
643 return result;
644 }
646 }
647};
648} // namespace
649
650DEF_GM(return new AsyncRescaleAndReadNoBleedGM();)
651
652namespace {
653class AsyncRescaleAndReadAlphaTypeGM : public AsyncReadGMBase {
654public:
655 AsyncRescaleAndReadAlphaTypeGM() : AsyncReadGMBase("async_rescale_and_read_alpha_type") {}
656
657 SkISize getISize() override { return {512, 512}; }
658
659 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
660 auto dContext = GrAsDirectContext(canvas->recordingContext());
661 if (!dContext && canvas->recordingContext()) {
662 *errorMsg = "Not supported in DDL mode";
664 }
665
666 if (canvas->recorder()) {
667 *errorMsg = "Reading to unpremul not supported in Graphite.";
669 }
670
672
673 auto pmII = upmII.makeAlphaType(kPremul_SkAlphaType);
674
675 auto upmSurf = SkSurfaces::Raster(upmII);
676 auto pmSurf = SkSurfaces::Raster(pmII);
677
678 SkColor4f colors[] = {
679 {.3f, .3f, .3f, .3f},
680 {1.f, .2f, .6f, .9f},
681 {0.f, .1f, 1.f, .1f},
682 {.7f, .8f, .2f, .7f},
683 };
684 auto shader = SkGradientShader::MakeRadial({100, 100},
685 230,
686 colors,
687 nullptr,
688 nullptr,
689 std::size(colors),
692 paint.setShader(std::move(shader));
693
694 upmSurf->getCanvas()->drawPaint(paint);
695 pmSurf ->getCanvas()->drawPaint(paint);
696
697 auto pmImg = pmSurf->makeImageSnapshot();
698 auto upmImg = upmSurf->makeImageSnapshot();
699
700 auto imageOrResult = convert_image_to_source<ReadSource::kImage>(canvas,
701 std::move(pmImg),
702 errorMsg);
703 if (const auto* dr = std::get_if<skiagm::DrawResult>(&imageOrResult)) {
704 return *dr;
705 }
706 pmImg = std::move(std::get<sk_sp<SkImage>>(imageOrResult));
707
708 imageOrResult = convert_image_to_source<ReadSource::kImage>(canvas,
709 std::move(upmImg),
710 errorMsg);
711 if (const auto* dr = std::get_if<skiagm::DrawResult>(&imageOrResult)) {
712 return *dr;
713 }
714 upmImg = std::move(std::get<sk_sp<SkImage>>(imageOrResult));
715
716 int size = 256;
717
719
720 for (const auto& img : {pmImg, upmImg}) {
721 canvas->save();
722 for (auto readAT : {kPremul_SkAlphaType, kUnpremul_SkAlphaType}) {
723 auto readInfo = img->imageInfo().makeAlphaType(readAT).makeWH(size, size);
724 auto result =
725 readAndScaleRGBA<ReadSource::kImage>(img.get(),
726 SkIRect::MakeSize(img->dimensions()),
727 dContext,
728 canvas->recorder(),
729 readInfo,
730 SkImage::RescaleGamma::kSrc,
731 SkImage::RescaleMode::kRepeatedCubic);
732 if (!result) {
733 *errorMsg = "async readback failed";
735 }
736 canvas->drawImage(result, 0, 0);
737 canvas->translate(size, 0);
738 }
739 canvas->restore();
740 canvas->translate(0, size);
741 }
743 }
744};
745} // namespace
746
747DEF_GM(return new AsyncRescaleAndReadAlphaTypeGM();)
const char * fName
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
kUnpremul_SkAlphaType
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition SkColorType.h:26
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition SkColorType.h:35
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
constexpr SkColor SK_ColorLTGRAY
Definition SkColor.h:118
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
constexpr SkColor SK_ColorDKGRAY
Definition SkColor.h:108
SkYUVColorSpace
Definition SkImageInfo.h:68
@ kLastEnum_SkYUVColorSpace
last valid value
Definition SkImageInfo.h:95
@ kRec601_SkYUVColorSpace
Definition SkImageInfo.h:99
Type::kYUV dog_down
#define DEF_RESCALE_AND_READ_GRID_GM(IMAGE_FILE, TAG, SRC_RECT, W, H, SOURCE, TYPE)
Type::kYUV Type::kRGBA text_down
Type::kYUV Type::kRGBA()() Type::kRGBA text_up_large
constexpr int kPad
bool submit(GrSyncCpu sync=GrSyncCpu::kNo)
bool abandoned() override
SkSurface * getSurface() const
Definition SkCanvas.cpp:369
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
sk_sp< SkSurface > makeSurface(const SkImageInfo &info, const SkSurfaceProps *props=nullptr)
virtual GrRecordingContext * recordingContext() const
virtual skgpu::graphite::Recorder * recorder() const
void clear(SkColor color)
Definition SkCanvas.h:1199
int save()
Definition SkCanvas.cpp:451
SkImageInfo imageInfo() const
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkShader > MakeRadial(const SkPoint &center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
const SkImageInfo & imageInfo() const
Definition SkImage.h:279
SkISize dimensions() const
Definition SkImage.h:297
RescaleMode
Definition SkImage.h:587
RescaleGamma
Definition SkImage.h:585
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:534
@ kY_U_V_A
Plane 0: Y, Plane 1: U, Plane 2: V, Plane 3: A.
@ kY_U_V
Plane 0: Y, Plane 1: U, Plane 2: V.
@ k420
1 set of UV values for each 2x2 block of Y values.
static SkYUVAPixmaps FromExternalPixmaps(const SkYUVAInfo &, const SkPixmap[kMaxPlanes])
static std::unique_ptr< LazyYUVImage > Make(sk_sp< SkData > data, skgpu::Mipmapped=skgpu::Mipmapped::kNo, sk_sp< SkColorSpace >=nullptr)
Definition YUVUtils.cpp:200
T * get() const
Definition SkRefCnt.h:303
void asyncRescaleAndReadPixelsYUV420(const SkImage *, SkYUVColorSpace yuvColorSpace, sk_sp< SkColorSpace > dstColorSpace, const SkIRect &srcRect, const SkISize &dstSize, SkImage::RescaleGamma rescaleGamma, SkImage::RescaleMode rescaleMode, SkImage::ReadPixelsCallback callback, SkImage::ReadPixelsContext context)
Definition Context.cpp:340
void asyncRescaleAndReadPixelsYUVA420(const SkImage *, SkYUVColorSpace yuvColorSpace, sk_sp< SkColorSpace > dstColorSpace, const SkIRect &srcRect, const SkISize &dstSize, SkImage::RescaleGamma rescaleGamma, SkImage::RescaleMode rescaleMode, SkImage::ReadPixelsCallback callback, SkImage::ReadPixelsContext context)
Definition Context.cpp:387
bool submit(SyncToCpu=SyncToCpu::kNo)
Definition Context.cpp:148
bool insertRecording(const InsertRecordingInfo &)
Definition Context.cpp:142
void asyncRescaleAndReadPixels(const SkImage *image, const SkImageInfo &dstImageInfo, const SkIRect &srcRect, SkImage::RescaleGamma rescaleGamma, SkImage::RescaleMode rescaleMode, SkImage::ReadPixelsCallback callback, SkImage::ReadPixelsContext context)
Definition Context.cpp:163
std::unique_ptr< Recording > snap()
Definition Recorder.cpp:149
GraphiteTestContext * graphiteTestContext() const
Definition gm.h:228
virtual SkString getName() const =0
const Paint & paint
@ kRGBA
Definition embedder.h:605
@ kYUVA
Definition embedder.h:604
VkSurfaceKHR surface
Definition main.cc:49
sk_sp< SkImage > image
Definition examples.cpp:29
GAsyncResult * result
const char * name
Definition fuchsia.cc:50
#define DEF_GM(CODE)
Definition gm.h:40
std::u16string text
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
SK_API sk_sp< SkImage > TextureFromImage(GrDirectContext *, const SkImage *, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Budgeted=skgpu::Budgeted::kYes)
PODArray< SkColor > colors
Definition SkRecords.h:276
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
void draw_checkerboard(SkCanvas *canvas, SkColor c1, SkColor c2, int size)
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition DecodeUtils.h:25
@ kInner
fuzzy inside, nothing outside
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 myers::Point & get(const myers::Segment &)
const char * fName
DrawResult
Definition gm.h:104
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition SkRect.h:56
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition SkRect.h:104
constexpr int32_t width() const
Definition SkSize.h:36
constexpr int32_t height() const
Definition SkSize.h:37
SkImageInfo makeDimensions(SkISize newSize) const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkColorType colorType() const
static SkRect Make(const SkISize &size)
Definition SkRect.h:669