xref: /aosp_15_r20/external/skia/src/gpu/ganesh/ops/OpsTask.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2019 Google Inc.
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 #ifndef OpsTask_DEFINED
8*c8dee2aaSAndroid Build Coastguard Worker #define OpsTask_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTypeTraits.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDstProxyView.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessorSet.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTask.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrXferProcessor.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrOp.h"
26*c8dee2aaSAndroid Build Coastguard Worker 
27*c8dee2aaSAndroid Build Coastguard Worker #include <array>
28*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
29*c8dee2aaSAndroid Build Coastguard Worker 
30*c8dee2aaSAndroid Build Coastguard Worker class GrAppliedClip;
31*c8dee2aaSAndroid Build Coastguard Worker class GrArenas;
32*c8dee2aaSAndroid Build Coastguard Worker class GrAuditTrail;
33*c8dee2aaSAndroid Build Coastguard Worker class GrCaps;
34*c8dee2aaSAndroid Build Coastguard Worker class GrDrawingManager;
35*c8dee2aaSAndroid Build Coastguard Worker class GrOpFlushState;
36*c8dee2aaSAndroid Build Coastguard Worker class GrRecordingContext;
37*c8dee2aaSAndroid Build Coastguard Worker class GrResourceAllocator;
38*c8dee2aaSAndroid Build Coastguard Worker class GrSurfaceProxyView;
39*c8dee2aaSAndroid Build Coastguard Worker class GrTextureResolveManager;
40*c8dee2aaSAndroid Build Coastguard Worker class OpsTaskTestingAccess;
41*c8dee2aaSAndroid Build Coastguard Worker class SkArenaAlloc;
42*c8dee2aaSAndroid Build Coastguard Worker class SkString;
43*c8dee2aaSAndroid Build Coastguard Worker enum GrSurfaceOrigin : int;
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::ganesh {
46*c8dee2aaSAndroid Build Coastguard Worker 
47*c8dee2aaSAndroid Build Coastguard Worker class SurfaceDrawContext;
48*c8dee2aaSAndroid Build Coastguard Worker 
49*c8dee2aaSAndroid Build Coastguard Worker class OpsTask : public GrRenderTask {
50*c8dee2aaSAndroid Build Coastguard Worker public:
51*c8dee2aaSAndroid Build Coastguard Worker     // Manage the arenas life time by maintaining are reference to it.
52*c8dee2aaSAndroid Build Coastguard Worker     OpsTask(GrDrawingManager*, GrSurfaceProxyView, GrAuditTrail*, sk_sp<GrArenas>);
53*c8dee2aaSAndroid Build Coastguard Worker     ~OpsTask() override;
54*c8dee2aaSAndroid Build Coastguard Worker 
asOpsTask()55*c8dee2aaSAndroid Build Coastguard Worker     OpsTask* asOpsTask() override { return this; }
56*c8dee2aaSAndroid Build Coastguard Worker 
isEmpty()57*c8dee2aaSAndroid Build Coastguard Worker     bool isEmpty() const { return fOpChains.empty(); }
usesMSAASurface()58*c8dee2aaSAndroid Build Coastguard Worker     bool usesMSAASurface() const { return fUsesMSAASurface; }
renderPassXferBarriers()59*c8dee2aaSAndroid Build Coastguard Worker     GrXferBarrierFlags renderPassXferBarriers() const { return fRenderPassXferBarriers; }
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker     /**
62*c8dee2aaSAndroid Build Coastguard Worker      * Empties the draw buffer of any queued up draws.
63*c8dee2aaSAndroid Build Coastguard Worker      */
64*c8dee2aaSAndroid Build Coastguard Worker     void endFlush(GrDrawingManager*) override;
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     void onPrePrepare(GrRecordingContext*) override;
67*c8dee2aaSAndroid Build Coastguard Worker     /**
68*c8dee2aaSAndroid Build Coastguard Worker      * Together these two functions flush all queued up draws to GrCommandBuffer. The return value
69*c8dee2aaSAndroid Build Coastguard Worker      * of onExecute() indicates whether any commands were actually issued to the GPU.
70*c8dee2aaSAndroid Build Coastguard Worker      */
71*c8dee2aaSAndroid Build Coastguard Worker     void onPrepare(GrOpFlushState* flushState) override;
72*c8dee2aaSAndroid Build Coastguard Worker     bool onExecute(GrOpFlushState* flushState) override;
73*c8dee2aaSAndroid Build Coastguard Worker 
addSampledTexture(GrSurfaceProxy * proxy)74*c8dee2aaSAndroid Build Coastguard Worker     void addSampledTexture(GrSurfaceProxy* proxy) {
75*c8dee2aaSAndroid Build Coastguard Worker         // This function takes a GrSurfaceProxy because all subsequent uses of the proxy do not
76*c8dee2aaSAndroid Build Coastguard Worker         // require the specifics of GrTextureProxy, so this avoids a number of unnecessary virtual
77*c8dee2aaSAndroid Build Coastguard Worker         // asTextureProxy() calls. However, sampling the proxy implicitly requires that the proxy
78*c8dee2aaSAndroid Build Coastguard Worker         // be a texture. Eventually, when proxies are a unified type with flags, this can just
79*c8dee2aaSAndroid Build Coastguard Worker         // assert that capability.
80*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(proxy->asTextureProxy());
81*c8dee2aaSAndroid Build Coastguard Worker         fSampledProxies.push_back(proxy);
82*c8dee2aaSAndroid Build Coastguard Worker     }
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     void addOp(GrDrawingManager*, GrOp::Owner, GrTextureResolveManager, const GrCaps&);
85*c8dee2aaSAndroid Build Coastguard Worker 
86*c8dee2aaSAndroid Build Coastguard Worker     void addDrawOp(GrDrawingManager*, GrOp::Owner, bool usesMSAA, const GrProcessorSet::Analysis&,
87*c8dee2aaSAndroid Build Coastguard Worker                    GrAppliedClip&&, const GrDstProxyView&, GrTextureResolveManager, const GrCaps&);
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker     void discard();
90*c8dee2aaSAndroid Build Coastguard Worker 
91*c8dee2aaSAndroid Build Coastguard Worker     enum class CanDiscardPreviousOps : bool {
92*c8dee2aaSAndroid Build Coastguard Worker         kYes = true,
93*c8dee2aaSAndroid Build Coastguard Worker         kNo = false
94*c8dee2aaSAndroid Build Coastguard Worker     };
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker     // Perform book-keeping for a fullscreen clear, regardless of how the clear is implemented later
97*c8dee2aaSAndroid Build Coastguard Worker     // (i.e. setColorLoadOp(), adding a ClearOp, or adding a FillRectOp that covers the device).
98*c8dee2aaSAndroid Build Coastguard Worker     // Returns true if the clear can be converted into a load op (barring device caps).
99*c8dee2aaSAndroid Build Coastguard Worker     bool resetForFullscreenClear(CanDiscardPreviousOps);
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker     // Must only be called if native color buffer clearing is enabled.
102*c8dee2aaSAndroid Build Coastguard Worker     void setColorLoadOp(GrLoadOp op, std::array<float, 4> color = {0, 0, 0, 0});
103*c8dee2aaSAndroid Build Coastguard Worker 
104*c8dee2aaSAndroid Build Coastguard Worker     // Returns whether the given opsTask can be appended at the end of this one.
105*c8dee2aaSAndroid Build Coastguard Worker     bool canMerge(const OpsTask*) const;
106*c8dee2aaSAndroid Build Coastguard Worker 
107*c8dee2aaSAndroid Build Coastguard Worker     // Merge as many opsTasks as possible from the head of 'tasks'. They should all be
108*c8dee2aaSAndroid Build Coastguard Worker     // renderPass compatible. Return the number of tasks merged into 'this'.
109*c8dee2aaSAndroid Build Coastguard Worker     int mergeFrom(SkSpan<const sk_sp<GrRenderTask>> tasks);
110*c8dee2aaSAndroid Build Coastguard Worker 
111*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
numClips()112*c8dee2aaSAndroid Build Coastguard Worker     int numClips() const override { return fNumClips; }
113*c8dee2aaSAndroid Build Coastguard Worker     void visitProxies_debugOnly(const GrVisitProxyFunc&) const override;
114*c8dee2aaSAndroid Build Coastguard Worker #endif
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
117*c8dee2aaSAndroid Build Coastguard Worker     void dump(const SkString& label,
118*c8dee2aaSAndroid Build Coastguard Worker               SkString indent,
119*c8dee2aaSAndroid Build Coastguard Worker               bool printDependencies,
120*c8dee2aaSAndroid Build Coastguard Worker               bool close) const override;
name()121*c8dee2aaSAndroid Build Coastguard Worker     const char* name() const final { return "Ops"; }
numOpChains()122*c8dee2aaSAndroid Build Coastguard Worker     int numOpChains() const { return fOpChains.size(); }
getChain(int index)123*c8dee2aaSAndroid Build Coastguard Worker     const GrOp* getChain(int index) const { return fOpChains[index].head(); }
124*c8dee2aaSAndroid Build Coastguard Worker #endif
125*c8dee2aaSAndroid Build Coastguard Worker 
126*c8dee2aaSAndroid Build Coastguard Worker protected:
127*c8dee2aaSAndroid Build Coastguard Worker     enum class StencilContent {
128*c8dee2aaSAndroid Build Coastguard Worker         kDontCare,
129*c8dee2aaSAndroid Build Coastguard Worker         kUserBitsCleared,  // User bits: cleared
130*c8dee2aaSAndroid Build Coastguard Worker                            // Clip bit: don't care (Ganesh always pre-clears the clip bit.)
131*c8dee2aaSAndroid Build Coastguard Worker         kPreserved
132*c8dee2aaSAndroid Build Coastguard Worker     };
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker     // Lets the caller specify what the content of the stencil buffer should be at the beginning
135*c8dee2aaSAndroid Build Coastguard Worker     // of the render pass.
136*c8dee2aaSAndroid Build Coastguard Worker     //
137*c8dee2aaSAndroid Build Coastguard Worker     // When requesting kClear: Tilers will load the stencil buffer with a "clear" op; non-tilers
138*c8dee2aaSAndroid Build Coastguard Worker     // will clear the stencil on first load, and then preserve it on subsequent loads. (Preserving
139*c8dee2aaSAndroid Build Coastguard Worker     // works because SurfaceDrawContexts are required to leave the user bits in a cleared state
140*c8dee2aaSAndroid Build Coastguard Worker     // once finished.)
141*c8dee2aaSAndroid Build Coastguard Worker     //
142*c8dee2aaSAndroid Build Coastguard Worker     // NOTE: initialContent must not be kClear if caps.performStencilClearsAsDraws() is true.
setInitialStencilContent(StencilContent initialContent)143*c8dee2aaSAndroid Build Coastguard Worker     void setInitialStencilContent(StencilContent initialContent) {
144*c8dee2aaSAndroid Build Coastguard Worker         fInitialStencilContent = initialContent;
145*c8dee2aaSAndroid Build Coastguard Worker     }
146*c8dee2aaSAndroid Build Coastguard Worker 
147*c8dee2aaSAndroid Build Coastguard Worker     void recordOp(GrOp::Owner, bool usesMSAA, GrProcessorSet::Analysis, GrAppliedClip*,
148*c8dee2aaSAndroid Build Coastguard Worker                   const GrDstProxyView*, const GrCaps&);
149*c8dee2aaSAndroid Build Coastguard Worker 
150*c8dee2aaSAndroid Build Coastguard Worker     ExpectedOutcome onMakeClosed(GrRecordingContext*, SkIRect* targetUpdateBounds) override;
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker private:
isColorNoOp()153*c8dee2aaSAndroid Build Coastguard Worker     bool isColorNoOp() const {
154*c8dee2aaSAndroid Build Coastguard Worker         // TODO: GrLoadOp::kDiscard (i.e., storing a discard) should also be grounds for skipping
155*c8dee2aaSAndroid Build Coastguard Worker         // execution. We currently don't because of Vulkan. See http://skbug.com/9373.
156*c8dee2aaSAndroid Build Coastguard Worker         return fOpChains.empty() && GrLoadOp::kLoad == fColorLoadOp;
157*c8dee2aaSAndroid Build Coastguard Worker     }
158*c8dee2aaSAndroid Build Coastguard Worker 
159*c8dee2aaSAndroid Build Coastguard Worker     void deleteOps();
160*c8dee2aaSAndroid Build Coastguard Worker 
161*c8dee2aaSAndroid Build Coastguard Worker     // If a surfaceDrawContext splits its opsTask, it uses this method to guarantee stencil values
162*c8dee2aaSAndroid Build Coastguard Worker     // get preserved across its split tasks.
setMustPreserveStencil()163*c8dee2aaSAndroid Build Coastguard Worker     void setMustPreserveStencil() { fMustPreserveStencil = true; }
164*c8dee2aaSAndroid Build Coastguard Worker 
165*c8dee2aaSAndroid Build Coastguard Worker     // Prevents this opsTask from merging backward. This is used by DMSAA when a non-multisampled
166*c8dee2aaSAndroid Build Coastguard Worker     // opsTask cannot be promoted to MSAA, or when we split a multisampled opsTask in order to
167*c8dee2aaSAndroid Build Coastguard Worker     // resolve its texture.
setCannotMergeBackward()168*c8dee2aaSAndroid Build Coastguard Worker     void setCannotMergeBackward() { fCannotMergeBackward = true; }
169*c8dee2aaSAndroid Build Coastguard Worker 
170*c8dee2aaSAndroid Build Coastguard Worker     class OpChain {
171*c8dee2aaSAndroid Build Coastguard Worker     public:
172*c8dee2aaSAndroid Build Coastguard Worker         OpChain(GrOp::Owner, GrProcessorSet::Analysis, GrAppliedClip*, const GrDstProxyView*);
~OpChain()173*c8dee2aaSAndroid Build Coastguard Worker         ~OpChain() {
174*c8dee2aaSAndroid Build Coastguard Worker             // The ops are stored in a GrMemoryPool and must be explicitly deleted via the pool.
175*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fList.empty());
176*c8dee2aaSAndroid Build Coastguard Worker         }
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker         OpChain(const OpChain&) = delete;
179*c8dee2aaSAndroid Build Coastguard Worker         OpChain& operator=(const OpChain&) = delete;
180*c8dee2aaSAndroid Build Coastguard Worker         OpChain(OpChain&&) = default;
181*c8dee2aaSAndroid Build Coastguard Worker         OpChain& operator=(OpChain&&) = default;
182*c8dee2aaSAndroid Build Coastguard Worker 
183*c8dee2aaSAndroid Build Coastguard Worker         void visitProxies(const GrVisitProxyFunc&) const;
184*c8dee2aaSAndroid Build Coastguard Worker 
head()185*c8dee2aaSAndroid Build Coastguard Worker         GrOp* head() const { return fList.head(); }
186*c8dee2aaSAndroid Build Coastguard Worker 
appliedClip()187*c8dee2aaSAndroid Build Coastguard Worker         GrAppliedClip* appliedClip() const { return fAppliedClip; }
dstProxyView()188*c8dee2aaSAndroid Build Coastguard Worker         const GrDstProxyView& dstProxyView() const { return fDstProxyView; }
bounds()189*c8dee2aaSAndroid Build Coastguard Worker         const SkRect& bounds() const { return fBounds; }
190*c8dee2aaSAndroid Build Coastguard Worker 
191*c8dee2aaSAndroid Build Coastguard Worker         // Deletes all the ops in the chain.
192*c8dee2aaSAndroid Build Coastguard Worker         void deleteOps();
193*c8dee2aaSAndroid Build Coastguard Worker 
194*c8dee2aaSAndroid Build Coastguard Worker         // Attempts to move the ops from the passed chain to this chain at the head. Also attempts
195*c8dee2aaSAndroid Build Coastguard Worker         // to merge ops between the chains. Upon success the passed chain is empty.
196*c8dee2aaSAndroid Build Coastguard Worker         // Fails when the chains aren't of the same op type, have different clips or dst proxies.
197*c8dee2aaSAndroid Build Coastguard Worker         bool prependChain(OpChain*, const GrCaps&, SkArenaAlloc* opsTaskArena, GrAuditTrail*);
198*c8dee2aaSAndroid Build Coastguard Worker 
199*c8dee2aaSAndroid Build Coastguard Worker         // Attempts to add 'op' to this chain either by merging or adding to the tail. Returns
200*c8dee2aaSAndroid Build Coastguard Worker         // 'op' to the caller upon failure, otherwise null. Fails when the op and chain aren't of
201*c8dee2aaSAndroid Build Coastguard Worker         // the same op type, have different clips or dst proxies.
202*c8dee2aaSAndroid Build Coastguard Worker         GrOp::Owner appendOp(GrOp::Owner op, GrProcessorSet::Analysis, const GrDstProxyView*,
203*c8dee2aaSAndroid Build Coastguard Worker                              const GrAppliedClip*, const GrCaps&, SkArenaAlloc* opsTaskArena,
204*c8dee2aaSAndroid Build Coastguard Worker                              GrAuditTrail*);
205*c8dee2aaSAndroid Build Coastguard Worker 
shouldExecute()206*c8dee2aaSAndroid Build Coastguard Worker         bool shouldExecute() const {
207*c8dee2aaSAndroid Build Coastguard Worker             return SkToBool(this->head());
208*c8dee2aaSAndroid Build Coastguard Worker         }
209*c8dee2aaSAndroid Build Coastguard Worker 
210*c8dee2aaSAndroid Build Coastguard Worker         using sk_is_trivially_relocatable = std::true_type;
211*c8dee2aaSAndroid Build Coastguard Worker 
212*c8dee2aaSAndroid Build Coastguard Worker     private:
213*c8dee2aaSAndroid Build Coastguard Worker         class List {
214*c8dee2aaSAndroid Build Coastguard Worker         public:
215*c8dee2aaSAndroid Build Coastguard Worker             List() = default;
216*c8dee2aaSAndroid Build Coastguard Worker             List(GrOp::Owner);
217*c8dee2aaSAndroid Build Coastguard Worker             List(List&&);
218*c8dee2aaSAndroid Build Coastguard Worker             List& operator=(List&& that);
219*c8dee2aaSAndroid Build Coastguard Worker 
empty()220*c8dee2aaSAndroid Build Coastguard Worker             bool empty() const { return !SkToBool(fHead); }
head()221*c8dee2aaSAndroid Build Coastguard Worker             GrOp* head() const { return fHead.get(); }
tail()222*c8dee2aaSAndroid Build Coastguard Worker             GrOp* tail() const { return fTail; }
223*c8dee2aaSAndroid Build Coastguard Worker 
224*c8dee2aaSAndroid Build Coastguard Worker             GrOp::Owner popHead();
225*c8dee2aaSAndroid Build Coastguard Worker             GrOp::Owner removeOp(GrOp* op);
226*c8dee2aaSAndroid Build Coastguard Worker             void pushHead(GrOp::Owner op);
227*c8dee2aaSAndroid Build Coastguard Worker             void pushTail(GrOp::Owner);
228*c8dee2aaSAndroid Build Coastguard Worker 
229*c8dee2aaSAndroid Build Coastguard Worker             void validate() const;
230*c8dee2aaSAndroid Build Coastguard Worker 
231*c8dee2aaSAndroid Build Coastguard Worker             using sk_is_trivially_relocatable = std::true_type;
232*c8dee2aaSAndroid Build Coastguard Worker 
233*c8dee2aaSAndroid Build Coastguard Worker         private:
234*c8dee2aaSAndroid Build Coastguard Worker             GrOp::Owner fHead{nullptr};
235*c8dee2aaSAndroid Build Coastguard Worker             GrOp* fTail{nullptr};
236*c8dee2aaSAndroid Build Coastguard Worker 
237*c8dee2aaSAndroid Build Coastguard Worker             static_assert(::sk_is_trivially_relocatable<decltype(fHead)>::value);
238*c8dee2aaSAndroid Build Coastguard Worker             static_assert(::sk_is_trivially_relocatable<decltype(fTail)>::value);
239*c8dee2aaSAndroid Build Coastguard Worker         };
240*c8dee2aaSAndroid Build Coastguard Worker 
241*c8dee2aaSAndroid Build Coastguard Worker         void validate() const;
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker         bool tryConcat(List*, GrProcessorSet::Analysis, const GrDstProxyView&, const GrAppliedClip*,
244*c8dee2aaSAndroid Build Coastguard Worker                        const SkRect& bounds, const GrCaps&, SkArenaAlloc* opsTaskArena,
245*c8dee2aaSAndroid Build Coastguard Worker                        GrAuditTrail*);
246*c8dee2aaSAndroid Build Coastguard Worker         static List DoConcat(List, List, const GrCaps&, SkArenaAlloc* opsTaskArena, GrAuditTrail*);
247*c8dee2aaSAndroid Build Coastguard Worker 
248*c8dee2aaSAndroid Build Coastguard Worker         List fList;
249*c8dee2aaSAndroid Build Coastguard Worker         GrProcessorSet::Analysis fProcessorAnalysis;
250*c8dee2aaSAndroid Build Coastguard Worker         GrDstProxyView fDstProxyView;
251*c8dee2aaSAndroid Build Coastguard Worker         GrAppliedClip* fAppliedClip;
252*c8dee2aaSAndroid Build Coastguard Worker         SkRect fBounds;
253*c8dee2aaSAndroid Build Coastguard Worker 
254*c8dee2aaSAndroid Build Coastguard Worker         static_assert(::sk_is_trivially_relocatable<decltype(fProcessorAnalysis)>::value);
255*c8dee2aaSAndroid Build Coastguard Worker         static_assert(::sk_is_trivially_relocatable<decltype(fDstProxyView)>::value);
256*c8dee2aaSAndroid Build Coastguard Worker         static_assert(::sk_is_trivially_relocatable<decltype(fAppliedClip)>::value);
257*c8dee2aaSAndroid Build Coastguard Worker         static_assert(::sk_is_trivially_relocatable<decltype(fBounds)>::value);
258*c8dee2aaSAndroid Build Coastguard Worker     };
259*c8dee2aaSAndroid Build Coastguard Worker 
260*c8dee2aaSAndroid Build Coastguard Worker     void onMakeSkippable() override;
261*c8dee2aaSAndroid Build Coastguard Worker 
262*c8dee2aaSAndroid Build Coastguard Worker     bool onIsUsed(GrSurfaceProxy*) const override;
263*c8dee2aaSAndroid Build Coastguard Worker 
264*c8dee2aaSAndroid Build Coastguard Worker     void gatherProxyIntervals(GrResourceAllocator*) const override;
265*c8dee2aaSAndroid Build Coastguard Worker 
266*c8dee2aaSAndroid Build Coastguard Worker     void forwardCombine(const GrCaps&);
267*c8dee2aaSAndroid Build Coastguard Worker 
268*c8dee2aaSAndroid Build Coastguard Worker     // Remove all ops, proxies, etc. Used in the merging algorithm when tasks can be skipped.
269*c8dee2aaSAndroid Build Coastguard Worker     void reset();
270*c8dee2aaSAndroid Build Coastguard Worker 
271*c8dee2aaSAndroid Build Coastguard Worker     friend class ::OpsTaskTestingAccess;
272*c8dee2aaSAndroid Build Coastguard Worker 
273*c8dee2aaSAndroid Build Coastguard Worker     // The SDC and OpsTask have to work together to handle buffer clears. In most cases, buffer
274*c8dee2aaSAndroid Build Coastguard Worker     // clearing can be done natively, in which case the op list's load ops are sufficient. In other
275*c8dee2aaSAndroid Build Coastguard Worker     // cases, draw ops must be used, which makes the SDC the best place for those decisions. This,
276*c8dee2aaSAndroid Build Coastguard Worker     // however, requires that the SDC be able to coordinate with the op list to achieve similar ends
277*c8dee2aaSAndroid Build Coastguard Worker     friend class skgpu::ganesh::SurfaceDrawContext;
278*c8dee2aaSAndroid Build Coastguard Worker 
279*c8dee2aaSAndroid Build Coastguard Worker     GrAuditTrail* fAuditTrail;
280*c8dee2aaSAndroid Build Coastguard Worker 
281*c8dee2aaSAndroid Build Coastguard Worker     bool fUsesMSAASurface;
282*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Swizzle fTargetSwizzle;
283*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceOrigin fTargetOrigin;
284*c8dee2aaSAndroid Build Coastguard Worker 
285*c8dee2aaSAndroid Build Coastguard Worker     GrLoadOp fColorLoadOp = GrLoadOp::kLoad;
286*c8dee2aaSAndroid Build Coastguard Worker     std::array<float, 4> fLoadClearColor = {0, 0, 0, 0};
287*c8dee2aaSAndroid Build Coastguard Worker     StencilContent fInitialStencilContent = StencilContent::kDontCare;
288*c8dee2aaSAndroid Build Coastguard Worker     bool fMustPreserveStencil = false;
289*c8dee2aaSAndroid Build Coastguard Worker     bool fCannotMergeBackward = false;
290*c8dee2aaSAndroid Build Coastguard Worker 
291*c8dee2aaSAndroid Build Coastguard Worker     uint32_t fLastClipStackGenID = SK_InvalidUniqueID;
292*c8dee2aaSAndroid Build Coastguard Worker     SkIRect fLastDevClipBounds;
293*c8dee2aaSAndroid Build Coastguard Worker     int fLastClipNumAnalyticElements;
294*c8dee2aaSAndroid Build Coastguard Worker 
295*c8dee2aaSAndroid Build Coastguard Worker     GrXferBarrierFlags fRenderPassXferBarriers = GrXferBarrierFlags::kNone;
296*c8dee2aaSAndroid Build Coastguard Worker 
297*c8dee2aaSAndroid Build Coastguard Worker     // For ops/opsTask we have mean: 5 stdDev: 28
298*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<25, OpChain> fOpChains;
299*c8dee2aaSAndroid Build Coastguard Worker 
300*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrArenas> fArenas;
301*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(int fNumClips;)
302*c8dee2aaSAndroid Build Coastguard Worker 
303*c8dee2aaSAndroid Build Coastguard Worker     // TODO: We could look into this being a set if we find we're adding a lot of duplicates that is
304*c8dee2aaSAndroid Build Coastguard Worker     // causing slow downs.
305*c8dee2aaSAndroid Build Coastguard Worker     skia_private::TArray<GrSurfaceProxy*, true> fSampledProxies;
306*c8dee2aaSAndroid Build Coastguard Worker 
307*c8dee2aaSAndroid Build Coastguard Worker     SkRect fTotalBounds = SkRect::MakeEmpty();
308*c8dee2aaSAndroid Build Coastguard Worker     SkIRect fClippedContentBounds = SkIRect::MakeEmpty();
309*c8dee2aaSAndroid Build Coastguard Worker };
310*c8dee2aaSAndroid Build Coastguard Worker 
311*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skgpu::ganesh
312*c8dee2aaSAndroid Build Coastguard Worker 
313*c8dee2aaSAndroid Build Coastguard Worker #endif // OpsTask_DEFINED
314