1d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com#include "DMTask.h"
2d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com#include "DMTaskRunner.h"
317f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark#include "SkCommonFlags.h"
4a65e2fdc9af4b0b0415888a560d6ebd779bc3148commit-bot@chromium.org
5d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.comnamespace DM {
6d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com
7d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.comTask::Task(Reporter* reporter, TaskRunner* taskRunner)
8ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    : fReporter(reporter)
9ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    , fTaskRunner(taskRunner)
10ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    , fDepth(0) {
1139e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org    fReporter->taskCreated();
12d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com}
13d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com
14d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comTask::Task(const Task& parent)
15ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    : fReporter(parent.fReporter)
16d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    , fTaskRunner(parent.fTaskRunner)
17ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    , fDepth(parent.depth() + 1) {
1839e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org    fReporter->taskCreated();
1939e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org}
2039e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org
2139e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.orgTask::~Task() {
2239e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org    fReporter->taskDestroyed();
23d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com}
24d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com
25ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.orgvoid Task::fail(const char* msg) {
26ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    SkString failure(this->name());
27ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    if (msg) {
28ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org        failure.appendf(": %s", msg);
29d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com    }
30ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    fReporter->fail(failure);
31ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org}
32ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org
33a39874b636f9954c6da335733fed646ba33dd614commit-bot@chromium.orgvoid Task::start() {
34a39874b636f9954c6da335733fed646ba33dd614commit-bot@chromium.org    fStart = SkTime::GetMSecs();
35a39874b636f9954c6da335733fed646ba33dd614commit-bot@chromium.org}
36a39874b636f9954c6da335733fed646ba33dd614commit-bot@chromium.org
37ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.orgvoid Task::finish() {
3839e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org    fReporter->printStatus(this->name(), SkTime::GetMSecs() - fStart);
39d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com}
40d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com
41406654be7a930b484159f5bca107d3b11d8a9edemtkleinvoid Task::reallySpawnChild(CpuTask* task) {
42406654be7a930b484159f5bca107d3b11d8a9edemtklein    fTaskRunner->add(task);
43d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com}
44d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com
45ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.orgCpuTask::CpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {}
46ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.orgCpuTask::CpuTask(const Task& parent) : Task(parent) {}
47ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org
48ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.orgvoid CpuTask::run() {
4953e0be6d2b76321c2012085a73f1e7b269406c78mtklein    // If the task says skip, or if we're starting a top-level CPU task and we don't want to, skip.
5053e0be6d2b76321c2012085a73f1e7b269406c78mtklein    const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_cpu);
5153e0be6d2b76321c2012085a73f1e7b269406c78mtklein    if (!skip) {
5239e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org        this->start();
53a65e2fdc9af4b0b0415888a560d6ebd779bc3148commit-bot@chromium.org        if (!FLAGS_dryRun) this->draw();
5439e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org        this->finish();
550dc5bd149a8b69e8dc6d3b4713b827659c9b0a6bcommit-bot@chromium.org    }
56ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    SkDELETE(this);
57d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com}
58d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com
59b0c7156d5be00509d0f80a8d223d5355122b6a3fcommit-bot@chromium.orgvoid CpuTask::spawnChild(CpuTask* task) {
60b0c7156d5be00509d0f80a8d223d5355122b6a3fcommit-bot@chromium.org    // Run children serially on this (CPU) thread.  This tends to save RAM and is usually no slower.
61406654be7a930b484159f5bca107d3b11d8a9edemtklein    // Calling reallySpawnChild() is nearly equivalent, but it'd pointlessly contend on the
62406654be7a930b484159f5bca107d3b11d8a9edemtklein    // threadpool; reallySpawnChild() is most useful when you want to change threadpools.
63b0c7156d5be00509d0f80a8d223d5355122b6a3fcommit-bot@chromium.org    task->run();
64b0c7156d5be00509d0f80a8d223d5355122b6a3fcommit-bot@chromium.org}
65b0c7156d5be00509d0f80a8d223d5355122b6a3fcommit-bot@chromium.org
66ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.orgGpuTask::GpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {}
67ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org
68406654be7a930b484159f5bca107d3b11d8a9edemtkleinvoid GpuTask::run(GrContextFactory* factory) {
6953e0be6d2b76321c2012085a73f1e7b269406c78mtklein    // If the task says skip, or if we're starting a top-level GPU task and we don't want to, skip.
7053e0be6d2b76321c2012085a73f1e7b269406c78mtklein    const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_gpu);
7153e0be6d2b76321c2012085a73f1e7b269406c78mtklein    if (!skip) {
7239e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org        this->start();
73406654be7a930b484159f5bca107d3b11d8a9edemtklein        if (!FLAGS_dryRun) this->draw(factory);
7439e8d93337c7e37d2b09dc710a05a9beefef5c2ccommit-bot@chromium.org        this->finish();
752354f8432a7205571f04f9638a0018fb0b1fb282bsalomon        if (FLAGS_abandonGpuContext) {
76406654be7a930b484159f5bca107d3b11d8a9edemtklein            factory->abandonContexts();
772354f8432a7205571f04f9638a0018fb0b1fb282bsalomon        }
782354f8432a7205571f04f9638a0018fb0b1fb282bsalomon        if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) {
79406654be7a930b484159f5bca107d3b11d8a9edemtklein            factory->destroyContexts();
8018515cf3702131ccc100de8d61a0490f595cf0dfMike Klein        }
81ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    }
82ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org    SkDELETE(this);
8338aeb0fd7a2bdab5e44531d96045dffe25c8e2b0commit-bot@chromium.org}
8438aeb0fd7a2bdab5e44531d96045dffe25c8e2b0commit-bot@chromium.org
85b0c7156d5be00509d0f80a8d223d5355122b6a3fcommit-bot@chromium.orgvoid GpuTask::spawnChild(CpuTask* task) {
86406654be7a930b484159f5bca107d3b11d8a9edemtklein    // Spawn a new task so it runs on the CPU threadpool instead of the GPU one we're on now.
873f032156c8b5d4decb0beccdc2cdbcf91867fa36commit-bot@chromium.org    // It goes on the front of the queue to minimize the time we must hold reference bitmaps in RAM.
88406654be7a930b484159f5bca107d3b11d8a9edemtklein    this->reallySpawnChild(task);
89b0c7156d5be00509d0f80a8d223d5355122b6a3fcommit-bot@chromium.org}
90ef57b7e65330d5f794a513630517907500f1c1d0commit-bot@chromium.org
91d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com}  // namespace DM
92