From 00a5eb8c12536f7843ccb137f94df88583813128 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Wed, 11 Jul 2018 15:32:05 -0400 Subject: Add gltestpersistentcache config that tests GrContextOption's cache. Uses a new GPU sink that runs each test twice, once to populate the cache and then again with a new GrContext but a warmed cache. It verifies that the two generated images are the same. Change-Id: Iaba195a69751f14ea946afe7174228a813b83a63 Reviewed-on: https://skia-review.googlesource.com/140567 Commit-Queue: Brian Salomon Reviewed-by: Brian Osman --- dm/DM.cpp | 7 +++++++ dm/DMSrcSink.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- dm/DMSrcSink.h | 20 ++++++++++++++++++++ 3 files changed, 77 insertions(+), 4 deletions(-) (limited to 'dm') diff --git a/dm/DM.cpp b/dm/DM.cpp index b8714d3fd9..5b3642ac84 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -862,11 +862,18 @@ static Sink* create_sink(const GrContextOptions& grCtxOptions, const SkCommandLi return nullptr; } if (gpuConfig->getTestThreading()) { + SkASSERT(!gpuConfig->getTestPersistentCache()); return new GPUThreadTestingSink( contextType, contextOverrides, gpuConfig->getSurfType(), gpuConfig->getSamples(), gpuConfig->getUseDIText(), gpuConfig->getColorType(), gpuConfig->getAlphaType(), sk_ref_sp(gpuConfig->getColorSpace()), FLAGS_gpu_threading, grCtxOptions); + } else if (gpuConfig->getTestPersistentCache()) { + return new GPUPersistentCacheTestingSink( + contextType, contextOverrides, gpuConfig->getSurfType(), + gpuConfig->getSamples(), gpuConfig->getUseDIText(), + gpuConfig->getColorType(), gpuConfig->getAlphaType(), + sk_ref_sp(gpuConfig->getColorSpace()), FLAGS_gpu_threading, grCtxOptions); } else { return new GPUSink(contextType, contextOverrides, gpuConfig->getSurfType(), gpuConfig->getSamples(), gpuConfig->getUseDIText(), diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index fb67c52cdc..25b87b376e 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -11,6 +11,10 @@ #include "../src/jumper/SkJumper.h" #include "DDLPromiseImageHelper.h" #include "DDLTileHelper.h" +#include "GrBackendSurface.h" +#include "GrContextPriv.h" +#include "GrGpu.h" +#include "MemoryCache.h" #include "Resources.h" #include "SkAndroidCodec.h" #include "SkAutoMalloc.h" @@ -75,10 +79,6 @@ #include "../third_party/skcms/skcms.h" -#include "GrBackendSurface.h" -#include "GrContextPriv.h" -#include "GrGpu.h" - DEFINE_bool(multiPage, false, "For document-type backends, render the source" " into multiple pages"); DEFINE_bool(RAW_threading, true, "Allow RAW decodes to run on multiple threads?"); @@ -1486,7 +1486,12 @@ Error GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log, const GrContextOptions& baseOptions) const { GrContextOptions grOptions = baseOptions; + // We don't expect the src to mess with the persistent cache or the executor. + SkDEBUGCODE(auto cache = grOptions.fPersistentCache); + SkDEBUGCODE(auto exec = grOptions.fExecutor); src.modifyGrContextOptions(&grOptions); + SkASSERT(cache == grOptions.fPersistentCache); + SkASSERT(exec == grOptions.fExecutor); GrContextFactory factory(grOptions); const SkISize size = src.size(); @@ -1617,6 +1622,47 @@ Error GPUThreadTestingSink::draw(const Src& src, SkBitmap* dst, SkWStream* wStre /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +GPUPersistentCacheTestingSink::GPUPersistentCacheTestingSink( + GrContextFactory::ContextType ct, + GrContextFactory::ContextOverrides overrides, + SkCommandLineConfigGpu::SurfType surfType, + int samples, + bool diText, + SkColorType colorType, + SkAlphaType alphaType, + sk_sp colorSpace, + bool threaded, + const GrContextOptions& grCtxOptions) + : INHERITED(ct, overrides, surfType, samples, diText, colorType, alphaType, + std::move(colorSpace), threaded, grCtxOptions) {} + +Error GPUPersistentCacheTestingSink::draw(const Src& src, SkBitmap* dst, SkWStream* wStream, + SkString* log) const { + // Draw twice, once with a cold cache, and again with a warm cache. Verify that we get the same + // result. + sk_gpu_test::MemoryCache memoryCache; + GrContextOptions contextOptions = this->baseContextOptions(); + contextOptions.fPersistentCache = &memoryCache; + + Error err = this->onDraw(src, dst, wStream, log, contextOptions); + if (!err.isEmpty() || !dst) { + return err; + } + + SkBitmap reference; + SkString refLog; + SkDynamicMemoryWStream refStream; + memoryCache.resetNumCacheMisses(); + Error refErr = this->onDraw(src, &reference, &refStream, &refLog, contextOptions); + if (!refErr.isEmpty()) { + return refErr; + } + SkASSERT(memoryCache.numCacheMisses()); + + return compare_bitmaps(reference, *dst); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ static Error draw_skdocument(const Src& src, SkDocument* doc, SkWStream* dst) { if (src.size().isEmpty()) { return "Source has empty dimensions"; diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 9c31c0ab22..86c2279439 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -386,6 +386,26 @@ private: typedef GPUSink INHERITED; }; +class GPUPersistentCacheTestingSink : public GPUSink { +public: + GPUPersistentCacheTestingSink(sk_gpu_test::GrContextFactory::ContextType, + sk_gpu_test::GrContextFactory::ContextOverrides, + SkCommandLineConfigGpu::SurfType surfType, int samples, + bool diText, SkColorType colorType, SkAlphaType alphaType, + sk_sp colorSpace, bool threaded, + const GrContextOptions& grCtxOptions); + + Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; + + const char* fileExtension() const override { + // Suppress writing out results from this config - we just want to do our matching test + return nullptr; + } + +private: + typedef GPUSink INHERITED; +}; + class PDFSink : public Sink { public: PDFSink(bool pdfa, SkScalar rasterDpi) : fPDFA(pdfa), fRasterDpi(rasterDpi) {} -- cgit v1.2.3