/* * Copyright 2020 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/gpu/GrDDLTask.h" #include "include/core/SkDeferredDisplayList.h" #include "src/core/SkDeferredDisplayListPriv.h" #include "src/gpu/GrResourceAllocator.h" GrDDLTask::GrDDLTask(GrDrawingManager* drawingMgr, sk_sp ddlTarget, sk_sp ddl, SkIPoint offset) : fDDL(std::move(ddl)) , fDDLTarget(std::move(ddlTarget)) , fOffset(offset) { (void) fOffset; // fOffset will be used shortly for (auto& task : fDDL->priv().renderTasks()) { SkASSERT(task->isClosed()); for (int i = 0; i < task->numTargets(); ++i) { drawingMgr->setLastRenderTask(task->target(i), task.get()); } } // The DDL task never accepts additional tasks this->setFlag(kClosed_Flag); } GrDDLTask::~GrDDLTask() { } void GrDDLTask::endFlush(GrDrawingManager* drawingManager) { for (auto& task : fDDL->priv().renderTasks()) { task->endFlush(drawingManager); } INHERITED::endFlush(drawingManager); } void GrDDLTask::disown(GrDrawingManager* drawingManager) { for (auto& task : fDDL->priv().renderTasks()) { task->disown(drawingManager); } INHERITED::disown(drawingManager); } bool GrDDLTask::onIsUsed(GrSurfaceProxy* proxy) const { if (proxy == fDDLTarget.get()) { return true; } for (auto& task : fDDL->priv().renderTasks()) { if (task->isUsed(proxy)) { return true; } } return false; } void GrDDLTask::gatherProxyIntervals(GrResourceAllocator* alloc) const { // We don't have any proxies, but the resource allocator will still bark // if a task doesn't claim any op indices, so we oblige it. alloc->incOps(); for (auto& task : fDDL->priv().renderTasks()) { task->gatherProxyIntervals(alloc); } } GrRenderTask::ExpectedOutcome GrDDLTask::onMakeClosed(GrRecordingContext*, SkIRect* targetUpdateBounds) { SkASSERT(0); return ExpectedOutcome::kTargetUnchanged; } void GrDDLTask::gatherIDs(SkSTArray<8, uint32_t, true>* idArray) const { for (auto& task : fDDL->priv().renderTasks()) { task->gatherIDs(idArray); } } void GrDDLTask::onPrepare(GrOpFlushState* flushState) { for (auto& task : fDDL->priv().renderTasks()) { task->prepare(flushState); } } bool GrDDLTask::onExecute(GrOpFlushState* flushState) { bool anyCommandsIssued = false; for (auto& task : fDDL->priv().renderTasks()) { if (task->execute(flushState)) { anyCommandsIssued = true; } } return anyCommandsIssued; } #if GR_TEST_UTILS void GrDDLTask::dump(const SkString& label, SkString indent, bool printDependencies, bool close) const { INHERITED::dump(label, indent, printDependencies, false); SkDebugf("%sDDL Target: ", indent.c_str()); if (fDDLTarget) { SkString proxyStr = fDDLTarget->dump(); SkDebugf("%s", proxyStr.c_str()); } SkDebugf("\n"); SkDebugf("%s%d sub-tasks\n", indent.c_str(), fDDL->priv().numRenderTasks()); SkString subIndent(indent); subIndent.append(" "); int index = 0; for (auto& task : fDDL->priv().renderTasks()) { SkString subLabel; subLabel.printf("sub-task %d/%d", index++, fDDL->priv().numRenderTasks()); task->dump(subLabel, subIndent, printDependencies, true); } if (close) { SkDebugf("%s--------------------------------------------------------------\n\n", indent.c_str()); } } #endif