diff options
Diffstat (limited to 'chromium/third_party/skia/dm')
-rw-r--r-- | chromium/third_party/skia/dm/DM.cpp | 159 | ||||
-rw-r--r-- | chromium/third_party/skia/dm/DMGpuTestProcs.cpp | 5 | ||||
-rw-r--r-- | chromium/third_party/skia/dm/DMSrcSink.cpp | 248 | ||||
-rw-r--r-- | chromium/third_party/skia/dm/DMSrcSink.h | 52 |
4 files changed, 295 insertions, 169 deletions
diff --git a/chromium/third_party/skia/dm/DM.cpp b/chromium/third_party/skia/dm/DM.cpp index d4df03d9a11..1a2e059a04f 100644 --- a/chromium/third_party/skia/dm/DM.cpp +++ b/chromium/third_party/skia/dm/DM.cpp @@ -154,7 +154,6 @@ static DEFINE_bool(rasterize_pdf, false, "Rasterize PDFs when possible."); static DEFINE_bool(runVerifiers, false, "if true, run SkQP-style verification of GM-produced images."); - #if defined(__MSVC_RUNTIME_CHECKS) #include <rtcapi.h> int RuntimeCheckErrorFunc(int errorType, const char* filename, int linenumber, @@ -206,13 +205,13 @@ static void info(const char* fmt) { } } -static SkTArray<SkString> gFailures; +static SkTArray<SkString>* gFailures = new SkTArray<SkString>; static void fail(const SkString& err) { static SkSpinlock mutex; SkAutoSpinlock lock(mutex); SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); - gFailures.push_back(err); + gFailures->push_back(err); } struct Running { @@ -231,19 +230,19 @@ static void dump_json() { } // We use a spinlock to make locking this in a signal handler _somewhat_ safe. -static SkSpinlock gMutex; -static int gPending; -static SkTArray<Running> gRunning; +static SkSpinlock* gMutex = new SkSpinlock; +static int gPending; +static SkTArray<Running>* gRunning = new SkTArray<Running>; static void done(const char* config, const char* src, const char* srcOptions, const char* name) { SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); vlog("done %s\n", id.c_str()); int pending; { - SkAutoSpinlock lock(gMutex); - for (int i = 0; i < gRunning.count(); i++) { - if (gRunning[i].id == id) { - gRunning.removeShuffle(i); + SkAutoSpinlock lock(*gMutex); + for (int i = 0; i < gRunning->count(); i++) { + if (gRunning->at(i).id == id) { + gRunning->removeShuffle(i); break; } } @@ -258,10 +257,10 @@ static void done(const char* config, const char* src, const char* srcOptions, co int curr = sk_tools::getCurrResidentSetSizeMB(), peak = sk_tools::getMaxResidentSetSizeMB(); - SkAutoSpinlock lock(gMutex); + SkAutoSpinlock lock(*gMutex); info("\n%dMB RAM, %dMB peak, %d queued, %d active:\n", - curr, peak, gPending - gRunning.count(), gRunning.count()); - for (auto& task : gRunning) { + curr, peak, gPending - gRunning->count(), gRunning->count()); + for (auto& task : *gRunning) { task.dump(); } } @@ -270,14 +269,14 @@ static void done(const char* config, const char* src, const char* srcOptions, co static void start(const char* config, const char* src, const char* srcOptions, const char* name) { SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); vlog("start %s\n", id.c_str()); - SkAutoSpinlock lock(gMutex); - gRunning.push_back({id,SkGetThreadID()}); + SkAutoSpinlock lock(*gMutex); + gRunning->push_back({id,SkGetThreadID()}); } static void find_culprit() { // Assumes gMutex is locked. SkThreadID thisThread = SkGetThreadID(); - for (auto& task : gRunning) { + for (auto& task : *gRunning) { if (task.thread == thisThread) { info("Likely culprit:\n"); task.dump(); @@ -300,7 +299,7 @@ static void find_culprit() { #undef _ }; - SkAutoSpinlock lock(gMutex); + SkAutoSpinlock lock(*gMutex); const DWORD code = e->ExceptionRecord->ExceptionCode; info("\nCaught exception %u", code); @@ -310,7 +309,7 @@ static void find_culprit() { } } info(", was running:\n"); - for (auto& task : gRunning) { + for (auto& task : *gRunning) { task.dump(); } find_culprit(); @@ -339,13 +338,13 @@ static void find_culprit() { static void (*previous_handler[max_of(SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGSEGV,SIGTERM)+1])(int); static void crash_handler(int sig) { - SkAutoSpinlock lock(gMutex); + SkAutoSpinlock lock(*gMutex); info("\nCaught signal %d [%s] (%dMB RAM, peak %dMB), was running:\n", sig, strsignal(sig), sk_tools::getCurrResidentSetSizeMB(), sk_tools::getMaxResidentSetSizeMB()); - for (auto& task : gRunning) { + for (auto& task : *gRunning) { task.dump(); } find_culprit(); @@ -398,10 +397,10 @@ struct Gold : public SkString { } }; }; -static SkTHashSet<Gold, Gold::Hash> gGold; +static SkTHashSet<Gold, Gold::Hash>* gGold = new SkTHashSet<Gold, Gold::Hash>; static void add_gold(JsonWriter::BitmapResult r) { - gGold.add(Gold(r.config, r.sourceType, r.sourceOptions, r.name, r.md5)); + gGold->add(Gold(r.config, r.sourceType, r.sourceOptions, r.name, r.md5)); } static void gather_gold() { @@ -417,12 +416,12 @@ static void gather_gold() { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #if defined(SK_BUILD_FOR_WIN) - static const char* kNewline = "\r\n"; + static constexpr char kNewline[] = "\r\n"; #else - static const char* kNewline = "\n"; + static constexpr char kNewline[] = "\n"; #endif -static SkTHashSet<SkString> gUninterestingHashes; +static SkTHashSet<SkString>* gUninterestingHashes = new SkTHashSet<SkString>; static void gather_uninteresting_hashes() { if (!FLAGS_uninterestingHashesFile.isEmpty()) { @@ -439,10 +438,10 @@ static void gather_uninteresting_hashes() { SkTArray<SkString> hashes; SkStrSplit(contents.c_str(), kNewline, &hashes); for (const SkString& hash : hashes) { - gUninterestingHashes.add(hash); + gUninterestingHashes->add(hash); } info("FYI: loaded %d distinct uninteresting hashes from %d lines\n", - gUninterestingHashes.count(), hashes.count()); + gUninterestingHashes->count(), hashes.count()); } } @@ -457,10 +456,10 @@ struct TaggedSink : public std::unique_ptr<Sink> { SkString tag; }; -static const bool kMemcpyOK = true; +static constexpr bool kMemcpyOK = true; -static SkTArray<TaggedSrc, kMemcpyOK> gSrcs; -static SkTArray<TaggedSink, kMemcpyOK> gSinks; +static SkTArray<TaggedSrc, kMemcpyOK>* gSrcs = new SkTArray<TaggedSrc, kMemcpyOK>; +static SkTArray<TaggedSink, kMemcpyOK>* gSinks = new SkTArray<TaggedSink, kMemcpyOK>; static bool in_shard() { static int N = 0; @@ -471,7 +470,7 @@ static void push_src(const char* tag, ImplicitString options, Src* s) { std::unique_ptr<Src> src(s); if (in_shard() && FLAGS_src.contains(tag) && !CommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) { - TaggedSrc& s = gSrcs.push_back(); + TaggedSrc& s = gSrcs->push_back(); s.reset(src.release()); s.tag = tag; s.options = options; @@ -611,6 +610,7 @@ static void push_image_gen_src(Path path, ImageGenSrc::Mode mode, SkAlphaType al push_src("image", folder, src); } +#ifdef SK_ENABLE_ANDROID_UTILS static void push_brd_src(Path path, CodecSrc::DstColorType dstColorType, BRDSrc::Mode mode, uint32_t sampleSize) { SkString folder("brd_android_codec"); @@ -669,6 +669,7 @@ static void push_brd_srcs(Path path, bool gray) { } } } +#endif // SK_ENABLE_ANDROID_UTILS static void push_codec_srcs(Path path) { sk_sp<SkData> encoded(SkData::MakeFromFileName(path.c_str())); @@ -797,6 +798,7 @@ static void push_codec_srcs(Path path) { } } +#ifdef SK_ENABLE_ANDROID_UTILS static const char* const brdExts[] = { "jpg", "jpeg", "png", "webp", "JPG", "JPEG", "PNG", "WEBP", @@ -808,6 +810,7 @@ static void push_codec_srcs(Path path) { break; } } +#endif } // Push image generator GPU test. @@ -902,7 +905,7 @@ static void push_sink(const SkCommandLineConfig& config, Sink* s) { // Try a simple Src as a canary. If it fails, skip this sink. struct : public Src { - Result draw(SkCanvas* c) const override { + Result draw(GrContext*, SkCanvas* c) const override { c->drawRect(SkRect::MakeWH(1,1), SkPaint()); return Result::Ok(); } @@ -919,7 +922,7 @@ static void push_sink(const SkCommandLineConfig& config, Sink* s) { exit(1); } - TaggedSink& ts = gSinks.push_back(); + TaggedSink& ts = gSinks->push_back(); ts.reset(sink.release()); ts.tag = config.getTag(); } @@ -946,6 +949,8 @@ static Sink* create_sink(const GrContextOptions& grCtxOptions, const SkCommandLi return new GPUPrecompileTestingSink(gpuConfig, grCtxOptions); } else if (gpuConfig->getUseDDLSink()) { return new GPUDDLSink(gpuConfig, grCtxOptions); + } else if (gpuConfig->getOOPRish()) { + return new GPUOOPRSink(gpuConfig, grCtxOptions); } else { return new GPUSink(gpuConfig, grCtxOptions); } @@ -1067,7 +1072,7 @@ static bool gather_sinks(const GrContextOptions& grCtxOptions, bool defaultConfi // If we're using the default configs, we're okay. defaultConfigs || // Otherwise, make sure that all specified configs have become sinks. - configs.count() == gSinks.count()) { + configs.count() == gSinks->count()) { return true; } return false; @@ -1098,7 +1103,7 @@ static bool is_blacklisted(const char* sink, const char* src, // Even when a Task Sink reports to be non-threadsafe (e.g. GPU), we know things like // .png encoding are definitely thread safe. This lets us offload that work to CPU threads. -static SkTaskGroup gDefinitelyThreadSafeWork; +static SkTaskGroup* gDefinitelyThreadSafeWork = new SkTaskGroup; // The finest-grained unit of work we can run: draw a single Src into a single Sink, // report any errors, and perhaps write out the output: a .png of the bitmap, or a raw stream. @@ -1146,7 +1151,7 @@ struct Task { // We're likely switching threads here, so we must capture by value, [=] or [foo,bar]. SkStreamAsset* data = stream.detachAsStream().release(); - gDefinitelyThreadSafeWork.add([task,name,bitmap,data]{ + gDefinitelyThreadSafeWork->add([task,name,bitmap,data]{ std::unique_ptr<SkStreamAsset> ownedData(data); std::unique_ptr<HashAndEncode> hashAndEncode; @@ -1168,8 +1173,8 @@ struct Task { } if (!FLAGS_readPath.isEmpty() && - !gGold.contains(Gold(task.sink.tag, task.src.tag, - task.src.options, name, md5))) { + !gGold->contains(Gold(task.sink.tag, task.src.tag, + task.src.options, name, md5))) { fail(SkStringPrintf("%s not found for %s %s %s %s in %s", md5.c_str(), task.sink.tag.c_str(), @@ -1204,21 +1209,18 @@ struct Task { h = (int)CGRectGetHeight(bounds); SkBitmap rasterized; - rasterized.allocPixels( - SkImageInfo::Make(w,h, kRGBA_8888_SkColorType, kPremul_SkAlphaType)); + rasterized.allocPixels(SkImageInfo::Make( + w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType)); rasterized.eraseColor(SK_ColorWHITE); - SkUniqueCFRef<CGColorSpaceRef> cs{ - CGColorSpaceCreateDeviceRGB()}; - CGBitmapInfo info = kCGBitmapByteOrder32Big - | kCGImageAlphaPremultipliedLast; + SkUniqueCFRef<CGColorSpaceRef> cs{CGColorSpaceCreateDeviceRGB()}; + CGBitmapInfo info = kCGBitmapByteOrder32Big | + (CGBitmapInfo)kCGImageAlphaPremultipliedLast; - SkUniqueCFRef<CGContextRef> ctx{ - CGBitmapContextCreate(rasterized.getPixels(), - w,h,8,rasterized.rowBytes(), cs.get(),info)}; + SkUniqueCFRef<CGContextRef> ctx{CGBitmapContextCreate( + rasterized.getPixels(), w,h,8, rasterized.rowBytes(), cs.get(), info)}; CGContextDrawPDFPage(ctx.get(), page); - // Skip calling hashAndEncode->write(SkMD5*)... we want the .pdf's hash. hashAndEncode.reset(new HashAndEncode(rasterized)); WriteToDisk(task, md5, "png", nullptr,0, &rasterized, hashAndEncode.get()); @@ -1346,7 +1348,7 @@ struct Task { // If an MD5 is uninteresting, we want it noted in the JSON file, // but don't want to dump it out as a .png (or whatever ext is). - if (gUninterestingHashes.contains(md5)) { + if (gUninterestingHashes->contains(md5)) { return; } @@ -1423,7 +1425,8 @@ struct Task { // Unit tests don't fit so well into the Src/Sink model, so we give them special treatment. -static SkTDArray<skiatest::Test> gParallelTests, gSerialTests; +static SkTDArray<skiatest::Test>* gParallelTests = new SkTDArray<skiatest::Test>; +static SkTDArray<skiatest::Test>* gSerialTests = new SkTDArray<skiatest::Test>; static void gather_tests() { if (!FLAGS_src.contains("tests")) { @@ -1437,9 +1440,9 @@ static void gather_tests() { continue; } if (test.needsGpu && FLAGS_gpu) { - gSerialTests.push_back(test); + gSerialTests->push_back(test); } else if (!test.needsGpu && FLAGS_cpu) { - gParallelTests.push_back(test); + gParallelTests->push_back(test); } } } @@ -1521,7 +1524,7 @@ int main(int argc, char** argv) { // TODO(dogben): This is a bit ugly. Find a cleaner way to do this. bool defaultConfigs = true; for (int i = 0; i < argc; i++) { - static const char* kConfigArg = "--config"; + static constexpr char kConfigArg[] = "--config"; if (strcmp(argv[i], kConfigArg) == 0) { defaultConfigs = false; break; @@ -1531,42 +1534,44 @@ int main(int argc, char** argv) { return 1; } gather_tests(); - gPending = gSrcs.count() * gSinks.count() + gParallelTests.count() + gSerialTests.count(); + gPending = gSrcs->count() * gSinks->count() + gParallelTests->count() + gSerialTests->count(); info("%d srcs * %d sinks + %d tests == %d tasks\n", - gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTests.count(), gPending); + gSrcs->count(), gSinks->count(), gParallelTests->count() + gSerialTests->count(), + gPending); // Kick off as much parallel work as we can, making note of any serial work we'll need to do. SkTaskGroup parallel; SkTArray<Task> serial; - for (auto& sink : gSinks) - for (auto& src : gSrcs) { - if (src->veto(sink->flags()) || - is_blacklisted(sink.tag.c_str(), src.tag.c_str(), - src.options.c_str(), src->name().c_str())) { - SkAutoSpinlock lock(gMutex); - gPending--; - continue; - } + for (TaggedSink& sink : *gSinks) { + for (TaggedSrc& src : *gSrcs) { + if (src->veto(sink->flags()) || + is_blacklisted(sink.tag.c_str(), src.tag.c_str(), + src.options.c_str(), src->name().c_str())) { + SkAutoSpinlock lock(*gMutex); + gPending--; + continue; + } - Task task(src, sink); - if (src->serial() || sink->serial()) { - serial.push_back(task); - } else { - parallel.add([task] { Task::Run(task); }); + Task task(src, sink); + if (src->serial() || sink->serial()) { + serial.push_back(task); + } else { + parallel.add([task] { Task::Run(task); }); + } } } - for (auto test : gParallelTests) { + for (skiatest::Test& test : *gParallelTests) { parallel.add([test, grCtxOptions] { run_test(test, grCtxOptions); }); } // With the parallel work running, run serial tasks and tests here on main thread. - for (auto task : serial) { Task::Run(task); } - for (auto test : gSerialTests) { run_test(test, grCtxOptions); } + for (Task& task : serial) { Task::Run(task); } + for (skiatest::Test& test : *gSerialTests) { run_test(test, grCtxOptions); } // Wait for any remaining parallel work to complete (including any spun off of serial tasks). parallel.wait(); - gDefinitelyThreadSafeWork.wait(); + gDefinitelyThreadSafeWork->wait(); // At this point we're back in single-threaded land. @@ -1575,12 +1580,12 @@ int main(int argc, char** argv) { // Make sure we've flushed all our results to disk. dump_json(); - if (gFailures.count() > 0) { + if (!gFailures->empty()) { info("Failures:\n"); - for (int i = 0; i < gFailures.count(); i++) { - info("\t%s\n", gFailures[i].c_str()); + for (const SkString& fail : *gFailures) { + info("\t%s\n", fail.c_str()); } - info("%d failures\n", gFailures.count()); + info("%d failures\n", gFailures->count()); return 1; } diff --git a/chromium/third_party/skia/dm/DMGpuTestProcs.cpp b/chromium/third_party/skia/dm/DMGpuTestProcs.cpp index 736c472c3b3..e9369d5f46c 100644 --- a/chromium/third_party/skia/dm/DMGpuTestProcs.cpp +++ b/chromium/third_party/skia/dm/DMGpuTestProcs.cpp @@ -22,6 +22,9 @@ bool IsVulkanContextType(sk_gpu_test::GrContextFactory::ContextType type) { bool IsMetalContextType(sk_gpu_test::GrContextFactory::ContextType type) { return GrBackendApi::kMetal == GrContextFactory::ContextTypeBackend(type); } +bool IsDirect3DContextType(sk_gpu_test::GrContextFactory::ContextType type) { + return GrBackendApi::kDirect3D == GrContextFactory::ContextTypeBackend(type); +} bool IsRenderingGLContextType(sk_gpu_test::GrContextFactory::ContextType type) { return IsGLContextType(type) && GrContextFactory::IsRenderingContext(type); } @@ -67,7 +70,7 @@ void RunWithGPUTestContexts(GrContextTestFn* test, GrContextTypeFilterFn* contex // In case the test changed the current context make sure we move it back before // calling flush. ctxInfo.testContext()->makeCurrent(); - ctxInfo.grContext()->flush(); + ctxInfo.grContext()->flushAndSubmit(); } } } diff --git a/chromium/third_party/skia/dm/DMSrcSink.cpp b/chromium/third_party/skia/dm/DMSrcSink.cpp index 5b2e161468c..8453871818a 100644 --- a/chromium/third_party/skia/dm/DMSrcSink.cpp +++ b/chromium/third_party/skia/dm/DMSrcSink.cpp @@ -68,6 +68,10 @@ #include "include/svg/SkSVGCanvas.h" #include "src/xml/SkXMLWriter.h" #endif + +#if defined(SK_ENABLE_ANDROID_UTILS) + #include "client_utils/android/BitmapRegionDecoder.h" +#endif #include "tests/TestUtils.h" #include <cmath> @@ -86,9 +90,18 @@ namespace DM { GMSrc::GMSrc(skiagm::GMFactory factory) : fFactory(factory) {} -Result GMSrc::draw(SkCanvas* canvas) const { +Result GMSrc::draw(GrContext* context, SkCanvas* canvas) const { std::unique_ptr<skiagm::GM> gm(fFactory()); SkString msg; + + skiagm::DrawResult gpuSetupResult = gm->gpuSetup(context, &msg); + switch (gpuSetupResult) { + case skiagm::DrawResult::kOk : break; + case skiagm::DrawResult::kFail: return Result(Result::Status::Fatal, msg); + case skiagm::DrawResult::kSkip: return Result(Result::Status::Skip, msg); + default: SK_ABORT(""); + } + skiagm::DrawResult drawResult = gm->draw(canvas, &msg); switch (drawResult) { case skiagm::DrawResult::kOk : return Result(Result::Status::Ok, msg); @@ -120,6 +133,11 @@ std::unique_ptr<skiagm::verifiers::VerifierList> GMSrc::getVerifiers() const { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +static SkString get_scaled_name(const Path& path, float scale) { + return SkStringPrintf("%s_%.3f", SkOSPath::Basename(path.c_str()).c_str(), scale); +} + +#ifdef SK_ENABLE_ANDROID_UTILS BRDSrc::BRDSrc(Path path, Mode mode, CodecSrc::DstColorType dstColorType, uint32_t sampleSize) : fPath(path) , fMode(mode) @@ -133,12 +151,9 @@ bool BRDSrc::veto(SinkFlags flags) const { || flags.approach != SinkFlags::kDirect; } -static SkBitmapRegionDecoder* create_brd(Path path) { +static std::unique_ptr<android::skia::BitmapRegionDecoder> create_brd(Path path) { sk_sp<SkData> encoded(SkData::MakeFromFileName(path.c_str())); - if (!encoded) { - return nullptr; - } - return SkBitmapRegionDecoder::Create(encoded, SkBitmapRegionDecoder::kAndroidCodec_Strategy); + return android::skia::BitmapRegionDecoder::Make(encoded); } static inline void alpha8_to_gray8(SkBitmap* bitmap) { @@ -151,7 +166,7 @@ static inline void alpha8_to_gray8(SkBitmap* bitmap) { } } -Result BRDSrc::draw(SkCanvas* canvas) const { +Result BRDSrc::draw(GrContext*, SkCanvas* canvas) const { SkColorType colorType = canvas->imageInfo().colorType(); if (kRGB_565_SkColorType == colorType && CodecSrc::kGetFromCanvas_DstColorType != fDstColorType) @@ -169,7 +184,7 @@ Result BRDSrc::draw(SkCanvas* canvas) const { break; } - std::unique_ptr<SkBitmapRegionDecoder> brd(create_brd(fPath)); + auto brd = create_brd(fPath); if (nullptr == brd.get()) { return Result::Skip("Could not create brd for %s.", fPath.c_str()); } @@ -273,7 +288,7 @@ Result BRDSrc::draw(SkCanvas* canvas) const { } SkISize BRDSrc::size() const { - std::unique_ptr<SkBitmapRegionDecoder> brd(create_brd(fPath)); + auto brd = create_brd(fPath); if (brd) { return {std::max(1, brd->width() / (int)fSampleSize), std::max(1, brd->height() / (int)fSampleSize)}; @@ -281,10 +296,6 @@ SkISize BRDSrc::size() const { return {0, 0}; } -static SkString get_scaled_name(const Path& path, float scale) { - return SkStringPrintf("%s_%.3f", SkOSPath::Basename(path.c_str()).c_str(), scale); -} - Name BRDSrc::name() const { // We will replicate the names used by CodecSrc so that images can // be compared in Gold. @@ -294,6 +305,8 @@ Name BRDSrc::name() const { return get_scaled_name(fPath, 1.0f / (float) fSampleSize); } +#endif // SK_ENABLE_ANDROID_UTILS + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ static bool serial_from_path_name(const SkString& path) { @@ -394,7 +407,7 @@ static void set_bitmap_color_space(SkImageInfo* info) { *info = info->makeColorSpace(SkColorSpace::MakeSRGB()); } -Result CodecSrc::draw(SkCanvas* canvas) const { +Result CodecSrc::draw(GrContext*, SkCanvas* canvas) const { sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str())); if (!encoded) { return Result::Fatal("Couldn't read %s.", fPath.c_str()); @@ -508,7 +521,7 @@ Result CodecSrc::draw(SkCanvas* canvas) const { return Result::Skip( "Cannot decode frame %i to 565 (%s).", i, fPath.c_str()); } - // Fall through. + [[fallthrough]]; default: return Result::Fatal( "Couldn't getPixels for frame %i in %s.", i, fPath.c_str()); @@ -779,7 +792,7 @@ bool AndroidCodecSrc::veto(SinkFlags flags) const { || flags.approach != SinkFlags::kDirect; } -Result AndroidCodecSrc::draw(SkCanvas* canvas) const { +Result AndroidCodecSrc::draw(GrContext*, SkCanvas* canvas) const { sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str())); if (!encoded) { return Result::Fatal("Couldn't read %s.", fPath.c_str()); @@ -871,7 +884,7 @@ bool ImageGenSrc::veto(SinkFlags flags) const { return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect; } -Result ImageGenSrc::draw(SkCanvas* canvas) const { +Result ImageGenSrc::draw(GrContext*, SkCanvas* canvas) const { if (kRGB_565_SkColorType == canvas->imageInfo().colorType()) { return Result::Skip("Uninteresting to test image generator to 565."); } @@ -969,7 +982,7 @@ bool ColorCodecSrc::veto(SinkFlags flags) const { return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect; } -Result ColorCodecSrc::draw(SkCanvas* canvas) const { +Result ColorCodecSrc::draw(GrContext*, SkCanvas* canvas) const { sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str())); if (!encoded) { return Result::Fatal("Couldn't read %s.", fPath.c_str()); @@ -1034,7 +1047,7 @@ static DEFINE_int(skpViewportSize, 1000, SKPSrc::SKPSrc(Path path) : fPath(path) { } -Result SKPSrc::draw(SkCanvas* canvas) const { +Result SKPSrc::draw(GrContext*, SkCanvas* canvas) const { std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(fPath.c_str()); if (!stream) { return Result::Fatal("Couldn't read %s.", fPath.c_str()); @@ -1076,7 +1089,7 @@ Name SKPSrc::name() const { return SkOSPath::Basename(fPath.c_str()); } BisectSrc::BisectSrc(Path path, const char* trail) : INHERITED(path), fTrail(trail) {} -Result BisectSrc::draw(SkCanvas* canvas) const { +Result BisectSrc::draw(GrContext* context, SkCanvas* canvas) const { struct FoundPath { SkPath fPath; SkPaint fPaint; @@ -1099,7 +1112,7 @@ Result BisectSrc::draw(SkCanvas* canvas) const { PathFindingCanvas pathFinder(canvas->getBaseLayerSize().width(), canvas->getBaseLayerSize().height()); - Result result = this->INHERITED::draw(&pathFinder); + Result result = this->INHERITED::draw(context, &pathFinder); if (!result.isOk()) { return result; } @@ -1127,9 +1140,12 @@ Result BisectSrc::draw(SkCanvas* canvas) const { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #if defined(SK_ENABLE_SKOTTIE) +static DEFINE_bool(useLottieGlyphPaths, false, + "Prioritize embedded glyph paths over native fonts."); + SkottieSrc::SkottieSrc(Path path) : fPath(std::move(path)) {} -Result SkottieSrc::draw(SkCanvas* canvas) const { +Result SkottieSrc::draw(GrContext*, SkCanvas* canvas) const { auto resource_provider = skresources::DataURIResourceProviderProxy::Make( skresources::FileResourceProvider::Make(SkOSPath::Dirname(fPath.c_str()), @@ -1140,7 +1156,12 @@ Result SkottieSrc::draw(SkCanvas* canvas) const { auto precomp_interceptor = sk_make_sp<skottie_utils::ExternalAnimationPrecompInterceptor>(resource_provider, kInterceptPrefix); - auto animation = skottie::Animation::Builder() + uint32_t flags = 0; + if (FLAGS_useLottieGlyphPaths) { + flags |= skottie::Animation::Builder::kPreferEmbeddedFonts; + } + + auto animation = skottie::Animation::Builder(flags) .setResourceProvider(std::move(resource_provider)) .setPrecompInterceptor(std::move(precomp_interceptor)) .makeFromFile(fPath.c_str()); @@ -1230,7 +1251,7 @@ SVGSrc::SVGSrc(Path path) } } -Result SVGSrc::draw(SkCanvas* canvas) const { +Result SVGSrc::draw(GrContext*, SkCanvas* canvas) const { if (!fDom) { return Result::Fatal("Unable to parse file: %s", fName.c_str()); } @@ -1281,8 +1302,10 @@ SkISize MSKPSrc::size(int i) const { return i >= 0 && i < fPages.count() ? fPages[i].fSize.toCeil() : SkISize{0, 0}; } -Result MSKPSrc::draw(SkCanvas* c) const { return this->draw(0, c); } -Result MSKPSrc::draw(int i, SkCanvas* canvas) const { +Result MSKPSrc::draw(GrContext* context, SkCanvas* c) const { + return this->draw(0, context, c); +} +Result MSKPSrc::draw(int i, GrContext*, SkCanvas* canvas) const { if (this->pageCount() == 0) { return Result::Fatal("Unable to parse MultiPictureDocument file: %s", fPath.c_str()); } @@ -1310,7 +1333,7 @@ Name MSKPSrc::name() const { return SkOSPath::Basename(fPath.c_str()); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ Result NullSink::draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const { - return src.draw(SkMakeNullCanvas().get()); + return src.draw(nullptr, SkMakeNullCanvas().get()); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ @@ -1419,12 +1442,6 @@ bool GPUSink::readBack(SkSurface* surface, SkBitmap* dst) const { SkISize size = surface->imageInfo().dimensions(); SkImageInfo info = SkImageInfo::Make(size, fColorType, fAlphaType, fColorSpace); - if (info.colorType() == kRGB_565_SkColorType || info.colorType() == kARGB_4444_SkColorType || - info.colorType() == kRGB_888x_SkColorType) { - // We don't currently support readbacks into these formats on the GPU backend. Convert to - // 32 bit. - info = SkImageInfo::Make(size, kRGBA_8888_SkColorType, kPremul_SkAlphaType, fColorSpace); - } dst->allocPixels(info); return canvas->readPixels(*dst, 0, 0); } @@ -1463,15 +1480,15 @@ Result GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log, factory.abandonContexts(); } SkCanvas* canvas = surface->getCanvas(); - Result result = src.draw(canvas); + Result result = src.draw(context, canvas); if (!result.isOk()) { return result; } - surface->flush(); + surface->flushAndSubmit(); if (FLAGS_gpuStats) { - canvas->getGrContext()->priv().dumpCacheStats(log); - canvas->getGrContext()->priv().dumpGpuStats(log); - canvas->getGrContext()->priv().dumpContextStats(log); + context->priv().dumpCacheStats(log); + context->priv().dumpGpuStats(log); + context->priv().dumpContextStats(log); } this->readBack(surface.get(), dst); @@ -1557,12 +1574,13 @@ Result GPUPersistentCacheTestingSink::draw(const Src& src, SkBitmap* dst, SkWStr SkBitmap reference; SkString refLog; SkDynamicMemoryWStream refStream; - memoryCache.resetNumCacheMisses(); + memoryCache.resetCacheStats(); Result refResult = this->onDraw(src, &reference, &refStream, &refLog, contextOptions); if (!refResult.isOk()) { return refResult; } SkASSERT(!memoryCache.numCacheMisses()); + SkASSERT(!memoryCache.numCacheStores()); return compare_bitmaps(reference, *dst); } @@ -1616,10 +1634,95 @@ Result GPUPrecompileTestingSink::draw(const Src& src, SkBitmap* dst, SkWStream* } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -GPUDDLSink::GPUDDLSink(const SkCommandLineConfigGpu* config, const GrContextOptions& grCtxOptions) - : INHERITED(config, grCtxOptions) - , fRecordingThreadPool(SkExecutor::MakeLIFOThreadPool(1)) // TODO: this should be at least 2 - , fGPUThread(SkExecutor::MakeFIFOThreadPool(1, false)) { +GPUOOPRSink::GPUOOPRSink(const SkCommandLineConfigGpu* config, const GrContextOptions& ctxOptions) + : INHERITED(config, ctxOptions) { +} + +Result GPUOOPRSink::ooprDraw(const Src& src, + sk_sp<SkSurface> dstSurface, + GrContext* context) const { + SkSurfaceCharacterization dstCharacterization; + SkAssertResult(dstSurface->characterize(&dstCharacterization)); + + SkDeferredDisplayListRecorder recorder(dstCharacterization); + + Result result = src.draw(context, recorder.getCanvas()); + if (!result.isOk()) { + return result; + } + + std::unique_ptr<SkDeferredDisplayList> ddl = recorder.detach(); + + SkDeferredDisplayList::ProgramIterator iter(context, ddl.get()); + for (; !iter.done(); iter.next()) { + iter.compile(); + } + + SkAssertResult(dstSurface->draw(ddl.get())); + + // TODO: remove this flush once DDLs are reffed by the drawing manager + context->flushAndSubmit(); + + ddl.reset(); + + return Result::Ok(); +} + +Result GPUOOPRSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const { + GrContextOptions contextOptions = this->baseContextOptions(); + src.modifyGrContextOptions(&contextOptions); + contextOptions.fPersistentCache = nullptr; + contextOptions.fExecutor = nullptr; + + GrContextFactory factory(contextOptions); + + ContextInfo ctxInfo = factory.getContextInfo(this->contextType(), this->contextOverrides()); + GrContext* context = ctxInfo.grContext(); + if (!context) { + return Result::Fatal("Could not create context."); + } + + SkASSERT(context->priv().getGpu()); + + GrBackendTexture backendTexture; + GrBackendRenderTarget backendRT; + sk_sp<SkSurface> surface = this->createDstSurface(context, src.size(), + &backendTexture, &backendRT); + if (!surface) { + return Result::Fatal("Could not create a surface."); + } + + Result result = this->ooprDraw(src, surface, context); + if (!result.isOk()) { + return result; + } + + if (FLAGS_gpuStats) { + context->priv().dumpCacheStats(log); + context->priv().dumpGpuStats(log); + context->priv().dumpContextStats(log); + } + + if (!this->readBack(surface.get(), dst)) { + return Result::Fatal("Could not readback from surface."); + } + + surface.reset(); + if (backendTexture.isValid()) { + context->deleteBackendTexture(backendTexture); + } + if (backendRT.isValid()) { + context->priv().getGpu()->deleteTestingOnlyBackendRenderTarget(backendRT); + } + + return Result::Ok(); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +GPUDDLSink::GPUDDLSink(const SkCommandLineConfigGpu* config, const GrContextOptions& ctxOptions) + : INHERITED(config, ctxOptions) + , fRecordingExecutor(SkExecutor::MakeLIFOThreadPool(1)) + , fGPUExecutor(SkExecutor::MakeFIFOThreadPool(1, false)) { } Result GPUDDLSink::ddlDraw(const Src& src, @@ -1635,20 +1738,11 @@ Result GPUDDLSink::ddlDraw(const Src& src, SkSurfaceCharacterization dstCharacterization; SkAssertResult(dstSurface->characterize(&dstCharacterization)); - // 'gpuTestCtx/gpuThreadCtx' is being shifted to the gpuThread. Leave the main (this) - // thread w/o a context. - gpuTestCtx->makeNotCurrent(); - - // Job one for the GPU thread is to make 'gpuTestCtx' current! - gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeCurrent(); }); - auto size = src.size(); SkPictureRecorder recorder; - Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), - SkIntToScalar(size.height()))); + Result result = src.draw(gpuThreadCtx, recorder.beginRecording(SkIntToScalar(size.width()), + SkIntToScalar(size.height()))); if (!result.isOk()) { - gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); }); - gpuTaskGroup->wait(); return result; } sk_sp<SkPicture> inputPicture(recorder.finishRecordingAsPicture()); @@ -1659,13 +1753,18 @@ Result GPUDDLSink::ddlDraw(const Src& src, DDLPromiseImageHelper promiseImageHelper; sk_sp<SkData> compressedPictureData = promiseImageHelper.deflateSKP(inputPicture.get()); if (!compressedPictureData) { - gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); }); - gpuTaskGroup->wait(); return Result::Fatal("GPUDDLSink: Couldn't deflate SkPicture"); } promiseImageHelper.createCallbackContexts(gpuThreadCtx); + // 'gpuTestCtx/gpuThreadCtx' is being shifted to the gpuThread. Leave the main (this) + // thread w/o a context. + gpuTestCtx->makeNotCurrent(); + + // Job one for the GPU thread is to make 'gpuTestCtx' current! + gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeCurrent(); }); + // TODO: move the image upload to the utility thread promiseImageHelper.uploadAllToGPU(gpuTaskGroup, gpuThreadCtx); @@ -1697,7 +1796,8 @@ Result GPUDDLSink::ddlDraw(const Src& src, dstSurface->draw(ddl); }); - // This should be the only explicit flush for the entire DDL draw + // This should be the only explicit flush for the entire DDL draw. + // TODO: remove the flushes in do_gpu_stuff gpuTaskGroup->add([gpuThreadCtx]() { // We need to ensure all the GPU work is finished so // the following 'deleteAllFromGPU' call will work @@ -1708,6 +1808,7 @@ Result GPUDDLSink::ddlDraw(const Src& src, GrFlushInfo flushInfoSyncCpu; flushInfoSyncCpu.fFlags = kSyncCpu_GrFlushFlag; gpuThreadCtx->flush(flushInfoSyncCpu); + gpuThreadCtx->submit(true); }); // The backend textures are created on the gpuThread by the 'uploadAllToGPU' call. @@ -1726,7 +1827,7 @@ Result GPUDDLSink::ddlDraw(const Src& src, return Result::Ok(); } -Result GPUDDLSink::draw(const Src& src, SkBitmap* dst, SkWStream* stream, SkString* log) const { +Result GPUDDLSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const { GrContextOptions contextOptions = this->baseContextOptions(); src.modifyGrContextOptions(&contextOptions); contextOptions.fPersistentCache = nullptr; @@ -1758,8 +1859,8 @@ Result GPUDDLSink::draw(const Src& src, SkBitmap* dst, SkWStream* stream, SkStri SkASSERT(otherCtx->priv().getGpu()); #endif - SkTaskGroup recordingTaskGroup(*fRecordingThreadPool); - SkTaskGroup gpuTaskGroup(*fGPUThread); + SkTaskGroup recordingTaskGroup(*fRecordingExecutor); + SkTaskGroup gpuTaskGroup(*fGPUExecutor); // Make sure 'mainCtx' is current mainTestCtx->makeCurrent(); @@ -1822,7 +1923,7 @@ static Result draw_skdocument(const Src& src, SkDocument* doc, SkWStream* dst) { if (!canvas) { return Result::Fatal("SkDocument::beginPage(w,h) returned nullptr"); } - Result result = src.draw(i, canvas); + Result result = src.draw(i, nullptr, canvas); if (!result.isOk()) { return result; } @@ -1893,7 +1994,7 @@ SKPSink::SKPSink() {} Result SKPSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const { auto size = SkSize::Make(src.size()); SkPictureRecorder recorder; - Result result = src.draw(recorder.beginRecording(size.width(), size.height())); + Result result = src.draw(nullptr, recorder.beginRecording(size.width(), size.height())); if (!result.isOk()) { return result; } @@ -1905,7 +2006,7 @@ Result SKPSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const Result DebugSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const { DebugCanvas debugCanvas(src.size().width(), src.size().height()); - Result result = src.draw(&debugCanvas); + Result result = src.draw(nullptr, &debugCanvas); if (!result.isOk()) { return result; } @@ -1932,7 +2033,7 @@ Result SVGSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const fPageIndex, pageCount); } } - return src.draw(fPageIndex, + return src.draw(fPageIndex, nullptr, SkSVGCanvas::Make(SkRect::MakeWH(SkIntToScalar(src.size().width()), SkIntToScalar(src.size().height())), dst) @@ -1959,7 +2060,7 @@ Result RasterSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString*) co SkBitmap::kZeroPixels_AllocFlag); SkCanvas canvas(*dst); - return src.draw(&canvas); + return src.draw(nullptr, &canvas); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ @@ -1974,7 +2075,7 @@ static Result draw_to_canvas(Sink* sink, SkBitmap* bitmap, SkWStream* stream, Sk class ProxySrc : public Src { public: ProxySrc(SkISize size, const Fn& draw) : fSize(size), fDraw(draw) {} - Result draw(SkCanvas* canvas) const override { return fDraw(canvas); } + Result draw(GrContext*, SkCanvas* canvas) const override { return fDraw(canvas); } Name name() const override { return "ProxySrc"; } SkISize size() const override { return fSize; } private: @@ -2023,7 +2124,7 @@ Result ViaMatrix::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkSt SkISize size = auto_compute_translate(&matrix, src.size().width(), src.size().height()); return draw_to_canvas(fSink.get(), bitmap, stream, log, size, [&](SkCanvas* canvas) { canvas->concat(matrix); - return src.draw(canvas); + return src.draw(nullptr, canvas); }); } @@ -2068,8 +2169,8 @@ Result ViaSerialization::draw( // Record our Src into a picture. auto size = src.size(); SkPictureRecorder recorder; - Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), - SkIntToScalar(size.height()))); + Result result = src.draw(nullptr, recorder.beginRecording(SkIntToScalar(size.width()), + SkIntToScalar(size.height()))); if (!result.isOk()) { return result; } @@ -2097,8 +2198,8 @@ ViaDDL::ViaDDL(int numReplays, int numDivisions, Sink* sink) Result ViaDDL::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { auto size = src.size(); SkPictureRecorder recorder; - Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), - SkIntToScalar(size.height()))); + Result result = src.draw(nullptr, recorder.beginRecording(SkIntToScalar(size.width()), + SkIntToScalar(size.height()))); if (!result.isOk()) { return result; } @@ -2178,6 +2279,7 @@ Result ViaDDL::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStrin GrFlushInfo flushInfoSyncCpu; flushInfoSyncCpu.fFlags = kSyncCpu_GrFlushFlag; context->flush(flushInfoSyncCpu); + context->submit(true); } return Result::Ok(); }; @@ -2191,8 +2293,8 @@ Result ViaPicture::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkS Result result = draw_to_canvas(fSink.get(), bitmap, stream, log, size, [&](SkCanvas* canvas) { SkPictureRecorder recorder; sk_sp<SkPicture> pic; - Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), - SkIntToScalar(size.height()))); + Result result = src.draw(nullptr, recorder.beginRecording(SkIntToScalar(size.width()), + SkIntToScalar(size.height()))); if (!result.isOk()) { return result; } diff --git a/chromium/third_party/skia/dm/DMSrcSink.h b/chromium/third_party/skia/dm/DMSrcSink.h index 3dd109b4f66..184841a91e6 100644 --- a/chromium/third_party/skia/dm/DMSrcSink.h +++ b/chromium/third_party/skia/dm/DMSrcSink.h @@ -9,7 +9,6 @@ #define DMSrcSink_DEFINED #include "gm/gm.h" -#include "include/android/SkBitmapRegionDecoder.h" #include "include/core/SkBBHFactory.h" #include "include/core/SkBitmap.h" #include "include/core/SkCanvas.h" @@ -87,15 +86,15 @@ struct SinkFlags { struct Src { virtual ~Src() {} - virtual Result SK_WARN_UNUSED_RESULT draw(SkCanvas*) const = 0; + virtual Result SK_WARN_UNUSED_RESULT draw(GrContext*, SkCanvas*) const = 0; virtual SkISize size() const = 0; virtual Name name() const = 0; virtual void modifyGrContextOptions(GrContextOptions* options) const {} virtual bool veto(SinkFlags) const { return false; } virtual int pageCount() const { return 1; } - virtual Result SK_WARN_UNUSED_RESULT draw(int, SkCanvas* canvas) const { - return this->draw(canvas); + virtual Result SK_WARN_UNUSED_RESULT draw(int, GrContext* context, SkCanvas* canvas) const { + return this->draw(context, canvas); } virtual SkISize size(int) const { return this->size(); } // Force Tasks using this Src to run on the main thread? @@ -131,7 +130,7 @@ class GMSrc : public Src { public: explicit GMSrc(skiagm::GMFactory); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; void modifyGrContextOptions(GrContextOptions* options) const override; @@ -163,7 +162,7 @@ public: }; CodecSrc(Path, Mode, DstColorType, SkAlphaType, float); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; bool veto(SinkFlags) const override; @@ -181,7 +180,7 @@ class AndroidCodecSrc : public Src { public: AndroidCodecSrc(Path, CodecSrc::DstColorType, SkAlphaType, int sampleSize); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; bool veto(SinkFlags) const override; @@ -194,6 +193,7 @@ private: bool fRunSerially; }; +#ifdef SK_ENABLE_ANDROID_UTILS // Allows for testing of various implementations of Android's BitmapRegionDecoder class BRDSrc : public Src { public: @@ -209,7 +209,7 @@ public: BRDSrc(Path, Mode, CodecSrc::DstColorType, uint32_t); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; bool veto(SinkFlags) const override; @@ -219,6 +219,7 @@ private: CodecSrc::DstColorType fDstColorType; uint32_t fSampleSize; }; +#endif class ImageGenSrc : public Src { public: @@ -228,7 +229,7 @@ public: }; ImageGenSrc(Path, Mode, SkAlphaType, bool); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; bool veto(SinkFlags) const override; @@ -245,7 +246,7 @@ class ColorCodecSrc : public Src { public: ColorCodecSrc(Path, bool decode_to_dst); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; bool veto(SinkFlags) const override; @@ -258,7 +259,7 @@ class SKPSrc : public Src { public: explicit SKPSrc(Path path); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; private: @@ -272,7 +273,7 @@ class BisectSrc : public SKPSrc { public: explicit BisectSrc(Path path, const char* trail); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; private: SkString fTrail; @@ -286,7 +287,7 @@ class SkottieSrc final : public Src { public: explicit SkottieSrc(Path path); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; bool veto(SinkFlags) const override; @@ -314,7 +315,7 @@ class SVGSrc : public Src { public: explicit SVGSrc(Path path); - Result draw(SkCanvas*) const override; + Result draw(GrContext*, SkCanvas*) const override; SkISize size() const override; Name name() const override; bool veto(SinkFlags) const override; @@ -334,8 +335,8 @@ public: explicit MSKPSrc(Path path); int pageCount() const override; - Result draw(SkCanvas* c) const override; - Result draw(int, SkCanvas*) const override; + Result draw(GrContext*, SkCanvas* c) const override; + Result draw(int, GrContext*, SkCanvas*) const override; SkISize size() const override; SkISize size(int) const override; Name name() const override; @@ -450,6 +451,21 @@ private: typedef GPUSink INHERITED; }; +// This sink attempts to emulate Chrome's OOP-R behavior. It: +// doesn't use promise images +// uses only a single thread for both DDL creation & drawing +class GPUOOPRSink : public GPUSink { +public: + GPUOOPRSink(const SkCommandLineConfigGpu*, const GrContextOptions&); + + Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; + +private: + Result ooprDraw(const Src&, sk_sp<SkSurface> dstSurface, GrContext*) const; + + typedef GPUSink INHERITED; +}; + // This sink attempts to better simulate the Chrome DDL use-case. It: // creates the DDLs on separate recording threads // performs all the GPU work on a separate GPU thread @@ -472,8 +488,8 @@ private: sk_gpu_test::TestContext* gpuTestCtx, GrContext* gpuThreadCtx) const; - std::unique_ptr<SkExecutor> fRecordingThreadPool; - std::unique_ptr<SkExecutor> fGPUThread; + std::unique_ptr<SkExecutor> fRecordingExecutor; + std::unique_ptr<SkExecutor> fGPUExecutor; typedef GPUSink INHERITED; }; |