[graphite] Expand GradientData to include everything needed for uniform generation
Bug: skia:12701 Change-Id: Ib081e07731d30d5da19fef9191958ee3ee3a23a5 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/502777 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
f34afe8725
commit
3998cdea26
@ -22,10 +22,10 @@
|
||||
|
||||
namespace skgpu {
|
||||
|
||||
using GradientData = GradientShaderBlocks::GradientData;
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO: For the sprint we only support 4 stops in the gradients
|
||||
static constexpr int kMaxStops = 4;
|
||||
// TODO: For the sprint we unify all the gradient uniforms into a standard set of 6:
|
||||
// kMaxStops colors
|
||||
// kMaxStops offsets
|
||||
@ -33,8 +33,8 @@ static constexpr int kMaxStops = 4;
|
||||
// 2 radii
|
||||
static constexpr int kNumGradientUniforms = 6;
|
||||
static constexpr SkUniform kGradientUniforms[kNumGradientUniforms] {
|
||||
{"colors", SkSLType::kHalf4 , kMaxStops },
|
||||
{"offsets", SkSLType::kFloat, kMaxStops },
|
||||
{"colors", SkSLType::kHalf4 , GradientData::kMaxStops },
|
||||
{"offsets", SkSLType::kFloat, GradientData::kMaxStops },
|
||||
{"point0", SkSLType::kFloat2 },
|
||||
{"point1", SkSLType::kFloat2 },
|
||||
{"radius0", SkSLType::kFloat },
|
||||
@ -90,8 +90,8 @@ sk_sp<SkUniformData> make_gradient_uniform_data_common(const void* srcs[kNumGrad
|
||||
|
||||
sk_sp<SkUniformData> make_linear_gradient_uniform_data(SkPoint startPoint,
|
||||
SkPoint endPoint,
|
||||
SkColor4f colors[kMaxStops],
|
||||
float offsets[kMaxStops]) {
|
||||
SkColor4f colors[GradientData::kMaxStops],
|
||||
float offsets[GradientData::kMaxStops]) {
|
||||
float unusedRadii[2] = { 0.0f, 0.0f };
|
||||
const void* srcs[kNumGradientUniforms] = {
|
||||
colors,
|
||||
@ -107,8 +107,8 @@ sk_sp<SkUniformData> make_linear_gradient_uniform_data(SkPoint startPoint,
|
||||
|
||||
sk_sp<SkUniformData> make_radial_gradient_uniform_data(SkPoint point,
|
||||
float radius,
|
||||
SkColor4f colors[kMaxStops],
|
||||
float offsets[kMaxStops]) {
|
||||
SkColor4f colors[GradientData::kMaxStops],
|
||||
float offsets[GradientData::kMaxStops]) {
|
||||
SkPoint unusedPoint = {0.0f, 0.0f};
|
||||
float unusedRadius = 0.0f;
|
||||
|
||||
@ -125,8 +125,8 @@ sk_sp<SkUniformData> make_radial_gradient_uniform_data(SkPoint point,
|
||||
};
|
||||
|
||||
sk_sp<SkUniformData> make_sweep_gradient_uniform_data(SkPoint point,
|
||||
SkColor4f colors[kMaxStops],
|
||||
float offsets[kMaxStops]) {
|
||||
SkColor4f colors[GradientData::kMaxStops],
|
||||
float offsets[GradientData::kMaxStops]) {
|
||||
SkPoint unusedPoint = {0.0f, 0.0f};
|
||||
float unusedRadii[2] = {0.0f, 0.0f};
|
||||
|
||||
@ -146,8 +146,8 @@ sk_sp<SkUniformData> make_conical_gradient_uniform_data(SkPoint point0,
|
||||
SkPoint point1,
|
||||
float radius0,
|
||||
float radius1,
|
||||
SkColor4f colors[kMaxStops],
|
||||
float offsets[kMaxStops]) {
|
||||
SkColor4f colors[GradientData::kMaxStops],
|
||||
float offsets[GradientData::kMaxStops]) {
|
||||
|
||||
const void* srcs[kNumGradientUniforms] = {
|
||||
colors,
|
||||
@ -161,26 +161,6 @@ sk_sp<SkUniformData> make_conical_gradient_uniform_data(SkPoint point0,
|
||||
return make_gradient_uniform_data_common(srcs);
|
||||
};
|
||||
|
||||
void to_color4fs(int numColors, SkColor colors[kMaxStops], SkColor4f color4fs[kMaxStops]) {
|
||||
SkASSERT(numColors >= 2 && numColors <= kMaxStops);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numColors; ++i) {
|
||||
color4fs[i] = SkColor4f::FromColor(colors[i]);
|
||||
}
|
||||
for ( ; i < kMaxStops; ++i) {
|
||||
color4fs[i] = color4fs[numColors-1];
|
||||
}
|
||||
}
|
||||
|
||||
void expand_stops(int numStops, float offsets[kMaxStops]) {
|
||||
SkASSERT(numStops >= 2 && numStops <= kMaxStops);
|
||||
|
||||
for (int i = numStops ; i < kMaxStops; ++i) {
|
||||
offsets[i] = offsets[numStops-1];
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<SkUniformData> make_solid_uniform_data(SkColor4f color) {
|
||||
UniformManager mgr(Layout::kMetal);
|
||||
|
||||
@ -207,81 +187,72 @@ std::tuple<SkUniquePaintParamsID, std::unique_ptr<SkUniformBlock>> ExtractPaintD
|
||||
|
||||
// TODO: add UniformData generation to PaintParams::toKey and use it here
|
||||
if (auto s = p.shader()) {
|
||||
SkColor colors[kMaxStops];
|
||||
SkColor4f color4fs[kMaxStops];
|
||||
float offsets[kMaxStops];
|
||||
SkColor colors[GradientData::kMaxStops];
|
||||
float offsets[GradientData::kMaxStops];
|
||||
SkShader::GradientInfo gradInfo;
|
||||
|
||||
gradInfo.fColorCount = kMaxStops;
|
||||
gradInfo.fColorCount = GradientData::kMaxStops;
|
||||
gradInfo.fColors = colors;
|
||||
gradInfo.fColorOffsets = offsets;
|
||||
|
||||
SkShader::GradientType type = s->asAGradient(&gradInfo);
|
||||
if (gradInfo.fColorCount > kMaxStops) {
|
||||
if (gradInfo.fColorCount > GradientData::kMaxStops) {
|
||||
type = SkShader::GradientType::kNone_GradientType;
|
||||
}
|
||||
|
||||
GradientData data(type, gradInfo.fPoint, gradInfo.fRadius,
|
||||
gradInfo.fTileMode, gradInfo.fColorCount,
|
||||
colors, offsets);
|
||||
|
||||
switch (type) {
|
||||
case SkShader::kLinear_GradientType: {
|
||||
to_color4fs(gradInfo.fColorCount, colors, color4fs);
|
||||
expand_stops(gradInfo.fColorCount, offsets);
|
||||
|
||||
GradientShaderBlocks::AddToKey(SkBackend::kGraphite,
|
||||
&key,
|
||||
block.get(),
|
||||
{ type, gradInfo.fTileMode, gradInfo.fColorCount });
|
||||
data);
|
||||
|
||||
// TODO: move this into GradientShaderBlocks::AddToKey
|
||||
uniforms = make_linear_gradient_uniform_data(gradInfo.fPoint[0],
|
||||
gradInfo.fPoint[1],
|
||||
color4fs,
|
||||
offsets);
|
||||
uniforms = make_linear_gradient_uniform_data(data.fPoints[0],
|
||||
data.fPoints[1],
|
||||
data.fColor4fs,
|
||||
data.fOffsets);
|
||||
} break;
|
||||
case SkShader::kRadial_GradientType: {
|
||||
to_color4fs(gradInfo.fColorCount, colors, color4fs);
|
||||
expand_stops(gradInfo.fColorCount, offsets);
|
||||
|
||||
GradientShaderBlocks::AddToKey(SkBackend::kGraphite,
|
||||
&key,
|
||||
block.get(),
|
||||
{ type, gradInfo.fTileMode, gradInfo.fColorCount });
|
||||
data);
|
||||
|
||||
// TODO: move this into GradientShaderBlocks::AddToKey
|
||||
uniforms = make_radial_gradient_uniform_data(gradInfo.fPoint[0],
|
||||
gradInfo.fRadius[0],
|
||||
color4fs,
|
||||
offsets);
|
||||
uniforms = make_radial_gradient_uniform_data(data.fPoints[0],
|
||||
data.fRadii[0],
|
||||
data.fColor4fs,
|
||||
data.fOffsets);
|
||||
} break;
|
||||
case SkShader::kSweep_GradientType:
|
||||
to_color4fs(gradInfo.fColorCount, colors, color4fs);
|
||||
expand_stops(gradInfo.fColorCount, offsets);
|
||||
|
||||
GradientShaderBlocks::AddToKey(SkBackend::kGraphite,
|
||||
&key,
|
||||
block.get(),
|
||||
{ type, gradInfo.fTileMode, gradInfo.fColorCount });
|
||||
data);
|
||||
|
||||
// TODO: move this into GradientShaderBlocks::AddToKey
|
||||
uniforms = make_sweep_gradient_uniform_data(gradInfo.fPoint[0],
|
||||
color4fs,
|
||||
offsets);
|
||||
uniforms = make_sweep_gradient_uniform_data(data.fPoints[0],
|
||||
data.fColor4fs,
|
||||
data.fOffsets);
|
||||
break;
|
||||
case SkShader::GradientType::kConical_GradientType:
|
||||
to_color4fs(gradInfo.fColorCount, colors, color4fs);
|
||||
expand_stops(gradInfo.fColorCount, offsets);
|
||||
|
||||
GradientShaderBlocks::AddToKey(SkBackend::kGraphite,
|
||||
&key,
|
||||
block.get(),
|
||||
{ type, gradInfo.fTileMode, gradInfo.fColorCount });
|
||||
data);
|
||||
|
||||
// TODO: move this into GradientShaderBlocks::AddToKey
|
||||
uniforms = make_conical_gradient_uniform_data(gradInfo.fPoint[0],
|
||||
gradInfo.fPoint[1],
|
||||
gradInfo.fRadius[0],
|
||||
gradInfo.fRadius[1],
|
||||
color4fs,
|
||||
offsets);
|
||||
uniforms = make_conical_gradient_uniform_data(data.fPoints[0],
|
||||
data.fPoints[1],
|
||||
data.fRadii[0],
|
||||
data.fRadii[1],
|
||||
data.fColor4fs,
|
||||
data.fOffsets);
|
||||
break;
|
||||
case SkShader::GradientType::kColor_GradientType: [[fallthrough]];
|
||||
// TODO: The solid color gradient type should use its color, not
|
||||
|
@ -106,6 +106,62 @@ void Dump(const SkPaintParamsKey& key, int headerOffset) {
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
namespace GradientShaderBlocks {
|
||||
|
||||
|
||||
GradientData::GradientData(SkShader::GradientType type,
|
||||
SkTileMode tm,
|
||||
int numStops)
|
||||
: fType(type)
|
||||
, fPoints{{0.0f, 0.0f}, {0.0f, 0.0f}}
|
||||
, fRadii{0.0f, 0.0f}
|
||||
, fTM(tm)
|
||||
, fNumStops(numStops) {
|
||||
sk_bzero(fColor4fs, sizeof(fColor4fs));
|
||||
sk_bzero(fOffsets, sizeof(fOffsets));
|
||||
}
|
||||
|
||||
GradientData::GradientData(SkShader::GradientType type,
|
||||
SkPoint points[2],
|
||||
float radii[2],
|
||||
SkTileMode tm,
|
||||
int numStops,
|
||||
SkColor colors[kMaxStops],
|
||||
float offsets[kMaxStops])
|
||||
: fType(type)
|
||||
, fTM(tm)
|
||||
, fNumStops(numStops) {
|
||||
memcpy(fPoints, points, sizeof(fPoints));
|
||||
memcpy(fRadii, radii, sizeof(fRadii));
|
||||
this->toColor4fs(fNumStops, colors);
|
||||
this->toOffsets(fNumStops, offsets);
|
||||
}
|
||||
|
||||
void GradientData::toColor4fs(int numColors, SkColor colors[kMaxStops]) {
|
||||
if (numColors < 2 || numColors > kMaxStops) {
|
||||
sk_bzero(fColor4fs, sizeof(fColor4fs));
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numColors; ++i) {
|
||||
fColor4fs[i] = SkColor4f::FromColor(colors[i]);
|
||||
}
|
||||
for ( ; i < kMaxStops; ++i) {
|
||||
fColor4fs[i] = fColor4fs[numColors-1];
|
||||
}
|
||||
}
|
||||
|
||||
void GradientData::toOffsets(int numStops, float inputOffsets[kMaxStops]) {
|
||||
if (numStops < 2 || numStops > kMaxStops) {
|
||||
sk_bzero(fOffsets, sizeof(fOffsets));
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(fOffsets, inputOffsets, numStops * sizeof(float));
|
||||
for (int i = numStops ; i < kMaxStops; ++i) {
|
||||
fOffsets[i] = fOffsets[numStops-1];
|
||||
}
|
||||
}
|
||||
|
||||
static const int kBlockDataSize = 1;
|
||||
|
||||
void AddToKey(SkBackend backend,
|
||||
|
@ -47,16 +47,50 @@ namespace SolidColorShaderBlock {
|
||||
namespace GradientShaderBlocks {
|
||||
|
||||
struct GradientData {
|
||||
// TODO: For the sprint we only support 4 stops in the gradients
|
||||
static constexpr int kMaxStops = 4;
|
||||
|
||||
// This ctor is used during pre-compilation when we don't have enough information to
|
||||
// extract uniform data. However, we must be able to provide enough data to make all the
|
||||
// relevant decisions about which code snippets to use.
|
||||
GradientData(SkShader::GradientType,
|
||||
SkTileMode,
|
||||
int numStops);
|
||||
|
||||
// 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,
|
||||
SkPoint points[2],
|
||||
float radii[2],
|
||||
SkTileMode,
|
||||
int numStops,
|
||||
SkColor colors[kMaxStops],
|
||||
float offsets[kMaxStops]);
|
||||
|
||||
bool operator==(const GradientData& rhs) const {
|
||||
return fType == rhs.fType &&
|
||||
fPoints[0] == rhs.fPoints[0] &&
|
||||
fPoints[1] == rhs.fPoints[1] &&
|
||||
fRadii[0] == rhs.fRadii[0] &&
|
||||
fRadii[1] == rhs.fRadii[1] &&
|
||||
fTM == rhs.fTM &&
|
||||
fNumStops == rhs.fNumStops;
|
||||
fNumStops == rhs.fNumStops &&
|
||||
!memcmp(fColor4fs, rhs.fColor4fs, sizeof(fColor4fs)) &&
|
||||
!memcmp(fOffsets, rhs.fOffsets, sizeof(fOffsets));
|
||||
}
|
||||
bool operator!=(const GradientData& rhs) const { return !(*this == rhs); }
|
||||
|
||||
SkShader::GradientType fType;
|
||||
SkPoint fPoints[2];
|
||||
float fRadii[2];
|
||||
SkTileMode fTM;
|
||||
int fNumStops;
|
||||
SkColor4f fColor4fs[kMaxStops];
|
||||
float fOffsets[kMaxStops];
|
||||
|
||||
private:
|
||||
void toColor4fs(int numColors, SkColor colors[kMaxStops]);
|
||||
void toOffsets(int numStops, float inputOffsets[kMaxStops]);
|
||||
};
|
||||
|
||||
void AddToKey(SkBackend,
|
||||
|
Loading…
Reference in New Issue
Block a user