[graphite] Force all snippets that need local coords to supply a localMatrix

It is also a requirement that the local matrix be the first uniform.
This will let us more generally handle nested local matrices (in a
follow up CL).

Bug: skia:12701
Change-Id: If093363c4820228f139f383b4e2f94dbc473017a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/536036
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Robert Phillips 2022-05-03 09:22:34 -04:00 committed by SkCQ
parent 21bfb4e6a6
commit 351a46f4fc
10 changed files with 476 additions and 431 deletions

View File

@ -5616,6 +5616,7 @@ generated_cc_atom(
visibility = ["//:__subpackages__"],
deps = [
"//include/core:SkBlendMode_hdr",
"//include/core:SkM44_hdr",
"//include/core:SkSamplingOptions_hdr",
"//include/core:SkShader_hdr",
"//include/core:SkTileMode_hdr",

View File

@ -124,6 +124,14 @@ void add_linear_gradient_uniform_data(const SkShaderCodeDictionary* dict,
const GradientData& gradData,
SkPipelineDataGatherer* gatherer) {
VALIDATE_UNIFORMS(gatherer, dict, kLinearGradientShader)
SkM44 lmInverse;
bool wasInverted = gradData.fLocalMatrix.invert(&lmInverse); // TODO: handle failure up stack
if (!wasInverted) {
lmInverse.setIdentity();
}
gatherer->write(lmInverse);
gatherer->write(gradData.fColor4fs, GradientData::kMaxStops);
gatherer->write(gradData.fOffsets, GradientData::kMaxStops);
gatherer->write(gradData.fPoints[0]);
@ -140,6 +148,14 @@ void add_radial_gradient_uniform_data(const SkShaderCodeDictionary* dict,
const GradientData& gradData,
SkPipelineDataGatherer* gatherer) {
VALIDATE_UNIFORMS(gatherer, dict, kRadialGradientShader)
SkM44 lmInverse;
bool wasInverted = gradData.fLocalMatrix.invert(&lmInverse); // TODO: handle failure up stack
if (!wasInverted) {
lmInverse.setIdentity();
}
gatherer->write(lmInverse);
gatherer->write(gradData.fColor4fs, GradientData::kMaxStops);
gatherer->write(gradData.fOffsets, GradientData::kMaxStops);
gatherer->write(gradData.fPoints[0]);
@ -156,6 +172,14 @@ void add_sweep_gradient_uniform_data(const SkShaderCodeDictionary* dict,
const GradientData& gradData,
SkPipelineDataGatherer* gatherer) {
VALIDATE_UNIFORMS(gatherer, dict, kSweepGradientShader)
SkM44 lmInverse;
bool wasInverted = gradData.fLocalMatrix.invert(&lmInverse); // TODO: handle failure up stack
if (!wasInverted) {
lmInverse.setIdentity();
}
gatherer->write(lmInverse);
gatherer->write(gradData.fColor4fs, GradientData::kMaxStops);
gatherer->write(gradData.fOffsets, GradientData::kMaxStops);
gatherer->write(gradData.fPoints[0]);
@ -172,6 +196,14 @@ void add_conical_gradient_uniform_data(const SkShaderCodeDictionary* dict,
const GradientData& gradData,
SkPipelineDataGatherer* gatherer) {
VALIDATE_UNIFORMS(gatherer, dict, kConicalGradientShader)
SkM44 lmInverse;
bool wasInverted = gradData.fLocalMatrix.invert(&lmInverse); // TODO: handle failure up stack
if (!wasInverted) {
lmInverse.setIdentity();
}
gatherer->write(lmInverse);
gatherer->write(gradData.fColor4fs, GradientData::kMaxStops);
gatherer->write(gradData.fOffsets, GradientData::kMaxStops);
gatherer->write(gradData.fPoints[0]);
@ -201,6 +233,7 @@ GradientData::GradientData(SkShader::GradientType type,
}
GradientData::GradientData(SkShader::GradientType type,
SkM44 localMatrix,
SkPoint point0, SkPoint point1,
float radius0, float radius1,
SkTileMode tm,
@ -208,6 +241,7 @@ GradientData::GradientData(SkShader::GradientType type,
SkColor4f* color4fs,
float* offsets)
: fType(type)
, fLocalMatrix(localMatrix)
, fTM(tm)
, fNumStops(std::min(numStops, kMaxStops)) {
SkASSERT(fNumStops >= 1);
@ -301,11 +335,6 @@ void add_image_uniform_data(const SkShaderCodeDictionary* dict,
const ImageData& imgData,
SkPipelineDataGatherer* gatherer) {
VALIDATE_UNIFORMS(gatherer, dict, kImageShader)
gatherer->write(imgData.fSubset);
gatherer->write(static_cast<int>(imgData.fTileModes[0]));
gatherer->write(static_cast<int>(imgData.fTileModes[1]));
gatherer->write(imgData.fTextureProxy->dimensions().fWidth);
gatherer->write(imgData.fTextureProxy->dimensions().fHeight);
SkMatrix lmInverse;
bool wasInverted = imgData.fLocalMatrix.invert(&lmInverse); // TODO: handle failure up stack
@ -314,6 +343,11 @@ void add_image_uniform_data(const SkShaderCodeDictionary* dict,
}
gatherer->write(SkM44(lmInverse));
gatherer->write(imgData.fSubset);
gatherer->write(static_cast<int>(imgData.fTileModes[0]));
gatherer->write(static_cast<int>(imgData.fTileModes[1]));
gatherer->write(imgData.fTextureProxy->dimensions().fWidth);
gatherer->write(imgData.fTextureProxy->dimensions().fHeight);
gatherer->addFlags(dict->getSnippetRequirementFlags(SkBuiltInCodeSnippetID::kImageShader));
}
@ -400,7 +434,7 @@ void add_blendshader_uniform_data(const SkShaderCodeDictionary* dict,
void AddToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder *builder,
SkPipelineDataGatherer* gatherer,
const BlendData& blendData) {
const BlendShaderData& blendData) {
#ifdef SK_GRAPHITE_ENABLED
if (builder->backend() == SkBackend::kGraphite) {

View File

@ -13,6 +13,7 @@
#endif
#include "include/core/SkBlendMode.h"
#include "include/core/SkM44.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/core/SkTileMode.h"
@ -62,6 +63,7 @@ namespace GradientShaderBlocks {
// This ctor is used when extracting information from PaintParams. It must provide
// enough data to generate the uniform data the selected code snippet will require.
GradientData(SkShader::GradientType,
SkM44 localMatrix,
SkPoint point0, SkPoint point1,
float radius0, float radius1,
SkTileMode,
@ -71,6 +73,7 @@ namespace GradientShaderBlocks {
bool operator==(const GradientData& rhs) const {
return fType == rhs.fType &&
fLocalMatrix == rhs.fLocalMatrix &&
fPoints[0] == rhs.fPoints[0] &&
fPoints[1] == rhs.fPoints[1] &&
fRadii[0] == rhs.fRadii[0] &&
@ -83,6 +86,7 @@ namespace GradientShaderBlocks {
bool operator!=(const GradientData& rhs) const { return !(*this == rhs); }
SkShader::GradientType fType;
SkM44 fLocalMatrix;
SkPoint fPoints[2];
float fRadii[2];
SkTileMode fTM;
@ -129,7 +133,7 @@ namespace ImageShaderBlock {
namespace BlendShaderBlock {
struct BlendData {
struct BlendShaderData {
SkShader* fDst;
SkShader* fSrc;
// TODO: add support for blenders
@ -139,7 +143,7 @@ namespace BlendShaderBlock {
void AddToKey(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const BlendData&);
const BlendShaderData&);
} // namespace BlendShaderBlock

View File

@ -245,6 +245,12 @@ std::string GenerateDefaultGlueCode(const std::string& resultName,
SkASSERT(childNames.empty());
const SkShaderSnippet* entry = reader.entry();
if (entry->needsLocalCoords()) {
// Every snippet that requests local coordinates must have a localMatrix as its first
// uniform
SkASSERT(reader.entry()->fUniforms.size() >= 1);
SkASSERT(reader.entry()->fUniforms[0].type() == SkSLType::kFloat4x4);
}
std::string result;
@ -253,16 +259,16 @@ std::string GenerateDefaultGlueCode(const std::string& resultName,
"%s = %s(", resultName.c_str(),
entry->fStaticFunctionName);
for (size_t i = 0; i < entry->fUniforms.size(); ++i) {
result += entry->getMangledUniformName(i, entryIndex);
if (i == 0 && reader.entry()->needsLocalCoords()) {
result += entry->getMangledUniformName(i, entryIndex);
result += " * dev2LocalUni";
} else {
result += entry->getMangledUniformName(i, entryIndex);
}
if (i+1 < entry->fUniforms.size()) {
result += ", ";
}
}
#ifdef SK_GRAPHITE_ENABLED
if (entry->fSnippetRequirementFlags & SnippetRequirementFlags::kLocalCoords) {
result += ", dev2LocalUni";
}
#endif
result += ");\n";
return result;
@ -276,15 +282,16 @@ static constexpr int kFourStopGradient = 4;
// kMaxStops offsets
// 2 points
// 2 radii
static constexpr int kNumGradientUniforms = 7;
static constexpr int kNumGradientUniforms = 8;
static constexpr SkUniform kGradientUniforms[kNumGradientUniforms] = {
{ "colors", SkSLType::kFloat4, kFourStopGradient },
{ "offsets", SkSLType::kFloat, kFourStopGradient },
{ "point0", SkSLType::kFloat2 },
{ "point1", SkSLType::kFloat2 },
{ "radius0", SkSLType::kFloat },
{ "radius1", SkSLType::kFloat },
{ "padding", SkSLType::kFloat2 } // TODO: add automatic uniform padding
{ "localMatrix", SkSLType::kFloat4x4 },
{ "colors", SkSLType::kFloat4, kFourStopGradient },
{ "offsets", SkSLType::kFloat, kFourStopGradient },
{ "point0", SkSLType::kFloat2 },
{ "point1", SkSLType::kFloat2 },
{ "radius0", SkSLType::kFloat },
{ "radius1", SkSLType::kFloat },
{ "padding", SkSLType::kFloat2 } // TODO: add automatic uniform padding
};
static constexpr char kLinearGradient4Name[] = "sk_linear_grad_4_shader";
@ -300,12 +307,12 @@ static constexpr char kSolidShaderName[] = "sk_solid_shader";
//--------------------------------------------------------------------------------------------------
static constexpr int kNumImageShaderUniforms = 6;
static constexpr SkUniform kImageShaderUniforms[kNumImageShaderUniforms] = {
{ "localMatrix", SkSLType::kFloat4x4 },
{ "subset", SkSLType::kFloat4 },
{ "tilemodeX", SkSLType::kInt },
{ "tilemodeY", SkSLType::kInt },
{ "imgWidth", SkSLType::kInt },
{ "imgHeight", SkSLType::kInt },
{ "localMatrix", SkSLType::kFloat4x4 },
};
static constexpr int kNumImageShaderTexturesAndSamplers = 1;
@ -334,25 +341,25 @@ std::string GenerateImageShaderGlueCode(const std::string& resultName,
std::string samplerVarName = std::string("sampler_") + std::to_string(entryIndex) + "_0";
std::string subsetName = reader.entry()->getMangledUniformName(0, entryIndex);
std::string tmXName = reader.entry()->getMangledUniformName(1, entryIndex);
std::string tmYName = reader.entry()->getMangledUniformName(2, entryIndex);
std::string imgWidthName = reader.entry()->getMangledUniformName(3, entryIndex);
std::string imgHeightName = reader.entry()->getMangledUniformName(4, entryIndex);
std::string localMatrixName = reader.entry()->getMangledUniformName(5, entryIndex);
std::string localMatrixName = reader.entry()->getMangledUniformName(0, entryIndex);
std::string subsetName = reader.entry()->getMangledUniformName(1, entryIndex);
std::string tmXName = reader.entry()->getMangledUniformName(2, entryIndex);
std::string tmYName = reader.entry()->getMangledUniformName(3, entryIndex);
std::string imgWidthName = reader.entry()->getMangledUniformName(4, entryIndex);
std::string imgHeightName = reader.entry()->getMangledUniformName(5, entryIndex);
std::string result;
add_indent(&result, indent);
SkSL::String::appendf(&result,
"float2 coords = %s(%s, %s, %s, %s, %s, dev2LocalUni, %s);",
"float2 coords = %s(%s * dev2LocalUni, %s, %s, %s, %s, %s);",
reader.entry()->fStaticFunctionName,
localMatrixName.c_str(),
subsetName.c_str(),
tmXName.c_str(),
tmYName.c_str(),
imgWidthName.c_str(),
imgHeightName.c_str(),
localMatrixName.c_str());
imgHeightName.c_str());
add_indent(&result, indent);
SkSL::String::appendf(&result,

View File

@ -113,6 +113,7 @@ void SkLinearGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineDataGatherer* gatherer) const {
GradientShaderBlocks::GradientData data(kLinear_GradientType,
SkM44(this->getLocalMatrix()),
fStart, fEnd,
0.0f, 0.0f,
fTileMode,

View File

@ -91,6 +91,7 @@ void SkRadialGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineDataGatherer* gatherer) const {
GradientShaderBlocks::GradientData data(kRadial_GradientType,
SkM44(this->getLocalMatrix()),
fCenter, { 0.0f, 0.0f },
fRadius, 0.0f,
fTileMode,

View File

@ -115,6 +115,7 @@ void SkSweepGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineDataGatherer* gatherer) const {
GradientShaderBlocks::GradientData data(kSweep_GradientType,
SkM44(this->getLocalMatrix()),
fCenter, { 0.0f, 0.0f },
0.0, 0.0f,
fTileMode,

View File

@ -285,6 +285,7 @@ void SkTwoPointConicalGradient::addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineDataGatherer* gatherer) const {
GradientShaderBlocks::GradientData data(kConical_GradientType,
SkM44(this->getLocalMatrix()),
fCenter1, fCenter2,
fRadius1, fRadius2,
fTileMode,

File diff suppressed because it is too large Load Diff

View File

@ -30,25 +30,26 @@ float $tile(int tm, float f, float min, float max, float normalizer) {
}
}
float2 sk_compute_coords(float4 subset,
int tmX, int tmY,
int imgWidth, int imgHeight,
float4x4 dev2Local,
float4x4 localMatrix) {
float4 localCoords = localMatrix * dev2Local * sk_FragCoord;
float2 sk_compute_coords(float4x4 dev2Local,
float4 subset,
int tmX,
int tmY,
int imgWidth,
int imgHeight) {
float4 localCoords = dev2Local * sk_FragCoord;
float2 coords = float2($tile(tmX, localCoords.x, subset.x, subset.z, float(imgWidth)),
$tile(tmY, localCoords.y, subset.y, subset.w, float(imgHeight)));
return coords;
}
half4 sk_linear_grad_4_shader(float4 colorsParam[4],
half4 sk_linear_grad_4_shader(float4x4 dev2Local,
float4 colorsParam[4],
float offsetsParam[4],
float2 point0Param,
float2 point1Param,
float radius0Param,
float radius1Param,
float2 padding,
float4x4 dev2Local) {
float2 padding) {
float2 pos = (dev2Local * sk_FragCoord).xy;
float2 delta = point1Param - point0Param;
float2 pt = pos - point0Param;