Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Macros | Enumerations | Functions | Variables
asyncrescaleandread.cpp File Reference
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkSurface.h"
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
#include "include/effects/SkGradientShader.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "src/base/SkScopeExit.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/YUVUtils.h"

Go to the source code of this file.

Macros

#define DEF_RESCALE_AND_READ_GM(IMAGE_FILE, TAG, SRC_RECT, W, H, SOURCE, TYPE)
 

Enumerations

enum class  ReadSource { kImage , kSurface }
 
enum class  Type {
  kRand , kRandN , kFore , kBack ,
  kSame , kRGBA , kYUV , kYUVA
}
 

Functions

static void async_callback (void *c, std::unique_ptr< const SkImage::AsyncReadResult > result)
 
template<typename Src >
static sk_sp< SkImagedo_read_and_scale (Src *src, GrDirectContext *direct, skgpu::graphite::Recorder *recorder, const SkIRect &srcRect, const SkImageInfo &ii, SkImage::RescaleGamma rescaleGamma, SkImage::RescaleMode rescaleMode)
 
template<typename Src >
static sk_sp< SkImagedo_read_and_scale_yuv (Src *src, GrDirectContext *direct, skgpu::graphite::Recorder *recorder, SkYUVColorSpace yuvCS, bool readAlpha, const SkIRect &srcRect, SkISize size, SkImage::RescaleGamma rescaleGamma, SkImage::RescaleMode rescaleMode, SkScopeExit *cleanup)
 
template<typename Src >
static skiagm::DrawResult do_rescale_grid (SkCanvas *canvas, Src *src, GrDirectContext *direct, skgpu::graphite::Recorder *recorder, const SkIRect &srcRect, SkISize newSize, Type type, SkString *errorMsg, int pad=0)
 
static skiagm::DrawResult do_rescale_image_grid (SkCanvas *canvas, const char *imageFile, const SkIRect &srcRect, SkISize newSize, ReadSource source, Type type, SkString *errorMsg)
 
 DEF_RESCALE_AND_READ_GM (images/yellow_rose.webp, yuv420_rose, SkIRect::MakeXYWH(50, 5, 200, 150), 410, 376, ReadSource::kSurface, Type::kYUVA) DEF_RESCALE_AND_READ_GM(images/yellow_rose.webp
 
Type::kYUV DEF_RESCALE_AND_READ_GM (images/yellow_rose.webp, rose, SkIRect::MakeXYWH(100, 20, 100, 100), 410, 410, ReadSource::kSurface, Type::kRGBA) DEF_RESCALE_AND_READ_GM(images/dog.jpg
 
Type::kYUV Type::kRGBA DEF_RESCALE_AND_READ_GM (images/dog.jpg, dog_up, SkIRect::MakeWH(180, 180), 800, 400, ReadSource::kImage, Type::kRGBA) DEF_RESCALE_AND_READ_GM(images/text.png
 
Type::kYUV Type::kRGBA() int (0.7 *637)
 
Type::kYUV Type::kRGBA()() Type::kRGBA DEF_RESCALE_AND_READ_GM (images/text.png, text_up, SkIRect::MakeWH(637, 105),(int)(1.2 *637),(int)(1.2 *105), ReadSource::kSurface, Type::kRGBA) DEF_RESCALE_AND_READ_GM(images/text.png
 
Type::kYUV Type::kRGBA()() Type::kRGBA() int (2.4 *300)
 
Type::kYUV Type::kRGBA()() Type::kRGBA()() Type::kRGBA DEF_SIMPLE_GM_CAN_FAIL (async_yuv_no_scale, canvas, errorMsg, 400, 300)
 
 DEF_SIMPLE_GM_CAN_FAIL (async_rescale_and_read_no_bleed, canvas, errorMsg, 60, 60)
 
 DEF_SIMPLE_GM_CAN_FAIL (async_rescale_and_read_alpha_type, canvas, errorMsg, 512, 512)
 

Variables

 yuv420_rose_down
 
Type::kYUV dog_down
 
Type::kYUV Type::kRGBA text_down
 
Type::kYUV Type::kRGBA()() Type::kRGBA text_up_large
 

Macro Definition Documentation

◆ DEF_RESCALE_AND_READ_GM

#define DEF_RESCALE_AND_READ_GM (   IMAGE_FILE,
  TAG,
  SRC_RECT,
  W,
  H,
  SOURCE,
  TYPE 
)
Value:
DEF_SIMPLE_GM_CAN_FAIL(async_rescale_and_read_##TAG, canvas, errorMsg, 3 * W, 2 * H) { \
ToolUtils::draw_checkerboard(canvas, SK_ColorDKGRAY, SK_ColorLTGRAY, 25); \
canvas, #IMAGE_FILE, SRC_RECT, {W, H}, SOURCE, TYPE, errorMsg); \
}
constexpr SkColor SK_ColorLTGRAY
Definition: SkColor.h:118
constexpr SkColor SK_ColorDKGRAY
Definition: SkColor.h:108
#define TYPE(t)
#define W
Definition: aaa.cpp:17
static skiagm::DrawResult do_rescale_image_grid(SkCanvas *canvas, const char *imageFile, const SkIRect &srcRect, SkISize newSize, ReadSource source, Type type, SkString *errorMsg)
#define DEF_SIMPLE_GM_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H)
Definition: gm.h:58
#define TAG()
Definition: SkMD5.cpp:129

Definition at line 349 of file asyncrescaleandread.cpp.

Enumeration Type Documentation

◆ ReadSource

enum class ReadSource
strong
Enumerator
kImage 
kSurface 

Definition at line 205 of file asyncrescaleandread.cpp.

205 {
206 kImage,
207 kSurface,
208};

◆ Type

enum class Type
strong
Enumerator
kRand 
kRandN 
kFore 
kBack 
kSame 
kRGBA 
kYUV 
kYUVA 

Definition at line 210 of file asyncrescaleandread.cpp.

210 {
211 kRGBA,
212 kYUV,
213 kYUVA
214};

Function Documentation

◆ async_callback()

static void async_callback ( void *  c,
std::unique_ptr< const SkImage::AsyncReadResult result 
)
static

Definition at line 42 of file asyncrescaleandread.cpp.

42 {
43 auto context = static_cast<AsyncContext*>(c);
44 context->fResult = std::move(result);
45 context->fCalled = true;
46}
GAsyncResult * result

◆ DEF_RESCALE_AND_READ_GM() [1/4]

Type::kYUV Type::kRGBA DEF_RESCALE_AND_READ_GM ( images/dog.  jpg,
dog_up  ,
SkIRect::MakeWH(180, 180)  ,
800  ,
400  ,
ReadSource::kImage  ,
Type::kRGBA   
)

◆ DEF_RESCALE_AND_READ_GM() [2/4]

Type::kYUV Type::kRGBA()() Type::kRGBA DEF_RESCALE_AND_READ_GM ( images/text.  png,
text_up  ,
SkIRect::MakeWH(637, 105)  ,
(int)(1.2 *637)  ,
(int)(1.2 *105)  ,
ReadSource::kSurface  ,
Type::kRGBA   
)

◆ DEF_RESCALE_AND_READ_GM() [3/4]

Type::kYUV DEF_RESCALE_AND_READ_GM ( images/yellow_rose.  webp,
rose  ,
SkIRect::MakeXYWH(100, 20, 100, 100)  ,
410  ,
410  ,
ReadSource::kSurface  ,
Type::kRGBA   
)

◆ DEF_RESCALE_AND_READ_GM() [4/4]

DEF_RESCALE_AND_READ_GM ( images/yellow_rose.  webp,
yuv420_rose  ,
SkIRect::MakeXYWH(50, 5, 200, 150)  ,
410  ,
376  ,
ReadSource::kSurface  ,
Type::kYUVA   
)

◆ DEF_SIMPLE_GM_CAN_FAIL() [1/3]

DEF_SIMPLE_GM_CAN_FAIL ( async_rescale_and_read_alpha_type  ,
canvas  ,
errorMsg  ,
512  ,
512   
)

Definition at line 508 of file asyncrescaleandread.cpp.

508 {
509 auto dContext = GrAsDirectContext(canvas->recordingContext());
510 if (!dContext && canvas->recordingContext()) {
511 *errorMsg = "Not supported in DDL mode";
513 }
514 if (dContext && dContext->abandoned()) {
516 }
517
519
520 auto pmII = upmII.makeAlphaType(kPremul_SkAlphaType);
521
522 auto upmSurf = SkSurfaces::Raster(upmII);
523 auto pmSurf = SkSurfaces::Raster(pmII);
524
525 SkColor4f colors[] = {
526 {.3f, .3f, .3f, .3f},
527 {1.f, .2f, .6f, .9f},
528 {0.f, .1f, 1.f, .1f},
529 {.7f, .8f, .2f, .7f},
530 };
531 auto shader = SkGradientShader::MakeRadial({100, 100},
532 230,
533 colors,
534 nullptr,
535 nullptr,
536 std::size(colors),
539 paint.setShader(std::move(shader));
540
541 upmSurf->getCanvas()->drawPaint(paint);
542 pmSurf ->getCanvas()->drawPaint(paint);
543
544 auto pmImg = pmSurf->makeImageSnapshot();
545 auto upmImg = upmSurf->makeImageSnapshot();
546
547 if (dContext) {
548 pmImg = SkImages::TextureFromImage(dContext, pmImg);
549 upmImg = SkImages::TextureFromImage(dContext, upmImg);
550 if (!pmImg || !upmImg) {
551 *errorMsg = "could not make texture images";
553 }
554 }
555 int size = 256;
556
558
559 for (const auto& img : {pmImg, upmImg}) {
560 canvas->save();
561 for (auto readAT : {kPremul_SkAlphaType, kUnpremul_SkAlphaType}) {
562 auto readInfo = img->imageInfo().makeAlphaType(readAT).makeWH(size, size);
563
564 auto* asyncContext = new AsyncContext();
565 img->asyncRescaleAndReadPixels(readInfo,
566 SkIRect::MakeSize(img->dimensions()),
567 SkImage::RescaleGamma::kSrc,
568 SkImage::RescaleMode::kRepeatedCubic,
570 asyncContext);
571 if (dContext) {
572 dContext->submit();
573 }
574 while (!asyncContext->fCalled) {
575 // Only GPU should actually be asynchronous.
576 SkASSERT(dContext);
577 dContext->checkAsyncWorkCompletion();
578 }
579 if (asyncContext->fResult) {
580 SkPixmap pixmap(readInfo,
581 asyncContext->fResult->data(0),
582 asyncContext->fResult->rowBytes(0));
583 auto releasePixels = [](const void*, void* c) {
584 delete static_cast<AsyncContext*>(c);
585 };
586 auto result = SkImages::RasterFromPixmap(pixmap, releasePixels, asyncContext);
587
588 canvas->drawImage(result, 0, 0);
589 } else {
590 delete asyncContext;
591 *errorMsg = "async readback failed";
593 }
594 canvas->translate(size, 0);
595 }
596 canvas->restore();
597 canvas->translate(0, size);
598 }
600}
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
static SkPaint paint(SkColor color, float strokeWidth=-1.f, SkPaint::Join join=SkPaint::kMiter_Join)
kUnpremul_SkAlphaType
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:100
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static void async_callback(void *c, std::unique_ptr< const SkImage::AsyncReadResult > result)
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)
void setShader(sk_sp< SkShader > shader)
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:269
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)
Definition: ToolUtils.cpp:183
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
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)

◆ DEF_SIMPLE_GM_CAN_FAIL() [2/3]

DEF_SIMPLE_GM_CAN_FAIL ( async_rescale_and_read_no_bleed  ,
canvas  ,
errorMsg  ,
60  ,
60   
)

Definition at line 455 of file asyncrescaleandread.cpp.

455 {
456 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) {
457 *errorMsg = "Not supported on recording/vector backends.";
459 }
460
461 auto dContext = GrAsDirectContext(canvas->recordingContext());
462 if (!dContext && canvas->recordingContext()) {
463 *errorMsg = "Not supported in DDL mode";
465 }
466 auto recorder = canvas->recorder();
467
468 static constexpr int kBorder = 5;
469 static constexpr int kInner = 5;
470 const auto srcRect = SkIRect::MakeXYWH(kBorder, kBorder, kInner, kInner);
471 auto surfaceII =
472 SkImageInfo::Make(kInner + 2 * kBorder, kInner + 2 * kBorder, kRGBA_8888_SkColorType,
474 auto surface = canvas->makeSurface(surfaceII);
475 if (!surface) {
476 *errorMsg = "Could not create surface for image.";
477 // When testing abandoned GrContext we expect surface creation to fail.
478 if (canvas->recordingContext() && canvas->recordingContext()->abandoned()) {
480 }
482 }
483 surface->getCanvas()->clear(SK_ColorRED);
484 surface->getCanvas()->save();
485 surface->getCanvas()->clipRect(SkRect::Make(srcRect), SkClipOp::kIntersect, false);
486 surface->getCanvas()->clear(SK_ColorBLUE);
487 surface->getCanvas()->restore();
488 static constexpr int kPad = 2;
489 canvas->translate(kPad, kPad);
491 SkISize downSize = {static_cast<int>(kInner/2), static_cast<int>(kInner / 2)};
492 result = do_rescale_grid(canvas, surface.get(), dContext, recorder, srcRect, downSize,
493 Type::kRGBA, errorMsg, kPad);
494
496 return result;
497 }
498 canvas->translate(0, 4 * downSize.height());
499 SkISize upSize = {static_cast<int>(kInner * 3.5), static_cast<int>(kInner * 4.6)};
500 result = do_rescale_grid(canvas, surface.get(), dContext, recorder, srcRect, upSize,
501 Type::kRGBA, errorMsg, kPad);
503 return result;
504 }
506}
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
@ kRGBA
static skiagm::DrawResult do_rescale_grid(SkCanvas *canvas, Src *src, GrDirectContext *direct, skgpu::graphite::Recorder *recorder, const SkIRect &srcRect, SkISize newSize, Type type, SkString *errorMsg, int pad=0)
constexpr int kPad
static sk_sp< SkColorSpace > MakeSRGB()
VkSurfaceKHR surface
Definition: main.cc:48
@ kInner
fuzzy inside, nothing outside
DrawResult
Definition: gm.h:100
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
Definition: SkSize.h:15
constexpr int32_t height() const
Definition: SkSize.h:36
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669

◆ DEF_SIMPLE_GM_CAN_FAIL() [3/3]

Type::kYUV Type::kRGBA()() Type::kRGBA()() Type::kRGBA DEF_SIMPLE_GM_CAN_FAIL ( async_yuv_no_scale  ,
canvas  ,
errorMsg  ,
400  ,
300   
)

Definition at line 422 of file asyncrescaleandread.cpp.

422 {
423 auto surface = canvas->getSurface();
424 if (!surface) {
425 *errorMsg = "Not supported on recording/vector backends.";
427 }
428
429 auto dContext = GrAsDirectContext(surface->recordingContext());
430 if (!dContext && surface->recordingContext()) {
431 *errorMsg = "Not supported in DDL mode";
433 }
434
435 auto image = GetResourceAsImage("images/yellow_rose.webp");
436 if (!image) {
438 }
440 canvas->drawImage(image.get(), 0, 0);
441
442 skgpu::graphite::Recorder* recorder = canvas->recorder();
443 SkScopeExit scopeExit;
444 auto yuvImage = do_read_and_scale_yuv(surface, dContext, recorder, kRec601_SkYUVColorSpace,
445 /*readAlpha=*/false, SkIRect::MakeWH(400, 300),
446 {400, 300}, SkImage::RescaleGamma::kSrc,
447 SkImage::RescaleMode::kNearest, &scopeExit);
448
449 canvas->clear(SK_ColorWHITE);
450 canvas->drawImage(yuvImage.get(), 0, 0);
451
453}
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition: Resources.h:39
@ kRec601_SkYUVColorSpace
Definition: SkImageInfo.h:85
static sk_sp< SkImage > do_read_and_scale_yuv(Src *src, GrDirectContext *direct, skgpu::graphite::Recorder *recorder, SkYUVColorSpace yuvCS, bool readAlpha, const SkIRect &srcRect, SkISize size, SkImage::RescaleGamma rescaleGamma, SkImage::RescaleMode rescaleMode, SkScopeExit *cleanup)
T * get() const
Definition: SkRefCnt.h:303
sk_sp< SkImage > image
Definition: examples.cpp:13
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56

◆ do_read_and_scale()

template<typename Src >
static sk_sp< SkImage > do_read_and_scale ( Src *  src,
GrDirectContext direct,
skgpu::graphite::Recorder recorder,
const SkIRect srcRect,
const SkImageInfo ii,
SkImage::RescaleGamma  rescaleGamma,
SkImage::RescaleMode  rescaleMode 
)
static

Definition at line 51 of file asyncrescaleandread.cpp.

57 {
58 auto* asyncContext = new AsyncContext();
59 if (recorder) {
60#if defined(SK_GRAPHITE)
61 skgpu::graphite::Context* graphiteContext = recorder->priv().context();
62 if (!graphiteContext) {
63 return nullptr;
64 }
65 // We need to flush the existing drawing commands before we try to read
66 std::unique_ptr<skgpu::graphite::Recording> recording = recorder->snap();
67 if (!recording) {
68 return nullptr;
69 }
71 recordingInfo.fRecording = recording.get();
72 if (!graphiteContext->insertRecording(recordingInfo)) {
73 return nullptr;
74 }
75
76 graphiteContext->asyncRescaleAndReadPixels(src, ii, srcRect, rescaleGamma, rescaleMode,
77 async_callback, asyncContext);
78 graphiteContext->submit();
79 while (!asyncContext->fCalled) {
80 graphiteContext->checkAsyncWorkCompletion();
81 }
82#endif
83 } else {
84 src->asyncRescaleAndReadPixels(ii, srcRect, rescaleGamma, rescaleMode, async_callback,
85 asyncContext);
86 if (direct) {
87 direct->submit();
88 }
89 while (!asyncContext->fCalled) {
90 // Only GPU should actually be asynchronous.
91 SkASSERT(direct);
93 }
94 }
95 if (!asyncContext->fResult) {
96 return nullptr;
97 }
98 SkPixmap pixmap(ii, asyncContext->fResult->data(0), asyncContext->fResult->rowBytes(0));
99 auto releasePixels = [](const void*, void* c) { delete static_cast<AsyncContext*>(c); };
100 return SkImages::RasterFromPixmap(pixmap, releasePixels, asyncContext);
101}
void checkAsyncWorkCompletion()
bool submit(GrSyncCpu sync=GrSyncCpu::kNo)
bool submit(SyncToCpu=SyncToCpu::kNo)
Definition: Context.cpp:140
bool insertRecording(const InsertRecordingInfo &)
Definition: Context.cpp:134
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:148
std::unique_ptr< Recording > snap()
Definition: Recorder.cpp:137

◆ do_read_and_scale_yuv()

template<typename Src >
static sk_sp< SkImage > do_read_and_scale_yuv ( Src *  src,
GrDirectContext direct,
skgpu::graphite::Recorder recorder,
SkYUVColorSpace  yuvCS,
bool  readAlpha,
const SkIRect srcRect,
SkISize  size,
SkImage::RescaleGamma  rescaleGamma,
SkImage::RescaleMode  rescaleMode,
SkScopeExit cleanup 
)
static

Definition at line 104 of file asyncrescaleandread.cpp.

113 {
114 SkASSERT(!(size.width() & 0b1) && !(size.height() & 0b1));
115
116 SkISize uvSize = {size.width()/2, size.height()/2};
119
120 AsyncContext asyncContext;
121 if (recorder) {
122#if defined(SK_GRAPHITE)
123 skgpu::graphite::Context* graphiteContext = recorder->priv().context();
124 if (!graphiteContext) {
125 return nullptr;
126 }
127 // We need to flush the existing drawing commands before we try to read
128 std::unique_ptr<skgpu::graphite::Recording> recording = recorder->snap();
129 if (!recording) {
130 return nullptr;
131 }
133 recordingInfo.fRecording = recording.get();
134 if (!graphiteContext->insertRecording(recordingInfo)) {
135 return nullptr;
136 }
137
138 if (readAlpha) {
139 graphiteContext->asyncRescaleAndReadPixelsYUVA420(src, yuvCS, SkColorSpace::MakeSRGB(),
140 srcRect, size, rescaleGamma,
141 rescaleMode, async_callback,
142 &asyncContext);
143 } else {
144 graphiteContext->asyncRescaleAndReadPixelsYUV420(src, yuvCS, SkColorSpace::MakeSRGB(),
145 srcRect, size, rescaleGamma,
146 rescaleMode, async_callback,
147 &asyncContext);
148 }
149 graphiteContext->submit();
150 while (!asyncContext.fCalled) {
151 graphiteContext->checkAsyncWorkCompletion();
152 }
153#endif
154 } else {
155 if (readAlpha) {
156 src->asyncRescaleAndReadPixelsYUVA420(yuvCS, SkColorSpace::MakeSRGB(),
157 srcRect, size, rescaleGamma, rescaleMode,
158 async_callback, &asyncContext);
159 } else {
160 src->asyncRescaleAndReadPixelsYUV420(yuvCS, SkColorSpace::MakeSRGB(),
161 srcRect, size, rescaleGamma, rescaleMode,
162 async_callback, &asyncContext);
163 }
164 if (direct) {
165 direct->submit();
166 }
167 while (!asyncContext.fCalled) {
168 // Only GPU should actually be asynchronous.
169 SkASSERT(direct);
170 direct->checkAsyncWorkCompletion();
171 }
172 }
173 if (!asyncContext.fResult) {
174 return nullptr;
175 }
176 auto planeConfig = readAlpha ? SkYUVAInfo::PlaneConfig::kY_U_V_A
178 SkYUVAInfo yuvaInfo(size,
179 planeConfig,
181 yuvCS);
182 SkPixmap yuvPMs[4] = {
183 {yaII, asyncContext.fResult->data(0), asyncContext.fResult->rowBytes(0)},
184 {uvII, asyncContext.fResult->data(1), asyncContext.fResult->rowBytes(1)},
185 {uvII, asyncContext.fResult->data(2), asyncContext.fResult->rowBytes(2)},
186 {},
187 };
188 if (readAlpha) {
189 yuvPMs[3] = {yaII, asyncContext.fResult->data(3), asyncContext.fResult->rowBytes(3)};
190 }
191 auto pixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, yuvPMs);
192 SkASSERT(pixmaps.isValid());
193 auto lazyYUVImage = sk_gpu_test::LazyYUVImage::Make(pixmaps);
194 SkASSERT(lazyYUVImage);
195#if defined(SK_GRAPHITE)
196 if (recorder) {
197 return lazyYUVImage->refImage(recorder, sk_gpu_test::LazyYUVImage::Type::kFromTextures);
198 } else
199#endif
200 {
201 return lazyYUVImage->refImage(direct, sk_gpu_test::LazyYUVImage::Type::kFromTextures);
202 }
203}
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:34
@ 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:198
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:322
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:369

◆ do_rescale_grid()

template<typename Src >
static skiagm::DrawResult do_rescale_grid ( SkCanvas canvas,
Src *  src,
GrDirectContext direct,
skgpu::graphite::Recorder recorder,
const SkIRect srcRect,
SkISize  newSize,
Type  type,
SkString errorMsg,
int  pad = 0 
)
static

Definition at line 219 of file asyncrescaleandread.cpp.

227 {
228 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) {
229 *errorMsg = "Not supported on recording/vector backends.";
231 }
232 const auto ii = canvas->imageInfo().makeDimensions(newSize);
233
235 canvas->save();
236 for (auto gamma : {SkImage::RescaleGamma::kSrc, SkImage::RescaleGamma::kLinear}) {
237 canvas->save();
238 for (auto mode : {
239 SkImage::RescaleMode::kNearest,
240 SkImage::RescaleMode::kRepeatedLinear,
241 SkImage::RescaleMode::kRepeatedCubic}) {
242 SkScopeExit cleanup;
244 switch (type) {
245 case Type::kRGBA:
246 result = do_read_and_scale(src, direct, recorder, srcRect, ii, gamma, mode);
247 if (!result) {
248 errorMsg->printf("async read call failed.");
250 }
251 break;
252 case Type::kYUV:
253 case Type::kYUVA:
254 result = do_read_and_scale_yuv(src, direct, recorder, yuvColorSpace,
255 /*readAlpha=*/type == Type::kYUVA, srcRect,
256 newSize, gamma, mode, &cleanup);
257 if (!result) {
258 errorMsg->printf("YUV[A]420 async call failed. Allowed for now.");
260 }
261 int nextCS =
262 static_cast<int>(yuvColorSpace + 1) % (kLastEnum_SkYUVColorSpace + 1);
263 yuvColorSpace = static_cast<SkYUVColorSpace>(nextCS);
264 break;
265 }
266 canvas->drawImage(result, 0, 0);
267 canvas->translate(newSize.width() + pad, 0);
268 }
269 canvas->restore();
270 canvas->translate(0, newSize.height() + pad);
271 }
272 canvas->restore();
274}
SkYUVColorSpace
Definition: SkImageInfo.h:68
@ kLastEnum_SkYUVColorSpace
last valid value
Definition: SkImageInfo.h:81
@ kYUVA
@ kYUV
static sk_sp< SkImage > do_read_and_scale(Src *src, GrDirectContext *direct, skgpu::graphite::Recorder *recorder, const SkIRect &srcRect, const SkImageInfo &ii, SkImage::RescaleGamma rescaleGamma, SkImage::RescaleMode rescaleMode)
void restore()
Definition: SkCanvas.cpp:444
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1240
int save()
Definition: SkCanvas.cpp:430
SkImageInfo imageInfo() const
Definition: SkCanvas.cpp:1168
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1455
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:533
enum flutter::testing::@2643::KeyboardChange::Type type
constexpr int32_t width() const
Definition: SkSize.h:35
SkImageInfo makeDimensions(SkISize newSize) const
Definition: SkImageInfo.h:440
SkColorType colorType() const
Definition: SkImageInfo.h:359

◆ do_rescale_image_grid()

static skiagm::DrawResult do_rescale_image_grid ( SkCanvas canvas,
const char *  imageFile,
const SkIRect srcRect,
SkISize  newSize,
ReadSource  source,
Type  type,
SkString errorMsg 
)
static

Definition at line 276 of file asyncrescaleandread.cpp.

282 {
283 auto image = GetResourceAsImage(imageFile);
284 if (!image) {
285 errorMsg->printf("Could not load image file %s.", imageFile);
287 }
288 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) {
289 *errorMsg = "Not supported on recording/vector backends.";
291 }
292
293 auto dContext = GrAsDirectContext(canvas->recordingContext());
294 if (!dContext && canvas->recordingContext()) {
295 *errorMsg = "Not supported in DDL mode";
297 }
298 auto recorder = canvas->recorder();
299
300 switch (source) {
302#if defined(SK_GRAPHITE)
303 if (recorder) {
305 if (!image) {
306 *errorMsg = "Could not create image.";
308 }
309 } else
310#endif
311 if (dContext) {
313 if (!image) {
314 *errorMsg = "Could not create image.";
315 // When testing abandoned GrContext we expect surface creation to fail.
316 if (canvas->recordingContext() && canvas->recordingContext()->abandoned()) {
318 }
320 }
321 }
322 return do_rescale_grid(canvas, image.get(), dContext, recorder, srcRect, newSize, type,
323 errorMsg);
325 // Turn the image into a surface in order to call the read and rescale API
326 auto surfInfo = image->imageInfo().makeDimensions(image->dimensions());
327 auto surface = canvas->makeSurface(surfInfo);
328 if (!surface && surfInfo.colorType() == kBGRA_8888_SkColorType) {
329 surfInfo = surfInfo.makeColorType(kRGBA_8888_SkColorType);
330 surface = canvas->makeSurface(surfInfo);
331 }
332 if (!surface) {
333 *errorMsg = "Could not create surface for image.";
334 // When testing abandoned GrContext we expect surface creation to fail.
335 if (canvas->recordingContext() && canvas->recordingContext()->abandoned()) {
337 }
339 }
342 surface->getCanvas()->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
343 return do_rescale_grid(canvas, surface.get(), dContext, recorder, srcRect, newSize,
344 type, errorMsg);
345 }
347}
#define SkUNREACHABLE
Definition: SkAssert.h:119
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
bool abandoned() override
sk_sp< SkSurface > makeSurface(const SkImageInfo &info, const SkSurfaceProps *props=nullptr)
Definition: SkCanvas.cpp:1157
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1599
virtual skgpu::graphite::Recorder * recorder() const
Definition: SkCanvas.cpp:1603
const SkImageInfo & imageInfo() const
Definition: SkImage.h:277
SkISize dimensions() const
Definition: SkImage.h:295
void setBlendMode(SkBlendMode mode)
Definition: SkPaint.cpp:151
SkBitmap source
Definition: examples.cpp:12

◆ int() [1/2]

Type::kYUV Type::kRGBA() int ( 0.7 *  637)

◆ int() [2/2]

Type::kYUV Type::kRGBA()() Type::kRGBA() int ( 2.4 *  300)

Variable Documentation

◆ dog_down

Type::kYUV dog_down

Definition at line 381 of file asyncrescaleandread.cpp.

◆ text_down

Definition at line 397 of file asyncrescaleandread.cpp.

◆ text_up_large

Type::kYUV Type::kRGBA()() Type::kRGBA text_up_large

Definition at line 413 of file asyncrescaleandread.cpp.

◆ yuv420_rose_down

yuv420_rose_down

Definition at line 365 of file asyncrescaleandread.cpp.