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