706 {
708 PixelTransferResult>;
709
714
715 if (!dContext) {
717 return;
718 }
720 if (rt && rt->wrapsVkSecondaryCB()) {
722 return;
723 }
724 if (rt && rt->framebufferOnly()) {
726 return;
727 }
730 return;
731 }
733 int y = srcRect.
fTop;
734 bool needsRescale = srcRect.
size() != dstSize ||
737 if (needsRescale) {
741 dstColorSpace);
742
745 srcRect,
746 rescaleGamma,
747 rescaleMode);
748 if (!tempFC) {
750 return;
751 }
755 srcView = tempFC->readSurfaceView();
759 std::move(srcView),
760 skgpu::Mipmapped::kNo,
761 srcRect,
764 "SurfaceContext_AsyncRescaleAndReadPixelsYUV420");
765 if (!srcView) {
766
768 return;
769 }
772 }
773
776 1,
777 skgpu::Mipmapped::kNo, skgpu::Protected::kNo);
778 std::unique_ptr<SurfaceFillContext> aFC;
779 if (readAlpha) {
781 1,
782 skgpu::Mipmapped::kNo, skgpu::Protected::kNo);
783 }
784
785 auto uvInfo = yaInfo.makeWH(yaInfo.width()/2, yaInfo.height()/2);
787 1,
788 skgpu::Mipmapped::kNo, skgpu::Protected::kNo);
790 1,
791 skgpu::Mipmapped::kNo, skgpu::Protected::kNo);
792
793 if (!yFC || !uFC || !vFC || (readAlpha && !aFC)) {
795 return;
796 }
797
798 float baseM[20];
800
801
802
804
805 auto [readCT, offsetAlignment] =
807 yFC->asSurfaceProxy()->backendFormat(),
811 return;
812 }
814 !offsetAlignment;
815 PixelTransferResult yTransfer, aTransfer, uTransfer, vTransfer;
816
817
818 float yM[20];
819 std::fill_n(yM, 15, 0.f);
820 std::copy_n(baseM + 0, 5, yM + 15);
821
824 yM,
825 false,
826 true,
827 false);
828 yFC->fillWithFP(std::move(yFP));
829 if (!doSynchronousRead) {
832 if (!yTransfer.fTransferBuffer) {
834 return;
835 }
836 }
837
838 if (readAlpha) {
841 baseM[16] == 0 &&
842 baseM[17] == 0 &&
843 baseM[18] == 1 &&
844 baseM[19] == 0);
845 aFC->fillWithFP(std::move(aFP));
846 if (!doSynchronousRead) {
849 if (!aTransfer.fTransferBuffer) {
851 return;
852 }
853 }
854 }
855
856 texMatrix.preScale(2.f, 2.f);
857
858 float uM[20];
859 std::fill_n(uM, 15, 0.f);
860 std::copy_n(baseM + 5, 5, uM + 15);
861
864 texMatrix,
865 GrSamplerState::Filter::kLinear);
867 uM,
868 false,
869 true,
870 false);
871 uFC->fillWithFP(std::move(uFP));
872 if (!doSynchronousRead) {
875 if (!uTransfer.fTransferBuffer) {
877 return;
878 }
879 }
880
881
882 float vM[20];
883 std::fill_n(vM, 15, 0.f);
884 std::copy_n(baseM + 10, 5, vM + 15);
887 texMatrix,
888 GrSamplerState::Filter::kLinear);
890 vM,
891 false,
892 true,
893 false);
894 vFC->fillWithFP(std::move(vFP));
895
896 if (!doSynchronousRead) {
899 if (!vTransfer.fTransferBuffer) {
901 return;
902 }
903 }
904
905 if (doSynchronousRead) {
910 if (readAlpha) {
912 }
913 if (!yFC->readPixels(dContext, yPmp, {0, 0}) ||
914 !uFC->readPixels(dContext, uPmp, {0, 0}) ||
915 !vFC->readPixels(dContext, vPmp, {0, 0}) ||
916 (readAlpha && !aFC->readPixels(dContext, aPmp, {0, 0}))) {
918 return;
919 }
924 if (readAlpha) {
926 }
928 return;
929 }
930
931 struct FinishContext {
936 PixelTransferResult fYTransfer;
937 PixelTransferResult fUTransfer;
938 PixelTransferResult fVTransfer;
939 PixelTransferResult fATransfer;
940 };
941
942
943
944 auto* finishContext =
new FinishContext{
callback,
945 callbackContext,
947 dstSize,
948 std::move(yTransfer),
949 std::move(uTransfer),
950 std::move(vTransfer),
951 std::move(aTransfer)};
953 const auto* context = reinterpret_cast<const FinishContext*>(c);
954 auto manager = context->fMappedBufferManager;
955 auto result = std::make_unique<AsyncReadResult>(
manager->ownerID());
956 if (!
result->addTransferResult(context->fYTransfer,
957 context->fSize,
958 context->fYTransfer.fRowBytes,
959 manager)) {
960 (*context->fClientCallback)(context->fClientContext, nullptr);
961 delete context;
962 return;
963 }
964 SkISize uvSize = {context->fSize.
width() / 2, context->fSize.height() / 2};
965 if (!
result->addTransferResult(context->fUTransfer,
966 uvSize,
967 context->fUTransfer.fRowBytes,
968 manager)) {
969 (*context->fClientCallback)(context->fClientContext, nullptr);
970 delete context;
971 return;
972 }
973 if (!
result->addTransferResult(context->fVTransfer,
974 uvSize,
975 context->fVTransfer.fRowBytes,
976 manager)) {
977 (*context->fClientCallback)(context->fClientContext, nullptr);
978 delete context;
979 return;
980 }
981 if (context->fATransfer.fTransferBuffer &&
982 !
result->addTransferResult(context->fATransfer,
983 context->fSize,
984 context->fATransfer.fRowBytes,
985 manager)) {
986 (*context->fClientCallback)(context->fClientContext, nullptr);
987 delete context;
988 return;
989 }
990 (*context->fClientCallback)(context->fClientContext, std::move(
result));
991 delete context;
992 };
998}
@ 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)