[graphite] Plumb Recorder down into KeyHelpers

The KeyContext is used in the addToKey methods but must appear in the
AddToKey methods bc the latter can call the former.

Bug: skia:12701
Change-Id: I3143afec8337b1e3e12f1c3cc198714009ca6930
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/520539
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2022-03-15 12:52:36 -04:00 committed by SkCQ
parent 4a3601ed39
commit 9565f4bd90
36 changed files with 277 additions and 104 deletions

View File

@ -19,6 +19,7 @@
#include "experimental/graphite/src/Renderer.h"
#include "experimental/graphite/src/ResourceProvider.h"
#include "include/core/SkPathTypes.h"
#include "src/core/SkKeyContext.h"
#include "src/core/SkKeyHelpers.h"
#include "src/core/SkShaderCodeDictionary.h"
@ -74,6 +75,7 @@ void Context::preCompile(const PaintCombo& paintCombo) {
};
SkShaderCodeDictionary* dict = fGlobalCache->shaderCodeDictionary();
SkKeyContext keyContext(dict);
SkPaintParamsKeyBuilder builder(dict, SkBackend::kGraphite);
@ -81,7 +83,7 @@ void Context::preCompile(const PaintCombo& paintCombo) {
for (auto& shaderCombo: paintCombo.fShaders) {
for (auto shaderType: shaderCombo.fTypes) {
for (auto tm: shaderCombo.fTileModes) {
auto uniqueID = CreateKey(dict, &builder, shaderType, tm, bm);
auto uniqueID = CreateKey(keyContext, &builder, shaderType, tm, bm);
GraphicsPipelineDesc desc;

View File

@ -11,24 +11,29 @@
#include "experimental/graphite/src/PaintParams.h"
#include "include/private/SkUniquePaintParamsID.h"
#include "src/core/SkBlenderBase.h"
#include "src/core/SkKeyContext.h"
#include "src/core/SkPipelineData.h"
#include "src/core/SkShaderCodeDictionary.h"
namespace skgpu {
std::tuple<SkUniquePaintParamsID, std::unique_ptr<SkPipelineData>> ExtractPaintData(
SkShaderCodeDictionary* dict,
Recorder* recorder,
SkPaintParamsKeyBuilder* builder,
const PaintParams& p) {
SkDEBUGCODE(builder->checkReset());
SkKeyContext keyContext(recorder);
std::unique_ptr<SkPipelineData> pipelineData = std::make_unique<SkPipelineData>();
p.toKey(dict, builder, pipelineData.get());
p.toKey(keyContext, builder, pipelineData.get());
SkPaintParamsKey key = builder->lockAsKey();
auto dict = keyContext.dict();
auto entry = dict->findOrCreate(key, pipelineData->blendInfo());
return { entry->uniqueID(), std::move(pipelineData) };

View File

@ -25,7 +25,7 @@ namespace skgpu {
class PaintParams;
std::tuple<SkUniquePaintParamsID, std::unique_ptr<SkPipelineData>> ExtractPaintData(
SkShaderCodeDictionary*,
Recorder*,
SkPaintParamsKeyBuilder* builder,
const PaintParams&);

View File

@ -305,7 +305,7 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
uint32_t shadingIndex = PipelineDataCache::kInvalidUniformID;
if (draw.fPaintParams.has_value()) {
std::unique_ptr<SkPipelineData> pipelineData;
std::tie(shaderID, pipelineData) = ExtractPaintData(dict, &builder,
std::tie(shaderID, pipelineData) = ExtractPaintData(recorder, &builder,
draw.fPaintParams.value());
shadingIndex = shadingUniformBindings.addUniforms(std::move(pipelineData));
} // else depth-only

View File

@ -40,20 +40,20 @@ sk_sp<SkBlender> PaintParams::refBlender() const { return fBlender; }
sk_sp<SkShader> PaintParams::refShader() const { return fShader; }
void PaintParams::toKey(SkShaderCodeDictionary* dict,
void PaintParams::toKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
if (fShader) {
as_SB(fShader)->addToKey(dict, builder, pipelineData);
as_SB(fShader)->addToKey(keyContext, builder, pipelineData);
} else {
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData, fColor.premul());
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, fColor.premul());
}
if (fBlender) {
as_BB(fBlender)->addToKey(dict, builder, pipelineData);
as_BB(fBlender)->addToKey(keyContext, builder, pipelineData);
} else {
BlendModeBlock::AddToKey(dict, builder, pipelineData, SkBlendMode::kSrcOver);
BlendModeBlock::AddToKey(keyContext, builder, pipelineData, SkBlendMode::kSrcOver);
}
SkASSERT(builder->sizeInBytes() > 0);

View File

@ -15,7 +15,7 @@ enum class SkBackend : uint8_t;
class SkPaintParamsKeyBuilder;
class SkPipelineData;
class SkShader;
class SkShaderCodeDictionary;
class SkKeyContext;
namespace skgpu {
@ -44,7 +44,7 @@ public:
SkShader* shader() const { return fShader.get(); }
sk_sp<SkShader> refShader() const;
void toKey(SkShaderCodeDictionary*,
void toKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const;

View File

@ -247,6 +247,8 @@ skia_core_sources = [
"$_src/core/SkImageFilter_Base.h",
"$_src/core/SkImageGenerator.cpp",
"$_src/core/SkImageInfo.cpp",
"$_src/core/SkKeyContext.cpp",
"$_src/core/SkKeyContext.h",
"$_src/core/SkKeyHelpers.cpp",
"$_src/core/SkKeyHelpers.h",
"$_src/core/SkLRUCache.h",

View File

@ -64,14 +64,14 @@ sk_sp<SkBlender> SkBlender::Mode(SkBlendMode mode) {
}
#ifdef SK_ENABLE_SKSL
void SkBlenderBase::addToKey(SkShaderCodeDictionary* dict,
void SkBlenderBase::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
if (std::optional<SkBlendMode> bm = as_BB(this)->asBlendMode(); bm.has_value()) {
BlendModeBlock::AddToKey(dict, builder, pipelineData, bm.value());
BlendModeBlock::AddToKey(keyContext, builder, pipelineData, bm.value());
} else {
BlendModeBlock::AddToKey(dict, builder, pipelineData, SkBlendMode::kSrcOver);
BlendModeBlock::AddToKey(keyContext, builder, pipelineData, SkBlendMode::kSrcOver);
}
}
#endif

View File

@ -21,7 +21,7 @@ class SkColorInfo;
class SkPaintParamsKeyBuilder;
class SkPipelineData;
class SkRuntimeEffect;
class SkShaderCodeDictionary;
class SkKeyContext;
/**
* Encapsulates a blend function, including non-public APIs.
@ -59,7 +59,7 @@ public:
#ifdef SK_ENABLE_SKSL
// TODO: make pure virtual
virtual void addToKey(SkShaderCodeDictionary*,
virtual void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const;
#endif

26
src/core/SkKeyContext.cpp Normal file
View File

@ -0,0 +1,26 @@
/*
* 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 "src/core/SkKeyContext.h"
#ifdef SK_GRAPHITE_ENABLED
#include "experimental/graphite/src/RecorderPriv.h"
#include "experimental/graphite/src/ResourceProvider.h"
SkKeyContext::SkKeyContext(skgpu::Recorder* recorder) : fRecorder(recorder) {
fDictionary = fRecorder->priv().resourceProvider()->shaderCodeDictionary();
}
#endif
#if SK_SUPPORT_GPU
#include "include/gpu/GrRecordingContext.h"
SkKeyContext::SkKeyContext(GrRecordingContext* rContext) : fRecordingContext(rContext) {
// TODO: fill this out for Ganesh
fDictionary = nullptr;
}
#endif

53
src/core/SkKeyContext.h Normal file
View File

@ -0,0 +1,53 @@
/*
* 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 SkKeyContext_DEFINED
#define SkKeyContext_DEFINED
#include "include/gpu/GrTypes.h"
#ifdef SK_GRAPHITE_ENABLED
namespace skgpu { class Recorder; }
#endif
#if SK_SUPPORT_GPU
class GrRecordingContext;
#endif
class SkShaderCodeDictionary;
// The key context must always be able to provide a valid SkShaderCodeDictionary. Depending
// on the calling context it can also supply a backend-specific resource providing
// object (e.g., a Recorder).
class SkKeyContext {
public:
// Constructor for the pre-compile code path
SkKeyContext(SkShaderCodeDictionary* dict) : fDictionary(dict) {}
#ifdef SK_GRAPHITE_ENABLED
SkKeyContext(skgpu::Recorder*);
skgpu::Recorder* recorder() const { return fRecorder; }
#endif
#if SK_SUPPORT_GPU
SkKeyContext(GrRecordingContext*);
GrRecordingContext* recordingContext() const { return fRecordingContext; }
#endif
SkShaderCodeDictionary* dict() const { return fDictionary; }
private:
#ifdef SK_GRAPHITE_ENABLED
skgpu::Recorder* fRecorder = nullptr;
#endif
#if SK_SUPPORT_GPU
GrRecordingContext* fRecordingContext = nullptr;
#endif
SkShaderCodeDictionary* fDictionary;
};
#endif // SkKeyContext_DEFINED

View File

@ -8,6 +8,7 @@
#include "src/core/SkKeyHelpers.h"
#include "src/core/SkDebugUtils.h"
#include "src/core/SkKeyContext.h"
#include "src/core/SkPaintParamsKey.h"
#include "src/core/SkPipelineData.h"
#include "src/core/SkShaderCodeDictionary.h"
@ -15,6 +16,7 @@
#include "src/shaders/SkShaderBase.h"
#ifdef SK_GRAPHITE_ENABLED
#include "experimental/graphite/src/TextureProxy.h"
#include "experimental/graphite/src/UniformManager.h"
#include "src/gpu/Blend.h"
#endif
@ -49,7 +51,7 @@ namespace DepthStencilOnlyBlock {
static const int kBlockDataSize = 0;
void AddToKey(SkShaderCodeDictionary* /* dict */,
void AddToKey(const SkKeyContext& /* keyContext */,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* /* pipelineData */) {
builder->beginBlock(SkBuiltInCodeSnippetID::kDepthStencilOnlyDraw);
@ -92,13 +94,15 @@ sk_sp<SkUniformData> make_solid_uniform_data(SkShaderCodeDictionary* dict,
} // anonymous namespace
void AddToKey(SkShaderCodeDictionary* dict,
void AddToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData,
const SkPMColor4f& premulColor) {
#ifdef SK_GRAPHITE_ENABLED
if (builder->backend() == SkBackend::kGraphite) {
auto dict = keyContext.dict();
builder->beginBlock(SkBuiltInCodeSnippetID::kSolidColorShader);
builder->endBlock();
@ -274,13 +278,14 @@ GradientData::GradientData(SkShader::GradientType type,
}
}
void AddToKey(SkShaderCodeDictionary* dict,
void AddToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder *builder,
SkPipelineData* pipelineData,
const GradientData& gradData) {
#ifdef SK_GRAPHITE_ENABLED
if (builder->backend() == SkBackend::kGraphite) {
auto dict = keyContext.dict();
SkBuiltInCodeSnippetID codeSnippetID = SkBuiltInCodeSnippetID::kSolidColorShader;
switch (gradData.fType) {
case SkShader::kLinear_GradientType:
@ -328,7 +333,7 @@ void AddToKey(SkShaderCodeDictionary* dict,
if (builder->backend() == SkBackend::kSkVM || builder->backend() == SkBackend::kGanesh) {
// TODO: add implementation of other backends
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData, kErrorColor);
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, kErrorColor);
}
}
@ -341,11 +346,9 @@ namespace {
#ifdef SK_GRAPHITE_ENABLED
// For now, the image shader doesn't have any uniforms. This will probably change.
#if 0
sk_sp<SkUniformData> make_image_uniform_data(SkShaderCodeDictionary* dict,
const ImageData& imgData) {
SkDEBUGCODE(static constexpr size_t kExpectedNumUniforms = 0;)
static constexpr size_t kExpectedNumUniforms = 1;
SkSpan<const SkUniform> uniforms = dict->getUniforms(SkBuiltInCodeSnippetID::kImageShader);
SkASSERT(uniforms.size() == kExpectedNumUniforms);
@ -357,23 +360,42 @@ sk_sp<SkUniformData> make_image_uniform_data(SkShaderCodeDictionary* dict,
sk_sp<SkUniformData> result = SkUniformData::Make(uniforms, dataSize);
// TODO: add the required data to ImageData and assemble the uniforms here
const void* srcs[kExpectedNumUniforms] = { &imgData.fSubset };
mgr.writeUniforms(result->uniforms(), nullptr, result->offsets(), result->data());
mgr.writeUniforms(result->uniforms(), srcs, result->offsets(), result->data());
return result;
}
#endif
#endif // SK_GRAPHITE_ENABLED
} // anonymous namespace
void AddToKey(SkShaderCodeDictionary* dict,
ImageData::ImageData(const SkSamplingOptions& sampling,
SkTileMode tileModeX,
SkTileMode tileModeY,
SkRect subset)
: fSampling(sampling)
, fTileModes{tileModeX, tileModeY}
, fSubset(subset) {
}
void AddToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData,
const ImageData& imgData) {
#ifdef SK_GRAPHITE_ENABLED
if (builder->backend() == SkBackend::kGraphite) {
if (pipelineData && !imgData.fTextureProxy) {
// We're dropping the ImageShader here. This could be an instance of trying to draw
// a raster-backed image w/ a Graphite-backed canvas.
// TODO: At some point the pre-compile path should also be creating a texture
// proxy (i.e., we can remove the 'pipelineData' in the above test).
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, kErrorColor);
return;
}
auto dict = keyContext.dict();
builder->beginBlock(SkBuiltInCodeSnippetID::kImageShader);
// TODO: bytes are overkill for just tilemodes. We could add smaller/bit-width
@ -384,12 +406,13 @@ void AddToKey(SkShaderCodeDictionary* dict,
builder->endBlock();
// For now, the image shader doesn't have any uniforms. This will probably change.
#if 0
if (pipelineData) {
pipelineData->addImage(imgData.fSampling,
imgData.fTileModes,
std::move(imgData.fTextureProxy));
pipelineData->add(make_image_uniform_data(dict, imgData));
}
#endif
return;
}
@ -397,7 +420,7 @@ void AddToKey(SkShaderCodeDictionary* dict,
if (builder->backend() == SkBackend::kSkVM || builder->backend() == SkBackend::kGanesh) {
// TODO: add implementation for other backends
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData, kErrorColor);
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, kErrorColor);
}
}
@ -433,13 +456,14 @@ sk_sp<SkUniformData> make_blendshader_uniform_data(SkShaderCodeDictionary* dict,
} // anonymous namespace
void AddToKey(SkShaderCodeDictionary* dict,
void AddToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder *builder,
SkPipelineData* pipelineData,
const BlendData& blendData) {
#ifdef SK_GRAPHITE_ENABLED
if (builder->backend() == SkBackend::kGraphite) {
auto dict = keyContext.dict();
// When extracted into SkShaderInfo::SnippetEntries the children will appear after their
// parent. Thus, the parent's uniform data must appear in the uniform block before the
// uniform data of the children.
@ -453,11 +477,11 @@ void AddToKey(SkShaderCodeDictionary* dict,
// TODO: add startChild/endChild entry points to SkPaintParamsKeyBuilder. They could be
// used to compute and store the number of children w/in a block's header.
int start = builder->sizeInBytes();
as_SB(blendData.fDst)->addToKey(dict, builder, pipelineData);
as_SB(blendData.fDst)->addToKey(keyContext, builder, pipelineData);
int firstShaderSize = builder->sizeInBytes() - start;
start = builder->sizeInBytes();
as_SB(blendData.fSrc)->addToKey(dict, builder, pipelineData);
as_SB(blendData.fSrc)->addToKey(keyContext, builder, pipelineData);
int secondShaderSize = builder->sizeInBytes() - start;
builder->endBlock();
@ -472,7 +496,7 @@ void AddToKey(SkShaderCodeDictionary* dict,
if (builder->backend() == SkBackend::kSkVM || builder->backend() == SkBackend::kGanesh) {
// TODO: add implementation for other backends
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData, kErrorColor);
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, kErrorColor);
}
}
@ -528,7 +552,7 @@ static const int kFixedFunctionBlockDataSize = 1;
static const int kShaderBasedBlockDataSize = 1;
#endif
void AddToKey(SkShaderCodeDictionary* dict,
void AddToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder *builder,
SkPipelineData* pipelineData,
SkBlendMode bm) {
@ -567,7 +591,7 @@ void AddToKey(SkShaderCodeDictionary* dict,
if (builder->backend() == SkBackend::kSkVM || builder->backend() == SkBackend::kGanesh) {
// TODO: add implementation for other backends
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData, kErrorColor);
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, kErrorColor);
}
}
@ -575,7 +599,7 @@ void AddToKey(SkShaderCodeDictionary* dict,
//--------------------------------------------------------------------------------------------------
#ifdef SK_GRAPHITE_ENABLED
SkUniquePaintParamsID CreateKey(SkShaderCodeDictionary* dict,
SkUniquePaintParamsID CreateKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
skgpu::ShaderCombo::ShaderType s,
SkTileMode tm,
@ -584,34 +608,36 @@ SkUniquePaintParamsID CreateKey(SkShaderCodeDictionary* dict,
switch (s) {
case skgpu::ShaderCombo::ShaderType::kNone:
DepthStencilOnlyBlock::AddToKey(dict, builder, nullptr);
DepthStencilOnlyBlock::AddToKey(keyContext, builder, nullptr);
break;
case skgpu::ShaderCombo::ShaderType::kSolidColor:
SolidColorShaderBlock::AddToKey(dict, builder, nullptr, kErrorColor);
SolidColorShaderBlock::AddToKey(keyContext, builder, nullptr, kErrorColor);
break;
case skgpu::ShaderCombo::ShaderType::kLinearGradient:
GradientShaderBlocks::AddToKey(dict, builder, nullptr,
GradientShaderBlocks::AddToKey(keyContext, builder, nullptr,
{ SkShader::kLinear_GradientType, tm, 0 });
break;
case skgpu::ShaderCombo::ShaderType::kRadialGradient:
GradientShaderBlocks::AddToKey(dict, builder, nullptr,
GradientShaderBlocks::AddToKey(keyContext, builder, nullptr,
{ SkShader::kRadial_GradientType, tm, 0 });
break;
case skgpu::ShaderCombo::ShaderType::kSweepGradient:
GradientShaderBlocks::AddToKey(dict, builder, nullptr,
GradientShaderBlocks::AddToKey(keyContext, builder, nullptr,
{ SkShader::kSweep_GradientType, tm, 0 });
break;
case skgpu::ShaderCombo::ShaderType::kConicalGradient:
GradientShaderBlocks::AddToKey(dict, builder, nullptr,
GradientShaderBlocks::AddToKey(keyContext, builder, nullptr,
{ SkShader::kConical_GradientType, tm, 0 });
break;
}
// TODO: the blendInfo should be filled in by BlendModeBlock::AddToKey
SkPipelineData::BlendInfo blendInfo = get_blend_info(bm);
BlendModeBlock::AddToKey(dict, builder, /* pipelineData*/ nullptr, bm);
BlendModeBlock::AddToKey(keyContext, builder, /* pipelineData*/ nullptr, bm);
SkPaintParamsKey key = builder->lockAsKey();
auto dict = keyContext.dict();
auto entry = dict->findOrCreate(key, blendInfo);
return entry->uniqueID();

View File

@ -13,21 +13,24 @@
#endif
#include "include/core/SkBlendMode.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/core/SkTileMode.h"
#include "include/private/SkColorData.h"
enum class SkBackend : uint8_t;
class SkPaintParamsKeyBuilder;
class SkShaderCodeDictionary;
class SkPipelineData;
class SkUniquePaintParamsID;
class SkKeyContext;
namespace skgpu { class TextureProxy; }
// The KeyHelpers can be used to manually construct an SkPaintParamsKey
namespace DepthStencilOnlyBlock {
void AddToKey(SkShaderCodeDictionary*,
void AddToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*);
@ -35,7 +38,7 @@ namespace DepthStencilOnlyBlock {
namespace SolidColorShaderBlock {
void AddToKey(SkShaderCodeDictionary*,
void AddToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*,
const SkPMColor4f&);
@ -88,7 +91,7 @@ namespace GradientShaderBlocks {
float fOffsets[kMaxStops];
};
void AddToKey(SkShaderCodeDictionary*,
void AddToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*,
const GradientData&);
@ -98,18 +101,24 @@ namespace GradientShaderBlocks {
namespace ImageShaderBlock {
struct ImageData {
bool operator==(const ImageData& rhs) const {
return fTileModes[0] == rhs.fTileModes[0] &&
fTileModes[1] == rhs.fTileModes[1];
}
bool operator!=(const ImageData& rhs) const { return !(*this == rhs); }
ImageData(const SkSamplingOptions& sampling,
SkTileMode tileModeX,
SkTileMode tileModeY,
SkRect subset);
// TODO: add the other image shader parameters that could impact code snippet selection
// (e.g., sampling options, subsetting, etc.)
SkSamplingOptions fSampling;
SkTileMode fTileModes[2];
SkRect fSubset;
#ifdef SK_GRAPHITE_ENABLED
// TODO: Currently this is only filled in when we're generating the key from an actual
// SkImageShader. In the pre-compile case we will need to create a Graphite promise
// image which holds the appropriate data.
sk_sp<skgpu::TextureProxy> fTextureProxy;
#endif
};
void AddToKey(SkShaderCodeDictionary*,
void AddToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*,
const ImageData&);
@ -125,7 +134,7 @@ namespace BlendShaderBlock {
SkBlendMode fBM;
};
void AddToKey(SkShaderCodeDictionary*,
void AddToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*,
const BlendData&);
@ -134,7 +143,7 @@ namespace BlendShaderBlock {
namespace BlendModeBlock {
void AddToKey(SkShaderCodeDictionary*,
void AddToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*,
SkBlendMode);
@ -143,7 +152,7 @@ namespace BlendModeBlock {
#ifdef SK_GRAPHITE_ENABLED
// Bridge between the combinations system and the SkPaintParamsKey
SkUniquePaintParamsID CreateKey(SkShaderCodeDictionary*,
SkUniquePaintParamsID CreateKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
skgpu::ShaderCombo::ShaderType,
SkTileMode,

View File

@ -18,6 +18,14 @@ void SkPipelineData::add(sk_sp<SkUniformData> uniforms) {
fUniformData.push_back(std::move(uniforms));
}
#ifdef SK_GRAPHITE_ENABLED
void SkPipelineData::addImage(const SkSamplingOptions& sampling,
const SkTileMode tileModes[2],
sk_sp<skgpu::TextureProxy> proxy) {
fProxies.push_back({std::move(proxy), sampling, {tileModes[0], tileModes[1]}});
}
#endif
size_t SkPipelineData::totalUniformSize() const {
size_t total = 0;

View File

@ -10,10 +10,13 @@
#include <vector>
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkTileMode.h"
#include "include/private/SkColorData.h"
#include "src/core/SkUniformData.h"
#ifdef SK_GRAPHITE_ENABLED
#include "experimental/graphite/src/TextureProxy.h"
#include "src/gpu/Blend.h"
#endif
@ -49,6 +52,8 @@ public:
fBlendInfo = blendInfo;
}
const BlendInfo& blendInfo() const { return fBlendInfo; }
void addImage(const SkSamplingOptions&, const SkTileMode[2], sk_sp<skgpu::TextureProxy>);
#endif
void add(sk_sp<SkUniformData>);
@ -75,6 +80,13 @@ private:
std::vector<sk_sp<SkUniformData>> fUniformData;
#ifdef SK_GRAPHITE_ENABLED
struct TextureInfo {
sk_sp<skgpu::TextureProxy> fProxy;
SkSamplingOptions fSamplingOptions;
SkTileMode fTileModes[2];
};
std::vector<TextureInfo> fProxies;
BlendInfo fBlendInfo;
#endif
};

View File

@ -320,11 +320,14 @@ static const char* kSolidShaderSkSL =
"}\n";
//--------------------------------------------------------------------------------------------------
static constexpr int kNumImageShaderUniforms = 0;
static constexpr int kNumImageShaderUniforms = 1;
static constexpr SkUniform kImageShaderUniforms[kNumImageShaderUniforms] = {
{ "subset", SkSLType::kFloat4 },
};
static const char* kImageShaderName = "image_shader";
static const char* kImageShaderSkSL =
"half4 image_shader() {\n"
"half4 image_shader(float4 subset) {\n"
" float c = fract(abs(sk_FragCoord.x/10.0));\n"
" return half4(1.0, 1.0 - c, 1.0 - c, 1.0);\n"
"}\n";
@ -596,7 +599,7 @@ SkShaderCodeDictionary::SkShaderCodeDictionary() {
{ kLinearGrad4Fields, kNumLinearGrad4Fields }
};
fBuiltInCodeSnippets[(int) SkBuiltInCodeSnippetID::kImageShader] = {
{ nullptr, kNumImageShaderUniforms },
SkMakeSpan(kImageShaderUniforms, kNumImageShaderUniforms),
kImageShaderName, kImageShaderSkSL,
GenerateDefaultGlueCode,
kNoChildren,
@ -611,7 +614,7 @@ SkShaderCodeDictionary::SkShaderCodeDictionary() {
};
fBuiltInCodeSnippets[(int) SkBuiltInCodeSnippetID::kFixedFunctionBlender] = {
{ }, // no uniforms
"", "", // fixed function blending doesn't have any static SkSL
"FF-blending", "", // fixed function blending doesn't have any static SkSL
GenerateFixedFunctionBlenderGlueCode,
kNoChildren,
{ kFixedFunctionBlenderFields, kNumFixedFunctionBlenderFields }

View File

@ -498,8 +498,9 @@ void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
const char* clampStopSwizzle) {
if (clamp) {
fb->codeAppendf("clampedCoord%s = clamp(subsetCoord%s, %s%s, %s%s);",
coordSwizzle, coordSwizzle, clampName, clampStartSwizzle, clampName,
clampStopSwizzle);
coordSwizzle, coordSwizzle,
clampName, clampStartSwizzle,
clampName, clampStopSwizzle);
} else {
fb->codeAppendf("clampedCoord%s = subsetCoord%s;", coordSwizzle, coordSwizzle);
}

View File

@ -453,6 +453,8 @@ GrBackendTexture SkImage_Base::onGetBackendTexture(bool flushPendingGrContextIO,
return GrBackendTexture(); // invalid
}
#endif // SK_SUPPORT_GPU
#ifdef SK_GRAPHITE_ENABLED
std::tuple<skgpu::TextureProxyView, SkColorType> SkImage_Base::asView(
skgpu::Recorder* recorder, skgpu::Mipmapped mipmapped) const {
@ -464,9 +466,7 @@ std::tuple<skgpu::TextureProxyView, SkColorType> SkImage_Base::asView(
}
return this->onAsView(recorder, mipmapped);
}
#endif
#endif // SK_SUPPORT_GPU
#endif // SK_GRAPHITE_ENABLED
GrDirectContext* SkImage_Base::directContext() const {
#if SK_SUPPORT_GPU

View File

@ -141,16 +141,16 @@ std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
#endif
#ifdef SK_ENABLE_SKSL
void SkColorShader::addToKey(SkShaderCodeDictionary* dict,
void SkColorShader::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData,
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData,
SkColor4f::FromColor(fColor).premul());
}
void SkColor4Shader::addToKey(SkShaderCodeDictionary* dict,
void SkColor4Shader::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData, fColor.premul());
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, fColor.premul());
}
#endif

View File

@ -35,7 +35,7 @@ public:
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif
@ -70,7 +70,7 @@ public:
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif

View File

@ -193,12 +193,13 @@ std::unique_ptr<GrFragmentProcessor> SkShader_Blend::asFragmentProcessor(
#endif
#ifdef SK_ENABLE_SKSL
void SkShader_Blend::addToKey(SkShaderCodeDictionary* dict,
void SkShader_Blend::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
// TODO: add blender support
SkASSERT(!fBlender);
BlendShaderBlock::AddToKey(dict, builder, pipelineData, { fDst.get(), fSrc.get(), fMode });
BlendShaderBlock::AddToKey(keyContext, builder, pipelineData,
{ fDst.get(), fSrc.get(), fMode });
}
#endif

View File

@ -31,7 +31,7 @@ public:
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif

View File

@ -27,6 +27,12 @@
#include "src/shaders/SkTransformShader.h"
#ifdef SK_ENABLE_SKSL
#ifdef SK_GRAPHITE_ENABLED
#include "experimental/graphite/src/Image_Graphite.h"
#endif
#include "src/core/SkKeyContext.h"
#include "src/core/SkKeyHelpers.h"
#endif
@ -379,10 +385,23 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
#endif
#ifdef SK_ENABLE_SKSL
void SkImageShader::addToKey(SkShaderCodeDictionary* dict,
void SkImageShader::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
ImageShaderBlock::AddToKey(dict, builder, pipelineData, { fTileModeX, fTileModeY });
ImageShaderBlock::ImageData imgData(fSampling, fTileModeX, fTileModeY, fSubset);
#ifdef SK_GRAPHITE_ENABLED
if (as_IB(fImage)->isGraphiteBacked()) {
skgpu::Image* grImage = static_cast<skgpu::Image*>(fImage.get());
auto mipmapped = (fSampling.mipmap != SkMipmapMode::kNone) ? skgpu::Mipmapped::kYes
: skgpu::Mipmapped::kNo;
auto[view, ct] = grImage->asView(keyContext.recorder(), mipmapped);
imgData.fTextureProxy = view.refProxy();
}
#endif
ImageShaderBlock::AddToKey(keyContext, builder, pipelineData, imgData);
}
#endif

View File

@ -13,7 +13,7 @@
#include "src/shaders/SkBitmapProcShader.h"
#include "src/shaders/SkShaderBase.h"
class SkShaderCodeDictionary;
class SkKeyContext;
class SkImageShader : public SkShaderBase {
public:
@ -46,7 +46,7 @@ public:
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif

View File

@ -154,10 +154,10 @@ SkUpdatableShader* SkShaderBase::onUpdatableShader(SkArenaAlloc* alloc) const {
#ifdef SK_ENABLE_SKSL
// TODO: add implementations for derived classes
void SkShaderBase::addToKey(SkShaderCodeDictionary* dict,
void SkShaderBase::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
SolidColorShaderBlock::AddToKey(dict, builder, pipelineData, {1, 0, 0, 1});
SolidColorShaderBlock::AddToKey(keyContext, builder, pipelineData, {1, 0, 0, 1});
}
#endif

View File

@ -33,7 +33,7 @@ class SkPaintParamsKeyBuilder;
class SkPipelineData;
class SkRasterPipeline;
class SkRuntimeEffect;
class SkShaderCodeDictionary;
class SkKeyContext;
class SkStageUpdater;
class SkUpdatableShader;
@ -219,11 +219,11 @@ public:
Add implementation details, for the specified backend, of this SkShader to the
provided key.
@param dictionary dictionary of code fragments available to be used in the key
@param keyContext backend context for key creation
@param builder builder for creating the key for this SkShader
@param pipelineData if non-null, storage for this shader's data
*/
virtual void addToKey(SkShaderCodeDictionary* dictionary,
virtual void addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const;
#endif

View File

@ -109,7 +109,7 @@ std::unique_ptr<GrFragmentProcessor> SkLinearGradient::asFragmentProcessor(
#endif
#ifdef SK_ENABLE_SKSL
void SkLinearGradient::addToKey(SkShaderCodeDictionary* dict,
void SkLinearGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
GradientShaderBlocks::GradientData data(kLinear_GradientType,
@ -120,6 +120,6 @@ void SkLinearGradient::addToKey(SkShaderCodeDictionary* dict,
fOrigColors4f,
fOrigPos);
GradientShaderBlocks::AddToKey(dict, builder, pipelineData, data);
GradientShaderBlocks::AddToKey(keyContext, builder, pipelineData, data);
}
#endif

View File

@ -21,7 +21,7 @@ public:
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif

View File

@ -87,7 +87,7 @@ std::unique_ptr<GrFragmentProcessor> SkRadialGradient::asFragmentProcessor(
#endif
#ifdef SK_ENABLE_SKSL
void SkRadialGradient::addToKey(SkShaderCodeDictionary* dict,
void SkRadialGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
GradientShaderBlocks::GradientData data(kRadial_GradientType,
@ -98,6 +98,6 @@ void SkRadialGradient::addToKey(SkShaderCodeDictionary* dict,
fOrigColors4f,
fOrigPos);
GradientShaderBlocks::AddToKey(dict, builder, pipelineData, data);
GradientShaderBlocks::AddToKey(keyContext, builder, pipelineData, data);
}
#endif

View File

@ -21,7 +21,7 @@ public:
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif

View File

@ -111,7 +111,7 @@ std::unique_ptr<GrFragmentProcessor> SkSweepGradient::asFragmentProcessor(
#endif
#ifdef SK_ENABLE_SKSL
void SkSweepGradient::addToKey(SkShaderCodeDictionary* dict,
void SkSweepGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
GradientShaderBlocks::GradientData data(kSweep_GradientType,
@ -122,6 +122,6 @@ void SkSweepGradient::addToKey(SkShaderCodeDictionary* dict,
fOrigColors4f,
fOrigPos);
GradientShaderBlocks::AddToKey(dict, builder, pipelineData, data);
GradientShaderBlocks::AddToKey(keyContext, builder, pipelineData, data);
}
#endif

View File

@ -22,7 +22,7 @@ public:
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif

View File

@ -281,7 +281,7 @@ std::unique_ptr<GrFragmentProcessor> SkTwoPointConicalGradient::asFragmentProces
#endif
#ifdef SK_ENABLE_SKSL
void SkTwoPointConicalGradient::addToKey(SkShaderCodeDictionary* dict,
void SkTwoPointConicalGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineData* pipelineData) const {
GradientShaderBlocks::GradientData data(kConical_GradientType,
@ -292,6 +292,6 @@ void SkTwoPointConicalGradient::addToKey(SkShaderCodeDictionary* dict,
fOrigColors4f,
fOrigPos);
GradientShaderBlocks::AddToKey(dict, builder, pipelineData, data);
GradientShaderBlocks::AddToKey(keyContext, builder, pipelineData, data);
}
#endif

View File

@ -54,7 +54,7 @@ public:
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
#endif
#ifdef SK_ENABLE_SKSL
void addToKey(SkShaderCodeDictionary*,
void addToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineData*) const override;
#endif

View File

@ -28,6 +28,7 @@
#include "experimental/graphite/src/UniformManager.h"
#include "experimental/graphite/src/geom/Shape.h"
#include "experimental/graphite/src/geom/Transform_graphite.h"
#include "src/core/SkKeyContext.h"
#include "src/core/SkKeyHelpers.h"
#include "src/core/SkShaderCodeDictionary.h"
#include "src/core/SkUniformData.h"
@ -235,8 +236,8 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(CommandBufferTest, reporter, context) {
gpu->testingOnly_startCapture();
#endif
auto recorder = context->makeRecorder();
SkKeyContext keyContext(recorder.get());
auto resourceProvider = recorder->priv().resourceProvider();
auto dict = resourceProvider->shaderCodeDictionary();
auto commandBuffer = resourceProvider->createCommandBuffer();
SkISize textureSize = { kTextureWidth, kTextureHeight };
@ -256,9 +257,11 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(CommandBufferTest, reporter, context) {
SkUniquePaintParamsID uniqueID;
{
auto dict = keyContext.dict();
SkPaintParamsKeyBuilder builder(dict, SkBackend::kGraphite);
uniqueID = CreateKey(dict,
uniqueID = CreateKey(keyContext,
&builder,
ShaderCombo::ShaderType::kSolidColor,
SkTileMode::kClamp,

View File

@ -17,6 +17,7 @@
#include "include/core/SkPaint.h"
#include "include/effects/SkGradientShader.h"
#include "include/private/SkUniquePaintParamsID.h"
#include "src/core/SkKeyContext.h"
#include "src/core/SkKeyHelpers.h"
#include "src/core/SkPipelineData.h"
#include "src/core/SkShaderCodeDictionary.h"
@ -74,7 +75,8 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(UniformTest, reporter, context) {
using namespace skgpu;
auto recorder = context->makeRecorder();
auto dict = recorder->priv().resourceProvider()->shaderCodeDictionary();
SkKeyContext keyContext(recorder.get());
auto dict = keyContext.dict();
SkPaintParamsKeyBuilder builder(dict, SkBackend::kGraphite);
@ -96,9 +98,10 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(UniformTest, reporter, context) {
for (auto bm : { SkBlendMode::kSrc, SkBlendMode::kSrcOver }) {
auto [ p, expectedNumUniforms ] = create_paint(s, tm, bm);
auto [ uniqueID1, pipelineData] = ExtractPaintData(dict, &builder, PaintParams(p));
auto [ uniqueID1, pipelineData] = ExtractPaintData(recorder.get(), &builder,
PaintParams(p));
SkUniquePaintParamsID uniqueID2 = CreateKey(dict, &builder, s, tm, bm);
SkUniquePaintParamsID uniqueID2 = CreateKey(keyContext, &builder, s, tm, bm);
// ExtractPaintData and CreateKey agree
REPORTER_ASSERT(reporter, uniqueID1 == uniqueID2);