#include "DMGpuTask.h" #include "DMComparisonTask.h" #include "DMUtil.h" #include "DMWriteTask.h" #include "SkCommandLineFlags.h" #include "SkGpuDevice.h" #include "SkTLS.h" namespace DM { GpuTask::GpuTask(const char* name, Reporter* reporter, TaskRunner* taskRunner, const skiagm::ExpectationsSource& expectations, skiagm::GMRegistry::Factory gmFactory, SkBitmap::Config config, GrContextFactory::GLContextType contextType, int sampleCount) : Task(reporter, taskRunner) , fGM(gmFactory(NULL)) , fName(UnderJoin(fGM->shortName(), name)) , fExpectations(expectations.get(Png(fName).c_str())) , fConfig(config) , fContextType(contextType) , fSampleCount(sampleCount) {} static void* new_gr_context_factory() { return SkNEW(GrContextFactory); } static void delete_gr_context_factory(void* factory) { SkDELETE((GrContextFactory*) factory); } static GrContextFactory* get_gr_factory() { return reinterpret_cast(SkTLS::Get(&new_gr_context_factory, &delete_gr_context_factory)); } void GpuTask::draw() { GrContext* gr = get_gr_factory()->get(fContextType); // Will be owned by device. SkGpuDevice device(gr, fConfig, SkScalarCeilToInt(fGM->width()), SkScalarCeilToInt(fGM->height()), fSampleCount); SkCanvas canvas(&device); canvas.concat(fGM->getInitialTransform()); fGM->draw(&canvas); canvas.flush(); SkBitmap bitmap; bitmap.setConfig(fConfig, SkScalarCeilToInt(fGM->width()), SkScalarCeilToInt(fGM->height())); canvas.readPixels(&bitmap, 0, 0); // We offload checksum comparison to the main CPU threadpool. // This cuts run time by about 30%. this->spawnChild(SkNEW_ARGS(ComparisonTask, (*this, fExpectations, bitmap))); this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap))); } bool GpuTask::shouldSkip() const { return SkToBool(fGM->getFlags() & skiagm::GM::kSkipGPU_Flag); } } // namespace DM