Move runtime-effect dictionary into Graphite ResourceProvider.

Putting the dictionary in the Recorder itself was not very useful; the
recorder is inaccessible throughout the call chain of pipeline setup.
The ResourceProvider, on the other hand, is accessible everywhere we
need it, hangs directly off the Recorder, and has the right lifetime
for our purposes.

Change-Id: I0f494e5890845d73343a71359900598d63b66764
Bug: skia:13405
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/556917
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2022-07-08 15:31:23 -04:00 committed by SkCQ
parent 655de12b82
commit bd472a01ed
11 changed files with 54 additions and 19 deletions

View File

@ -342,6 +342,7 @@ skia_core_sources = [
"$_src/core/SkRegion_path.cpp",
"$_src/core/SkResourceCache.cpp",
"$_src/core/SkRuntimeEffect.cpp",
"$_src/core/SkRuntimeEffectDictionary.h",
"$_src/core/SkRuntimeEffectPriv.h",
"$_src/core/SkSLTypeShared.cpp",
"$_src/core/SkSLTypeShared.h",

View File

@ -109,11 +109,6 @@ private:
std::unique_ptr<sktext::gpu::StrikeCache> fStrikeCache;
std::unique_ptr<sktext::gpu::TextBlobRedrawCoordinator> fTextBlobCache;
// We keep track of all SkRuntimeEffects that are connected to a Recorder, along with their code
// snippet ID. This ensures that we have a live reference to every effect that we're going to
// paint, and gives us a way to retrieve their shader text when we see an their code-snippet ID.
SkTHashMap<int, sk_sp<const SkRuntimeEffect>> fRuntimeEffectMap;
// In debug builds we guard against improper thread handling
// This guard is passed to the ResourceCache.
// TODO: Should we also pass this to Device, DrawContext, and similar classes?

View File

@ -625,6 +625,7 @@ BASE_SRCS_ALL = [
"src/core/SkResourceCache.cpp",
"src/core/SkResourceCache.h",
"src/core/SkRuntimeEffect.cpp",
"src/core/SkRuntimeEffectDictionary.h",
"src/core/SkRuntimeEffectPriv.h",
"src/core/SkSLTypeShared.cpp",
"src/core/SkSLTypeShared.h",

View File

@ -291,6 +291,7 @@ CORE_FILES = [
"SkRegion_path.cpp",
"SkResourceCache.cpp",
"SkResourceCache.h",
"SkRuntimeEffectDictionary.h",
"SkRuntimeEffectPriv.h",
"SkSafeMath.h",
"SkSafeRange.h",

View File

@ -20,6 +20,7 @@
#ifdef SK_GRAPHITE_ENABLED
#include "src/gpu/Blend.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/TextureProxy.h"
#include "src/gpu/graphite/UniformManager.h"
@ -588,8 +589,8 @@ void RuntimeShaderBlock::BeginBlock(const SkKeyContext& keyContext,
int codeSnippetID = dict->findOrCreateRuntimeEffectSnippet(shaderData.fEffect.get());
skgpu::graphite::Recorder* recorder = keyContext.recorder();
recorder->priv().addRuntimeEffect(codeSnippetID, shaderData.fEffect);
recorder->priv().resourceProvider()->runtimeEffectDictionary()->set(codeSnippetID,
shaderData.fEffect);
if (gatherer) {
const SkShaderSnippet* entry = dict->getEntry(codeSnippetID);
SkASSERT(entry);

View File

@ -0,0 +1,36 @@
/*
* 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 SkRuntimeEffectDictionary_DEFINED
#define SkRuntimeEffectDictionary_DEFINED
#include "include/core/SkRefCnt.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/SkTHash.h"
#include "src/core/SkRuntimeEffectPriv.h"
class SkRuntimeEffect;
// We keep track of all SkRuntimeEffects that are used by a recording, along with their code
// snippet ID. This ensures that we have a live reference to every effect that we're going to
// paint, and gives us a way to retrieve their shader text when we see an their code-snippet ID.
class SkRuntimeEffectDictionary {
public:
void set(int codeSnippetID, sk_sp<const SkRuntimeEffect> effect) {
// The same code-snippet ID should never refer to two different effects.
SkASSERT(!fDict.find(codeSnippetID) || (SkRuntimeEffectPriv::Hash(*fDict[codeSnippetID]) ==
SkRuntimeEffectPriv::Hash(*effect)));
fDict.set(codeSnippetID, std::move(effect));
}
void reset() { fDict.reset(); }
private:
SkTHashMap<int, sk_sp<const SkRuntimeEffect>> fDict;
};
#endif // SkRuntimeEffectDictionary_DEFINED

View File

@ -84,7 +84,7 @@ std::unique_ptr<Recording> Recorder::snap() {
fTextureDataCache = std::make_unique<TextureDataCache>();
// We leave the UniformDataCache alone
fGraph->reset();
fRuntimeEffectMap.reset();
fResourceProvider->resetAfterSnap();
return nullptr;
}
@ -93,7 +93,7 @@ std::unique_ptr<Recording> Recorder::snap() {
fUploadBufferManager->transferToRecording(recording.get());
fGraph = std::make_unique<TaskGraph>();
fRuntimeEffectMap.reset();
fResourceProvider->resetAfterSnap();
fTextureDataCache = std::make_unique<TextureDataCache>();
return recording;
}

View File

@ -76,15 +76,6 @@ void RecorderPriv::add(sk_sp<Task> task) {
fRecorder->fGraph->add(std::move(task));
}
void RecorderPriv::addRuntimeEffect(int codeSnippetID, sk_sp<const SkRuntimeEffect> effect) {
ASSERT_SINGLE_OWNER
// The same code-snippet ID should never refer to two different effects.
SkASSERT(!fRecorder->fRuntimeEffectMap.find(codeSnippetID) ||
(SkRuntimeEffectPriv::Hash(*fRecorder->fRuntimeEffectMap[codeSnippetID]) ==
SkRuntimeEffectPriv::Hash(*effect)));
fRecorder->fRuntimeEffectMap.set(codeSnippetID, std::move(effect));
}
void RecorderPriv::flushTrackedDevices() {
ASSERT_SINGLE_OWNER
for (Device* device : fRecorder->fTrackedDevices) {

View File

@ -16,7 +16,6 @@ namespace skgpu::graphite {
class RecorderPriv {
public:
void add(sk_sp<Task>);
void addRuntimeEffect(int codeSnippetID, sk_sp<const SkRuntimeEffect>);
ResourceProvider* resourceProvider() const;
UniformDataCache* uniformDataCache() const;

View File

@ -197,5 +197,8 @@ sk_sp<Buffer> ResourceProvider::findOrCreateBuffer(size_t size,
return buffer;
}
void ResourceProvider::resetAfterSnap() {
fRuntimeEffectDictionary.reset();
}
} // namespace skgpu::graphite

View File

@ -11,6 +11,7 @@
#include "include/core/SkSize.h"
#include "include/core/SkTileMode.h"
#include "src/core/SkLRUCache.h"
#include "src/core/SkRuntimeEffectDictionary.h"
#include "src/gpu/ResourceKey.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/GraphicsPipelineDesc.h"
@ -63,6 +64,10 @@ public:
SkShaderCodeDictionary* shaderCodeDictionary() const;
SkRuntimeEffectDictionary* runtimeEffectDictionary() { return &fRuntimeEffectDictionary; }
void resetAfterSnap();
#if GRAPHITE_TEST_UTILS
ResourceCache* resourceCache() { return fResourceCache.get(); }
const Gpu* gpu() { return fGpu; }
@ -116,6 +121,8 @@ private:
// Cache of GraphicsPipelines
// TODO: Move this onto GlobalCache
std::unique_ptr<GraphicsPipelineCache> fGraphicsPipelineCache;
SkRuntimeEffectDictionary fRuntimeEffectDictionary;
};
} // namespace skgpu::graphite