diff options
Diffstat (limited to 'dm')
-rw-r--r-- | dm/DM.cpp | 32 | ||||
-rw-r--r-- | dm/DMBenchTask.cpp | 10 | ||||
-rw-r--r-- | dm/DMBenchTask.h | 11 | ||||
-rw-r--r-- | dm/DMCpuGMTask.cpp (renamed from dm/DMCpuTask.cpp) | 20 | ||||
-rw-r--r-- | dm/DMCpuGMTask.h (renamed from dm/DMCpuTask.h) | 21 | ||||
-rw-r--r-- | dm/DMExpectationsTask.cpp | 2 | ||||
-rw-r--r-- | dm/DMExpectationsTask.h | 3 | ||||
-rw-r--r-- | dm/DMGpuGMTask.cpp (renamed from dm/DMGpuTask.cpp) | 24 | ||||
-rw-r--r-- | dm/DMGpuGMTask.h (renamed from dm/DMGpuTask.h) | 27 | ||||
-rw-r--r-- | dm/DMPipeTask.cpp | 2 | ||||
-rw-r--r-- | dm/DMPipeTask.h | 3 | ||||
-rw-r--r-- | dm/DMReplayTask.cpp | 2 | ||||
-rw-r--r-- | dm/DMReplayTask.h | 3 | ||||
-rw-r--r-- | dm/DMSerializeTask.cpp | 2 | ||||
-rw-r--r-- | dm/DMSerializeTask.h | 3 | ||||
-rw-r--r-- | dm/DMTask.cpp | 60 | ||||
-rw-r--r-- | dm/DMTask.h | 55 | ||||
-rw-r--r-- | dm/DMTaskRunner.cpp | 45 | ||||
-rw-r--r-- | dm/DMTaskRunner.h | 19 | ||||
-rw-r--r-- | dm/DMTestTask.cpp | 36 | ||||
-rw-r--r-- | dm/DMTestTask.h | 49 | ||||
-rw-r--r-- | dm/DMTileGridTask.cpp | 2 | ||||
-rw-r--r-- | dm/DMTileGridTask.h | 3 | ||||
-rw-r--r-- | dm/DMWriteTask.cpp | 2 | ||||
-rw-r--r-- | dm/DMWriteTask.h | 3 |
25 files changed, 224 insertions, 215 deletions
@@ -12,8 +12,8 @@ #include "gm.h" #include "DMBenchTask.h" -#include "DMCpuTask.h" -#include "DMGpuTask.h" +#include "DMCpuGMTask.h" +#include "DMGpuGMTask.h" #include "DMReporter.h" #include "DMTask.h" #include "DMTaskRunner.h" @@ -28,6 +28,7 @@ using skiatest::Test; using skiatest::TestRegistry; DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS."); +DEFINE_int32(gpuThreads, 1, "Threads for GPU work."); DEFINE_string2(expectations, r, "", "If a directory, compare generated images against images under this path. " "If a file, compare generated images against JSON expectations at this path."); @@ -86,15 +87,15 @@ static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms, } for (int i = 0; i < gms.count(); i++) { for (int j = 0; j < configs.count(); j++) { - START("565", CpuTask, kRGB_565_SkColorType); - START("8888", CpuTask, kPMColor_SkColorType); - START("gpu", GpuTask, native, 0); - START("msaa4", GpuTask, native, 4); - START("msaa16", GpuTask, native, 16); - START("gpunull", GpuTask, null, 0); - START("gpudebug", GpuTask, debug, 0); - START("angle", GpuTask, angle, 0); - START("mesa", GpuTask, mesa, 0); + START("565", CpuGMTask, kRGB_565_SkColorType); + START("8888", CpuGMTask, kPMColor_SkColorType); + START("gpu", GpuGMTask, native, 0); + START("msaa4", GpuGMTask, native, 4); + START("msaa16", GpuGMTask, native, 16); + START("gpunull", GpuGMTask, null, 0); + START("gpudebug", GpuGMTask, debug, 0); + START("angle", GpuGMTask, angle, 0); + START("mesa", GpuGMTask, mesa, 0); } } #undef START @@ -129,7 +130,12 @@ static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests, DM::Reporter* reporter, DM::TaskRunner* tasks) { for (int i = 0; i < tests.count(); i++) { - tasks->add(SkNEW_ARGS(DM::TestTask, (reporter, tasks, tests[i]))); + SkAutoTDelete<Test> test(tests[i](NULL)); + if (test->isGPUTest()) { + tasks->add(SkNEW_ARGS(DM::GpuTestTask, (reporter, tasks, tests[i]))); + } else { + tasks->add(SkNEW_ARGS(DM::CpuTestTask, (reporter, tasks, tests[i]))); + } } } @@ -201,7 +207,7 @@ int tool_main(int argc, char** argv) { SkDebugf("(%d GMs, %d benches) x %d configs, %d tests\n", gms.count(), benches.count(), configs.count(), tests.count()); DM::Reporter reporter; - DM::TaskRunner tasks(FLAGS_threads); + DM::TaskRunner tasks(FLAGS_threads, FLAGS_gpuThreads); kick_off_gms(gms, configs, *expectations, &reporter, &tasks); kick_off_benches(benches, configs, &reporter, &tasks); kick_off_tests(tests, &reporter, &tasks); diff --git a/dm/DMBenchTask.cpp b/dm/DMBenchTask.cpp index 4e251de2e9..30561a407d 100644 --- a/dm/DMBenchTask.cpp +++ b/dm/DMBenchTask.cpp @@ -14,7 +14,7 @@ NonRenderingBenchTask::NonRenderingBenchTask(const char* config, Reporter* reporter, TaskRunner* tasks, BenchRegistry::Factory factory) - : Task(reporter, tasks) + : CpuTask(reporter, tasks) , fBench(factory(NULL)) , fName(bench_name(fBench->getName(), config)) {} @@ -23,7 +23,7 @@ CpuBenchTask::CpuBenchTask(const char* config, TaskRunner* tasks, BenchRegistry::Factory factory, SkColorType colorType) - : Task(reporter, tasks) + : CpuTask(reporter, tasks) , fBench(factory(NULL)) , fName(bench_name(fBench->getName(), config)) , fColorType(colorType) {} @@ -34,7 +34,7 @@ GpuBenchTask::GpuBenchTask(const char* config, BenchRegistry::Factory factory, GrContextFactory::GLContextType contextType, int sampleCount) - : Task(reporter, tasks) + : GpuTask(reporter, tasks) , fBench(factory(NULL)) , fName(bench_name(fBench->getName(), config)) , fContextType(contextType) @@ -70,13 +70,13 @@ void CpuBenchTask::draw() { draw_raster(fBench.get(), fColorType); } -void GpuBenchTask::draw() { +void GpuBenchTask::draw(GrContextFactory* grFactory) { SkImageInfo info = SkImageInfo::Make(fBench->getSize().x(), fBench->getSize().y(), kPMColor_SkColorType, kPremul_SkAlphaType); SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget( - this->getGrContextFactory()->get(fContextType), info, fSampleCount)); + grFactory->get(fContextType), info, fSampleCount)); fBench->preDraw(); fBench->draw(1, surface->getCanvas()); diff --git a/dm/DMBenchTask.h b/dm/DMBenchTask.h index 1e9bc9912e..ac7030b5f0 100644 --- a/dm/DMBenchTask.h +++ b/dm/DMBenchTask.h @@ -12,12 +12,11 @@ namespace DM { -class NonRenderingBenchTask : public Task { +class NonRenderingBenchTask : public CpuTask { public: NonRenderingBenchTask(const char* config, Reporter*, TaskRunner*, BenchRegistry::Factory); virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } @@ -26,12 +25,11 @@ private: const SkString fName; }; -class CpuBenchTask : public Task { +class CpuBenchTask : public CpuTask { public: CpuBenchTask(const char* config, Reporter*, TaskRunner*, BenchRegistry::Factory, SkColorType); virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } @@ -41,7 +39,7 @@ private: const SkColorType fColorType; }; -class GpuBenchTask : public Task { +class GpuBenchTask : public GpuTask { public: GpuBenchTask(const char* config, Reporter*, @@ -50,8 +48,7 @@ public: GrContextFactory::GLContextType, int sampleCount); - virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return true; } + virtual void draw(GrContextFactory*) SK_OVERRIDE; virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } diff --git a/dm/DMCpuTask.cpp b/dm/DMCpuGMTask.cpp index acbe8d2185..6ab0014fd5 100644 --- a/dm/DMCpuTask.cpp +++ b/dm/DMCpuGMTask.cpp @@ -1,4 +1,4 @@ -#include "DMCpuTask.h" +#include "DMCpuGMTask.h" #include "DMExpectationsTask.h" #include "DMPipeTask.h" #include "DMReplayTask.h" @@ -9,13 +9,13 @@ namespace DM { -CpuTask::CpuTask(const char* config, - Reporter* reporter, - TaskRunner* taskRunner, - const Expectations& expectations, - skiagm::GMRegistry::Factory gmFactory, - SkColorType colorType) - : Task(reporter, taskRunner) +CpuGMTask::CpuGMTask(const char* config, + Reporter* reporter, + TaskRunner* taskRunner, + const Expectations& expectations, + skiagm::GMRegistry::Factory gmFactory, + SkColorType colorType) + : CpuTask(reporter, taskRunner) , fGMFactory(gmFactory) , fGM(fGMFactory(NULL)) , fName(UnderJoin(fGM->getName(), config)) @@ -23,7 +23,7 @@ CpuTask::CpuTask(const char* config, , fColorType(colorType) {} -void CpuTask::draw() { +void CpuGMTask::draw() { SkBitmap bitmap; SetupBitmap(fColorType, fGM.get(), &bitmap); @@ -47,7 +47,7 @@ void CpuTask::draw() { #undef SPAWN } -bool CpuTask::shouldSkip() const { +bool CpuGMTask::shouldSkip() const { if (kRGB_565_SkColorType == fColorType && (fGM->getFlags() & skiagm::GM::kSkip565_Flag)) { return true; } diff --git a/dm/DMCpuTask.h b/dm/DMCpuGMTask.h index 0ae112f754..7712da88d0 100644 --- a/dm/DMCpuTask.h +++ b/dm/DMCpuGMTask.h @@ -1,5 +1,5 @@ -#ifndef DMCpuTask_DEFINED -#define DMCpuTask_DEFINED +#ifndef DMCpuGMTask_DEFINED +#define DMCpuGMTask_DEFINED #include "DMExpectations.h" #include "DMReporter.h" @@ -15,17 +15,16 @@ namespace DM { -class CpuTask : public Task { +class CpuGMTask : public CpuTask { public: - CpuTask(const char* config, - Reporter*, - TaskRunner*, - const Expectations&, - skiagm::GMRegistry::Factory, - SkColorType); + CpuGMTask(const char* config, + Reporter*, + TaskRunner*, + const Expectations&, + skiagm::GMRegistry::Factory, + SkColorType); virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } @@ -39,4 +38,4 @@ private: } // namespace DM -#endif // DMCpuTask_DEFINED +#endif // DMCpuGMTask_DEFINED diff --git a/dm/DMExpectationsTask.cpp b/dm/DMExpectationsTask.cpp index cb92486269..e29257afbd 100644 --- a/dm/DMExpectationsTask.cpp +++ b/dm/DMExpectationsTask.cpp @@ -6,7 +6,7 @@ namespace DM { ExpectationsTask::ExpectationsTask(const Task& parent, const Expectations& expectations, SkBitmap bitmap) - : Task(parent) + : CpuTask(parent) , fName(parent.name()) // Masquerade as parent so failures are attributed to it. , fExpectations(expectations) , fBitmap(bitmap) diff --git a/dm/DMExpectationsTask.h b/dm/DMExpectationsTask.h index cf76fc8bdf..7000de4b68 100644 --- a/dm/DMExpectationsTask.h +++ b/dm/DMExpectationsTask.h @@ -10,12 +10,11 @@ namespace DM { // ExpectationsTask compares an SkBitmap against some Expectations. // Moving this off the GPU threadpool is a nice (~30%) runtime win. -class ExpectationsTask : public Task { +class ExpectationsTask : public CpuTask { public: ExpectationsTask(const Task& parent, const Expectations&, SkBitmap); virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE { return false; } virtual SkString name() const SK_OVERRIDE { return fName; } diff --git a/dm/DMGpuTask.cpp b/dm/DMGpuGMTask.cpp index c285d88fd7..cffa2291c5 100644 --- a/dm/DMGpuTask.cpp +++ b/dm/DMGpuGMTask.cpp @@ -1,4 +1,4 @@ -#include "DMGpuTask.h" +#include "DMGpuGMTask.h" #include "DMExpectationsTask.h" #include "DMUtil.h" @@ -9,14 +9,14 @@ namespace DM { -GpuTask::GpuTask(const char* config, - Reporter* reporter, - TaskRunner* taskRunner, - const Expectations& expectations, - skiagm::GMRegistry::Factory gmFactory, - GrContextFactory::GLContextType contextType, - int sampleCount) - : Task(reporter, taskRunner) +GpuGMTask::GpuGMTask(const char* config, + Reporter* reporter, + TaskRunner* taskRunner, + const Expectations& expectations, + skiagm::GMRegistry::Factory gmFactory, + GrContextFactory::GLContextType contextType, + int sampleCount) + : GpuTask(reporter, taskRunner) , fGM(gmFactory(NULL)) , fName(UnderJoin(fGM->getName(), config)) , fExpectations(expectations) @@ -24,13 +24,13 @@ GpuTask::GpuTask(const char* config, , fSampleCount(sampleCount) {} -void GpuTask::draw() { +void GpuGMTask::draw(GrContextFactory* grFactory) { SkImageInfo info = SkImageInfo::Make(SkScalarCeilToInt(fGM->width()), SkScalarCeilToInt(fGM->height()), kPMColor_SkColorType, kPremul_SkAlphaType); SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget( - this->getGrContextFactory()->get(fContextType), info, fSampleCount)); + grFactory->get(fContextType), info, fSampleCount)); SkCanvas* canvas = surface->getCanvas(); canvas->concat(fGM->getInitialTransform()); @@ -49,7 +49,7 @@ void GpuTask::draw() { this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap))); } -bool GpuTask::shouldSkip() const { +bool GpuGMTask::shouldSkip() const { return SkToBool(fGM->getFlags() & skiagm::GM::kSkipGPU_Flag); } diff --git a/dm/DMGpuTask.h b/dm/DMGpuGMTask.h index f74950c088..141994e6d3 100644 --- a/dm/DMGpuTask.h +++ b/dm/DMGpuGMTask.h @@ -1,5 +1,5 @@ -#ifndef DMGpuTask_DEFINED -#define DMGpuTask_DEFINED +#ifndef DMGpuGMTask_DEFINED +#define DMGpuGMTask_DEFINED #include "DMExpectations.h" #include "DMReporter.h" @@ -15,18 +15,17 @@ namespace DM { -class GpuTask : public Task { +class GpuGMTask : public GpuTask { public: - GpuTask(const char* config, - Reporter*, - TaskRunner*, - const Expectations&, - skiagm::GMRegistry::Factory, - GrContextFactory::GLContextType, - int sampleCount); - - virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return true; } + GpuGMTask(const char* config, + Reporter*, + TaskRunner*, + const Expectations&, + skiagm::GMRegistry::Factory, + GrContextFactory::GLContextType, + int sampleCount); + + virtual void draw(GrContextFactory*) SK_OVERRIDE; virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } @@ -40,4 +39,4 @@ private: } // namespace DM -#endif // DMGpuTask_DEFINED +#endif // DMGpuGMTask_DEFINED diff --git a/dm/DMPipeTask.cpp b/dm/DMPipeTask.cpp index 163f1e64db..513594e0ea 100644 --- a/dm/DMPipeTask.cpp +++ b/dm/DMPipeTask.cpp @@ -38,7 +38,7 @@ PipeTask::PipeTask(const Task& parent, SkBitmap reference, bool crossProcess, bool sharedAddressSpace) - : Task(parent) + : CpuTask(parent) , fFlags(get_flags(crossProcess, sharedAddressSpace)) , fName(UnderJoin(parent.name().c_str(), get_name(fFlags))) , fGM(gm) diff --git a/dm/DMPipeTask.h b/dm/DMPipeTask.h index 23bbfef114..c251d08328 100644 --- a/dm/DMPipeTask.h +++ b/dm/DMPipeTask.h @@ -11,7 +11,7 @@ namespace DM { -class PipeTask : public Task { +class PipeTask : public CpuTask { public: PipeTask(const Task& parent, // PipeTask must be a child task. Pass its parent here. @@ -21,7 +21,6 @@ public: bool sharedAddressSpace); // If cross process, should it assume shared address space? virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } diff --git a/dm/DMReplayTask.cpp b/dm/DMReplayTask.cpp index 3d010358c2..c915be20d2 100644 --- a/dm/DMReplayTask.cpp +++ b/dm/DMReplayTask.cpp @@ -14,7 +14,7 @@ ReplayTask::ReplayTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, bool useRTree) - : Task(parent) + : CpuTask(parent) , fName(UnderJoin(parent.name().c_str(), useRTree ? "rtree" : "replay")) , fGM(gm) , fReference(reference) diff --git a/dm/DMReplayTask.h b/dm/DMReplayTask.h index 1245009923..78bef0dfd8 100644 --- a/dm/DMReplayTask.h +++ b/dm/DMReplayTask.h @@ -11,7 +11,7 @@ namespace DM { -class ReplayTask : public Task { +class ReplayTask : public CpuTask { public: ReplayTask(const Task& parent, // ReplayTask must be a child task. Pass its parent here. @@ -20,7 +20,6 @@ public: bool useRTree); // Record with an RTree? virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } diff --git a/dm/DMSerializeTask.cpp b/dm/DMSerializeTask.cpp index 7e45d49be5..4f55de57d5 100644 --- a/dm/DMSerializeTask.cpp +++ b/dm/DMSerializeTask.cpp @@ -13,7 +13,7 @@ namespace DM { SerializeTask::SerializeTask(const Task& parent, skiagm::GM* gm, SkBitmap reference) - : Task(parent) + : CpuTask(parent) , fName(UnderJoin(parent.name().c_str(), "serialize")) , fGM(gm) , fReference(reference) diff --git a/dm/DMSerializeTask.h b/dm/DMSerializeTask.h index 30a4303b06..1f8b83632b 100644 --- a/dm/DMSerializeTask.h +++ b/dm/DMSerializeTask.h @@ -11,7 +11,7 @@ namespace DM { -class SerializeTask : public Task { +class SerializeTask : public CpuTask { public: SerializeTask(const Task& parent, @@ -19,7 +19,6 @@ public: SkBitmap reference); virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } diff --git a/dm/DMTask.cpp b/dm/DMTask.cpp index d26971c890..1c4cc25693 100644 --- a/dm/DMTask.cpp +++ b/dm/DMTask.cpp @@ -1,53 +1,59 @@ #include "DMTask.h" - #include "DMTaskRunner.h" -#include "DMUtil.h" -#include "SkBitmap.h" -#include "SkCommandLineFlags.h" namespace DM { Task::Task(Reporter* reporter, TaskRunner* taskRunner) - : fReporter(reporter), fTaskRunner(taskRunner), fDepth(0) { + : fReporter(reporter) + , fTaskRunner(taskRunner) + , fDepth(0) { fReporter->start(); } Task::Task(const Task& parent) - : INHERITED(parent) - , fReporter(parent.fReporter) + : fReporter(parent.fReporter) , fTaskRunner(parent.fTaskRunner) - , fDepth(parent.depth()+1) { + , fDepth(parent.depth() + 1) { fReporter->start(); } -Task::~Task() {} - -void Task::run() { - if (!this->shouldSkip()) { - this->draw(); +void Task::fail(const char* msg) { + SkString failure(this->name()); + if (msg) { + failure.appendf(": %s", msg); } + fReporter->fail(failure); +} + +void Task::finish() { fReporter->finish(this->name()); - delete this; } -void Task::spawnChild(Task* task) { - if (!task->usesGpu()) { - fTaskRunner->add(task); - } else { - SkDEBUGFAIL("Sorry, we can't spawn GPU tasks. :( See comment in TaskRunner::wait()."); - } +void Task::spawnChild(CpuTask* task) { + fTaskRunner->add(task); } -void Task::fail(const char* msg) { - SkString failure(this->name()); - if (msg) { - failure.appendf(": %s", msg); +CpuTask::CpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {} +CpuTask::CpuTask(const Task& parent) : Task(parent) {} + +void CpuTask::run() { + if (!this->shouldSkip()) { + this->draw(); } - fReporter->fail(failure); + this->finish(); + SkDELETE(this); } -GrContextFactory* Task::getGrContextFactory() const { - return fTaskRunner->getGrContextFactory(); +GpuTask::GpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {} + +void GpuTask::run(GrContextFactory& factory) { + if (!this->shouldSkip()) { + this->draw(&factory); + } + this->finish(); + SkDELETE(this); } + + } // namespace DM diff --git a/dm/DMTask.h b/dm/DMTask.h index e8598df85e..cad8234c05 100644 --- a/dm/DMTask.h +++ b/dm/DMTask.h @@ -4,28 +4,21 @@ #include "DMReporter.h" #include "GrContextFactory.h" #include "SkRunnable.h" -#include "SkThreadPool.h" -// DM will run() these tasks on one of two threadpools, depending on the result -// of usesGpu(). The subclasses can call fail() to mark this task as failed, -// or make any number of spawnChild() calls to kick off dependent tasks. +// DM will run() these tasks on one of two threadpools. +// Subclasses can call fail() to mark this task as failed, or make any number of spawnChild() calls +// to kick off dependent tasks. // -// Task deletes itself when run. +// Tasks delete themselves when run. namespace DM { class TaskRunner; -class Task : public SkRunnable { -public: - Task(Reporter* reporter, TaskRunner* taskRunner); - Task(const Task& parent); - virtual ~Task(); - - void run() SK_OVERRIDE; +class CpuTask; - virtual void draw() = 0; - virtual bool usesGpu() const = 0; +class Task { +public: virtual bool shouldSkip() const = 0; virtual SkString name() const = 0; @@ -34,19 +27,37 @@ public: int depth() const { return fDepth; } protected: - void spawnChild(Task* task); - void fail(const char* msg = NULL); + Task(Reporter* reporter, TaskRunner* taskRunner); + Task(const Task& parent); + virtual ~Task() {} - // This can only be safely called from a GPU task's draw() method. - GrContextFactory* getGrContextFactory() const; + void fail(const char* msg = NULL); + void finish(); + void spawnChild(CpuTask* task); // For now we don't allow GPU child tasks. private: - // Both unowned. - Reporter* fReporter; - TaskRunner* fTaskRunner; + Reporter* fReporter; // Unowned. + TaskRunner* fTaskRunner; // Unowned. int fDepth; +}; + +class CpuTask : public Task, public SkRunnable { +public: + CpuTask(Reporter* reporter, TaskRunner* taskRunner); + CpuTask(const Task& parent); + virtual ~CpuTask() {} + + void run() SK_OVERRIDE; + virtual void draw() = 0; +}; + +class GpuTask : public Task, public SkTRunnable<GrContextFactory> { + public: + GpuTask(Reporter* reporter, TaskRunner* taskRunner); + virtual ~GpuTask() {} - typedef SkRunnable INHERITED; + void run(GrContextFactory&) SK_OVERRIDE; + virtual void draw(GrContextFactory*) = 0; }; } // namespace DM diff --git a/dm/DMTaskRunner.cpp b/dm/DMTaskRunner.cpp index bd53ce615a..e0bd977288 100644 --- a/dm/DMTaskRunner.cpp +++ b/dm/DMTaskRunner.cpp @@ -3,48 +3,19 @@ namespace DM { +TaskRunner::TaskRunner(int cpuThreads, int gpuThreads) : fCpu(cpuThreads), fGpu(gpuThreads) {} -TaskRunner::TaskRunner(int cputhreads) - : fMain(cputhreads) - , fGpu(1) { - // Enqueue a task on the GPU thread to create a GrContextFactory. - struct Create : public SkRunnable { - Create(GrContextFactory** ptr) : fPtr(ptr) {} - void run() SK_OVERRIDE { - *fPtr = SkNEW(GrContextFactory); - delete this; - } - GrContextFactory** fPtr; - }; - fGpu.add(SkNEW_ARGS(Create, (&fGrContextFactory))); -} +void TaskRunner::add(CpuTask* task) { fCpu.add(task); } -void TaskRunner::add(Task* task) { - if (task->usesGpu()) { - fGpu.add(task); - } else { - fMain.add(task); - } -} +void TaskRunner::add(GpuTask* task) { fGpu.add(task); } void TaskRunner::wait() { - // Enqueue a task on the GPU thread to destroy the GrContextFactory. - struct Delete : public SkRunnable { - Delete(GrContextFactory* ptr) : fPtr(ptr) {} - void run() SK_OVERRIDE { - delete fPtr; - delete this; - } - GrContextFactory* fPtr; - }; - fGpu.add(SkNEW_ARGS(Delete, (fGrContextFactory))); - - // These wait calls block until the threadpool is done. We don't allow - // children to spawn new GPU tasks so we can wait for that first knowing - // we'll never try to add to it later. Same can't be said of fMain: fGpu - // and fMain can both add tasks to fMain, so we have to wait for that last. + // These wait calls block until each threadpool is done. We don't allow + // spawning new child GPU tasks, so we can wait for that first knowing + // we'll never try to add to it later. Same can't be said of the CPU pool: + // both CPU and GPU tasks can spawn off new CPU work, so we wait for that last. fGpu.wait(); - fMain.wait(); + fCpu.wait(); } } // namespace DM diff --git a/dm/DMTaskRunner.h b/dm/DMTaskRunner.h index 8af1b63719..c7b40588e9 100644 --- a/dm/DMTaskRunner.h +++ b/dm/DMTaskRunner.h @@ -5,26 +5,25 @@ #include "SkThreadPool.h" #include "SkTypes.h" -// TaskRunner runs Tasks on one of two threadpools depending on the Task's usesGpu() method. This -// lets us drive the GPU from a single thread while parallelizing CPU-bound work. +// TaskRunner runs Tasks on one of two threadpools depending on the need for a GrContextFactory. +// It's typically a good idea to run fewer GPU threads than CPU threads (go nuts with those). namespace DM { -class Task; +class CpuTask; +class GpuTask; class TaskRunner : SkNoncopyable { public: - explicit TaskRunner(int cputhreads); + explicit TaskRunner(int cpuThreads, int gpuThreads); - void add(Task* task); + void add(CpuTask* task); + void add(GpuTask* task); void wait(); - // This can only be safely called from a GPU task's draw() method. - GrContextFactory* getGrContextFactory() const { return fGrContextFactory; } - private: - SkThreadPool fMain, fGpu; - GrContextFactory* fGrContextFactory; // Created and destroyed on fGpu threadpool. + SkTThreadPool<void> fCpu; + SkTThreadPool<GrContextFactory> fGpu; }; } // namespace DM diff --git a/dm/DMTestTask.cpp b/dm/DMTestTask.cpp index 32a698c673..6c3fcedf54 100644 --- a/dm/DMTestTask.cpp +++ b/dm/DMTestTask.cpp @@ -8,23 +8,32 @@ DEFINE_bool2(pathOpsVerbose, V, false, "Tell pathOps tests to be verbose.") namespace DM { +bool TestReporter::allowExtendedTest() const { return FLAGS_pathOpsExtended; } +bool TestReporter::allowThreaded() const { return !FLAGS_pathOpsSingleThread; } +bool TestReporter::verbose() const { return FLAGS_pathOpsVerbose; } + static SkString test_name(const char* name) { SkString result("test "); result.append(name); return result; } -TestTask::TestTask(Reporter* reporter, - TaskRunner* taskRunner, - skiatest::TestRegistry::Factory factory) - : Task(reporter, taskRunner) +CpuTestTask::CpuTestTask(Reporter* reporter, + TaskRunner* taskRunner, + skiatest::TestRegistry::Factory factory) + : CpuTask(reporter, taskRunner) , fTest(factory(NULL)) , fName(test_name(fTest->getName())) {} -void TestTask::draw() { - if (this->usesGpu()) { - fTest->setGrContextFactory(this->getGrContextFactory()); - } +GpuTestTask::GpuTestTask(Reporter* reporter, + TaskRunner* taskRunner, + skiatest::TestRegistry::Factory factory) + : GpuTask(reporter, taskRunner) + , fTest(factory(NULL)) + , fName(test_name(fTest->getName())) {} + + +void CpuTestTask::draw() { fTest->setReporter(&fTestReporter); fTest->run(); if (!fTest->passed()) { @@ -32,8 +41,13 @@ void TestTask::draw() { } } -bool TestTask::TestReporter::allowExtendedTest() const { return FLAGS_pathOpsExtended; } -bool TestTask::TestReporter::allowThreaded() const { return !FLAGS_pathOpsSingleThread; } -bool TestTask::TestReporter::verbose() const { return FLAGS_pathOpsVerbose; } +void GpuTestTask::draw(GrContextFactory* grFactory) { + fTest->setGrContextFactory(grFactory); + fTest->setReporter(&fTestReporter); + fTest->run(); + if (!fTest->passed()) { + this->fail(fTestReporter.failure()); + } +} } // namespace DM diff --git a/dm/DMTestTask.h b/dm/DMTestTask.h index 49a8e773b6..87f59209b2 100644 --- a/dm/DMTestTask.h +++ b/dm/DMTestTask.h @@ -11,34 +11,47 @@ // Runs a unit test. namespace DM { -class TestTask : public Task { +class TestReporter : public skiatest::Reporter { public: - TestTask(Reporter*, TaskRunner*, skiatest::TestRegistry::Factory); + TestReporter() {} + + const char* failure() const { return fFailure.c_str(); } + +private: + virtual bool allowExtendedTest() const SK_OVERRIDE; + virtual bool allowThreaded() const SK_OVERRIDE; + virtual bool verbose() const SK_OVERRIDE; + + virtual void onReportFailed(const SkString& desc) SK_OVERRIDE { + fFailure = desc; + } + + SkString fFailure; +}; + +class CpuTestTask : public CpuTask { +public: + CpuTestTask(Reporter*, TaskRunner*, skiatest::TestRegistry::Factory); virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return fTest->isGPUTest(); } virtual bool shouldSkip() const SK_OVERRIDE { return false; } virtual SkString name() const SK_OVERRIDE { return fName; } private: - class TestReporter : public skiatest::Reporter { - public: - TestReporter() {} - - const char* failure() const { return fFailure.c_str(); } - - private: - virtual bool allowExtendedTest() const SK_OVERRIDE; - virtual bool allowThreaded() const SK_OVERRIDE; - virtual bool verbose() const SK_OVERRIDE; + TestReporter fTestReporter; + SkAutoTDelete<skiatest::Test> fTest; + const SkString fName; +}; - virtual void onReportFailed(const SkString& desc) SK_OVERRIDE { - fFailure = desc; - } +class GpuTestTask : public GpuTask { +public: + GpuTestTask(Reporter*, TaskRunner*, skiatest::TestRegistry::Factory); - SkString fFailure; - }; + virtual void draw(GrContextFactory*) SK_OVERRIDE; + virtual bool shouldSkip() const SK_OVERRIDE { return false; } + virtual SkString name() const SK_OVERRIDE { return fName; } +private: TestReporter fTestReporter; SkAutoTDelete<skiatest::Test> fTest; const SkString fName; diff --git a/dm/DMTileGridTask.cpp b/dm/DMTileGridTask.cpp index beffbb0371..f9cac07de3 100644 --- a/dm/DMTileGridTask.cpp +++ b/dm/DMTileGridTask.cpp @@ -12,7 +12,7 @@ DEFINE_bool(tileGrid, false, "If true, run picture replay tests with a tile grid namespace DM { TileGridTask::TileGridTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, SkISize tileSize) - : Task(parent) + : CpuTask(parent) , fName(UnderJoin(parent.name().c_str(), "tilegrid")) , fGM(gm) , fReference(reference) diff --git a/dm/DMTileGridTask.h b/dm/DMTileGridTask.h index 4a522b956c..911a1c52a1 100644 --- a/dm/DMTileGridTask.h +++ b/dm/DMTileGridTask.h @@ -11,7 +11,7 @@ namespace DM { -class TileGridTask : public Task { +class TileGridTask : public CpuTask { public: TileGridTask(const Task& parent, // TileGridTask must be a child task. Pass its parent here. @@ -20,7 +20,6 @@ public: SkISize tileSize); // Tile size to use. virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } diff --git a/dm/DMWriteTask.cpp b/dm/DMWriteTask.cpp index 5adb1d0437..e30cbdbf85 100644 --- a/dm/DMWriteTask.cpp +++ b/dm/DMWriteTask.cpp @@ -26,7 +26,7 @@ static int split_suffixes(int N, const char* name, SkTArray<SkString>* out) { return consumed; } -WriteTask::WriteTask(const Task& parent, SkBitmap bitmap) : Task(parent), fBitmap(bitmap) { +WriteTask::WriteTask(const Task& parent, SkBitmap bitmap) : CpuTask(parent), fBitmap(bitmap) { const int suffixes = parent.depth() + 1; const SkString& name = parent.name(); const int totalSuffixLength = split_suffixes(suffixes, name.c_str(), &fSuffixes); diff --git a/dm/DMWriteTask.h b/dm/DMWriteTask.h index 49a5c746a6..839abd7ef1 100644 --- a/dm/DMWriteTask.h +++ b/dm/DMWriteTask.h @@ -12,14 +12,13 @@ namespace DM { -class WriteTask : public Task { +class WriteTask : public CpuTask { public: WriteTask(const Task& parent, // WriteTask must be a child Task. Pass its parent here. SkBitmap bitmap); // Bitmap to write. virtual void draw() SK_OVERRIDE; - virtual bool usesGpu() const SK_OVERRIDE { return false; } virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE; |