diff options
author | Brian Salomon <bsalomon@google.com> | 2018-07-11 15:32:05 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-11 20:06:33 +0000 |
commit | 00a5eb8c12536f7843ccb137f94df88583813128 (patch) | |
tree | b9f2bfe7a8397427704969c8211f64c5f6edd0c5 /tools | |
parent | ba383208043a69666ada6c22757e656927fd6bfc (diff) |
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 <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/flags/SkCommonFlagsConfig.cpp | 122 | ||||
-rw-r--r-- | tools/flags/SkCommonFlagsConfig.h | 4 | ||||
-rw-r--r-- | tools/gpu/MemoryCache.cpp | 56 | ||||
-rw-r--r-- | tools/gpu/MemoryCache.h | 62 |
4 files changed, 186 insertions, 58 deletions
diff --git a/tools/flags/SkCommonFlagsConfig.cpp b/tools/flags/SkCommonFlagsConfig.cpp index aff7a3f960..7aca8f5be1 100644 --- a/tools/flags/SkCommonFlagsConfig.cpp +++ b/tools/flags/SkCommonFlagsConfig.cpp @@ -29,6 +29,7 @@ static const char defaultConfigs[] = #undef DEFAULT_GPU_CONFIG +// clang-format off static const struct { const char* predefinedConfig; const char* backend; @@ -67,6 +68,7 @@ static const struct { { "gldft", "gpu", "api=gl,dit=true" }, { "glesdft", "gpu", "api=gles,dit=true" }, { "gltestthreading", "gpu", "api=gl,testThreading=true" }, + { "gltestpersistentcache", "gpu", "api=gl,testPersistentCache=true" }, { "debuggl", "gpu", "api=debuggl" }, { "nullgl", "gpu", "api=nullgl" }, { "angle_d3d11_es2", "gpu", "api=angle_d3d11_es2" }, @@ -103,6 +105,7 @@ static const struct { ,{ "mtlmsaa8", "gpu", "api=metal,samples=8" } #endif }; +// clang-format on static const char configHelp[] = "Options: 565 8888 srgb f16 nonrendering null pdf pdfa skp pipe svg xps"; @@ -118,63 +121,65 @@ static const char* config_help_fn() { } static const char configExtendedHelp[] = - "Extended form: 'backend(option=value,...)'\n\n" - "Possible backends and options:\n" - "\n" - "gpu[api=string,color=string,dit=bool,nvpr=bool,inst=bool,samples=int]\n" - "\tapi\ttype: string\trequired\n" - "\t Select graphics API to use with gpu backend.\n" - "\t Options:\n" - "\t\tgl \t\t\tUse OpenGL.\n" - "\t\tgles \t\t\tUse OpenGL ES.\n" - "\t\tdebuggl \t\tUse debug OpenGL.\n" - "\t\tnullgl \t\t\tUse null OpenGL.\n" - "\t\tangle_d3d9_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D9 backend.\n" - "\t\tangle_d3d11_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D11 backend.\n" - "\t\tangle_d3d11_es3\t\tUse OpenGL ES3 on the ANGLE Direct3D11 backend.\n" - "\t\tangle_gl_es2\t\tUse OpenGL ES2 on the ANGLE OpenGL backend.\n" - "\t\tangle_gl_es3\t\tUse OpenGL ES3 on the ANGLE OpenGL backend.\n" - "\t\tcommandbuffer\t\tUse command buffer.\n" - "\t\tmock\t\t\tUse mock context.\n" + "Extended form: 'backend(option=value,...)'\n\n" + "Possible backends and options:\n" + "\n" + "gpu[api=string,color=string,dit=bool,nvpr=bool,inst=bool,samples=int]\n" + "\tapi\ttype: string\trequired\n" + "\t Select graphics API to use with gpu backend.\n" + "\t Options:\n" + "\t\tgl \t\t\tUse OpenGL.\n" + "\t\tgles \t\t\tUse OpenGL ES.\n" + "\t\tdebuggl \t\tUse debug OpenGL.\n" + "\t\tnullgl \t\t\tUse null OpenGL.\n" + "\t\tangle_d3d9_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D9 backend.\n" + "\t\tangle_d3d11_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D11 backend.\n" + "\t\tangle_d3d11_es3\t\tUse OpenGL ES3 on the ANGLE Direct3D11 backend.\n" + "\t\tangle_gl_es2\t\tUse OpenGL ES2 on the ANGLE OpenGL backend.\n" + "\t\tangle_gl_es3\t\tUse OpenGL ES3 on the ANGLE OpenGL backend.\n" + "\t\tcommandbuffer\t\tUse command buffer.\n" + "\t\tmock\t\t\tUse mock context.\n" #ifdef SK_VULKAN - "\t\tvulkan\t\t\tUse Vulkan.\n" + "\t\tvulkan\t\t\tUse Vulkan.\n" #endif #ifdef SK_METAL - "\t\tmetal\t\t\tUse Metal.\n" + "\t\tmetal\t\t\tUse Metal.\n" #endif - "\tcolor\ttype: string\tdefault: 8888.\n" - "\t Select framebuffer color format.\n" - "\t Options:\n" - "\t\t8888\t\t\tLinear 8888.\n" - "\t\t888x\t\t\tLinear 888x.\n" - "\t\t4444\t\t\tLinear 4444.\n" - "\t\t565\t\t\tLinear 565.\n" - "\t\t1010102\t\t\tLinear 1010102.\n" - "\t\tsrgb\t\t\tsRGB 8888.\n" - "\t\tesrgb\t\t\tsRGB 16-bit floating point.\n" - "\t\tnarrow\t\t\tNarrow gamut 8888.\n" - "\t\tenarrow\t\t\tNarrow gamut 16-bit floating point.\n" - "\t\tf16\t\t\tLinearly blended 16-bit floating point.\n" - "\tdit\ttype: bool\tdefault: false.\n" - "\t Use device independent text.\n" - "\tnvpr\ttype: bool\tdefault: false.\n" - "\t Use NV_path_rendering OpenGL and OpenGL ES extension.\n" - "\tsamples\ttype: int\tdefault: 0.\n" - "\t Use multisampling with N samples.\n" - "\tstencils\ttype: bool\tdefault: true.\n" - "\t Allow the use of stencil buffers.\n" - "\ttestThreading\ttype: bool\tdefault: false.\n" - "\t Run with and without worker threads, check that results match.\n" - "\tsurf\ttype: string\tdefault: default.\n" - "\t Controls the type of backing store for SkSurfaces.\n" - "\t Options:\n" - "\t\tdefault\t\t\tA renderable texture created in Skia's resource cache.\n" - "\t\tbetex\t\t\tA wrapped backend texture.\n" - "\t\tbert\t\t\tA wrapped backend render target\n" - "\n" - "Predefined configs:\n\n" - // Help text for pre-defined configs is auto-generated from gPredefinedConfigs - ; + "\tcolor\ttype: string\tdefault: 8888.\n" + "\t Select framebuffer color format.\n" + "\t Options:\n" + "\t\t8888\t\t\tLinear 8888.\n" + "\t\t888x\t\t\tLinear 888x.\n" + "\t\t4444\t\t\tLinear 4444.\n" + "\t\t565\t\t\tLinear 565.\n" + "\t\t1010102\t\t\tLinear 1010102.\n" + "\t\tsrgb\t\t\tsRGB 8888.\n" + "\t\tesrgb\t\t\tsRGB 16-bit floating point.\n" + "\t\tnarrow\t\t\tNarrow gamut 8888.\n" + "\t\tenarrow\t\t\tNarrow gamut 16-bit floating point.\n" + "\t\tf16\t\t\tLinearly blended 16-bit floating point.\n" + "\tdit\ttype: bool\tdefault: false.\n" + "\t Use device independent text.\n" + "\tnvpr\ttype: bool\tdefault: false.\n" + "\t Use NV_path_rendering OpenGL and OpenGL ES extension.\n" + "\tsamples\ttype: int\tdefault: 0.\n" + "\t Use multisampling with N samples.\n" + "\tstencils\ttype: bool\tdefault: true.\n" + "\t Allow the use of stencil buffers.\n" + "\ttestThreading\ttype: bool\tdefault: false.\n" + "\t Run with and without worker threads, check that results match.\n" + "\ttestPersistentCache\ttype: bool\tdefault: false.\n" + "\t Run using a pre-warmed GrContextOption::fPersistentCache.\n" + "\tsurf\ttype: string\tdefault: default.\n" + "\t Controls the type of backing store for SkSurfaces.\n" + "\t Options:\n" + "\t\tdefault\t\t\tA renderable texture created in Skia's resource cache.\n" + "\t\tbetex\t\t\tA wrapped backend texture.\n" + "\t\tbert\t\t\tA wrapped backend render target\n" + "\n" + "Predefined configs:\n\n" + // Help text for pre-defined configs is auto-generated from gPredefinedConfigs + ; static const char* config_extended_help_fn() { static SkString helpString; @@ -423,7 +428,7 @@ SkCommandLineConfigGpu::SkCommandLineConfigGpu( const SkString& tag, const SkTArray<SkString>& viaParts, ContextType contextType, bool useNVPR, bool useDIText, int samples, SkColorType colorType, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace, bool useStencilBuffers, bool testThreading, - SurfType surfType) + bool testPersistentCache, SurfType surfType) : SkCommandLineConfig(tag, SkString("gpu"), viaParts) , fContextType(contextType) , fContextOverrides(ContextOverrides::kNone) @@ -433,6 +438,7 @@ SkCommandLineConfigGpu::SkCommandLineConfigGpu( , fAlphaType(alphaType) , fColorSpace(std::move(colorSpace)) , fTestThreading(testThreading) + , fTestPersistentCache(testPersistentCache) , fSurfType(surfType) { if (useNVPR) { fContextOverrides |= ContextOverrides::kRequireNVPRSupport; @@ -459,6 +465,7 @@ SkCommandLineConfigGpu* parse_command_line_config_gpu(const SkString& tag, sk_sp<SkColorSpace> colorSpace = nullptr; bool useStencils = true; bool testThreading = false; + bool testPersistentCache = false; SkCommandLineConfigGpu::SurfType surfType = SkCommandLineConfigGpu::SurfType::kDefault; bool parseSucceeded = false; @@ -475,16 +482,17 @@ SkCommandLineConfigGpu* parse_command_line_config_gpu(const SkString& tag, extendedOptions.get_option_gpu_color("color", &colorType, &alphaType, &colorSpace) && extendedOptions.get_option_bool("stencils", &useStencils) && extendedOptions.get_option_bool("testThreading", &testThreading) && - extendedOptions.get_option_bool("testThreading", &testThreading) && + extendedOptions.get_option_bool("testPersistentCache", &testPersistentCache) && extendedOptions.get_option_gpu_surf_type("surf", &surfType); - if (!validOptions) { + // testing threading and the persistent cache are mutually exclusive. + if (!validOptions || (testThreading && testPersistentCache)) { return nullptr; } return new SkCommandLineConfigGpu(tag, vias, contextType, useNVPR, useDIText, samples, colorType, alphaType, colorSpace, useStencils, testThreading, - surfType); + testPersistentCache, surfType); } SkCommandLineConfigSvg::SkCommandLineConfigSvg(const SkString& tag, diff --git a/tools/flags/SkCommonFlagsConfig.h b/tools/flags/SkCommonFlagsConfig.h index 7c097ea888..fa11cc622d 100644 --- a/tools/flags/SkCommonFlagsConfig.h +++ b/tools/flags/SkCommonFlagsConfig.h @@ -57,7 +57,7 @@ public: ContextType contextType, bool useNVPR, bool useDIText, int samples, SkColorType colorType, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace, bool useStencilBuffers, - bool testThreading, SurfType); + bool testThreading, bool testPersistentCache, SurfType); const SkCommandLineConfigGpu* asConfigGpu() const override { return this; } ContextType getContextType() const { return fContextType; } @@ -73,6 +73,7 @@ public: SkAlphaType getAlphaType() const { return fAlphaType; } SkColorSpace* getColorSpace() const { return fColorSpace.get(); } bool getTestThreading() const { return fTestThreading; } + bool getTestPersistentCache() const { return fTestPersistentCache; } SurfType getSurfType() const { return fSurfType; } private: @@ -84,6 +85,7 @@ private: SkAlphaType fAlphaType; sk_sp<SkColorSpace> fColorSpace; bool fTestThreading; + bool fTestPersistentCache; SurfType fSurfType; }; diff --git a/tools/gpu/MemoryCache.cpp b/tools/gpu/MemoryCache.cpp new file mode 100644 index 0000000000..7fc3e1b5d0 --- /dev/null +++ b/tools/gpu/MemoryCache.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "MemoryCache.h" +#include "SkBase64.h" + +// Change this to 1 to log cache hits/misses/stores using SkDebugf. +#define LOG_MEMORY_CACHE 0 + +static SkString data_to_str(const SkData& data) { + size_t encodeLength = SkBase64::Encode(data.data(), data.size(), nullptr); + SkString str; + str.resize(encodeLength); + SkBase64::Encode(data.data(), data.size(), str.writable_str()); + static constexpr size_t kMaxLength = 60; + static constexpr char kTail[] = "..."; + static const size_t kTailLen = strlen(kTail); + bool overlength = encodeLength > kMaxLength; + if (overlength) { + str = SkString(str.c_str(), kMaxLength - kTailLen); + str.append(kTail); + } + return str; +} + +namespace sk_gpu_test { + +sk_sp<SkData> MemoryCache::load(const SkData& key) { + auto result = fMap.find(key); + if (result == fMap.end()) { + if (LOG_MEMORY_CACHE) { + SkDebugf("Load Key: %s\n\tNot Found.\n\n", data_to_str(key).c_str()); + } + ++fCacheMissCnt; + return nullptr; + } + if (LOG_MEMORY_CACHE) { + SkDebugf("Load Key: %s\n\tFound Data: %s\n\n", data_to_str(key).c_str(), + data_to_str(*result->second).c_str()); + } + return result->second; +} + +void MemoryCache::store(const SkData& key, const SkData& data) { + if (LOG_MEMORY_CACHE) { + SkDebugf("Store Key: %s\n\tData: %s\n\n", data_to_str(key).c_str(), + data_to_str(data).c_str()); + } + fMap[Key(key)] = SkData::MakeWithCopy(data.data(), data.size()); +} + +} // namespace sk_gpu_test diff --git a/tools/gpu/MemoryCache.h b/tools/gpu/MemoryCache.h new file mode 100644 index 0000000000..568f755ac5 --- /dev/null +++ b/tools/gpu/MemoryCache.h @@ -0,0 +1,62 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef MemoryCache_DEFINED +#define MemoryCache_DEFINED + +#include <unordered_map> +#include "GrContextOptions.h" +#include "SkChecksum.h" +#include "SkData.h" + +namespace sk_gpu_test { + +/** + * This class can be used to maintain an in memory record of all programs cached by GrContext. + * It can be shared by multiple GrContexts so long as those GrContexts are created with the same + * options and will have the same GrCaps (e.g. same backend, same GL context creation parameters, + * ...). + */ +class MemoryCache : public GrContextOptions::PersistentCache { +public: + MemoryCache() = default; + MemoryCache(const MemoryCache&) = delete; + MemoryCache& operator=(const MemoryCache&) = delete; + + sk_sp<SkData> load(const SkData& key) override; + void store(const SkData& key, const SkData& data) override; + int numCacheMisses() const { return fCacheMissCnt; } + void resetNumCacheMisses() { fCacheMissCnt = 0; } + +private: + struct Key { + Key() = default; + Key(const SkData& key) : fKey(SkData::MakeWithCopy(key.data(), key.size())) {} + Key(const Key& that) = default; + Key& operator=(const Key&) = default; + bool operator==(const Key& that) const { + return that.fKey->size() == fKey->size() && + !memcmp(fKey->data(), that.fKey->data(), that.fKey->size()); + } + sk_sp<const SkData> fKey; + }; + + struct Hash { + using argument_type = Key; + using result_type = uint32_t; + uint32_t operator()(const Key& key) const { + return key.fKey ? SkOpts::hash_fn(key.fKey->data(), key.fKey->size(), 0) : 0; + } + }; + + int fCacheMissCnt = 0; + std::unordered_map<Key, sk_sp<SkData>, Hash> fMap; +}; + +} // namespace sk_gpu_test + +#endif |