xref: /aosp_15_r20/external/skia/src/gpu/graphite/task/UploadTask.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2022 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_task_UploadTask_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_task_UploadTask_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/task/Task.h"
12*c8dee2aaSAndroid Build Coastguard Worker 
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/CommandTypes.h"
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
22*c8dee2aaSAndroid Build Coastguard Worker 
23*c8dee2aaSAndroid Build Coastguard Worker class Buffer;
24*c8dee2aaSAndroid Build Coastguard Worker class Recorder;
25*c8dee2aaSAndroid Build Coastguard Worker class TextureProxy;
26*c8dee2aaSAndroid Build Coastguard Worker 
27*c8dee2aaSAndroid Build Coastguard Worker struct MipLevel {
28*c8dee2aaSAndroid Build Coastguard Worker     const void* fPixels = nullptr;
29*c8dee2aaSAndroid Build Coastguard Worker     size_t fRowBytes = 0;
30*c8dee2aaSAndroid Build Coastguard Worker };
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker /**
33*c8dee2aaSAndroid Build Coastguard Worker  * The ConditionalUploadContext, if set, is used to determine whether an upload needs to occur
34*c8dee2aaSAndroid Build Coastguard Worker  * on Recording playback. Clients will need to create their own subclasses to store the
35*c8dee2aaSAndroid Build Coastguard Worker  * necessary data and override the needsUpload() method to do this check.
36*c8dee2aaSAndroid Build Coastguard Worker  */
37*c8dee2aaSAndroid Build Coastguard Worker class ConditionalUploadContext {
38*c8dee2aaSAndroid Build Coastguard Worker public:
~ConditionalUploadContext()39*c8dee2aaSAndroid Build Coastguard Worker     virtual ~ConditionalUploadContext() {}
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker     // Return true if the upload needs to occur; false if it should be skipped this time.
42*c8dee2aaSAndroid Build Coastguard Worker     virtual bool needsUpload(Context*) = 0;
43*c8dee2aaSAndroid Build Coastguard Worker 
44*c8dee2aaSAndroid Build Coastguard Worker     // Return true if the upload should be kept in the task (and possibly re-executed on replay
45*c8dee2aaSAndroid Build Coastguard Worker     // depending on needsUpload()'s return value), or false if it should be discarded and never
46*c8dee2aaSAndroid Build Coastguard Worker     // attempt to be uploaded on any replay.
uploadSubmitted()47*c8dee2aaSAndroid Build Coastguard Worker     virtual bool uploadSubmitted() { return true; }
48*c8dee2aaSAndroid Build Coastguard Worker };
49*c8dee2aaSAndroid Build Coastguard Worker 
50*c8dee2aaSAndroid Build Coastguard Worker /**
51*c8dee2aaSAndroid Build Coastguard Worker  * ImageUploadContext is an implementation of ConditionalUploadContext that returns true on
52*c8dee2aaSAndroid Build Coastguard Worker  * the first call to needsUpload() and then returns false on subsequent calls. This is used to
53*c8dee2aaSAndroid Build Coastguard Worker  * upload an image once and then avoid redundant uploads after that.
54*c8dee2aaSAndroid Build Coastguard Worker  */
55*c8dee2aaSAndroid Build Coastguard Worker class ImageUploadContext : public ConditionalUploadContext {
56*c8dee2aaSAndroid Build Coastguard Worker public:
~ImageUploadContext()57*c8dee2aaSAndroid Build Coastguard Worker     ~ImageUploadContext() override {}
58*c8dee2aaSAndroid Build Coastguard Worker 
59*c8dee2aaSAndroid Build Coastguard Worker     // Always upload, since it will be discarded right afterwards
needsUpload(Context *)60*c8dee2aaSAndroid Build Coastguard Worker     bool needsUpload(Context*) override { return true; }
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker     // Always return false so the upload instance is discarded after the first execution
uploadSubmitted()63*c8dee2aaSAndroid Build Coastguard Worker     bool uploadSubmitted() override { return false; }
64*c8dee2aaSAndroid Build Coastguard Worker };
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker /**
67*c8dee2aaSAndroid Build Coastguard Worker  * An UploadInstance represents a single set of uploads from a buffer to texture that
68*c8dee2aaSAndroid Build Coastguard Worker  * can be processed in a single command.
69*c8dee2aaSAndroid Build Coastguard Worker  */
70*c8dee2aaSAndroid Build Coastguard Worker class UploadInstance {
71*c8dee2aaSAndroid Build Coastguard Worker public:
72*c8dee2aaSAndroid Build Coastguard Worker     static UploadInstance Make(Recorder*,
73*c8dee2aaSAndroid Build Coastguard Worker                                sk_sp<TextureProxy> targetProxy,
74*c8dee2aaSAndroid Build Coastguard Worker                                const SkColorInfo& srcColorInfo,
75*c8dee2aaSAndroid Build Coastguard Worker                                const SkColorInfo& dstColorInfo,
76*c8dee2aaSAndroid Build Coastguard Worker                                SkSpan<const MipLevel> levels,
77*c8dee2aaSAndroid Build Coastguard Worker                                const SkIRect& dstRect,
78*c8dee2aaSAndroid Build Coastguard Worker                                std::unique_ptr<ConditionalUploadContext>);
79*c8dee2aaSAndroid Build Coastguard Worker     static UploadInstance MakeCompressed(Recorder*,
80*c8dee2aaSAndroid Build Coastguard Worker                                          sk_sp<TextureProxy> targetProxy,
81*c8dee2aaSAndroid Build Coastguard Worker                                          const void* data,
82*c8dee2aaSAndroid Build Coastguard Worker                                          size_t dataSize);
83*c8dee2aaSAndroid Build Coastguard Worker 
Invalid()84*c8dee2aaSAndroid Build Coastguard Worker     static UploadInstance Invalid() { return {}; }
85*c8dee2aaSAndroid Build Coastguard Worker 
86*c8dee2aaSAndroid Build Coastguard Worker     UploadInstance(UploadInstance&&);
87*c8dee2aaSAndroid Build Coastguard Worker     UploadInstance& operator=(UploadInstance&&);
88*c8dee2aaSAndroid Build Coastguard Worker     ~UploadInstance();
89*c8dee2aaSAndroid Build Coastguard Worker 
isValid()90*c8dee2aaSAndroid Build Coastguard Worker     bool isValid() const { return fBuffer != nullptr && fTextureProxy != nullptr; }
91*c8dee2aaSAndroid Build Coastguard Worker 
92*c8dee2aaSAndroid Build Coastguard Worker     bool prepareResources(ResourceProvider*);
93*c8dee2aaSAndroid Build Coastguard Worker 
94*c8dee2aaSAndroid Build Coastguard Worker     // Adds upload command to the given CommandBuffer, returns false if the instance should be
95*c8dee2aaSAndroid Build Coastguard Worker     // discarded.
96*c8dee2aaSAndroid Build Coastguard Worker     Task::Status addCommand(Context*, CommandBuffer*, Task::ReplayTargetData) const;
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker private:
99*c8dee2aaSAndroid Build Coastguard Worker     UploadInstance();
100*c8dee2aaSAndroid Build Coastguard Worker     // Copy data is appended directly after the object is created
101*c8dee2aaSAndroid Build Coastguard Worker     UploadInstance(const Buffer*,
102*c8dee2aaSAndroid Build Coastguard Worker                    size_t bytesPerPixel,
103*c8dee2aaSAndroid Build Coastguard Worker                    sk_sp<TextureProxy>,
104*c8dee2aaSAndroid Build Coastguard Worker                    std::unique_ptr<ConditionalUploadContext> = nullptr);
105*c8dee2aaSAndroid Build Coastguard Worker 
106*c8dee2aaSAndroid Build Coastguard Worker     const Buffer* fBuffer;
107*c8dee2aaSAndroid Build Coastguard Worker     size_t fBytesPerPixel;
108*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<TextureProxy> fTextureProxy;
109*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<1, BufferTextureCopyData> fCopyData;
110*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<ConditionalUploadContext> fConditionalContext;
111*c8dee2aaSAndroid Build Coastguard Worker };
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker /**
114*c8dee2aaSAndroid Build Coastguard Worker  * An UploadList is a mutable collection of UploadCommands.
115*c8dee2aaSAndroid Build Coastguard Worker  *
116*c8dee2aaSAndroid Build Coastguard Worker  * Currently commands are accumulated in order and processed in the same order. Dependency
117*c8dee2aaSAndroid Build Coastguard Worker  * management is expected to be handled by the TaskGraph.
118*c8dee2aaSAndroid Build Coastguard Worker  *
119*c8dee2aaSAndroid Build Coastguard Worker  * When an upload is appended to the list its data will be copied to a Buffer in
120*c8dee2aaSAndroid Build Coastguard Worker  * preparation for a deferred upload.
121*c8dee2aaSAndroid Build Coastguard Worker  */
122*c8dee2aaSAndroid Build Coastguard Worker class UploadList {
123*c8dee2aaSAndroid Build Coastguard Worker public:
124*c8dee2aaSAndroid Build Coastguard Worker     bool recordUpload(Recorder*,
125*c8dee2aaSAndroid Build Coastguard Worker                       sk_sp<TextureProxy> targetProxy,
126*c8dee2aaSAndroid Build Coastguard Worker                       const SkColorInfo& srcColorInfo,
127*c8dee2aaSAndroid Build Coastguard Worker                       const SkColorInfo& dstColorInfo,
128*c8dee2aaSAndroid Build Coastguard Worker                       SkSpan<const MipLevel> levels,
129*c8dee2aaSAndroid Build Coastguard Worker                       const SkIRect& dstRect,
130*c8dee2aaSAndroid Build Coastguard Worker                       std::unique_ptr<ConditionalUploadContext>);
131*c8dee2aaSAndroid Build Coastguard Worker 
size()132*c8dee2aaSAndroid Build Coastguard Worker     int size() { return fInstances.size(); }
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker private:
135*c8dee2aaSAndroid Build Coastguard Worker     friend class UploadTask;
136*c8dee2aaSAndroid Build Coastguard Worker 
137*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<1, UploadInstance> fInstances;
138*c8dee2aaSAndroid Build Coastguard Worker };
139*c8dee2aaSAndroid Build Coastguard Worker 
140*c8dee2aaSAndroid Build Coastguard Worker /*
141*c8dee2aaSAndroid Build Coastguard Worker  * An UploadTask is a immutable collection of UploadCommands.
142*c8dee2aaSAndroid Build Coastguard Worker  *
143*c8dee2aaSAndroid Build Coastguard Worker  * When adding commands to the commandBuffer the texture proxies in those
144*c8dee2aaSAndroid Build Coastguard Worker  * commands will be instantiated and the copy command added.
145*c8dee2aaSAndroid Build Coastguard Worker  */
146*c8dee2aaSAndroid Build Coastguard Worker class UploadTask final : public Task {
147*c8dee2aaSAndroid Build Coastguard Worker public:
148*c8dee2aaSAndroid Build Coastguard Worker     static sk_sp<UploadTask> Make(UploadList*);
149*c8dee2aaSAndroid Build Coastguard Worker     static sk_sp<UploadTask> Make(UploadInstance);
150*c8dee2aaSAndroid Build Coastguard Worker 
151*c8dee2aaSAndroid Build Coastguard Worker     ~UploadTask() override;
152*c8dee2aaSAndroid Build Coastguard Worker 
153*c8dee2aaSAndroid Build Coastguard Worker     Status prepareResources(ResourceProvider*,
154*c8dee2aaSAndroid Build Coastguard Worker                             ScratchResourceManager*,
155*c8dee2aaSAndroid Build Coastguard Worker                             const RuntimeEffectDictionary*) override;
156*c8dee2aaSAndroid Build Coastguard Worker 
157*c8dee2aaSAndroid Build Coastguard Worker     Status addCommands(Context*, CommandBuffer*, ReplayTargetData) override;
158*c8dee2aaSAndroid Build Coastguard Worker 
159*c8dee2aaSAndroid Build Coastguard Worker private:
160*c8dee2aaSAndroid Build Coastguard Worker     UploadTask(skia_private::TArray<UploadInstance>&&);
161*c8dee2aaSAndroid Build Coastguard Worker     UploadTask(UploadInstance);
162*c8dee2aaSAndroid Build Coastguard Worker 
163*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<1, UploadInstance> fInstances;
164*c8dee2aaSAndroid Build Coastguard Worker };
165*c8dee2aaSAndroid Build Coastguard Worker 
166*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
167*c8dee2aaSAndroid Build Coastguard Worker 
168*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_task_UploadTask_DEFINED
169