| /* | |
| * Copyright 2021 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/graphite/task/TaskList.h" | |
| #include "src/core/SkTraceEvent.h" | |
| #include "src/gpu/graphite/ScratchResourceManager.h" | |
| #include <cstdint> | |
| namespace skgpu::graphite { | |
| using Status = Task::Status; | |
| template <typename Fn> | |
| Status TaskList::visitTasks(Fn fn) { | |
| int discardCount = 0; | |
| for (sk_sp<Task>& task: fTasks) { | |
| if (!task) { | |
| discardCount++; | |
| continue; // Skip over discarded tasks | |
| } | |
| Status status = fn(task.get()); | |
| if (status == Status::kFail) { | |
| return Status::kFail; | |
| } else if (status == Status::kDiscard) { | |
| task.reset(); | |
| discardCount++; | |
| } | |
| } | |
| return discardCount == fTasks.size() ? Status::kDiscard : Status::kSuccess; | |
| } | |
| Status TaskList::prepareResources(ResourceProvider* resourceProvider, | |
| ScratchResourceManager* scratchManager, | |
| sk_sp<const RuntimeEffectDictionary> runtimeDict) { | |
| TRACE_EVENT1("skia.gpu", TRACE_FUNC, "# tasks", fTasks.size()); | |
| scratchManager->pushScope(); | |
| Status status = this->visitTasks([&](Task* task) { | |
| return task->prepareResources(resourceProvider, scratchManager, runtimeDict); | |
| }); | |
| scratchManager->popScope(); | |
| return status; | |
| } | |
| Status TaskList::addCommands(Context* context, | |
| CommandBuffer* commandBuffer, | |
| Task::ReplayTargetData replayData) { | |
| TRACE_EVENT1("skia.gpu", TRACE_FUNC, "# tasks", fTasks.size()); | |
| return this->visitTasks([&](Task* task) { | |
| return task->addCommands(context, commandBuffer, replayData); | |
| }); | |
| } | |
| bool TaskList::visitPipelines(const std::function<bool(const GraphicsPipeline*)>& visitor) { | |
| Status status = this->visitTasks([&](Task* task) { | |
| return task->visitPipelines(visitor) ? Status::kSuccess : Status::kFail; | |
| }); | |
| // Map back to simple bool (treat kDiscard as true too, no pipelines to visit means all | |
| // pipelines were visited). | |
| return status != Status::kFail; | |
| } | |
| bool TaskList::visitProxies(const std::function<bool(const TextureProxy*)>& visitor, | |
| bool readsOnly) { | |
| Status status = this->visitTasks([&](Task* task) { | |
| return task->visitProxies(visitor, readsOnly) ? Status::kSuccess : Status::kFail; | |
| }); | |
| // Map back to simple bool (treat kDiscard as true too, no pipelines to visit means all | |
| // pipelines were visited). | |
| return status != Status::kFail; | |
| } | |
| #if defined(SK_DUMP_TASKS) | |
| void TaskList::visit(const std::function<void(const Task* task, bool isLast)>& visitor) const { | |
| // Find the last non-null task so we know when to draw the corner branch. | |
| const Task* lastNonNullTask = nullptr; | |
| for (int i = fTasks.size() - 1; i >= 0; --i) { | |
| if (fTasks[i]) { | |
| lastNonNullTask = fTasks[i].get(); | |
| break; | |
| } | |
| } | |
| for (const sk_sp<Task>& task : fTasks) { | |
| if (task) { | |
| visitor(task.get(), task.get() == lastNonNullTask); | |
| } | |
| } | |
| } | |
| #endif | |
| } // namespace skgpu::graphite |