xref: /aosp_15_r20/external/skia/tools/gpu/YUVUtils.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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