Cleanup: GPU: Use StringRef for vertex format function arguments

And slightly simplify two string processing functions in this API,
`GPU_vertformat_safe_attr_name` and `copy_attr_name`.
This makes the API easier to interface with from C++ code,
and can avoid unnecessary string length measurements.

Pull Request: https://projects.blender.org/blender/blender/pulls/134882
This commit is contained in:
Hans Goudey
2025-02-25 14:53:51 +01:00
committed by Hans Goudey
parent 1b902e305c
commit e522a6c826
2 changed files with 28 additions and 37 deletions

View File

@@ -12,6 +12,7 @@
#include "BLI_assert.h"
#include "BLI_compiler_compat.h"
#include "BLI_string_ref.hh"
#include "BLI_sys_types.h"
struct GPUShader;
@@ -92,14 +93,14 @@ void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat &src);
void GPU_vertformat_from_shader(GPUVertFormat *format, const GPUShader *shader);
uint GPU_vertformat_attr_add(
GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode);
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
GPUVertFormat *, blender::StringRef name, GPUVertCompType, uint comp_len, GPUVertFetchMode);
void GPU_vertformat_alias_add(GPUVertFormat *, blender::StringRef alias);
/**
* Return a vertex format from a single attribute description.
* The attribute ID is ensured to be 0.
*/
GPUVertFormat GPU_vertformat_from_attribute(const char *name,
GPUVertFormat GPU_vertformat_from_attribute(blender::StringRef name,
const GPUVertCompType comp_type,
const uint comp_len,
const GPUVertFetchMode fetch_mode);
@@ -133,7 +134,7 @@ void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count);
*/
void GPU_vertformat_deinterleave(GPUVertFormat *format);
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
int GPU_vertformat_attr_id_get(const GPUVertFormat *, blender::StringRef name);
BLI_INLINE const char *GPU_vertformat_attr_name_get(const GPUVertFormat *format,
const GPUVertAttr *attr,
@@ -152,4 +153,4 @@ void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr, const char *new
* \warning Always add a prefix to the result of this function as
* the generated string can start with a number and not be a valid attribute name.
*/
void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint max_len);
void GPU_vertformat_safe_attr_name(blender::StringRef attr_name, char *r_safe_name, uint max_len);

View File

@@ -20,7 +20,7 @@
#include <cstddef>
#include <cstring>
#include "BLI_ghash.h"
#include "BLI_hash_mm2a.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -30,6 +30,7 @@
# include <stdio.h>
#endif
using blender::StringRef;
using namespace blender::gpu;
using namespace blender::gpu::shader;
@@ -93,31 +94,22 @@ uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len)
return format->stride * vertex_len;
}
static uchar copy_attr_name(GPUVertFormat *format, const char *name)
static uchar copy_attr_name(GPUVertFormat *format, const StringRef name)
{
/* `strncpy` does 110% of what we need; let's do exactly 100% */
uchar name_offset = format->name_offset;
char *name_copy = format->names + name_offset;
uint available = GPU_VERT_ATTR_NAMES_BUF_LEN - name_offset;
bool terminated = false;
const uchar name_offset = format->name_offset;
/* Subtract one to make sure there's enough space for the last null terminator. */
const int64_t available = GPU_VERT_ATTR_NAMES_BUF_LEN - name_offset - 1;
const int64_t chars_to_copy = std::min(name.size(), available);
name.substr(0, available).copy_unsafe(format->names + name_offset);
format->name_offset += chars_to_copy + 1;
for (uint i = 0; i < available; i++) {
const char c = name[i];
name_copy[i] = c;
if (c == '\0') {
terminated = true;
format->name_offset += (i + 1);
break;
}
}
BLI_assert(terminated);
BLI_assert(format->name_offset <= GPU_VERT_ATTR_NAMES_BUF_LEN);
UNUSED_VARS_NDEBUG(terminated);
return name_offset;
}
uint GPU_vertformat_attr_add(GPUVertFormat *format,
const char *name,
const StringRef name,
GPUVertCompType comp_type,
uint comp_len,
GPUVertFetchMode fetch_mode)
@@ -166,7 +158,7 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format,
return attr_id;
}
void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
void GPU_vertformat_alias_add(GPUVertFormat *format, const StringRef alias)
{
GPUVertAttr *attr = &format->attrs[format->attr_len - 1];
BLI_assert(format->name_len < GPU_VERT_FORMAT_MAX_NAMES); /* there's room for more */
@@ -175,7 +167,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
attr->names[attr->name_len++] = copy_attr_name(format, alias);
}
GPUVertFormat GPU_vertformat_from_attribute(const char *name,
GPUVertFormat GPU_vertformat_from_attribute(const StringRef name,
const GPUVertCompType comp_type,
const uint comp_len,
const GPUVertFetchMode fetch_mode)
@@ -215,13 +207,13 @@ void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count)
}
}
int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const StringRef name)
{
for (int i = 0; i < format->attr_len; i++) {
const GPUVertAttr *attr = &format->attrs[i];
for (int j = 0; j < attr->name_len; j++) {
const char *attr_name = GPU_vertformat_attr_name_get(format, attr, j);
if (STREQ(name, attr_name)) {
if (name == attr_name) {
return i;
}
}
@@ -255,27 +247,25 @@ static void safe_bytes(char out[11], const char data[8])
}
}
void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint /*max_len*/)
void GPU_vertformat_safe_attr_name(const StringRef attr_name, char *r_safe_name, uint /*max_len*/)
{
char data[8] = {0};
uint len = strlen(attr_name);
uint len = attr_name.size();
if (len > 8) {
/* Start with the first 4 chars of the name. */
for (int i = 0; i < 4; i++) {
data[i] = attr_name[i];
}
memcpy(data, attr_name.data(), 4);
/* We use a hash to identify each data layer based on its name.
* NOTE: This is still prone to hash collision but the risks are very low. */
/* Start hashing after the first 2 chars. */
*(uint *)&data[4] = BLI_ghashutil_strhash_p_murmur(attr_name + 4);
const StringRef to_hash = attr_name.drop_prefix(4);
*(uint *)&data[4] = BLI_hash_mm2(
reinterpret_cast<const uchar *>(to_hash.data()), to_hash.size(), 0);
}
else {
/* Copy the whole name. Collision is barely possible
* (hash would have to be equal to the last 4 bytes). */
for (int i = 0; i < 8 && attr_name[i] != '\0'; i++) {
data[i] = attr_name[i];
}
memcpy(data, attr_name.data(), std::min<int>(8, len));
}
/* Convert to safe bytes characters. */
safe_bytes(r_safe_name, data);