[graphite] Pass SkUniforms around as an SkSpan
Bug: skia:12701
Change-Id: Iee63650517a739029f81121cabd45dfcc2e8fa38
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/502698
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/experimental/graphite/src/ContextUtils.cpp b/experimental/graphite/src/ContextUtils.cpp
index 2a8f94d..0b9579f 100644
--- a/experimental/graphite/src/ContextUtils.cpp
+++ b/experimental/graphite/src/ContextUtils.cpp
@@ -70,21 +70,17 @@
// that only defines a [[depth]] attribute but no color calculation.
static const char* kNoneSkSL = "outColor = half4(0.0, 0.0, 1.0, 1.0);\n";
-sk_sp<SkUniformData> make_gradient_uniform_data_common(const void* srcs[kNumGradientUniforms]) {
+sk_sp<SkUniformData> make_gradient_uniform_data_common(SkSpan<const SkUniform> uniforms,
+ const void* srcs[kNumGradientUniforms]) {
UniformManager mgr(Layout::kMetal);
// TODO: Given that, for the sprint, we always know the uniforms we could cache 'dataSize'
// for each layout and skip the first call.
- size_t dataSize = mgr.writeUniforms(SkSpan<const SkUniform>(kGradientUniforms,
- kNumGradientUniforms),
- nullptr, nullptr, nullptr);
+ size_t dataSize = mgr.writeUniforms(uniforms, nullptr, nullptr, nullptr);
- sk_sp<SkUniformData> result = SkUniformData::Make(kNumGradientUniforms,
- kGradientUniforms,
- dataSize);
+ sk_sp<SkUniformData> result = SkUniformData::Make(uniforms, dataSize);
- mgr.writeUniforms(SkSpan<const SkUniform>(kGradientUniforms, kNumGradientUniforms),
- srcs, result->offsets(), result->data());
+ mgr.writeUniforms(result->uniforms(), srcs, result->offsets(), result->data());
return result;
}
@@ -92,8 +88,13 @@
SkPoint endPoint,
SkColor4f colors[GradientData::kMaxStops],
float offsets[GradientData::kMaxStops]) {
+ static constexpr size_t kExpectedNumUniforms = 6;
+
+ SkSpan<const SkUniform> uniforms = skgpu::GetUniforms(CodeSnippetID::kLinearGradientShader);
+ SkASSERT(uniforms.size() == kExpectedNumUniforms);
+
float unusedRadii[2] = { 0.0f, 0.0f };
- const void* srcs[kNumGradientUniforms] = {
+ const void* srcs[kExpectedNumUniforms] = {
colors,
offsets,
&startPoint,
@@ -102,17 +103,22 @@
&unusedRadii[1],
};
- return make_gradient_uniform_data_common(srcs);
+ return make_gradient_uniform_data_common(uniforms, srcs);
};
sk_sp<SkUniformData> make_radial_gradient_uniform_data(SkPoint point,
float radius,
SkColor4f colors[GradientData::kMaxStops],
float offsets[GradientData::kMaxStops]) {
+ static constexpr size_t kExpectedNumUniforms = 6;
+
+ SkSpan<const SkUniform> uniforms = skgpu::GetUniforms(CodeSnippetID::kRadialGradientShader);
+ SkASSERT(uniforms.size() == kExpectedNumUniforms);
+
SkPoint unusedPoint = {0.0f, 0.0f};
float unusedRadius = 0.0f;
- const void* srcs[kNumGradientUniforms] = {
+ const void* srcs[kExpectedNumUniforms] = {
colors,
offsets,
&point,
@@ -121,16 +127,21 @@
&unusedRadius,
};
- return make_gradient_uniform_data_common(srcs);
+ return make_gradient_uniform_data_common(uniforms, srcs);
};
sk_sp<SkUniformData> make_sweep_gradient_uniform_data(SkPoint point,
SkColor4f colors[GradientData::kMaxStops],
float offsets[GradientData::kMaxStops]) {
+ static constexpr size_t kExpectedNumUniforms = 6;
+
+ SkSpan<const SkUniform> uniforms = skgpu::GetUniforms(CodeSnippetID::kSweepGradientShader);
+ SkASSERT(uniforms.size() == kExpectedNumUniforms);
+
SkPoint unusedPoint = {0.0f, 0.0f};
float unusedRadii[2] = {0.0f, 0.0f};
- const void* srcs[kNumGradientUniforms] = {
+ const void* srcs[kExpectedNumUniforms] = {
colors,
offsets,
&point,
@@ -139,7 +150,7 @@
&unusedRadii[1],
};
- return make_gradient_uniform_data_common(srcs);
+ return make_gradient_uniform_data_common(uniforms, srcs);
};
sk_sp<SkUniformData> make_conical_gradient_uniform_data(SkPoint point0,
@@ -148,8 +159,12 @@
float radius1,
SkColor4f colors[GradientData::kMaxStops],
float offsets[GradientData::kMaxStops]) {
+ static constexpr size_t kExpectedNumUniforms = 6;
- const void* srcs[kNumGradientUniforms] = {
+ SkSpan<const SkUniform> uniforms = skgpu::GetUniforms(CodeSnippetID::kConicalGradientShader);
+ SkASSERT(uniforms.size() == kExpectedNumUniforms);
+
+ const void* srcs[kExpectedNumUniforms] = {
colors,
offsets,
&point0,
@@ -158,21 +173,24 @@
&radius1,
};
- return make_gradient_uniform_data_common(srcs);
+ return make_gradient_uniform_data_common(uniforms, srcs);
};
sk_sp<SkUniformData> make_solid_uniform_data(SkColor4f color) {
+ static constexpr size_t kExpectedNumUniforms = 1;
+
+ SkSpan<const SkUniform> uniforms = skgpu::GetUniforms(CodeSnippetID::kSolidColorShader);
+ SkASSERT(uniforms.size() == kExpectedNumUniforms);
+
UniformManager mgr(Layout::kMetal);
- size_t dataSize = mgr.writeUniforms(SkSpan<const SkUniform>(kSolidUniforms, kNumSolidUniforms),
- nullptr, nullptr, nullptr);
+ size_t dataSize = mgr.writeUniforms(uniforms, nullptr, nullptr, nullptr);
- sk_sp<SkUniformData> result = SkUniformData::Make(kNumSolidUniforms, kSolidUniforms, dataSize);
+ sk_sp<SkUniformData> result = SkUniformData::Make(uniforms, dataSize);
- const void* srcs[kNumSolidUniforms] = { &color };
+ const void* srcs[kExpectedNumUniforms] = { &color };
- mgr.writeUniforms(SkSpan<const SkUniform>(kSolidUniforms, kNumSolidUniforms),
- srcs, result->offsets(), result->data());
+ mgr.writeUniforms(result->uniforms(), srcs, result->offsets(), result->data());
return result;
}
@@ -290,12 +308,12 @@
switch (snippetID) {
case CodeSnippetID::kDepthStencilOnlyDraw:
return {nullptr, 0};
- case CodeSnippetID::kLinearGradientShader:
+ case CodeSnippetID::kLinearGradientShader: [[fallthrough]];
+ case CodeSnippetID::kRadialGradientShader: [[fallthrough]];
+ case CodeSnippetID::kSweepGradientShader: [[fallthrough]];
+ case CodeSnippetID::kConicalGradientShader:
return SkMakeSpan(kGradientUniforms, kNumGradientUniforms);
case CodeSnippetID::kSolidColorShader:
- case CodeSnippetID::kRadialGradientShader:
- case CodeSnippetID::kSweepGradientShader:
- case CodeSnippetID::kConicalGradientShader:
default:
return SkMakeSpan(kSolidUniforms, kNumSolidUniforms);
}
@@ -305,12 +323,12 @@
switch (snippetID) {
case CodeSnippetID::kDepthStencilOnlyDraw:
return kNoneSkSL;
- case CodeSnippetID::kLinearGradientShader:
+ case CodeSnippetID::kLinearGradientShader: [[fallthrough]];
+ case CodeSnippetID::kRadialGradientShader: [[fallthrough]];
+ case CodeSnippetID::kSweepGradientShader: [[fallthrough]];
+ case CodeSnippetID::kConicalGradientShader:
return kGradientSkSL;
case CodeSnippetID::kSolidColorShader:
- case CodeSnippetID::kRadialGradientShader:
- case CodeSnippetID::kSweepGradientShader:
- case CodeSnippetID::kConicalGradientShader:
default:
return kSolidColorSkSL;
}
diff --git a/src/core/SkUniformData.cpp b/src/core/SkUniformData.cpp
index 4349fd5..c073ac0 100644
--- a/src/core/SkUniformData.cpp
+++ b/src/core/SkUniformData.cpp
@@ -9,24 +9,24 @@
#include "src/core/SkOpts.h"
-sk_sp<SkUniformData> SkUniformData::Make(int count,
- const SkUniform* uniforms,
+sk_sp<SkUniformData> SkUniformData::Make(SkSpan<const SkUniform> uniforms,
size_t dataSize) {
// TODO: the offsets and data should just be allocated right after UniformData in an arena
- uint32_t* offsets = new uint32_t[count];
+ uint32_t* offsets = new uint32_t[uniforms.size()];
char* data = new char[dataSize];
- return sk_sp<SkUniformData>(new SkUniformData(count, uniforms, offsets, data, dataSize));
+ return sk_sp<SkUniformData>(new SkUniformData(uniforms, offsets, data, dataSize));
}
bool SkUniformData::operator==(const SkUniformData& other) const {
- if (this->count() != other.count() ||
- this->uniforms() != other.uniforms() ||
+ if (this->uniforms().size() != other.uniforms().size() ||
this->dataSize() != other.dataSize()) {
return false;
}
- return !memcmp(this->data(), other.data(), this->dataSize()) &&
+ return !memcmp(this->uniforms().data(), other.uniforms().data(),
+ this->uniforms().size_bytes()) &&
+ !memcmp(this->data(), other.data(), this->dataSize()) &&
!memcmp(this->offsets(), other.offsets(), this->count()*sizeof(uint32_t));
}
diff --git a/src/core/SkUniformData.h b/src/core/SkUniformData.h
index 1392479..d0398b6 100644
--- a/src/core/SkUniformData.h
+++ b/src/core/SkUniformData.h
@@ -9,10 +9,10 @@
#define SkUniformData_DEFINED
#include "include/core/SkRefCnt.h"
+#include "include/core/SkSpan.h"
+#include "src/core/SkUniform.h"
#include <vector>
-class SkUniform;
-
/*
* TODO: Here is the plan of record for SkUniformData
* allocate them (and their ancillary data (offsets & data)) in an arena - and rm SkRefCnt
@@ -33,9 +33,7 @@
// TODO: should we require a name (e.g., "gradient_uniforms") for each uniform block so
// we can better name the Metal FS uniform struct?
- static sk_sp<SkUniformData> Make(int count,
- const SkUniform* uniforms,
- size_t dataSize);
+ static sk_sp<SkUniformData> Make(SkSpan<const SkUniform>, size_t dataSize);
~SkUniformData() override {
// TODO: fOffsets and fData should just be allocated right after UniformData in an arena
@@ -43,12 +41,12 @@
delete [] fData;
}
- int count() const { return fCount; }
- const SkUniform* uniforms() const { return fUniforms; }
+ int count() const { return static_cast<unsigned int>(fUniforms.size()); }
+ SkSpan<const SkUniform> uniforms() const { return fUniforms; }
uint32_t* offsets() { return fOffsets; }
const uint32_t* offsets() const { return fOffsets; }
uint32_t offset(int index) {
- SkASSERT(index >= 0 && index < fCount);
+ SkASSERT(index >= 0 && static_cast<size_t>(index) < fUniforms.size());
return fOffsets[index];
}
char* data() { return fData; }
@@ -59,20 +57,17 @@
bool operator!=(const SkUniformData& other) const { return !(*this == other); }
private:
- SkUniformData(int count,
- const SkUniform* uniforms,
+ SkUniformData(SkSpan<const SkUniform> uniforms,
uint32_t* offsets,
char* data,
size_t dataSize)
- : fCount(count)
- , fUniforms(uniforms)
+ : fUniforms(uniforms)
, fOffsets(offsets)
, fData(data)
, fDataSize(dataSize) {
}
- const int fCount;
- const SkUniform* fUniforms;
+ SkSpan<const SkUniform> fUniforms;
uint32_t* fOffsets; // offset of each uniform in 'fData'
char* fData;
const size_t fDataSize;
diff --git a/tests/graphite/CommandBufferTest.cpp b/tests/graphite/CommandBufferTest.cpp
index c64cffc..c1a453a 100644
--- a/tests/graphite/CommandBufferTest.cpp
+++ b/tests/graphite/CommandBufferTest.cpp
@@ -84,8 +84,7 @@
SkASSERT(shape.isRect());
// TODO: A << API for uniforms would be nice, particularly if it could take pre-computed
// offsets for each uniform.
- auto uniforms = SkUniformData::Make(this->numUniforms(), this->uniforms().data(),
- sizeof(float) * 4);
+ auto uniforms = SkUniformData::Make(this->uniforms(), sizeof(float) * 4);
float2 scale = shape.rect().size();
float2 translate = shape.rect().topLeft();
memcpy(uniforms->data(), &scale, sizeof(float2));
@@ -147,8 +146,7 @@
const SkIRect&,
const Transform&,
const Shape&) const override {
- auto uniforms = SkUniformData::Make(this->numUniforms(), this->uniforms().data(),
- sizeof(float) * 4);
+ auto uniforms = SkUniformData::Make(this->uniforms(), sizeof(float) * 4);
float data[4] = {2.f, 2.f, -1.f, -1.f};
memcpy(uniforms->data(), data, 4 * sizeof(float));
return uniforms;
diff --git a/tests/graphite/UniformCacheTest.cpp b/tests/graphite/UniformCacheTest.cpp
index 952252a..709bedf 100644
--- a/tests/graphite/UniformCacheTest.cpp
+++ b/tests/graphite/UniformCacheTest.cpp
@@ -28,7 +28,8 @@
SkASSERT(numUniforms <= kMaxUniforms);
- sk_sp<SkUniformData> ud = SkUniformData::Make(numUniforms, kUniforms, dataSize);
+ sk_sp<SkUniformData> ud = SkUniformData::Make(SkSpan<const SkUniform>(kUniforms, numUniforms),
+ dataSize);
for (int i = 0; i < numUniforms; ++i) {
ud->offsets()[i] = i;
}