[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:
parent
3d25a39b35
commit
bc1e97ee5f
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
19
experimental/graphite/src/GlobalCache.cpp
Normal file
19
experimental/graphite/src/GlobalCache.cpp
Normal 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
|
||||
|
32
experimental/graphite/src/GlobalCache.h
Normal file
32
experimental/graphite/src/GlobalCache.h
Normal 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
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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&);
|
||||
|
@ -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],
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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));
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user