Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 63a0a75

Browse files
bsalomonSkia Commit-Bot
authored andcommitted
Reland "Add async rescale and read APIs to SkImage."
This reverts commit 1caf378. Makes the image GMs detect an abandoned context just like the surface GMs. Bug: skia:10431 Change-Id: I56a3631a75e6b0383f96a73f461cfa314ee29afa Reviewed-on: https://skia-review.googlesource.com/c/skia/+/299379 Reviewed-by: Brian Salomon <[email protected]> Commit-Queue: Brian Salomon <[email protected]>
1 parent 56079c4 commit 63a0a75

22 files changed

+1381
-820
lines changed

BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,8 @@ if (skia_enable_tools) {
14101410
deps = []
14111411
public_deps = []
14121412
sources = [
1413+
"tools/gpu/BackendTextureImageFactory.cpp",
1414+
"tools/gpu/BackendTextureImageFactory.h",
14131415
"tools/gpu/GrContextFactory.cpp",
14141416
"tools/gpu/GrTest.cpp",
14151417
"tools/gpu/MemoryCache.cpp",

RELEASE_NOTES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Milestone 86
1616
* Enable BackendSemaphores for the Direct3D backend.
1717
https://review.skia.org/298752
1818

19+
* Added SkImage:asyncRescaleAndReadPixels and SkImage::asyncRescaleAndReadPixelsYUV420
20+
https://review.skia.org/299281
21+
1922
* * *
2023

2124
Milestone 85

gm/asyncrescaleandread.cpp

Lines changed: 149 additions & 91 deletions
Large diffs are not rendered by default.

gn/core.gni

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ skia_core_sources = [
418418
"$_src/image/SkImage_Lazy.cpp",
419419
"$_src/image/SkImage_Lazy.h",
420420
"$_src/image/SkImage_Raster.cpp",
421+
"$_src/image/SkRescaleAndReadPixels.cpp",
422+
"$_src/image/SkRescaleAndReadPixels.h",
421423
"$_src/image/SkSurface.cpp",
422424
"$_src/image/SkSurface_Base.h",
423425

include/core/SkImage.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,108 @@ class SK_API SkImage : public SkRefCnt {
958958
bool readPixels(const SkPixmap& dst, int srcX, int srcY,
959959
CachingHint cachingHint = kAllow_CachingHint) const;
960960

961+
/** The result from asyncRescaleAndReadPixels() or asyncRescaleAndReadPixelsYUV420(). */
962+
class AsyncReadResult {
963+
public:
964+
AsyncReadResult(const AsyncReadResult&) = delete;
965+
AsyncReadResult(AsyncReadResult&&) = delete;
966+
AsyncReadResult& operator=(const AsyncReadResult&) = delete;
967+
AsyncReadResult& operator=(AsyncReadResult&&) = delete;
968+
969+
virtual ~AsyncReadResult() = default;
970+
virtual int count() const = 0;
971+
virtual const void* data(int i) const = 0;
972+
virtual size_t rowBytes(int i) const = 0;
973+
974+
protected:
975+
AsyncReadResult() = default;
976+
};
977+
978+
/** Client-provided context that is passed to client-provided ReadPixelsContext. */
979+
using ReadPixelsContext = void*;
980+
981+
/** Client-provided callback to asyncRescaleAndReadPixels() or
982+
asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure.
983+
*/
984+
using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>);
985+
986+
enum class RescaleGamma : bool { kSrc, kLinear };
987+
988+
/** Makes image pixel data available to caller, possibly asynchronously. It can also rescale
989+
the image pixels.
990+
991+
Currently asynchronous reads are only supported on the GPU backend and only when the
992+
underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all
993+
other cases this operates synchronously.
994+
995+
Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is
996+
rescaled to the size indicated by 'info', is then converted to the color space, color type,
997+
and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the image
998+
causes failure.
999+
1000+
When the pixel data is ready the caller's ReadPixelsCallback is called with a
1001+
AsyncReadResult containing pixel data in the requested color type, alpha type, and color
1002+
space. The AsyncReadResult will have count() == 1. Upon failure the callback is called with
1003+
nullptr for AsyncReadResult. For a GPU image this flushes work but a submit must occur to
1004+
guarantee a finite time before the callback is called.
1005+
1006+
The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
1007+
is GPU-backed the data is immediately invalidated if the GrContext is abandoned or
1008+
destroyed.
1009+
1010+
@param info info of the requested pixels
1011+
@param srcRect subrectangle of image to read
1012+
@param rescaleGamma controls whether rescaling is done in the image's gamma or whether
1013+
the source data is transformed to a linear gamma before rescaling.
1014+
@param rescaleQuality controls the quality (and cost) of the rescaling
1015+
@param callback function to call with result of the read
1016+
@param context passed to callback
1017+
*/
1018+
void asyncRescaleAndReadPixels(const SkImageInfo& info,
1019+
const SkIRect& srcRect,
1020+
RescaleGamma rescaleGamma,
1021+
SkFilterQuality rescaleQuality,
1022+
ReadPixelsCallback callback,
1023+
ReadPixelsContext context);
1024+
1025+
/**
1026+
Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The
1027+
RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three
1028+
planes ordered y, u, v. The u and v planes are half the width and height of the resized
1029+
rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize'
1030+
width and height are not even. A 'srcRect' that is not contained by the bounds of the
1031+
image causes failure.
1032+
1033+
When the pixel data is ready the caller's ReadPixelsCallback is called with a
1034+
AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3.
1035+
Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU image this
1036+
flushes work but a submit must occur to guarantee a finite time before the callback is
1037+
called.
1038+
1039+
The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
1040+
is GPU-backed the data is immediately invalidated if the GrContext is abandoned or
1041+
destroyed.
1042+
1043+
@param yuvColorSpace The transformation from RGB to YUV. Applied to the resized image
1044+
after it is converted to dstColorSpace.
1045+
@param dstColorSpace The color space to convert the resized image to, after rescaling.
1046+
@param srcRect The portion of the image to rescale and convert to YUV planes.
1047+
@param dstSize The size to rescale srcRect to
1048+
@param rescaleGamma controls whether rescaling is done in the image's gamma or whether
1049+
the source data is transformed to a linear gamma before rescaling.
1050+
@param rescaleQuality controls the quality (and cost) of the rescaling
1051+
@param callback function to call with the planar read result
1052+
@param context passed to callback
1053+
*/
1054+
void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
1055+
sk_sp<SkColorSpace> dstColorSpace,
1056+
const SkIRect& srcRect,
1057+
const SkISize& dstSize,
1058+
RescaleGamma rescaleGamma,
1059+
SkFilterQuality rescaleQuality,
1060+
ReadPixelsCallback callback,
1061+
ReadPixelsContext context);
1062+
9611063
/** Copies SkImage to dst, scaling pixels to fit dst.width() and dst.height(), and
9621064
converting pixels to match dst.colorType() and dst.alphaType(). Returns true if
9631065
pixels are copied. Returns false if dst.addr() is nullptr, or dst.rowBytes() is

include/core/SkSurface.h

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -769,22 +769,7 @@ class SK_API SkSurface : public SkRefCnt {
769769
*/
770770
bool readPixels(const SkBitmap& dst, int srcX, int srcY);
771771

772-
/** The result from asyncRescaleAndReadPixels() or asyncRescaleAndReadPixelsYUV420(). */
773-
class AsyncReadResult {
774-
public:
775-
AsyncReadResult(const AsyncReadResult&) = delete;
776-
AsyncReadResult(AsyncReadResult&&) = delete;
777-
AsyncReadResult& operator=(const AsyncReadResult&) = delete;
778-
AsyncReadResult& operator=(AsyncReadResult&&) = delete;
779-
780-
virtual ~AsyncReadResult() = default;
781-
virtual int count() const = 0;
782-
virtual const void* data(int i) const = 0;
783-
virtual size_t rowBytes(int i) const = 0;
784-
785-
protected:
786-
AsyncReadResult() = default;
787-
};
772+
using AsyncReadResult = SkImage::AsyncReadResult;
788773

789774
/** Client-provided context that is passed to client-provided ReadPixelsContext. */
790775
using ReadPixelsContext = void*;
@@ -797,7 +782,7 @@ class SK_API SkSurface : public SkRefCnt {
797782
/** Controls the gamma that rescaling occurs in for asyncRescaleAndReadPixels() and
798783
asyncRescaleAndReadPixelsYUV420().
799784
*/
800-
enum RescaleGamma : bool { kSrc, kLinear };
785+
using RescaleGamma = SkImage::RescaleGamma;
801786

802787
/** Makes surface pixel data available to caller, possibly asynchronously. It can also rescale
803788
the surface pixels.
@@ -829,9 +814,12 @@ class SK_API SkSurface : public SkRefCnt {
829814
@param callback function to call with result of the read
830815
@param context passed to callback
831816
*/
832-
void asyncRescaleAndReadPixels(const SkImageInfo& info, const SkIRect& srcRect,
833-
RescaleGamma rescaleGamma, SkFilterQuality rescaleQuality,
834-
ReadPixelsCallback callback, ReadPixelsContext context);
817+
void asyncRescaleAndReadPixels(const SkImageInfo& info,
818+
const SkIRect& srcRect,
819+
RescaleGamma rescaleGamma,
820+
SkFilterQuality rescaleQuality,
821+
ReadPixelsCallback callback,
822+
ReadPixelsContext context);
835823

836824
/**
837825
Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The
@@ -869,7 +857,7 @@ class SK_API SkSurface : public SkRefCnt {
869857
RescaleGamma rescaleGamma,
870858
SkFilterQuality rescaleQuality,
871859
ReadPixelsCallback callback,
872-
ReadPixelsContext);
860+
ReadPixelsContext context);
873861

874862
/** Copies SkRect of pixels from the src SkPixmap to the SkSurface.
875863

infra/bots/gen_tasks_logic/dm_flags.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ func (b *taskBuilder) dmFlags(internalHardwareLabel string) {
956956
match = append(match, "~WritePixelsNonTextureMSAA_Gpu")
957957
}
958958

959-
if b.extraConfig("Direct3D") {
959+
if b.extraConfig("Direct3D") {
960960
// skia:9935
961961
match = append(match, "~^ColorTypeBackendAllocationTest$")
962962
match = append(match, "~^CompressedBackendAllocationTest$")
@@ -971,10 +971,13 @@ func (b *taskBuilder) dmFlags(internalHardwareLabel string) {
971971
match = append(match, "~^TextureIdleStateTest$")
972972
match = append(match, "~^TextureProxyTest$")
973973
}
974-
975-
if b.extraConfig("Direct3D") && b.gpu("RadeonHD7770") && b.matchOs("Win") {
974+
if b.extraConfig("Direct3D") && b.matchOs("Win") {
975+
// skia:9935
976+
match = append(match, "~^ImageAsyncReadPixels$")
977+
}
978+
if b.extraConfig("Direct3D") && b.gpu("RadeonHD7770") && b.matchOs("Win") {
976979
// skia:9935
977-
match = append(match, "~^AsyncReadPixels$")
980+
match = append(match, "~^SurfaceAsyncReadPixels$")
978981
match = append(match, "~^MorphologyFilterRadiusWithMirrorCTM_Gpu$")
979982
match = append(match, "~^ReadPixels_Gpu$")
980983
match = append(match, "~^ReadPixels_Texture$")

0 commit comments

Comments
 (0)