xref: /aosp_15_r20/external/skia/src/gpu/graphite/Image_Base_Graphite.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 Google LLC
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 skgpu_graphite_Image_Base_Graphite_DEFINED
9 #define skgpu_graphite_Image_Base_Graphite_DEFINED
10 
11 #include "include/gpu/GpuTypes.h"
12 #include "include/private/base/SkTArray.h"
13 #include "src/base/SkSpinlock.h"
14 #include "src/image/SkImage_Base.h"
15 
16 #include <string_view>
17 
18 enum class SkBackingFit;
19 
20 namespace skgpu::graphite {
21 
22 class Context;
23 class Device;
24 class DrawContext;
25 class Image;
26 class Recorder;
27 class TextureProxy;
28 
29 class Image_Base : public SkImage_Base {
30 public:
31     ~Image_Base() override;
32 
33     // Must be called at the time of recording an action that reads from the image, be it a draw
34     // or a copy operation. `drawContext` can be null if the "use" is scoped by a draw.
35     void notifyInUse(Recorder*, DrawContext* drawContext) const;
36 
37     // Returns true if this image is linked to a device that may render their shared texture(s).
38     bool isDynamic() const;
39 
40     // Always copy this image, even if 'subset' and mipmapping match this image exactly.
41     // The base implementation performs all copies as draws.
42     virtual sk_sp<Image> copyImage(Recorder*,
43                                    const SkIRect& subset,
44                                    Budgeted,
45                                    Mipmapped,
46                                    SkBackingFit,
47                                    std::string_view label) const;
48 
49     // From SkImage.h
50     // TODO(egdaniel) This feels wrong. Re-think how this method is used and works.
isValid(GrRecordingContext *)51     bool isValid(GrRecordingContext*) const override { return true; }
52 
53     // From SkImage_Base.h
54     sk_sp<SkImage> onMakeSubset(Recorder*, const SkIRect&, RequiredProperties) const override;
55     sk_sp<SkImage> makeColorTypeAndColorSpace(Recorder*,
56                                               SkColorType targetCT,
57                                               sk_sp<SkColorSpace> targetCS,
58                                               RequiredProperties) const override;
59 
60     // No-ops for Ganesh APIs
onReadPixels(GrDirectContext *,const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY,CachingHint)61     bool onReadPixels(GrDirectContext*,
62                       const SkImageInfo& dstInfo,
63                       void* dstPixels,
64                       size_t dstRowBytes,
65                       int srcX,
66                       int srcY,
67                       CachingHint) const override { return false; }
68 
69     bool getROPixels(GrDirectContext*,
70                      SkBitmap*,
71                      CachingHint = kAllow_CachingHint) const override { return false; }
72 
73     sk_sp<SkImage> onMakeSubset(GrDirectContext*, const SkIRect&) const override;
74 
75     sk_sp<SkSurface> onMakeSurface(Recorder*, const SkImageInfo&) const override;
76 
77     sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType,
78                                                 sk_sp<SkColorSpace>,
79                                                 GrDirectContext*) const override;
80 
81     void onAsyncRescaleAndReadPixels(const SkImageInfo&,
82                                      SkIRect srcRect,
83                                      RescaleGamma,
84                                      RescaleMode,
85                                      ReadPixelsCallback,
86                                      ReadPixelsContext) const override;
87 
88     void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace,
89                                            bool readAlpha,
90                                            sk_sp<SkColorSpace>,
91                                            SkIRect srcRect,
92                                            SkISize dstSize,
93                                            RescaleGamma,
94                                            RescaleMode,
95                                            ReadPixelsCallback,
96                                            ReadPixelsContext) const override;
97 
98 protected:
99     Image_Base(const SkImageInfo& info, uint32_t uniqueID);
100 
101     // If the passed-in image is linked with Devices that modify its texture, copy the links to
102     // this Image. This is used when a new Image is created that shares the same texture proxy as
103     // a dynamic image. This can only be called before the Image has been returned from a factory.
104     void linkDevices(const Image_Base*);
105     // Link this image to the Device that can write to their shared texture proxy, so that when the
106     // image is sampled in a draw, any pending work from the Device is automatically flushed. This
107     // can only be called before the Image has been returned from a factory function.
108     void linkDevice(sk_sp<Device>);
109 
110 private:
111     // Devices are flushed in notifyImageInUse(). If a linked device is uniquely held by the image
112     // or if it's marked as immutable, it will be unlinked (allowing it to be destroyed eventually).
113     // If all linked devices are removed, this array will become empty. Other than initialization,
114     // this array cannot transition from an empty state to having linked devices, so while it's
115     // empty no locking is required.
116     mutable skia_private::STArray<1, sk_sp<Device>> fLinkedDevices SK_GUARDED_BY(fDeviceLinkLock);
117     mutable SkSpinlock fDeviceLinkLock;
118 };
119 
120 } // namespace skgpu::graphite
121 
122 #endif // skgpu_graphite_Image_Base_Graphite_DEFINED
123