1 /* 2 * Copyright 2019 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef YUVUtils_DEFINED 9 #define YUVUtils_DEFINED 10 11 #include "include/core/SkColorSpace.h" 12 #include "include/core/SkImage.h" 13 #include "include/core/SkYUVAPixmaps.h" 14 #include "include/gpu/ganesh/GrBackendSurface.h" 15 #include "src/base/SkAutoMalloc.h" 16 17 #include <tuple> 18 19 class SkData; 20 #if defined(SK_GRAPHITE) 21 namespace skgpu::graphite { class Recorder; } 22 #endif 23 24 namespace sk_gpu_test { 25 26 // Splits an input image into A8 YUV[A] planes using the passed subsampling and YUV color space. If 27 // the src image is opaque there will be three planes (Y, U, and V) and if not there will be a 28 // fourth A plane. The planes are returned along with a SkYUVAInfo describing the resulting planar 29 // image. Images are made as textures if GrRecordingContext is not null, otherwise as cpu images. 30 std::tuple<std::array<sk_sp<SkImage>, SkYUVAInfo::kMaxPlanes>, SkYUVAInfo> 31 MakeYUVAPlanesAsA8(SkImage*, 32 SkYUVColorSpace, 33 SkYUVAInfo::Subsampling, 34 GrRecordingContext*); 35 36 // Utility that decodes a JPEG but preserves the YUVA8 planes in the image, and uses 37 // MakeFromYUVAPixmaps to create a GPU multiplane YUVA image for a context. It extracts the planar 38 // data once, and lazily creates the actual SkImage when the GrContext is provided (and refreshes 39 // the image if the context has changed, as in Viewer) 40 class LazyYUVImage { 41 public: 42 // Returns null if the data could not be extracted into YUVA planes 43 static std::unique_ptr<LazyYUVImage> Make(sk_sp<SkData> data, 44 skgpu::Mipmapped = skgpu::Mipmapped::kNo, 45 sk_sp<SkColorSpace> = nullptr); 46 static std::unique_ptr<LazyYUVImage> Make(SkYUVAPixmaps, 47 skgpu::Mipmapped = skgpu::Mipmapped::kNo, 48 sk_sp<SkColorSpace> = nullptr); 49 50 enum class Type { kFromPixmaps, kFromGenerator, kFromTextures, kFromImages }; 51 dimensions()52 SkISize dimensions() const { return fPixmaps.yuvaInfo().dimensions(); } 53 54 sk_sp<SkImage> refImage(GrRecordingContext* rContext, Type); 55 #if defined(SK_GRAPHITE) 56 sk_sp<SkImage> refImage(skgpu::graphite::Recorder* recorder, Type); 57 #endif 58 59 private: 60 // Decoded YUV data 61 SkYUVAPixmaps fPixmaps; 62 63 skgpu::Mipmapped fMipmapped; 64 65 sk_sp<SkColorSpace> fColorSpace; 66 67 // Memoized SkImages formed with planes, one for each Type. 68 sk_sp<SkImage> fYUVImage[4]; 69 70 LazyYUVImage() = default; 71 72 bool reset(sk_sp<SkData> data, skgpu::Mipmapped, sk_sp<SkColorSpace>); 73 bool reset(SkYUVAPixmaps pixmaps, skgpu::Mipmapped, sk_sp<SkColorSpace>); 74 75 bool ensureYUVImage(GrRecordingContext* rContext, Type type); 76 #if defined(SK_GRAPHITE) 77 bool ensureYUVImage(skgpu::graphite::Recorder* recorder, Type type); 78 #endif 79 }; 80 81 } // namespace sk_gpu_test 82 83 #endif // YUVUtils_DEFINED 84