#include "DMTask.h" #include "DMTaskRunner.h" #include "SkCommonFlags.h" namespace DM { Task::Task(Reporter* reporter, TaskRunner* taskRunner) : fReporter(reporter) , fTaskRunner(taskRunner) , fDepth(0) { fReporter->taskCreated(); } Task::Task(const Task& parent) : fReporter(parent.fReporter) , fTaskRunner(parent.fTaskRunner) , fDepth(parent.depth() + 1) { fReporter->taskCreated(); } Task::~Task() { fReporter->taskDestroyed(); } void Task::fail(const char* msg) { SkString failure(this->name()); if (msg) { failure.appendf(": %s", msg); } fReporter->fail(failure); } void Task::start() { fStart = SkTime::GetMSecs(); } void Task::finish() { fReporter->printStatus(this->name(), SkTime::GetMSecs() - fStart); } void Task::reallySpawnChild(CpuTask* task) { fTaskRunner->add(task); } CpuTask::CpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {} CpuTask::CpuTask(const Task& parent) : Task(parent) {} void CpuTask::run() { // If the task says skip, or if we're starting a top-level CPU task and we don't want to, skip. const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_cpu); if (!skip) { this->start(); if (!FLAGS_dryRun) this->draw(); this->finish(); } SkDELETE(this); } void CpuTask::spawnChild(CpuTask* task) { // Run children serially on this (CPU) thread. This tends to save RAM and is usually no slower. // Calling reallySpawnChild() is nearly equivalent, but it'd pointlessly contend on the // threadpool; reallySpawnChild() is most useful when you want to change threadpools. task->run(); } GpuTask::GpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {} void GpuTask::run(GrContextFactory* factory) { // If the task says skip, or if we're starting a top-level GPU task and we don't want to, skip. const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_gpu); if (!skip) { this->start(); if (!FLAGS_dryRun) this->draw(factory); this->finish(); if (FLAGS_abandonGpuContext) { factory->abandonContexts(); } if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { factory->destroyContexts(); } } SkDELETE(this); } void GpuTask::spawnChild(CpuTask* task) { // Spawn a new task so it runs on the CPU threadpool instead of the GPU one we're on now. // It goes on the front of the queue to minimize the time we must hold reference bitmaps in RAM. this->reallySpawnChild(task); } } // namespace DM