714 {
716 PixelTransferResult>;
717
722
723 if (!dContext) {
725 return;
726 }
728 if (rt && rt->wrapsVkSecondaryCB()) {
730 return;
731 }
732 if (rt && rt->framebufferOnly()) {
734 return;
735 }
738 return;
739 }
741 int y = srcRect.
fTop;
742 bool needsRescale = srcRect.
size() != dstSize ||
745 if (needsRescale) {
749 dstColorSpace);
750
753 srcRect,
754 rescaleGamma,
755 rescaleMode);
756 if (!tempFC) {
758 return;
759 }
763 srcView = tempFC->readSurfaceView();
767 std::move(srcView),
769 srcRect,
772 "SurfaceContext_AsyncRescaleAndReadPixelsYUV420");
773 if (!srcView) {
774
776 return;
777 }
780 }
781
784 1,
786 std::unique_ptr<SurfaceFillContext> aFC;
787 if (readAlpha) {
789 1,
791 }
792
793 auto uvInfo = yaInfo.makeWH(yaInfo.width()/2, yaInfo.height()/2);
795 1,
798 1,
800
801 if (!yFC || !uFC || !vFC || (readAlpha && !aFC)) {
803 return;
804 }
805
806 float baseM[20];
808
809
810
812
813 auto [readCT, offsetAlignment] =
815 yFC->asSurfaceProxy()->backendFormat(),
819 return;
820 }
822 !offsetAlignment;
823 PixelTransferResult yTransfer, aTransfer, uTransfer, vTransfer;
824
825
826 float yM[20];
827 std::fill_n(yM, 15, 0.f);
828 std::copy_n(baseM + 0, 5, yM + 15);
829
832 yM,
833 false,
834 true,
835 false);
836 yFC->fillWithFP(std::move(yFP));
837 if (!doSynchronousRead) {
840 if (!yTransfer.fTransferBuffer) {
842 return;
843 }
844 }
845
846 if (readAlpha) {
849 baseM[16] == 0 &&
850 baseM[17] == 0 &&
851 baseM[18] == 1 &&
852 baseM[19] == 0);
853 aFC->fillWithFP(std::move(aFP));
854 if (!doSynchronousRead) {
857 if (!aTransfer.fTransferBuffer) {
859 return;
860 }
861 }
862 }
863
864 texMatrix.preScale(2.f, 2.f);
865
866 float uM[20];
867 std::fill_n(uM, 15, 0.f);
868 std::copy_n(baseM + 5, 5, uM + 15);
869
872 texMatrix,
875 uM,
876 false,
877 true,
878 false);
879 uFC->fillWithFP(std::move(uFP));
880 if (!doSynchronousRead) {
883 if (!uTransfer.fTransferBuffer) {
885 return;
886 }
887 }
888
889
890 float vM[20];
891 std::fill_n(vM, 15, 0.f);
892 std::copy_n(baseM + 10, 5, vM + 15);
895 texMatrix,
898 vM,
899 false,
900 true,
901 false);
902 vFC->fillWithFP(std::move(vFP));
903
904 if (!doSynchronousRead) {
907 if (!vTransfer.fTransferBuffer) {
909 return;
910 }
911 }
912
913 if (doSynchronousRead) {
918 if (readAlpha) {
920 }
921 if (!yFC->readPixels(dContext, yPmp, {0, 0}) ||
922 !uFC->readPixels(dContext, uPmp, {0, 0}) ||
923 !vFC->readPixels(dContext, vPmp, {0, 0}) ||
924 (readAlpha && !aFC->readPixels(dContext, aPmp, {0, 0}))) {
926 return;
927 }
932 if (readAlpha) {
934 }
936 return;
937 }
938
939 struct FinishContext {
944 PixelTransferResult fYTransfer;
945 PixelTransferResult fUTransfer;
946 PixelTransferResult fVTransfer;
947 PixelTransferResult fATransfer;
948 };
949
950
951
952 auto* finishContext =
new FinishContext{
callback,
953 callbackContext,
955 dstSize,
956 std::move(yTransfer),
957 std::move(uTransfer),
958 std::move(vTransfer),
959 std::move(aTransfer)};
961 const auto* context = reinterpret_cast<const FinishContext*>(c);
962 auto manager = context->fMappedBufferManager;
963 auto result = std::make_unique<AsyncReadResult>(
manager->ownerID());
964 if (!
result->addTransferResult(context->fYTransfer,
965 context->fSize,
966 context->fYTransfer.fRowBytes,
968 (*context->fClientCallback)(context->fClientContext, nullptr);
969 delete context;
970 return;
971 }
972 SkISize uvSize = {context->fSize.
width() / 2, context->fSize.height() / 2};
973 if (!
result->addTransferResult(context->fUTransfer,
974 uvSize,
975 context->fUTransfer.fRowBytes,
977 (*context->fClientCallback)(context->fClientContext, nullptr);
978 delete context;
979 return;
980 }
981 if (!
result->addTransferResult(context->fVTransfer,
982 uvSize,
983 context->fVTransfer.fRowBytes,
985 (*context->fClientCallback)(context->fClientContext, nullptr);
986 delete context;
987 return;
988 }
989 if (context->fATransfer.fTransferBuffer &&
990 !
result->addTransferResult(context->fATransfer,
991 context->fSize,
992 context->fATransfer.fRowBytes,
994 (*context->fClientCallback)(context->fClientContext, nullptr);
995 delete context;
996 return;
997 }
998 (*context->fClientCallback)(context->fClientContext, std::move(
result));
999 delete context;
1000 };
1006}
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
void SkColorMatrix_RGB2YUV(SkYUVColorSpace cs, float m[20])
bool transferFromSurfaceToBufferSupport() const
DirectContextID directContextID() const
static std::unique_ptr< GrFragmentProcessor > ColorMatrix(std::unique_ptr< GrFragmentProcessor > child, const float matrix[20], bool unpremulInput, bool clampRGBOutput, bool premulOutput)
std::unique_ptr< skgpu::ganesh::SurfaceFillContext > makeSFCWithFallback(GrImageInfo, SkBackingFit, int sampleCount, skgpu::Mipmapped, skgpu::Protected, GrSurfaceOrigin=kTopLeft_GrSurfaceOrigin, skgpu::Budgeted=skgpu::Budgeted::kYes)
static GrSurfaceProxyView Copy(GrRecordingContext *context, GrSurfaceProxyView src, skgpu::Mipmapped mipmapped, SkIRect srcRect, SkBackingFit fit, skgpu::Budgeted budgeted, std::string_view label)
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
GrSurfaceProxyView readSurfaceView()
int32_t fBottom
larger y-axis bounds
static constexpr SkIRect MakeSize(const SkISize &size)
int32_t fRight
larger x-axis bounds
constexpr int32_t width() const
constexpr int32_t height() const
static SkImageInfo MakeA8(int width, int height)