Convert SkRuntimeEffect::Uniform to use string_view.

Change-Id: I07c0cb63286cb2c74853a49a44a9ee5ae7b994c9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/557102
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
John Stiles 2022-07-12 11:26:15 -04:00 committed by SkCQ
parent d0066ba138
commit 955b73beec
14 changed files with 70 additions and 65 deletions

View File

@ -9,6 +9,9 @@ Milestone 104
* SkRasterHandleAllocator::MakeCanvas now takes optional SkSurfaceProps.
* SkImage::MakeFromPicture and SkImageGenerator::MakeFromPicture now take an optional
SkSurfaceProps to use when rasterizing the picture.
* SkRuntimeEffect::Uniform now stores the uniform name as a string_view, rather than a
SkString. Related methods SkRuntimeEffect::findUniform and SkRuntimeEffectBuilder::uniform
also take std::string_view instead of const char*.
* skcms.h has been relocated to //modules/skcms/skcms.h (was //include/third_party/skcms/skcms.h)
* New functions SkCanvas::getBaseProps and SkCanvas::getTopProps; SkCanvas::getBaseProps is a
direct replacement for the (now deprecated) SkCanvas::getProps function, while getTopProps is

View File

@ -157,7 +157,7 @@ public:
SkSpan<const Uniform> uniforms() const { return SkSpan(fUniforms); }
/** Returns pointer to the named uniform variable's description, or nullptr if not found. */
const Uniform* findUniform(const char* name) const;
const Uniform* findUniform(std::string_view name) const;
size_t stride() const { return fStride; }

View File

@ -91,11 +91,11 @@ public:
kHalfPrecision_Flag = 0x10,
};
SkString name;
size_t offset;
Type type;
int count;
uint32_t flags;
std::string_view name;
size_t offset;
Type type;
int count;
uint32_t flags;
bool isArray() const { return SkToBool(this->flags & kArray_Flag); }
bool isColor() const { return SkToBool(this->flags & kColor_Flag); }
@ -254,7 +254,7 @@ public:
SkSpan<const Child> children() const { return SkSpan(fChildren); }
// Returns pointer to the named uniform variable's description, or nullptr if not found
const Uniform* findUniform(const char* name) const;
const Uniform* findUniform(std::string_view name) const;
// Returns pointer to the named child's description, or nullptr if not found
const Child* findChild(const char* name) const;
@ -410,7 +410,7 @@ public:
const SkRuntimeEffect* effect() const { return fEffect.get(); }
BuilderUniform uniform(const char* name) { return { this, fEffect->findUniform(name) }; }
BuilderUniform uniform(std::string_view name) { return { this, fEffect->findUniform(name) }; }
BuilderChild child(const char* name) {
const SkRuntimeEffect::Child* child = fEffect->findChild(name);
return { this, child };

View File

@ -36,20 +36,20 @@ static void ShaderBuilder_Release(JNIEnv* env, jobject, jlong native_instance) {
static void ShaderBuilder_SetUniformFloat(JNIEnv* env, jobject, jlong native_instance, jstring jname, float val) {
if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
builder->uniform(androidkit::utils::CString(env, jname)) = val;
builder->uniform(androidkit::utils::CString(env, jname).str()) = val;
}
}
static void ShaderBuilder_SetUniformFloat3(JNIEnv* env, jobject, jlong native_instance, jstring jname, float valX, float valY, float valZ) {
if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
builder->uniform(androidkit::utils::CString(env, jname)) = SkV3{valX, valY, valZ};
builder->uniform(androidkit::utils::CString(env, jname).str()) = SkV3{valX, valY, valZ};
}
}
static void ShaderBuilder_SetUniformMatrix(JNIEnv* env, jobject, jlong native_instance, jstring jname, jlong native_matrix) {
if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
if (auto* matrix = reinterpret_cast<SkM44*>(native_matrix)) {
builder->uniform(androidkit::utils::CString(env, jname)) = *matrix;
builder->uniform(androidkit::utils::CString(env, jname).str()) = *matrix;
}
}
}

View File

@ -28,6 +28,7 @@ public:
fEnv->ReleaseStringUTFChars(fJString, fCString);
}
const char* str() const { return fCString; }
operator const char*() const { return fCString; }
private:
@ -35,7 +36,6 @@ private:
const jstring& fJString;
const char* fCString;
CString(CString&&) = delete;
CString(const CString&) = delete;
CString& operator=(CString&&) = delete;

View File

@ -1996,7 +1996,7 @@ EMSCRIPTEN_BINDINGS(Skia) {
}))
.function("getUniformName", optional_override([](SkRuntimeEffect& self, int i)->JSString {
auto it = self.uniforms().begin() + i;
return emscripten::val(it->name.c_str());
return emscripten::val(std::string(it->name).c_str());
}))
.function("getUniform", optional_override([](SkRuntimeEffect& self, int i)->RuntimeEffectUniform {
auto it = self.uniforms().begin() + i;

View File

@ -51,9 +51,7 @@ using Uniform = SkMeshSpecification::Uniform;
static std::vector<Uniform>::iterator find_uniform(std::vector<Uniform>& uniforms,
std::string_view name) {
return std::find_if(uniforms.begin(), uniforms.end(),
[name](const SkMeshSpecification::Uniform& u) {
return u.name.equals(name.data(), name.size());
});
[name](const SkMeshSpecification::Uniform& u) { return u.name == name; });
}
static std::tuple<bool, SkString>
@ -86,14 +84,14 @@ gather_uniforms_and_check_for_main(const SkSL::Program& program,
if (uniform.isArray() != iter->isArray() ||
uniform.type != iter->type ||
uniform.count != iter->count) {
return {false, SkStringPrintf("Uniform %s declared with different types"
" in vertex and fragment shaders.",
iter->name.c_str())};
return {false, SkStringPrintf("Uniform %.*s declared with different types"
" in vertex and fragment shaders.",
(int)iter->name.size(), iter->name.data())};
}
if (uniform.isColor() != iter->isColor()) {
return {false, SkStringPrintf("Uniform %s declared with different color"
return {false, SkStringPrintf("Uniform %.*s declared with different color"
" layout in vertex and fragment shaders.",
iter->name.c_str())};
(int)iter->name.size(), iter->name.data())};
}
(*iter).flags |= stage;
}
@ -450,11 +448,9 @@ size_t SkMeshSpecification::uniformSize() const {
: SkAlign4(fUniforms.back().offset + fUniforms.back().sizeInBytes());
}
const Uniform* SkMeshSpecification::findUniform(const char* name) const {
SkASSERT(name);
size_t len = strlen(name);
auto iter = std::find_if(fUniforms.begin(), fUniforms.end(), [name, len] (const Uniform& u) {
return u.name.equals(name, len);
const Uniform* SkMeshSpecification::findUniform(std::string_view name) const {
auto iter = std::find_if(fUniforms.begin(), fUniforms.end(), [name] (const Uniform& u) {
return u.name == name;
});
return iter == fUniforms.end() ? nullptr : &(*iter);
}

View File

@ -95,7 +95,7 @@ SkRuntimeEffect::Uniform SkRuntimeEffectPriv::VarAsUniform(const SkSL::Variable&
using Uniform = SkRuntimeEffect::Uniform;
SkASSERT(var.modifiers().fFlags & SkSL::Modifiers::kUniform_Flag);
Uniform uni;
uni.name = SkString(var.name());
uni.name = var.name();
uni.flags = 0;
uni.count = 1;
@ -635,11 +635,9 @@ size_t SkRuntimeEffect::uniformSize() const {
: SkAlign4(fUniforms.back().offset + fUniforms.back().sizeInBytes());
}
const SkRuntimeEffect::Uniform* SkRuntimeEffect::findUniform(const char* name) const {
SkASSERT(name);
size_t len = strlen(name);
auto iter = std::find_if(fUniforms.begin(), fUniforms.end(), [name, len](const Uniform& u) {
return u.name.equals(name, len);
const SkRuntimeEffect::Uniform* SkRuntimeEffect::findUniform(std::string_view name) const {
auto iter = std::find_if(fUniforms.begin(), fUniforms.end(), [name](const Uniform& u) {
return u.name == name;
});
return iter == fUniforms.end() ? nullptr : &(*iter);
}

View File

@ -849,10 +849,10 @@ SkSpan<const SkUniform> SkShaderCodeDictionary::convertUniforms(const SkRuntimeE
}
const Uniform& u = uniforms[index - 1];
// The existing uniform names are in SkStrings and may disappear. Copy them into fArena.
// (It's safe to do this within makeInitializedArray; the entire array is allocated in one
// big slab before any initialization calls are done.)
const char* name = this->addTextToArena(std::string_view(u.name.c_str(), u.name.size()));
// The existing uniform names live in the passed-in SkRuntimeEffect and may eventually
// disappear. Copy them into fArena. (It's safe to do this within makeInitializedArray; the
// entire array is allocated in one big slab before any initialization calls are done.)
const char* name = this->addTextToArena(u.name);
// Add one SkUniform to our array.
SkSLType type = uniform_type_to_sksl_type(u);

View File

@ -398,7 +398,7 @@ void GrSkSLFP::onAddToKey(const GrShaderCaps& caps, skgpu::KeyBuilder* b) const
bool specialize = specialized[i] == Specialized::kYes;
b->addBool(specialize, "specialize");
if (specialize) {
b->addBytes(iter->sizeInBytes(), uniformData + iter->offset, iter->name.c_str());
b->addBytes(iter->sizeInBytes(), uniformData + iter->offset, iter->name);
}
}
}

View File

@ -304,7 +304,9 @@ private:
uniform_iterator uEnd,
child_iterator cIter,
child_iterator cEnd) {
SkASSERTF(uIter == uEnd, "Expected more uniforms, starting with '%s'", uIter->name.c_str());
SkASSERTF(uIter == uEnd,
"Expected more uniforms, starting with '%.*s'",
(int)uIter->name.size(), uIter->name.data());
SkASSERTF(cIter == cEnd, "Expected more children, starting with '%s'", cIter->name.c_str());
}
static void checkOneChild(child_iterator cIter, child_iterator cEnd, const char* name) {
@ -373,9 +375,9 @@ private:
const T* /*val*/,
size_t valSize) {
SkASSERTF(uIter != uEnd, "Too many uniforms, wasn't expecting '%s'", name);
SkASSERTF(uIter->name.equals(name),
"Expected uniform '%s', got '%s' instead",
uIter->name.c_str(), name);
SkASSERTF(uIter->name == name,
"Expected uniform '%.*s', got '%s' instead",
(int)uIter->name.size(), uIter->name.data(), name);
SkASSERTF(uIter->sizeInBytes() == valSize,
"Expected uniform '%s' to be %zu bytes, got %zu instead",
name, uIter->sizeInBytes(), valSize);

View File

@ -125,7 +125,7 @@ private:
auto it = std::find_if(uniforms.begin(),
uniforms.end(),
[&name](SkMeshSpecification::Uniform uniform) {
return uniform.name == name;
return uniform.name == std::string_view(name.c_str(), name.size());
});
SkASSERT(it != uniforms.end());

View File

@ -279,12 +279,16 @@ static void test_good_uniforms(skiatest::Reporter* r) {
constexpr Flags kColor = Uniform::kColor_Flag;
constexpr Flags kHalfP = Uniform::kHalfPrecision_Flag;
auto make_uni = [](Type type, const char* name, size_t offset, uint32_t flags, int count = 0) {
auto make_uni = [](Type type,
std::string_view name,
size_t offset,
uint32_t flags,
int count = 0) {
if (count) {
return Uniform{SkString(name), offset, type, count, flags | Uniform::kArray_Flag};
return Uniform{name, offset, type, count, flags | Uniform::kArray_Flag};
} else {
SkASSERT(!(flags & Uniform::kArray_Flag));
return Uniform{SkString(name), offset, type, 1, flags};
return Uniform{name, offset, type, 1, flags};
}
};
@ -441,7 +445,7 @@ static void test_good_uniforms(skiatest::Reporter* r) {
return;
}
SkString desc = make_description(attrs, kValidStride, varys, vs, fs);
auto uniforms = spec->uniforms();
SkSpan<const Uniform> uniforms = spec->uniforms();
if (uniforms.size() != c.expectations.size()) {
ERRORF(r,
"Expected %zu uniforms but actually %zu:\n%s",
@ -451,18 +455,18 @@ static void test_good_uniforms(skiatest::Reporter* r) {
return;
}
for (const auto& [actual, expected] : SkMakeZip(uniforms, c.expectations)) {
if (actual.name != expected.name) {
std::string name = std::string(actual.name);
if (name != expected.name) {
ERRORF(r,
"Actual uniform name (%s) does not match expected name (%s)",
actual.name.c_str(),
expected.name.c_str());
"Actual uniform name (%s) does not match expected name (%.*s)",
name.c_str(),
(int)expected.name.size(), expected.name.data());
return;
}
const char* name = actual.name.c_str();
if (actual.type != expected.type) {
ERRORF(r,
"Uniform %s: Actual type (%d) does not match expected type (%d)",
name,
name.c_str(),
static_cast<int>(actual.type),
static_cast<int>(expected.type));
return;
@ -470,7 +474,7 @@ static void test_good_uniforms(skiatest::Reporter* r) {
if (actual.count != expected.count) {
ERRORF(r,
"Uniform %s: Actual count (%d) does not match expected count (%d)",
name,
name.c_str(),
actual.count,
expected.count);
return;
@ -478,7 +482,7 @@ static void test_good_uniforms(skiatest::Reporter* r) {
if (actual.flags != expected.flags) {
ERRORF(r,
"Uniform %s: Actual flags (0x%04x) do not match expected flags (0x%04x)",
name,
name.c_str(),
actual.flags,
expected.flags);
return;
@ -486,7 +490,7 @@ static void test_good_uniforms(skiatest::Reporter* r) {
if (actual.offset != expected.offset) {
ERRORF(r,
"Uniform %s: Actual offset (%zu) does not match expected offset (%zu)",
name,
name.c_str(),
actual.offset,
expected.offset);
return;

View File

@ -171,17 +171,17 @@ void SkSLSlide::draw(SkCanvas* canvas) {
fMousePos.z = abs(fMousePos.z) * (ImGui::IsMouseDown(0) ? 1 : -1);
fMousePos.w = abs(fMousePos.w) * (ImGui::IsMouseClicked(0) ? 1 : -1);
for (const auto& v : fEffect->uniforms()) {
for (const SkRuntimeEffect::Uniform& v : fEffect->uniforms()) {
char* data = fInputs.get() + v.offset;
if (v.name.equals("iResolution")) {
if (v.name == "iResolution") {
memcpy(data, &fResolution, sizeof(fResolution));
continue;
}
if (v.name.equals("iTime")) {
if (v.name == "iTime") {
memcpy(data, &fSeconds, sizeof(fSeconds));
continue;
}
if (v.name.equals("iMouse")) {
if (v.name == "iMouse") {
memcpy(data, &fMousePos, sizeof(fMousePos));
continue;
}
@ -193,8 +193,9 @@ void SkSLSlide::draw(SkCanvas* canvas) {
int rows = ((int)v.type - (int)SkRuntimeEffect::Uniform::Type::kFloat) + 1;
float* f = reinterpret_cast<float*>(data);
for (int c = 0; c < v.count; ++c, f += rows) {
SkString name = v.isArray() ? SkStringPrintf("%s[%d]", v.name.c_str(), c)
: v.name;
SkString name = v.isArray()
? SkStringPrintf("%.*s[%d]", (int)v.name.size(), v.name.data(), c)
: SkString(v.name);
ImGui::PushID(c);
ImGui::DragScalarN(name.c_str(), ImGuiDataType_Float, f, rows, 1.0f);
ImGui::PopID();
@ -210,8 +211,8 @@ void SkSLSlide::draw(SkCanvas* canvas) {
for (int e = 0; e < v.count; ++e) {
for (int c = 0; c < cols; ++c, f += rows) {
SkString name = v.isArray()
? SkStringPrintf("%s[%d][%d]", v.name.c_str(), e, c)
: SkStringPrintf("%s[%d]", v.name.c_str(), c);
? SkStringPrintf("%.*s[%d][%d]", (int)v.name.size(), v.name.data(), e, c)
: SkStringPrintf("%.*s[%d]", (int)v.name.size(), v.name.data(), c);
ImGui::DragScalarN(name.c_str(), ImGuiDataType_Float, f, rows, 1.0f);
}
}
@ -224,8 +225,9 @@ void SkSLSlide::draw(SkCanvas* canvas) {
int rows = ((int)v.type - (int)SkRuntimeEffect::Uniform::Type::kInt) + 1;
int* i = reinterpret_cast<int*>(data);
for (int c = 0; c < v.count; ++c, i += rows) {
SkString name = v.isArray() ? SkStringPrintf("%s[%d]", v.name.c_str(), c)
: v.name;
SkString name = v.isArray()
? SkStringPrintf("%.*s[%d]", (int)v.name.size(), v.name.data(), c)
: SkString(v.name);
ImGui::PushID(c);
ImGui::DragScalarN(name.c_str(), ImGuiDataType_S32, i, rows, 1.0f);
ImGui::PopID();