@@ -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
0 commit comments