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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user