get rid of utils::StaticString

In most places this is simply replaced by `std::string_view`.

We also change a few internal/private headers so they accept 
`std::string_view` instead of `utils::CString`.
This commit is contained in:
Mathias Agopian
2022-08-01 14:16:14 -07:00
committed by Mathias Agopian
parent 971df18b3c
commit 5b71274fa5
28 changed files with 155 additions and 340 deletions

View File

@@ -164,8 +164,7 @@ private:
### Strings
- Never use `std::string` in the Filament core renderer. Prefer `utils::CString` or
`utils::StaticString`.
- Never use `std::string` in the Filament core renderer. Prefer `utils::CString` or `std::string_view`.
- When using `std::string` in tools, always include the `std::` qualifier to disambiguate it
from other string types.

View File

@@ -27,6 +27,7 @@
#include <backend/DriverEnums.h>
#include <array>
#include <string_view>
namespace filament::backend {
@@ -77,7 +78,7 @@ public:
// not permitted in glsl. The backend needs a way to associate a uniform block
// to a binding point.
//
Program& setUniformBlock(size_t bindingPoint, utils::CString uniformBlockName) noexcept;
Program& setUniformBlock(size_t bindingPoint, std::string_view uniformBlockName) noexcept;
// sets the 'bindingPoint' sampler group descriptor for this program.
// 'samplers' can be destroyed after this call.

View File

@@ -40,8 +40,8 @@ Program& Program::shader(Program::Shader shader, void const* data, size_t size)
return *this;
}
Program& Program::setUniformBlock(size_t bindingPoint, utils::CString uniformBlockName) noexcept {
mUniformBlocks[bindingPoint] = std::move(uniformBlockName);
Program& Program::setUniformBlock(size_t bindingPoint, std::string_view uniformBlockName) noexcept {
mUniformBlocks[bindingPoint] = { uniformBlockName.data(), uniformBlockName.size() };
return *this;
}

View File

@@ -126,7 +126,7 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform,
bool validationFeaturesSupported = false;
#if VK_ENABLE_VALIDATION
const utils::StaticString DESIRED_LAYERS[] = {
const std::string_view DESIRED_LAYERS[] = {
"VK_LAYER_KHRONOS_validation",
#if FILAMENT_VULKAN_DUMP_API
"VK_LAYER_LUNARG_api_dump",
@@ -145,9 +145,9 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform,
auto enabledLayers = FixedCapacityVector<const char*>::with_capacity(kMaxEnabledLayersCount);
for (const auto& desired : DESIRED_LAYERS) {
for (const VkLayerProperties& layer : availableLayers) {
const utils::CString availableLayer(layer.layerName);
const std::string_view availableLayer(layer.layerName);
if (availableLayer == desired) {
enabledLayers.push_back(desired.c_str());
enabledLayers.push_back(desired.data());
}
}
}
@@ -1949,16 +1949,16 @@ void VulkanDriver::refreshSwapChain() {
void VulkanDriver::debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept {
DriverBase::debugCommandBegin(cmds, synchronous, methodName);
#ifndef NDEBUG
static const std::set<utils::StaticString> OUTSIDE_COMMANDS = {
static const std::set<std::string_view> OUTSIDE_COMMANDS = {
"loadUniformBuffer",
"updateBufferObject",
"updateIndexBuffer",
"update3DImage",
};
static const utils::StaticString BEGIN_COMMAND = "beginRenderPass";
static const utils::StaticString END_COMMAND = "endRenderPass";
static const std::string_view BEGIN_COMMAND = "beginRenderPass";
static const std::string_view END_COMMAND = "endRenderPass";
static bool inRenderPass = false; // for debug only
const utils::StaticString command = utils::StaticString::make(methodName, strlen(methodName));
const std::string_view command{ methodName };
if (command == BEGIN_COMMAND) {
assert_invariant(!inRenderPass);
inRenderPass = true;
@@ -1966,7 +1966,7 @@ void VulkanDriver::debugCommandBegin(CommandStream* cmds, bool synchronous, cons
assert_invariant(inRenderPass);
inRenderPass = false;
} else if (inRenderPass && OUTSIDE_COMMANDS.find(command) != OUTSIDE_COMMANDS.end()) {
utils::slog.e << command.c_str() << " issued inside a render pass." << utils::io::endl;
utils::slog.e << command.data() << " issued inside a render pass." << utils::io::endl;
}
#endif
}

View File

@@ -419,7 +419,7 @@ TEST_F(BackendTest, DepthMinify) {
Program prog = shaderGen.getProgram();
Program::Sampler psamplers[] = { utils::CString("tex"), 0, false };
prog.setSamplerGroup(0, ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
prog.setUniformBlock(1, utils::CString("params"));
prog.setUniformBlock(1, "params");
program = api.createProgram(std::move(prog));
}
@@ -561,7 +561,7 @@ TEST_F(BackendTest, ColorResolve) {
Program prog = shaderGen.getProgram();
Program::Sampler psamplers[] = { utils::CString("tex"), 0, false };
prog.setSamplerGroup(0, ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
prog.setUniformBlock(1, utils::CString("params"));
prog.setUniformBlock(1, "params");
program = api.createProgram(std::move(prog));
}
@@ -669,7 +669,7 @@ TEST_F(BackendTest, DepthResolve) {
Program prog = shaderGen.getProgram();
Program::Sampler psamplers[] = { utils::CString("tex"), 0, false };
prog.setSamplerGroup(0, ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
prog.setUniformBlock(1, utils::CString("params"));
prog.setUniformBlock(1, "params");
program = api.createProgram(std::move(prog));
}

View File

@@ -202,7 +202,7 @@ TEST_F(BackendTest, BufferObjectUpdateWithOffset) {
// Create a program.
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform);
Program p = shaderGen.getProgram();
p.setUniformBlock(1, utils::CString("params"));
p.setUniformBlock(1, "params");
auto program = getDriverApi().createProgram(std::move(p));
// Create a uniform buffer.

View File

@@ -135,7 +135,7 @@ TEST_F(BackendTest, FeedbackLoops) {
Program prog = shaderGen.getProgram();
Program::Sampler psamplers[] = { utils::CString("tex"), 0, false };
prog.setSamplerGroup(0, ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
prog.setUniformBlock(1, utils::CString("params"));
prog.setUniformBlock(1, "params");
program = api.createProgram(std::move(prog));
}

View File

@@ -300,7 +300,7 @@ bool ChunkUniformInterfaceBlock::unflatten(Unflattener& unflattener,
return false;
}
builder.name(std::move(name));
builder.name({ name.data(), name.size() });
// Read number of fields.
uint64_t numFields = 0;
@@ -331,7 +331,7 @@ bool ChunkUniformInterfaceBlock::unflatten(Unflattener& unflattener,
}
// a size of 1 means not an array
builder.add(fieldName, fieldSize == 1 ? 0 : fieldSize,
builder.add({ fieldName.data(), fieldName.size() }, fieldSize == 1 ? 0 : fieldSize,
UniformInterfaceBlock::Type(fieldType),
UniformInterfaceBlock::Precision(fieldPrecision));
}
@@ -349,7 +349,7 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
if (!unflattener.read(&name)) {
return false;
}
builder.name(name);
builder.name({ name.data(), name.size() });
// Read number of fields.
uint64_t numFields = 0;
@@ -384,7 +384,7 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
return false;
}
builder.add(fieldName, SamplerInterfaceBlock::Type(fieldType),
builder.add({ fieldName.data(), fieldName.size() }, SamplerInterfaceBlock::Type(fieldType),
SamplerInterfaceBlock::Format(fieldFormat),
SamplerInterfaceBlock::Precision(fieldPrecision),
fieldMultisample);

View File

@@ -186,12 +186,12 @@ PostProcessManager::PostProcessManager(FEngine& engine) noexcept
PostProcessManager::~PostProcessManager() noexcept = default;
UTILS_NOINLINE
void PostProcessManager::registerPostProcessMaterial(utils::StaticString name, uint8_t const* data, int size) {
void PostProcessManager::registerPostProcessMaterial(std::string_view name, uint8_t const* data, int size) {
mMaterialRegistry.try_emplace(name, mEngine, data, size);
}
UTILS_NOINLINE
PostProcessManager::PostProcessMaterial& PostProcessManager::getPostProcessMaterial(utils::StaticString name) noexcept {
PostProcessManager::PostProcessMaterial& PostProcessManager::getPostProcessMaterial(std::string_view name) noexcept {
assert_invariant(mMaterialRegistry.find(name) != mMaterialRegistry.end());
return mMaterialRegistry[name];
}
@@ -199,7 +199,7 @@ PostProcessManager::PostProcessMaterial& PostProcessManager::getPostProcessMater
#define MATERIAL(n) MATERIALS_ ## n ## _DATA, MATERIALS_ ## n ## _SIZE
struct MaterialInfo {
utils::StaticString name;
std::string_view name;
uint8_t const* data;
int size;
};
@@ -1052,25 +1052,18 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::gaussianBlurPass(FrameGraph&
FGTD const& outDesc = resources.getDescriptor(data.out);
FGTD const& tempDesc = resources.getDescriptor(data.temp);
utils::StaticString materialName;
using namespace std::literals;
std::string_view materialName;
const bool is2dArray = inDesc.type == SamplerType::SAMPLER_2D_ARRAY;
switch (backend::getFormatSize(outDesc.format)) {
case 1: materialName = is2dArray ?
utils::StaticString("separableGaussianBlur1L") :
utils::StaticString("separableGaussianBlur1");
break;
"separableGaussianBlur1L"sv : "separableGaussianBlur1"sv; break;
case 2: materialName = is2dArray ?
utils::StaticString("separableGaussianBlur2L") :
utils::StaticString("separableGaussianBlur2");
break;
"separableGaussianBlur2L"sv : "separableGaussianBlur2"sv; break;
case 3: materialName = is2dArray ?
utils::StaticString("separableGaussianBlur3L") :
utils::StaticString("separableGaussianBlur3");
break;
"separableGaussianBlur3L"sv : "separableGaussianBlur3"sv; break;
default: materialName = is2dArray ?
utils::StaticString("separableGaussianBlur4L") :
utils::StaticString("separableGaussianBlur4");
break;
"separableGaussianBlur4L"sv : "separableGaussianBlur4"sv; break;
}
auto const& separableGaussianBlur = getPostProcessMaterial(materialName);
@@ -2740,7 +2733,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscale(FrameGraph& fg, bool
}
{ // just a scope to not leak local variables
const StaticString blitterNames[4] = {
const std::string_view blitterNames[4] = {
"blitLow", "fsr_easu_mobile", "fsr_easu_mobile", "fsr_easu" };
unsigned index = std::min(3u, (unsigned)dsrOptions.quality);
easuMaterial = &getPostProcessMaterial(blitterNames[index]);

View File

@@ -317,14 +317,13 @@ private:
};
using MaterialRegistryMap = tsl::robin_map<
utils::StaticString,
PostProcessMaterial,
utils::StaticString::Hasher>;
std::string_view,
PostProcessMaterial>;
MaterialRegistryMap mMaterialRegistry;
void registerPostProcessMaterial(utils::StaticString name, uint8_t const* data, int size);
PostProcessMaterial& getPostProcessMaterial(utils::StaticString name) noexcept;
void registerPostProcessMaterial(std::string_view name, uint8_t const* data, int size);
PostProcessMaterial& getPostProcessMaterial(std::string_view name) noexcept;
backend::Handle<backend::HwTexture> mStarburstTexture;

View File

@@ -35,7 +35,7 @@ FDebugRegistry::FDebugRegistry() noexcept = default;
UTILS_NOINLINE
void* FDebugRegistry::getPropertyAddress(const char* name) noexcept {
StaticString key = StaticString::make(name, strlen(name));
std::string_view key{ name };
auto& propertyMap = mPropertyMap;
if (propertyMap.find(key) == propertyMap.end()) {
return nullptr;
@@ -43,7 +43,7 @@ void* FDebugRegistry::getPropertyAddress(const char* name) noexcept {
return propertyMap[key];
}
void FDebugRegistry::registerProperty(utils::StaticString name, void* p, Type type) noexcept {
void FDebugRegistry::registerProperty(std::string_view name, void* p, Type type) noexcept {
auto& propertyMap = mPropertyMap;
if (propertyMap.find(name) == propertyMap.end()) {
propertyMap[name] = p;
@@ -91,7 +91,7 @@ template bool FDebugRegistry::getProperty<float2>(const char* name, float2* v) c
template bool FDebugRegistry::getProperty<float3>(const char* name, float3* v) const noexcept;
template bool FDebugRegistry::getProperty<float4>(const char* name, float4* v) const noexcept;
void FDebugRegistry::registerDataSource(StaticString name,
void FDebugRegistry::registerDataSource(std::string_view name,
void const* data, size_t count) noexcept {
auto& dataSourceMap = mDataSourceMap;
if (dataSourceMap.find(name) == dataSourceMap.end()) {
@@ -100,7 +100,7 @@ void FDebugRegistry::registerDataSource(StaticString name,
}
DebugRegistry::DataSource FDebugRegistry::getDataSource(const char* name) const noexcept {
StaticString key = StaticString::make(name, strlen(name));
std::string_view key{ name };
auto& dataSourceMap = mDataSourceMap;
auto const& it = dataSourceMap.find(key);
if (it == dataSourceMap.end()) {

View File

@@ -22,8 +22,8 @@
#include <filament/DebugRegistry.h>
#include <utils/compiler.h>
#include <utils/CString.h>
#include <string_view>
#include <unordered_map>
namespace filament {
@@ -34,31 +34,31 @@ class FDebugRegistry : public DebugRegistry {
public:
FDebugRegistry() noexcept;
void registerProperty(utils::StaticString name, bool* p) noexcept {
void registerProperty(std::string_view name, bool* p) noexcept {
registerProperty(name, p, BOOL);
}
void registerProperty(utils::StaticString name, int* p) noexcept {
void registerProperty(std::string_view name, int* p) noexcept {
registerProperty(name, p, INT);
}
void registerProperty(utils::StaticString name, float* p) noexcept {
void registerProperty(std::string_view name, float* p) noexcept {
registerProperty(name, p, FLOAT);
}
void registerProperty(utils::StaticString name, math::float2* p) noexcept {
void registerProperty(std::string_view name, math::float2* p) noexcept {
registerProperty(name, p, FLOAT2);
}
void registerProperty(utils::StaticString name, math::float3* p) noexcept {
void registerProperty(std::string_view name, math::float3* p) noexcept {
registerProperty(name, p, FLOAT3);
}
void registerProperty(utils::StaticString name, math::float4* p) noexcept {
void registerProperty(std::string_view name, math::float4* p) noexcept {
registerProperty(name, p, FLOAT4);
}
void registerDataSource(utils::StaticString name, void const* data, size_t count) noexcept;
void registerDataSource(std::string_view name, void const* data, size_t count) noexcept;
#if !defined(_MSC_VER)
private:
@@ -68,12 +68,12 @@ private:
private:
friend class DebugRegistry;
void registerProperty(utils::StaticString name, void* p, Type type) noexcept;
void registerProperty(std::string_view name, void* p, Type type) noexcept;
bool hasProperty(const char* name) const noexcept;
void* getPropertyAddress(const char* name) noexcept;
DataSource getDataSource(const char* name) const noexcept;
std::unordered_map<utils::StaticString, void*, utils::StaticString::Hasher> mPropertyMap;
std::unordered_map<utils::StaticString, DataSource, utils::StaticString::Hasher> mDataSourceMap;
std::unordered_map<std::string_view, void*> mPropertyMap;
std::unordered_map<std::string_view, DataSource> mDataSourceMap;
};
FILAMENT_UPCAST(DebugRegistry)

View File

@@ -341,8 +341,8 @@ bool FMaterial::isSampler(const char* name) const noexcept {
}
UniformInterfaceBlock::UniformInfo const* FMaterial::reflect(
utils::StaticString const& name) const noexcept {
return mUniformInterfaceBlock.getUniformInfo({ name.c_str(), name.length() });
std::string_view name) const noexcept {
return mUniformInterfaceBlock.getUniformInfo(name);
}
void FMaterial::prepareProgramSlow(Variant variant) const noexcept {
@@ -374,7 +374,8 @@ void FMaterial::getSurfaceProgramSlow(Variant variant) const noexcept {
.setUniformBlock(BindingPoints::LIGHTS, LightsUib::_name)
.setUniformBlock(BindingPoints::SHADOW, ShadowUib::_name)
.setUniformBlock(BindingPoints::FROXEL_RECORDS, FroxelRecordUib::_name)
.setUniformBlock(BindingPoints::PER_MATERIAL_INSTANCE, mUniformInterfaceBlock.getName());
.setUniformBlock(BindingPoints::PER_MATERIAL_INSTANCE,
{ mUniformInterfaceBlock.getName().data(), mUniformInterfaceBlock.getName().size() });
if (Variant(variant).hasSkinningOrMorphing()) {
pb.setUniformBlock(BindingPoints::PER_RENDERABLE_BONES, PerRenderableBoneUib::_name);
@@ -397,7 +398,8 @@ void FMaterial::getPostProcessProgramSlow(Variant variant) const noexcept {
Program pb = getProgramBuilderWithVariants(variant, variant, variant);
pb.setUniformBlock(BindingPoints::PER_VIEW, PerViewUib::_name)
.setUniformBlock(BindingPoints::PER_MATERIAL_INSTANCE, mUniformInterfaceBlock.getName());
.setUniformBlock(BindingPoints::PER_MATERIAL_INSTANCE,
{ mUniformInterfaceBlock.getName().data(), mUniformInterfaceBlock.getName().size() });
addSamplerGroup(pb, BindingPoints::PER_MATERIAL_INSTANCE, mSamplerInterfaceBlock, mSamplerBindings);

View File

@@ -69,7 +69,7 @@ public:
bool isSampler(const char* name) const noexcept;
UniformInterfaceBlock::UniformInfo const* reflect(utils::StaticString const& name) const noexcept;
UniformInterfaceBlock::UniformInfo const* reflect(std::string_view name) const noexcept;
FMaterialInstance const* getDefaultInstance() const noexcept { return &mDefaultInstance; }
FMaterialInstance* getDefaultInstance() noexcept { return &mDefaultInstance; }

View File

@@ -16,9 +16,7 @@
#include "fg/Blackboard.h"
#include <utils/CString.h>
using namespace utils;
#include <string_view>
namespace filament {
@@ -26,7 +24,7 @@ Blackboard::Blackboard() noexcept = default;
Blackboard::~Blackboard() noexcept = default;
FrameGraphHandle Blackboard::getHandle(utils::StaticString const& name) const noexcept {
FrameGraphHandle Blackboard::getHandle(std::string_view name) const noexcept {
auto it = mMap.find(name);
if (it != mMap.end()) {
return it->second;
@@ -34,17 +32,17 @@ FrameGraphHandle Blackboard::getHandle(utils::StaticString const& name) const no
return {};
}
FrameGraphHandle& Blackboard::operator [](utils::StaticString const& name) noexcept {
FrameGraphHandle& Blackboard::operator [](std::string_view name) noexcept {
auto[pos, _] = mMap.insert_or_assign(name, FrameGraphHandle{});
return pos->second;
}
void Blackboard::put(utils::StaticString const& name, FrameGraphHandle handle) noexcept {
void Blackboard::put(std::string_view name, FrameGraphHandle handle) noexcept {
operator[](name) = handle;
}
void Blackboard::remove(utils::StaticString const& name) noexcept {
void Blackboard::remove(std::string_view name) noexcept {
mMap.erase(name);
}

View File

@@ -19,35 +19,33 @@
#include <fg/FrameGraphId.h>
#include <utils/CString.h>
#include <string_view>
#include <unordered_map>
namespace filament {
class Blackboard {
using Container = std::unordered_map<
utils::StaticString,
FrameGraphHandle,
utils::StaticString::Hasher>;
std::string_view,
FrameGraphHandle>;
public:
Blackboard() noexcept;
~Blackboard() noexcept;
FrameGraphHandle& operator [](utils::StaticString const& name) noexcept;
FrameGraphHandle& operator [](std::string_view name) noexcept;
void put(utils::StaticString const& name, FrameGraphHandle handle) noexcept;
void put(std::string_view name, FrameGraphHandle handle) noexcept;
template<typename T>
FrameGraphId<T> get(utils::StaticString&& name) const noexcept {
return static_cast<FrameGraphId<T>>(getHandle(std::forward<utils::StaticString>(name)));
FrameGraphId<T> get(std::string_view&& name) const noexcept {
return static_cast<FrameGraphId<T>>(getHandle(std::forward<std::string_view>(name)));
}
void remove(utils::StaticString const& name) noexcept;
void remove(std::string_view name) noexcept;
private:
FrameGraphHandle getHandle(utils::StaticString const& name) const noexcept;
FrameGraphHandle getHandle(std::string_view name) const noexcept;
Container mMap;
};

View File

@@ -169,7 +169,7 @@ utils::CString ResourceNode::graphvizify() const noexcept {
}
utils::CString ResourceNode::graphvizifyEdgeColor() const noexcept {
return utils::StaticString{ "darkolivegreen" };
return "darkolivegreen";
}
} // namespace filament

View File

@@ -62,7 +62,7 @@ public:
~Builder() noexcept;
struct ListEntry { // NOLINT(cppcoreguidelines-pro-type-member-init)
utils::StaticString name; // name of this sampler
std::string_view name; // name of this sampler
Type type; // type of this sampler
Format format; // format of this sampler
Precision precision; // precision of this sampler
@@ -70,12 +70,12 @@ public:
};
// Give a name to this sampler interface block
Builder& name(utils::CString interfaceBlockName);
Builder& name(std::string_view interfaceBlockName);
Builder& stageFlags(backend::ShaderStageFlags stageFlags);
// Add a sampler
Builder& add(utils::CString samplerName, Type type, Format format,
Builder& add(std::string_view samplerName, Type type, Format format,
Precision precision = Precision::MEDIUM,
bool multisample = false) noexcept;

View File

@@ -22,7 +22,7 @@
#include <private/filament/EngineEnums.h>
#include <utils/CString.h>
#include <string_view>
/*
* Here we define all the UBOs known by filament as C structs. It is used by filament to
@@ -39,7 +39,7 @@ namespace filament {
*/
struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
static constexpr utils::StaticString _name{ "FrameUniforms" };
static constexpr std::string_view _name{ "FrameUniforms" };
// --------------------------------------------------------------------------------------------
// Values that can be accessed in both surface and post-process materials
@@ -210,7 +210,7 @@ static_assert(sizeof(PerRenderableData) == 256,
"sizeof(PerRenderableData) must be 256 bytes");
struct alignas(256) PerRenderableUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
static constexpr utils::StaticString _name{ "ObjectUniforms" };
static constexpr std::string_view _name{ "ObjectUniforms" };
PerRenderableData data[64];
};
// PerRenderableUib must have an alignment of 256 to be compatible with all versions of GLES.
@@ -221,7 +221,7 @@ static_assert(sizeof(PerRenderableUib) <= 16384,
// MARK: -
struct LightsUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
static constexpr utils::StaticString _name{ "LightsUniforms" };
static constexpr std::string_view _name{ "LightsUniforms" };
math::float4 positionFalloff; // { float3(pos), 1/falloff^2 }
math::float3 direction; // dir
float reserved1; // 0
@@ -247,7 +247,7 @@ static_assert(sizeof(LightsUib) == 64,
// UBO for punctual (spot light) shadows.
struct ShadowUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
static constexpr utils::StaticString _name{ "ShadowUniforms" };
static constexpr std::string_view _name{ "ShadowUniforms" };
struct alignas(16) ShadowData {
math::mat4f lightFromWorldMatrix;
math::float3 direction;
@@ -268,7 +268,7 @@ static_assert(sizeof(ShadowUib) <= 16384,
// UBO froxel record buffer.
struct FroxelRecordUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
static constexpr utils::StaticString _name{ "FroxelRecordUniforms" };
static constexpr std::string_view _name{ "FroxelRecordUniforms" };
math::uint4 records[1024];
};
static_assert(sizeof(FroxelRecordUib) == 16384,
@@ -279,7 +279,7 @@ static_assert(sizeof(FroxelRecordUib) == 16384,
// This is not the UBO proper, but just an element of a bone array.
struct PerRenderableBoneUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
static constexpr utils::StaticString _name{ "BonesUniforms" };
static constexpr std::string_view _name{ "BonesUniforms" };
struct alignas(16) BoneData {
// bone transform, last row assumed [0,0,0,1]
math::float4 transform[3];
@@ -295,7 +295,7 @@ static_assert(sizeof(PerRenderableBoneUib) <= 16384,
// MARK: -
struct alignas(16) PerRenderableMorphingUib {
static constexpr utils::StaticString _name{ "MorphingUniforms" };
static constexpr std::string_view _name{ "MorphingUniforms" };
// The array stride(the bytes between array elements) is always rounded up to the size of a vec4 in std140.
math::float4 weights[CONFIG_MAX_MORPH_TARGET_COUNT];
};

View File

@@ -53,31 +53,31 @@ public:
~Builder() noexcept;
// Give a name to this uniform interface block
Builder& name(utils::CString interfaceBlockName);
Builder& name(std::string_view interfaceBlockName);
// Add a uniform field
Builder& add(utils::CString uniformName,
Builder& add(std::string_view uniformName,
Type type, Precision precision = Precision::DEFAULT);
// Add a uniform array
Builder& add(utils::CString uniformName, size_t size,
Builder& add(std::string_view uniformName, size_t size,
Type type, Precision precision = Precision::DEFAULT);
// Add a known struct field
Builder& add(utils::CString uniformName,
utils::CString structName, size_t stride);
Builder& add(std::string_view uniformName,
std::string_view structName, size_t stride);
// Add a known struct array
Builder& add(utils::CString uniformName, size_t size,
utils::CString structName, size_t stride);
Builder& add(std::string_view uniformName, size_t size,
std::string_view structName, size_t stride);
// build and return the UniformInterfaceBlock
UniformInterfaceBlock build();
private:
friend class UniformInterfaceBlock;
struct Entry {
Entry(utils::CString name, uint32_t size, Type type, Precision precision) noexcept;
Entry(utils::CString name, uint32_t size, utils::CString structName, size_t stride) noexcept;
Entry(std::string_view name, uint32_t size, Type type, Precision precision) noexcept;
Entry(std::string_view name, uint32_t size, std::string_view structName, size_t stride) noexcept;
utils::CString name;
uint32_t size;
Type type;

View File

@@ -31,8 +31,8 @@ SamplerInterfaceBlock::Builder::Builder() = default;
SamplerInterfaceBlock::Builder::~Builder() noexcept = default;
SamplerInterfaceBlock::Builder&
SamplerInterfaceBlock::Builder::name(utils::CString interfaceBlockName) {
mName = std::move(interfaceBlockName);
SamplerInterfaceBlock::Builder::name(std::string_view interfaceBlockName) {
mName = { interfaceBlockName.data(), interfaceBlockName.size() };
return *this;
}
@@ -43,10 +43,11 @@ SamplerInterfaceBlock::Builder::stageFlags(backend::ShaderStageFlags stageFlags)
}
SamplerInterfaceBlock::Builder& SamplerInterfaceBlock::Builder::add(
utils::CString samplerName, Type type, Format format,
std::string_view samplerName, Type type, Format format,
Precision precision, bool multisample) noexcept {
mEntries.push_back({
std::move(samplerName), uint8_t(mEntries.size()), type, format, precision, multisample });
{ samplerName.data(), samplerName.size() },
uint8_t(mEntries.size()), type, format, precision, multisample });
return *this;
}

View File

@@ -25,15 +25,16 @@ using namespace utils;
namespace filament {
UniformInterfaceBlock::Builder::Entry::Entry(utils::CString name, uint32_t size,
UniformInterfaceBlock::Builder::Entry::Entry(std::string_view name, uint32_t size,
UniformInterfaceBlock::Type type, UniformInterfaceBlock::Precision precision) noexcept
: name(std::move(name)), size(size), type(type), precision(precision),
: name(name.data(), name.size()), size(size), type(type), precision(precision),
stride(strideForType(type, 0)) {
}
UniformInterfaceBlock::Builder::Entry::Entry(utils::CString name, uint32_t size,
utils::CString structName, size_t stride) noexcept
: name(std::move(name)), size(size), type(Type::STRUCT), structName(std::move(structName)),
UniformInterfaceBlock::Builder::Entry::Entry(std::string_view name, uint32_t size,
std::string_view structName, size_t stride) noexcept
: name(name.data(), name.size()), size(size), type(Type::STRUCT),
structName(structName.data(), structName.size()),
stride(stride) {
}
@@ -41,36 +42,36 @@ UniformInterfaceBlock::Builder::Builder() noexcept = default;
UniformInterfaceBlock::Builder::~Builder() noexcept = default;
UniformInterfaceBlock::Builder&
UniformInterfaceBlock::Builder::name(utils::CString interfaceBlockName) {
mName = std::move(interfaceBlockName);
UniformInterfaceBlock::Builder::name(std::string_view interfaceBlockName) {
mName = { interfaceBlockName.data(), interfaceBlockName.size() };
return *this;
}
UniformInterfaceBlock::Builder& UniformInterfaceBlock::Builder::add(
utils::CString uniformName, UniformInterfaceBlock::Type type,
std::string_view uniformName, UniformInterfaceBlock::Type type,
UniformInterfaceBlock::Precision precision) {
mEntries.emplace_back(std::move(uniformName), 0u, type, precision);
mEntries.emplace_back(uniformName, 0u, type, precision);
return *this;
}
UniformInterfaceBlock::Builder& UniformInterfaceBlock::Builder::add(
utils::CString uniformName, size_t size, UniformInterfaceBlock::Type type,
std::string_view uniformName, size_t size, UniformInterfaceBlock::Type type,
UniformInterfaceBlock::Precision precision) {
mEntries.emplace_back(std::move(uniformName), (uint32_t)size, type, precision);
mEntries.emplace_back(uniformName, (uint32_t)size, type, precision);
return *this;
}
UniformInterfaceBlock::Builder& UniformInterfaceBlock::Builder::add(
utils::CString uniformName,
utils::CString structName, size_t stride) {
mEntries.emplace_back(std::move(uniformName), 0u, std::move(structName), stride);
std::string_view uniformName,
std::string_view structName, size_t stride) {
mEntries.emplace_back(uniformName, 0u, structName, stride);
return *this;
}
UniformInterfaceBlock::Builder& UniformInterfaceBlock::Builder::add(
utils::CString uniformName, size_t size,
utils::CString structName, size_t stride) {
mEntries.emplace_back(std::move(uniformName), (uint32_t)size, std::move(structName), stride);
std::string_view uniformName, size_t size,
std::string_view structName, size_t stride) {
mEntries.emplace_back(uniformName, (uint32_t)size, structName, stride);
return *this;
}

View File

@@ -439,9 +439,11 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept {
for (size_t i = 0, c = mParameterCount; i < c; i++) {
auto const& param = mParameters[i];
if (param.isSampler()) {
sbb.add(param.name, param.samplerType, param.format, param.precision);
sbb.add({ param.name.data(), param.name.size() },
param.samplerType, param.format, param.precision);
} else if (param.isUniform()) {
ibb.add(param.name, param.size == 1 ? 0 : param.size, param.uniformType, param.precision);
ibb.add({ param.name.data(), param.name.size() },
param.size == 1 ? 0 : param.size, param.uniformType, param.precision);
} else if (param.isSubpass()) {
// For now, we only support a single subpass for attachment 0.
// Subpasses belong to the "MaterialParams" block.

View File

@@ -22,11 +22,11 @@
#include <math/vec4.h>
#include <utils/Panic.h>
#include <utils/CString.h>
#include <memory>
#include <vector>
#include <string>
#include <unordered_map>
#include <vector>
using namespace image;
@@ -363,20 +363,19 @@ uint32_t getMipmapCount(const LinearImage& source) {
Filter filterFromString(const char* rawname) {
using namespace utils;
using std::unordered_map;
static const unordered_map<StaticString, Filter, StaticString::Hasher> map = {
{ "BOX", Filter::BOX},
{ "NEAREST", Filter::NEAREST},
{ "HERMITE", Filter::HERMITE},
{ "GAUSSIAN", Filter::GAUSSIAN_SCALARS},
{ "NORMALS", Filter::GAUSSIAN_NORMALS},
{ "MITCHELL", Filter::MITCHELL},
{ "LANCZOS", Filter::LANCZOS},
{ "MINIMUM", Filter::MINIMUM},
static const std::unordered_map<std::string_view, Filter> map = {
{ "BOX", Filter::BOX },
{ "NEAREST", Filter::NEAREST },
{ "HERMITE", Filter::HERMITE },
{ "GAUSSIAN", Filter::GAUSSIAN_SCALARS },
{ "NORMALS", Filter::GAUSSIAN_NORMALS },
{ "MITCHELL", Filter::MITCHELL },
{ "LANCZOS", Filter::LANCZOS },
{ "MINIMUM", Filter::MINIMUM },
};
std::string name = rawname;
for (auto& c: name) { c = toupper((unsigned char)c); }
auto iter = map.find(StaticString::make(name.c_str(), name.size()));
for (auto& c: name) { c = (char)toupper((unsigned char)c); }
auto iter = map.find(name);
return iter == map.end() ? Filter::DEFAULT : iter->second;
}

View File

@@ -40,6 +40,7 @@
#include <sstream>
#include <string>
#include <string_view>
using utils::FixedCapacityVector;
@@ -60,11 +61,11 @@ using namespace filament::backend;
using filaflat::ChunkContainer;
using filamat::ChunkType;
static const StaticString kSuccessHeader =
static const std::string_view kSuccessHeader =
"HTTP/1.1 200 OK\r\nContent-Type: %s\r\n"
"Connection: close\r\n\r\n";
static const StaticString kErrorHeader =
static const std::string_view kErrorHeader =
"HTTP/1.1 404 Not Found\r\nContent-Type: %s\r\n"
"Connection: close\r\n\r\n";
@@ -75,7 +76,7 @@ static void spirvToAsm(struct mg_connection *conn, const uint32_t* spirv, size_t
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES;
spvBinaryToText(context, spirv, size / 4, options, &text, nullptr);
mg_printf(conn, kSuccessHeader.c_str(), "application/txt");
mg_printf(conn, kSuccessHeader.data(), "application/txt");
mg_write(conn, text->str, text->length);
spvTextDestroy(text);
spvContextDestroy(context);
@@ -83,7 +84,7 @@ static void spirvToAsm(struct mg_connection *conn, const uint32_t* spirv, size_t
static void spirvToGlsl(struct mg_connection *conn, const uint32_t* spirv, size_t size) {
auto glsl = ShaderExtractor::spirvToGLSL(spirv, size / 4);
mg_printf(conn, kSuccessHeader.c_str(), "application/txt");
mg_printf(conn, kSuccessHeader.data(), "application/txt");
mg_printf(conn, glsl.c_str(), glsl.size());
}
@@ -97,7 +98,7 @@ public:
#if SERVE_FROM_SOURCE_TREE
mg_send_file(conn, "libs/matdbg/web/index.html");
#else
mg_printf(conn, kSuccessHeader.c_str(), "text/html");
mg_printf(conn, kSuccessHeader.data(), "text/html");
mg_write(conn, mServer->mHtml.c_str(), mServer->mHtml.size());
#endif
return true;
@@ -106,7 +107,7 @@ public:
#if SERVE_FROM_SOURCE_TREE
mg_send_file(conn, "libs/matdbg/web/style.css");
#else
mg_printf(conn, kSuccessHeader.c_str(), "text/css");
mg_printf(conn, kSuccessHeader.data(), "text/css");
mg_write(conn, mServer->mCss.c_str(), mServer->mCss.size());
#endif
return true;
@@ -115,7 +116,7 @@ public:
#if SERVE_FROM_SOURCE_TREE
mg_send_file(conn, "libs/matdbg/web/script.js");
#else
mg_printf(conn, kSuccessHeader.c_str(), "text/javascript");
mg_printf(conn, kSuccessHeader.data(), "text/javascript");
mg_write(conn, mServer->mJavascript.c_str(), mServer->mJavascript.size());
#endif
return true;
@@ -151,14 +152,14 @@ public:
const auto softError = [request, conn](const char* msg) {
slog.e << "DebugServer: " << msg << ": " << request->query_string << io::endl;
mg_printf(conn, kErrorHeader.c_str(), "application/txt");
mg_printf(conn, kErrorHeader.data(), "application/txt");
mg_write(conn, msg, strlen(msg));
return true;
};
if (uri == "/api/active") {
mServer->updateActiveVariants();
mg_printf(conn, kSuccessHeader.c_str(), "application/json");
mg_printf(conn, kSuccessHeader.data(), "application/json");
mg_printf(conn, "{");
// If the backend has not been resolved to Vulkan, Metal, etc., then return an empty
@@ -188,7 +189,7 @@ public:
}
if (uri == "/api/matids") {
mg_printf(conn, kSuccessHeader.c_str(), "application/json");
mg_printf(conn, kSuccessHeader.data(), "application/json");
mg_printf(conn, "[");
int index = 0;
for (const auto& record : mServer->mMaterialRecords) {
@@ -200,7 +201,7 @@ public:
}
if (uri == "/api/materials") {
mg_printf(conn, kSuccessHeader.c_str(), "application/json");
mg_printf(conn, kSuccessHeader.data(), "application/json");
mg_printf(conn, "[");
int index = 0;
for (const auto& record : mServer->mMaterialRecords) {
@@ -248,21 +249,21 @@ public:
if (!writer.writeMaterialInfo(package)) {
return error(__LINE__);
}
mg_printf(conn, kSuccessHeader.c_str(), "application/json");
mg_printf(conn, kSuccessHeader.data(), "application/json");
mg_printf(conn, "{ %s }", writer.getJsonString());
return true;
}
const StaticString glsl("glsl");
const StaticString msl("msl");
const StaticString spirv("spirv");
const std::string_view glsl("glsl");
const std::string_view msl("msl");
const std::string_view spirv("spirv");
char type[6] = {};
if (mg_get_var(request->query_string, qlength, "type", type, sizeof(type)) < 0) {
return error(__LINE__);
}
CString language(type, strlen(type));
std::string_view language(type, strlen(type));
char glindex[4] = {};
char vkindex[4] = {};
@@ -303,7 +304,7 @@ public:
filaflat::ShaderContent content;
extractor.getShader(item.shaderModel, item.variant, item.pipelineStage, content);
mg_printf(conn, kSuccessHeader.c_str(), "application/txt");
mg_printf(conn, kSuccessHeader.data(), "application/txt");
mg_write(conn, content.data(), content.size() - 1);
return true;
}
@@ -362,7 +363,7 @@ public:
extractor.getShader(item.shaderModel, item.variant, item.pipelineStage, content);
if (language == msl) {
mg_printf(conn, kSuccessHeader.c_str(), "application/txt");
mg_printf(conn, kSuccessHeader.data(), "application/txt");
mg_write(conn, content.data(), content.size() - 1);
return true;
}
@@ -437,10 +438,10 @@ public:
// EDIT [material id] [api index] [shader index] [shader length] [shader source....]
//
const static StaticString kEditCmd = "EDIT ";
const static std::string_view kEditCmd = "EDIT ";
const static size_t kEditCmdLength = kEditCmd.size();
if (0 == strncmp(data, kEditCmd.c_str(), kEditCmdLength)) {
if (0 == strncmp(data, kEditCmd.data(), kEditCmdLength)) {
std::string command(data + kEditCmdLength, size - kEditCmdLength);
std::istringstream str(command);
uint32_t matid;

View File

@@ -42,157 +42,9 @@ struct hashCStrings {
}
};
//! \privatesection
struct equalCStrings {
typedef const char* first_argument_type;
typedef const char* second_argument_type;
typedef bool result_type;
bool operator()(const char* lhs, const char* rhs) const noexcept {
return !strcmp(lhs, rhs);
}
};
//! \privatesection
struct lessCStrings {
typedef const char* first_argument_type;
typedef const char* second_argument_type;
typedef bool result_type;
result_type operator()(first_argument_type lhs, second_argument_type rhs) const noexcept {
return strcmp(lhs, rhs) < 0;
}
};
// This can be used to creates a string from a string literal -- w/o underlying allocations.
// e.g.:
// StaticString s("Hello World!");
//
template <size_t N>
using StringLiteral = const char[N];
//! \publicsection
class UTILS_PUBLIC StaticString {
public:
using value_type = char;
using size_type = uint32_t;
using difference_type = int32_t;
using const_reference = const value_type&;
using const_pointer = const value_type*;
using const_iterator = const value_type*;
constexpr StaticString() noexcept {} // NOLINT(modernize-use-equals-default), Ubuntu compiler bug
// initialization from a string literal
template<size_t N>
constexpr StaticString(StringLiteral<N> const& other) noexcept // NOLINT(google-explicit-constructor)
: mString(other),
mLength(size_type(N - 1)),
mHash(computeHash(other, N - 1)) {
// we rely on inlining for computeHash. It would be nice to do this with constexpr
// instead, but unfortunately 'other' is not constexpr once a parameter.
}
// assignment from a string literal
template<size_t N>
StaticString& operator=(StringLiteral<N> const& other) noexcept {
mString = other;
mLength = size_type(N - 1);
// we rely on inlining for computeHash. It would be nice to do this with constexpr
// instead, but unfortunately 'other' is not constexpr once a parameter.
mHash = computeHash(other, N - 1);
return *this;
}
// helper to make a StaticString from a C string that is known to be a string literal
static constexpr StaticString make(const_pointer literal, size_t length) noexcept {
StaticString r;
r.mString = literal;
r.mLength = size_type(length);
r.mHash = computeHash(literal, length);
return r;
}
static StaticString make(const_pointer literal) noexcept {
return make(literal, strlen(literal));
}
const_pointer c_str() const noexcept { return mString; }
const_pointer data() const noexcept { return mString; }
size_type size() const noexcept { return mLength; }
size_type length() const noexcept { return mLength; }
bool empty() const noexcept { return size() == 0; }
void clear() noexcept { mString = nullptr; mLength = 0; }
const_iterator begin() const noexcept { return mString; }
const_iterator end() const noexcept { return mString + mLength; }
const_iterator cbegin() const noexcept { return begin(); }
const_iterator cend() const noexcept { return end(); }
const_reference operator[](size_type pos) const noexcept {
assert(pos < size());
return begin()[pos];
}
const_reference at(size_type pos) const noexcept {
assert(pos < size());
return begin()[pos];
}
const_reference front() const noexcept {
assert(size());
return begin()[0];
}
const_reference back() const noexcept {
assert(size());
return begin()[size() - 1];
}
size_type getHash() const noexcept { return mHash; }
struct Hasher {
typedef StaticString argument_type;
typedef size_t result_type;
result_type operator()(const argument_type& s) const noexcept {
return s.getHash();
}
};
private:
const_pointer mString = nullptr;
size_type mLength = 0;
size_type mHash = 0;
static constexpr size_type computeHash(const char* s, const size_t N) noexcept {
size_type hash = 5381;
UTILS_NOUNROLL
for (size_t i = 0; i < N - 1; i++) {
hash = (hash * 33u) ^ size_type(s[i]);
}
return hash;
}
int compare(const StaticString& rhs) const noexcept;
friend bool operator==(StaticString const& lhs, StaticString const& rhs) noexcept {
return (lhs.data() == rhs.data()) ||
((lhs.size() == rhs.size()) && !strncmp(lhs.data(), rhs.data(), lhs.size()));
}
friend bool operator!=(StaticString const& lhs, StaticString const& rhs) noexcept {
return !(lhs == rhs);
}
friend bool operator<(StaticString const& lhs, StaticString const& rhs) noexcept {
return lhs.compare(rhs) < 0;
}
friend bool operator>(StaticString const& lhs, StaticString const& rhs) noexcept {
return lhs.compare(rhs) > 0;
}
friend bool operator>=(StaticString const& lhs, StaticString const& rhs) noexcept {
return !(lhs < rhs);
}
friend bool operator<=(StaticString const& lhs, StaticString const& rhs) noexcept {
return !(lhs > rhs);
}
};
// ------------------------------------------------------------------------------------------------
@@ -220,7 +72,7 @@ public:
explicit CString(size_t length);
// Allocates memory and copies traditional C string content. Unlike the above constructor, this
// does not alllow embedded nulls. This is explicit because this operation is costly.
// does not allow embedded nulls. This is explicit because this operation is costly.
explicit CString(const char* cstr);
template<size_t N>
@@ -228,8 +80,6 @@ public:
: CString(other, N - 1) {
}
CString(StaticString const& s) : CString(s.c_str(), s.size()) {} // NOLINT(google-explicit-constructor)
CString(const CString& rhs);
CString(CString&& rhs) noexcept {
@@ -349,10 +199,6 @@ private:
return strncmp(data(), rhs.data(), size());
}
friend bool operator==(CString const& lhs, StaticString const& rhs) noexcept {
return (lhs.data() == rhs.data()) ||
((lhs.size() == rhs.size()) && !strncmp(lhs.data(), rhs.data(), lhs.size()));
}
friend bool operator==(CString const& lhs, CString const& rhs) noexcept {
return (lhs.data() == rhs.data()) ||
((lhs.size() == rhs.size()) && !strncmp(lhs.data(), rhs.data(), lhs.size()));

View File

@@ -23,16 +23,6 @@
namespace utils {
int StaticString::compare(const StaticString& rhs) const noexcept {
size_type lhs_size = size();
size_type rhs_size = rhs.size();
if (lhs_size < rhs_size) return -1;
if (lhs_size > rhs_size) return 1;
return strncmp(data(), rhs.data(), size());
}
// ------------------------------------------------------------------------------------------------
UTILS_NOINLINE
CString::CString(const char* cstr, size_t length) {
if (length && cstr) {

View File

@@ -25,21 +25,6 @@ TEST(CString, EmptyString) {
EXPECT_STREQ("", emptyString.c_str_safe());
}
TEST(StaticString, hash) {
StaticString a("Hello World!");
StaticString b = StaticString::make("Hello World!");
StaticString c("Hello World");
StaticString d("Hello World!");
EXPECT_EQ(a.getHash(), b.getHash());
EXPECT_EQ(a.getHash(), d.getHash());
EXPECT_NE(a.getHash(), c.getHash());
EXPECT_NE(b.getHash(), c.getHash());
StaticString::Hasher ha;
EXPECT_EQ(ha(a), a.getHash());
}
TEST(CString, Replace) {
{
CString str("foo bar baz");