2013-10-16 13:02:15 +00:00
|
|
|
#include "DMTaskRunner.h"
|
|
|
|
#include "DMTask.h"
|
|
|
|
|
|
|
|
namespace DM {
|
|
|
|
|
2014-02-26 16:31:22 +00:00
|
|
|
|
|
|
|
TaskRunner::TaskRunner(int cputhreads)
|
2013-10-16 13:02:15 +00:00
|
|
|
: fMain(cputhreads)
|
2014-02-26 16:31:22 +00:00
|
|
|
, 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)));
|
|
|
|
}
|
2013-10-16 13:02:15 +00:00
|
|
|
|
|
|
|
void TaskRunner::add(Task* task) {
|
|
|
|
if (task->usesGpu()) {
|
|
|
|
fGpu.add(task);
|
|
|
|
} else {
|
|
|
|
fMain.add(task);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TaskRunner::wait() {
|
2014-02-26 16:31:22 +00:00
|
|
|
// 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)));
|
|
|
|
|
2013-10-16 13:02:15 +00:00
|
|
|
// 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.
|
|
|
|
fGpu.wait();
|
|
|
|
fMain.wait();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace DM
|