1 /*
2  * Copyright 2020 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 #include "src/gpu/ganesh/GrDDLTask.h"
9 
10 #include "include/core/SkDeferredDisplayList.h"
11 #include "src/core/SkDeferredDisplayListPriv.h"
12 #include "src/gpu/ganesh/GrRenderTargetProxy.h"
13 #include "src/gpu/ganesh/GrResourceAllocator.h"
14 
GrDDLTask(GrDrawingManager * drawingMgr,sk_sp<GrRenderTargetProxy> ddlTarget,sk_sp<const SkDeferredDisplayList> ddl,SkIPoint offset)15 GrDDLTask::GrDDLTask(GrDrawingManager* drawingMgr,
16                      sk_sp<GrRenderTargetProxy> ddlTarget,
17                      sk_sp<const SkDeferredDisplayList> ddl,
18                      SkIPoint offset)
19         : fDDL(std::move(ddl))
20         , fDDLTarget(std::move(ddlTarget))
21         , fOffset(offset) {
22     (void) fOffset;  // fOffset will be used shortly
23 
24     for (auto& task : fDDL->priv().renderTasks()) {
25         SkASSERT(task->isClosed());
26 
27         for (int i = 0; i < task->numTargets(); ++i) {
28             drawingMgr->setLastRenderTask(task->target(i), task.get());
29         }
30     }
31 
32     // The DDL task never accepts additional tasks
33     this->setFlag(kClosed_Flag);
34 }
35 
~GrDDLTask()36 GrDDLTask::~GrDDLTask() { }
37 
endFlush(GrDrawingManager * drawingManager)38 void GrDDLTask::endFlush(GrDrawingManager* drawingManager) {
39     for (auto& task : fDDL->priv().renderTasks()) {
40         task->endFlush(drawingManager);
41     }
42 
43     INHERITED::endFlush(drawingManager);
44 }
45 
disown(GrDrawingManager * drawingManager)46 void GrDDLTask::disown(GrDrawingManager* drawingManager) {
47     for (auto& task : fDDL->priv().renderTasks()) {
48         task->disown(drawingManager);
49     }
50 
51     INHERITED::disown(drawingManager);
52 }
53 
onIsUsed(GrSurfaceProxy * proxy) const54 bool GrDDLTask::onIsUsed(GrSurfaceProxy* proxy) const {
55     if (proxy == fDDLTarget.get()) {
56         return true;
57     }
58 
59     for (auto& task : fDDL->priv().renderTasks()) {
60         if (task->isUsed(proxy)) {
61             return true;
62         }
63     }
64 
65     return false;
66 }
67 
gatherProxyIntervals(GrResourceAllocator * alloc) const68 void GrDDLTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
69     // We don't have any proxies, but the resource allocator will still bark
70     // if a task doesn't claim any op indices, so we oblige it.
71     alloc->incOps();
72 
73     for (auto& task : fDDL->priv().renderTasks()) {
74         task->gatherProxyIntervals(alloc);
75     }
76 }
77 
onMakeClosed(GrRecordingContext *,SkIRect * targetUpdateBounds)78 GrRenderTask::ExpectedOutcome GrDDLTask::onMakeClosed(GrRecordingContext*,
79                                                       SkIRect* targetUpdateBounds) {
80     SkASSERT(0);
81     return ExpectedOutcome::kTargetUnchanged;
82 }
83 
onPrepare(GrOpFlushState * flushState)84 void GrDDLTask::onPrepare(GrOpFlushState* flushState) {
85     for (auto& task : fDDL->priv().renderTasks()) {
86         task->prepare(flushState);
87     }
88 }
89 
onExecute(GrOpFlushState * flushState)90 bool GrDDLTask::onExecute(GrOpFlushState* flushState) {
91     bool anyCommandsIssued = false;
92     for (auto& task : fDDL->priv().renderTasks()) {
93         if (task->execute(flushState)) {
94             anyCommandsIssued = true;
95         }
96     }
97 
98     return anyCommandsIssued;
99 }
100 
101 #if GR_TEST_UTILS
dump(const SkString & label,SkString indent,bool printDependencies,bool close) const102 void GrDDLTask::dump(const SkString& label,
103                      SkString indent,
104                      bool printDependencies,
105                      bool close) const {
106     INHERITED::dump(label, indent, printDependencies, false);
107 
108     SkDebugf("%sDDL Target: ", indent.c_str());
109     if (fDDLTarget) {
110         SkString proxyStr = fDDLTarget->dump();
111         SkDebugf("%s", proxyStr.c_str());
112     }
113     SkDebugf("\n");
114 
115     SkDebugf("%s%d sub-tasks\n", indent.c_str(), fDDL->priv().numRenderTasks());
116 
117     SkString subIndent(indent);
118     subIndent.append("    ");
119 
120     int index = 0;
121     for (auto& task : fDDL->priv().renderTasks()) {
122         SkString subLabel;
123         subLabel.printf("sub-task %d/%d", index++, fDDL->priv().numRenderTasks());
124         task->dump(subLabel, subIndent, printDependencies, true);
125     }
126 
127     if (close) {
128         SkDebugf("%s--------------------------------------------------------------\n\n",
129                  indent.c_str());
130     }
131 }
132 #endif
133