1 #include "DMTask.h" 2 #include "DMTaskRunner.h" 3 #include "SkCommonFlags.h" 4 5 namespace DM { 6 7 Task::Task(Reporter* reporter, TaskRunner* taskRunner) 8 : fReporter(reporter) 9 , fTaskRunner(taskRunner) 10 , fDepth(0) { 11 fReporter->taskCreated(); 12 } 13 14 Task::Task(const Task& parent) 15 : fReporter(parent.fReporter) 16 , fTaskRunner(parent.fTaskRunner) 17 , fDepth(parent.depth() + 1) { 18 fReporter->taskCreated(); 19 } 20 21 Task::~Task() { 22 fReporter->taskDestroyed(); 23 } 24 25 void Task::fail(const char* msg) { 26 SkString failure(this->name()); 27 if (msg) { 28 failure.appendf(": %s", msg); 29 } 30 fReporter->fail(failure); 31 } 32 33 void Task::start() { 34 fStart = SkTime::GetMSecs(); 35 } 36 37 void Task::finish() { 38 fReporter->printStatus(this->name(), SkTime::GetMSecs() - fStart); 39 } 40 41 void Task::reallySpawnChild(CpuTask* task) { 42 fTaskRunner->add(task); 43 } 44 45 CpuTask::CpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {} 46 CpuTask::CpuTask(const Task& parent) : Task(parent) {} 47 48 void CpuTask::run() { 49 // If the task says skip, or if we're starting a top-level CPU task and we don't want to, skip. 50 const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_cpu); 51 if (!skip) { 52 this->start(); 53 if (!FLAGS_dryRun) this->draw(); 54 this->finish(); 55 } 56 SkDELETE(this); 57 } 58 59 void CpuTask::spawnChild(CpuTask* task) { 60 // Run children serially on this (CPU) thread. This tends to save RAM and is usually no slower. 61 // Calling reallySpawnChild() is nearly equivalent, but it'd pointlessly contend on the 62 // threadpool; reallySpawnChild() is most useful when you want to change threadpools. 63 task->run(); 64 } 65 66 GpuTask::GpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {} 67 68 void GpuTask::run(GrContextFactory* factory) { 69 // If the task says skip, or if we're starting a top-level GPU task and we don't want to, skip. 70 const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_gpu); 71 if (!skip) { 72 this->start(); 73 if (!FLAGS_dryRun) this->draw(factory); 74 this->finish(); 75 if (FLAGS_abandonGpuContext) { 76 factory->abandonContexts(); 77 } 78 if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 79 factory->destroyContexts(); 80 } 81 } 82 SkDELETE(this); 83 } 84 85 void GpuTask::spawnChild(CpuTask* task) { 86 // Spawn a new task so it runs on the CPU threadpool instead of the GPU one we're on now. 87 // It goes on the front of the queue to minimize the time we must hold reference bitmaps in RAM. 88 this->reallySpawnChild(task); 89 } 90 91 } // namespace DM 92