[graphite] Add GlobalCache class to hold objects that can be accesed by all Recorders.

This class will be used to provide thread safe access to various shared
resources in Graphite. Currently the only thing moved onto here is
the SkShaderCodeDictionary. Eventually it will have things like the
pipeline cache on it as well.

The plan is that users will not access this class directly but instead
via a ResourceProvider (see follow on change).

Bug: skia:12754
Change-Id: I2ae2c4bf7025945de850a618055e59ccd403aaaa
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/502315
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2022-02-01 16:15:04 -05:00 committed by SkCQ
parent 3d25a39b35
commit bc1e97ee5f
18 changed files with 114 additions and 46 deletions

View File

@ -16,12 +16,11 @@
#include "experimental/graphite/include/GraphiteTypes.h"
class SkShaderCodeDictionary;
namespace skgpu {
class BackendTexture;
class ContextPriv;
class GlobalCache;
class Gpu;
class Recorder;
class Recording;
@ -103,8 +102,8 @@ private:
std::vector<std::unique_ptr<Recording>> fRecordings;
sk_sp<Gpu> fGpu;
sk_sp<GlobalCache> fGlobalCache;
BackendApi fBackend;
std::unique_ptr<SkShaderCodeDictionary> fShaderCodeDictionary;
};
} // namespace skgpu

View File

@ -14,6 +14,7 @@
#include "experimental/graphite/src/Caps.h"
#include "experimental/graphite/src/CommandBuffer.h"
#include "experimental/graphite/src/ContextUtils.h"
#include "experimental/graphite/src/GlobalCache.h"
#include "experimental/graphite/src/Gpu.h"
#include "experimental/graphite/src/GraphicsPipelineDesc.h"
#include "experimental/graphite/src/Renderer.h"
@ -29,8 +30,8 @@ namespace skgpu {
Context::Context(sk_sp<Gpu> gpu, BackendApi backend)
: fGpu(std::move(gpu))
, fBackend(backend)
, fShaderCodeDictionary(std::make_unique<SkShaderCodeDictionary>()) {
, fGlobalCache(sk_make_sp<GlobalCache>())
, fBackend(backend) {
}
Context::~Context() {}
@ -83,8 +84,8 @@ void Context::preCompile(const PaintCombo& paintCombo) {
for (const Renderer* r : kRenderers) {
for (auto&& s : r->steps()) {
if (s->performsShading()) {
auto entry = fShaderCodeDictionary->findOrCreate(key);
auto entry =
fGlobalCache->shaderCodeDictionary()->findOrCreate(key);
desc.setProgram(s, entry->uniqueID());
}
// TODO: Combine with renderpass description set to generate full

View File

@ -23,12 +23,8 @@ ResourceProvider* ContextPriv::resourceProvider() {
return this->gpu()->resourceProvider();
}
SkShaderCodeDictionary* ContextPriv::shaderCodeDictionary() {
return fContext->fShaderCodeDictionary.get();
}
const SkShaderCodeDictionary* ContextPriv::shaderCodeDictionary() const {
return fContext->fShaderCodeDictionary.get();
GlobalCache* ContextPriv::globalCache() {
return fContext->fGlobalCache.get();
}
} // namespace skgpu

View File

@ -12,6 +12,7 @@
namespace skgpu {
class GlobalCache;
class Gpu;
class ResourceProvider;
@ -25,8 +26,9 @@ public:
ResourceProvider* resourceProvider();
SkShaderCodeDictionary* shaderCodeDictionary();
const SkShaderCodeDictionary* shaderCodeDictionary() const;
// TODO: Remove accessor from Context. Users should get this through ResourceProvider once
// future changes land.
GlobalCache* globalCache();
private:
friend class Context; // to construct/copy this type.

View File

@ -199,12 +199,10 @@ sk_sp<SkUniformData> make_solid_uniform_data(SkColor4f color) {
} // anonymous namespace
std::tuple<SkUniquePaintParamsID, std::unique_ptr<SkUniformBlock>> ExtractPaintData(
Context* context, const PaintParams& p) {
SkShaderCodeDictionary* dictionary, const PaintParams& p) {
SkPaintParamsKey key;
sk_sp<SkUniformData> uniforms;
auto dict = context->priv().shaderCodeDictionary();
std::unique_ptr<SkUniformBlock> block = std::make_unique<SkUniformBlock>();
// TODO: add UniformData generation to PaintParams::toKey and use it here
@ -305,12 +303,12 @@ std::tuple<SkUniquePaintParamsID, std::unique_ptr<SkUniformBlock>> ExtractPaintD
}
if (p.blender()) {
as_BB(p.blender())->addToKey(dict, SkBackend::kGraphite, &key, block.get());
as_BB(p.blender())->addToKey(dictionary, SkBackend::kGraphite, &key, block.get());
} else {
BlendModeBlock::AddToKey(SkBackend::kGraphite, &key, block.get(), SkBlendMode::kSrcOver);
}
auto entry = context->priv().shaderCodeDictionary()->findOrCreate(key);
auto entry = dictionary->findOrCreate(key);
block->add(std::move(uniforms));

View File

@ -14,6 +14,7 @@
#include "include/core/SkTileMode.h"
enum class CodeSnippetID : uint8_t;
class SkShaderCodeDictionary;
class SkUniform;
class SkUniformBlock;
class SkUniquePaintParamsID;
@ -23,7 +24,8 @@ namespace skgpu {
class PaintParams;
std::tuple<SkUniquePaintParamsID, std::unique_ptr<SkUniformBlock>> ExtractPaintData(
Context*, const PaintParams&);
SkShaderCodeDictionary*, const PaintParams&);
SkSpan<const SkUniform> GetUniforms(CodeSnippetID);
// TODO: Temporary way to get at SkSL snippet for handling the given shader type, which will be

View File

@ -15,6 +15,7 @@
#include "experimental/graphite/src/DrawContext.h"
#include "experimental/graphite/src/DrawList.h"
#include "experimental/graphite/src/DrawWriter.h"
#include "experimental/graphite/src/GlobalCache.h"
#include "experimental/graphite/src/GraphicsPipeline.h"
#include "experimental/graphite/src/GraphicsPipelineDesc.h"
#include "experimental/graphite/src/Renderer.h"
@ -293,8 +294,9 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
std::unique_ptr<SkUniformBlock> shadingUniforms;
uint32_t shadingIndex = UniformCache::kInvalidUniformID;
if (draw.fPaintParams.has_value()) {
std::tie(shaderID, shadingUniforms) = ExtractPaintData(recorder->context(),
draw.fPaintParams.value());
SkShaderCodeDictionary* dict =
recorder->context()->priv().globalCache()->shaderCodeDictionary();
std::tie(shaderID, shadingUniforms) = ExtractPaintData(dict, draw.fPaintParams.value());
shadingIndex = shadingUniformBindings.addUniforms(std::move(shadingUniforms));
} // else depth-only
@ -436,7 +438,9 @@ void DrawPass::addCommands(Context* context, CommandBuffer* buffer,
fullPipelines.reserve(fPipelineDescs.count());
for (const GraphicsPipelineDesc& pipelineDesc : fPipelineDescs.items()) {
fullPipelines.push_back(resourceProvider->findOrCreateGraphicsPipeline(
context, pipelineDesc, renderPassDesc));
context->priv().globalCache()->shaderCodeDictionary(),
pipelineDesc,
renderPassDesc));
}
// Set viewport to the entire texture for now (eventually, we may have logically smaller bounds

View File

@ -0,0 +1,19 @@
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "experimental/graphite/src/GlobalCache.h"
#include "include/private/SkShaderCodeDictionary.h"
namespace skgpu {
GlobalCache::GlobalCache() : fShaderCodeDictionary(std::make_unique<SkShaderCodeDictionary>()) {}
GlobalCache::~GlobalCache() {};
} // namespace skgpu

View File

@ -0,0 +1,32 @@
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef skgpu_GlobalCache_DEFINED
#define skgpu_GlobalCache_DEFINED
#include "include/core/SkRefCnt.h"
class SkShaderCodeDictionary;
namespace skgpu {
// TODO: This class needs to be thread safe. In the current version there is no thread safety and
// we need to go back and add protection around access to any of its memebers.
class GlobalCache : public SkRefCnt {
public:
GlobalCache();
~GlobalCache() override;
SkShaderCodeDictionary* shaderCodeDictionary() const { return fShaderCodeDictionary.get(); }
private:
std::unique_ptr<SkShaderCodeDictionary> fShaderCodeDictionary;
};
} // namespace skgpu
#endif // skgpu_GlobalCache_DEFINED

View File

@ -27,9 +27,10 @@ ResourceProvider::~ResourceProvider() {
}
sk_sp<GraphicsPipeline> ResourceProvider::findOrCreateGraphicsPipeline(
Context* context, const GraphicsPipelineDesc& pipelineDesc,
SkShaderCodeDictionary* dict,
const GraphicsPipelineDesc& pipelineDesc,
const RenderPassDesc& renderPassDesc) {
return fGraphicsPipelineCache->refPipeline(context, pipelineDesc, renderPassDesc);
return fGraphicsPipelineCache->refPipeline(dict, fGpu->caps(), pipelineDesc, renderPassDesc);
}
////////////////////////////////////////////////////////////////////////////////////////////////
@ -53,15 +54,17 @@ void ResourceProvider::GraphicsPipelineCache::release() {
}
sk_sp<GraphicsPipeline> ResourceProvider::GraphicsPipelineCache::refPipeline(
Context* context, const GraphicsPipelineDesc& pipelineDesc,
SkShaderCodeDictionary* dictionary,
const Caps* caps,
const GraphicsPipelineDesc& pipelineDesc,
const RenderPassDesc& renderPassDesc) {
Gpu* gpu = context->priv().gpu();
UniqueKey pipelineKey = gpu->caps()->makeGraphicsPipelineKey(pipelineDesc, renderPassDesc);
UniqueKey pipelineKey = caps->makeGraphicsPipelineKey(pipelineDesc, renderPassDesc);
std::unique_ptr<Entry>* entry = fMap.find(pipelineKey);
if (!entry) {
auto pipeline = fResourceProvider->onCreateGraphicsPipeline(context, pipelineDesc,
auto pipeline = fResourceProvider->onCreateGraphicsPipeline(dictionary,
pipelineDesc,
renderPassDesc);
if (!pipeline) {
return nullptr;

View File

@ -22,6 +22,7 @@ namespace skgpu {
class BackendTexture;
class Buffer;
class Caps;
class Gpu;
class GraphicsPipeline;
class Sampler;
@ -34,7 +35,8 @@ public:
virtual sk_sp<CommandBuffer> createCommandBuffer() = 0;
sk_sp<GraphicsPipeline> findOrCreateGraphicsPipeline(Context*, const GraphicsPipelineDesc&,
sk_sp<GraphicsPipeline> findOrCreateGraphicsPipeline(SkShaderCodeDictionary*,
const GraphicsPipelineDesc&,
const RenderPassDesc&);
sk_sp<Texture> findOrCreateTexture(SkISize, const TextureInfo&);
@ -52,7 +54,7 @@ protected:
const Gpu* fGpu;
private:
virtual sk_sp<GraphicsPipeline> onCreateGraphicsPipeline(Context*,
virtual sk_sp<GraphicsPipeline> onCreateGraphicsPipeline(SkShaderCodeDictionary*,
const GraphicsPipelineDesc&,
const RenderPassDesc&) = 0;
virtual sk_sp<Texture> createTexture(SkISize, const TextureInfo&) = 0;
@ -68,7 +70,9 @@ private:
~GraphicsPipelineCache();
void release();
sk_sp<GraphicsPipeline> refPipeline(Context*, const GraphicsPipelineDesc&,
sk_sp<GraphicsPipeline> refPipeline(SkShaderCodeDictionary*,
const Caps* caps,
const GraphicsPipelineDesc&,
const RenderPassDesc&);
private:

View File

@ -15,6 +15,8 @@
#import <Metal/Metal.h>
class SkShaderCodeDictionary;
namespace skgpu {
class Context;
class GraphicsPipelineDesc;
@ -32,7 +34,7 @@ public:
inline static constexpr unsigned int kVertexBufferIndex = 3;
inline static constexpr unsigned int kInstanceBufferIndex = 4;
static sk_sp<GraphicsPipeline> Make(const Context*,
static sk_sp<GraphicsPipeline> Make(const SkShaderCodeDictionary*,
const Gpu*,
const skgpu::GraphicsPipelineDesc&,
const skgpu::RenderPassDesc&);

View File

@ -8,7 +8,6 @@
#include "experimental/graphite/src/mtl/MtlGraphicsPipeline.h"
#include "experimental/graphite/include/TextureInfo.h"
#include "experimental/graphite/src/ContextPriv.h"
#include "experimental/graphite/src/GraphicsPipelineDesc.h"
#include "experimental/graphite/src/Log.h"
#include "experimental/graphite/src/Renderer.h"
@ -155,13 +154,13 @@ SkSL::String get_sksl_vs(const GraphicsPipelineDesc& desc) {
return sksl;
}
SkSL::String get_sksl_fs(const Context* context,
SkSL::String get_sksl_fs(const SkShaderCodeDictionary* dictionary,
const GraphicsPipelineDesc& desc,
bool* writesColor) {
SkSL::String sksl;
SkPaintParamsKey key;
auto entry = context->priv().shaderCodeDictionary()->lookup(desc.paintParamsID());
auto entry = dictionary->lookup(desc.paintParamsID());
if (entry) {
key = entry->paintParamsKey();
}
@ -338,7 +337,7 @@ enum ShaderType {
};
static const int kShaderTypeCount = kLast_ShaderType + 1;
sk_sp<GraphicsPipeline> GraphicsPipeline::Make(const Context* context,
sk_sp<GraphicsPipeline> GraphicsPipeline::Make(const SkShaderCodeDictionary* dictionary,
const Gpu* gpu,
const skgpu::GraphicsPipelineDesc& pipelineDesc,
const skgpu::RenderPassDesc& renderPassDesc) {
@ -361,7 +360,7 @@ sk_sp<GraphicsPipeline> GraphicsPipeline::Make(const Context* context,
bool writesColor;
if (!SkSLToMSL(gpu,
get_sksl_fs(context, pipelineDesc, &writesColor),
get_sksl_fs(dictionary, pipelineDesc, &writesColor),
SkSL::ProgramKind::kFragment,
settings,
&msl[kFragment_ShaderType],

View File

@ -36,7 +36,7 @@ private:
const Gpu* mtlGpu();
sk_sp<skgpu::CommandBuffer> createCommandBuffer() override;
sk_sp<skgpu::GraphicsPipeline> onCreateGraphicsPipeline(Context*,
sk_sp<skgpu::GraphicsPipeline> onCreateGraphicsPipeline(SkShaderCodeDictionary*,
const GraphicsPipelineDesc&,
const RenderPassDesc&) override;
sk_sp<skgpu::Texture> createTexture(SkISize, const skgpu::TextureInfo&) override;

View File

@ -33,9 +33,10 @@ sk_sp<skgpu::CommandBuffer> ResourceProvider::createCommandBuffer() {
}
sk_sp<skgpu::GraphicsPipeline> ResourceProvider::onCreateGraphicsPipeline(
Context* context, const GraphicsPipelineDesc& pipelineDesc,
SkShaderCodeDictionary* dict,
const GraphicsPipelineDesc& pipelineDesc,
const RenderPassDesc& renderPassDesc) {
return GraphicsPipeline::Make(context, this->mtlGpu(), pipelineDesc, renderPassDesc);
return GraphicsPipeline::Make(dict, this->mtlGpu(), pipelineDesc, renderPassDesc);
}
sk_sp<skgpu::Texture> ResourceProvider::createTexture(SkISize dimensions,

View File

@ -48,6 +48,8 @@ skia_graphite_sources = [
"$_src/DrawWriter.cpp",
"$_src/DrawWriter.h",
"$_src/EnumBitMask.h",
"$_src/GlobalCache.cpp",
"$_src/GlobalCache.h",
"$_src/Gpu.cpp",
"$_src/Gpu.h",
"$_src/GpuWorkSubmission.h",

View File

@ -17,6 +17,7 @@
#include "experimental/graphite/src/ContextUtils.h"
#include "experimental/graphite/src/DrawBufferManager.h"
#include "experimental/graphite/src/DrawWriter.h"
#include "experimental/graphite/src/GlobalCache.h"
#include "experimental/graphite/src/Gpu.h"
#include "experimental/graphite/src/GraphicsPipeline.h"
#include "experimental/graphite/src/Renderer.h"
@ -257,7 +258,8 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(CommandBufferTest, reporter, context) {
SkTileMode::kClamp,
SkBlendMode::kSrc);
auto entry = context->priv().shaderCodeDictionary()->findOrCreate(key);
auto dict = context->priv().globalCache()->shaderCodeDictionary();
auto entry = dict->findOrCreate(key);
auto target = sk_sp<TextureProxy>(new TextureProxy(textureSize, textureInfo));
REPORTER_ASSERT(reporter, target);
@ -304,7 +306,7 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(CommandBufferTest, reporter, context) {
drawWriter.newPipelineState(step->primitiveType(),
step->vertexStride(),
step->instanceStride());
auto pipeline = gpu->resourceProvider()->findOrCreateGraphicsPipeline(context,
auto pipeline = gpu->resourceProvider()->findOrCreateGraphicsPipeline(dict,
pipelineDesc,
renderPassDesc);
commandBuffer->bindGraphicsPipeline(std::move(pipeline));

View File

@ -9,6 +9,7 @@
#include "experimental/graphite/src/ContextPriv.h"
#include "experimental/graphite/src/ContextUtils.h"
#include "experimental/graphite/src/GlobalCache.h"
#include "experimental/graphite/src/PaintParams.h"
#include "include/core/SkPaint.h"
#include "include/effects/SkGradientShader.h"
@ -87,10 +88,11 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(UniformTest, reporter, context) {
SkPaintParamsKey expected = CreateKey(SkBackend::kGraphite, s, tm, bm);
auto [ p, expectedNumUniforms ] = create_paint(s, tm, bm);
auto [ actualID, uniformBlock] = ExtractPaintData(context, PaintParams(p));
auto dict = context->priv().globalCache()->shaderCodeDictionary();
auto [ actualID, uniformBlock] = ExtractPaintData(dict, PaintParams(p));
int actualNumUniforms = uniformBlock->count();
auto entry = context->priv().shaderCodeDictionary()->lookup(actualID);
auto entry = dict->lookup(actualID);
REPORTER_ASSERT(reporter, expected == entry->paintParamsKey());