implement vertex and index caches

hopefully these work and actually help with performance
This commit is contained in:
jacekpoz 2024-09-09 22:25:22 +02:00
parent be1ae4c531
commit 40c2329b3c
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8
3 changed files with 76 additions and 15 deletions

View file

@ -28,6 +28,8 @@ typedef enum {
PTK_COMPONENT_TYPE_CLICKABLE = 4, PTK_COMPONENT_TYPE_CLICKABLE = 4,
} PtkComponentType; } PtkComponentType;
const char *ptk_component_type_to_str(PtkComponentType type);
PTK_LIST_DEFINE(PtkHandle); PTK_LIST_DEFINE(PtkHandle);
#define PTK_COMPONENT_DEFINE(name, ...) \ #define PTK_COMPONENT_DEFINE(name, ...) \

View file

@ -142,6 +142,19 @@ bool ptk_init(const size_t width, const size_t height, const char *title, const
return true; return true;
} }
const char *ptk_component_type_to_str(PtkComponentType type) {
const char *res;
switch (type) {
case PTK_COMPONENT_TYPE_BOX: res = "box"; break;
case PTK_COMPONENT_TYPE_TRIANGLE: res = "triangle"; break;
case PTK_COMPONENT_TYPE_RECT: res = "rect"; break;
case PTK_COMPONENT_TYPE_ELLIPSE: res = "ellipse"; break;
case PTK_COMPONENT_TYPE_CLICKABLE: res = "clickable"; break;
default: res = "unknown"; break;
}
return res;
}
static uint64_t m_component_count = 0; static uint64_t m_component_count = 0;
PtkHandle ptk_box(const size_t child_count, PtkHandle *children) { PtkHandle ptk_box(const size_t child_count, PtkHandle *children) {

View file

@ -18,6 +18,15 @@ static PtkHandle m_root_component;
// so we have to use _Bool here // so we have to use _Bool here
static PTK_LIST(_Bool) m_update; static PTK_LIST(_Bool) m_update;
typedef PTK_LIST(Vertex) Vertices;
typedef PTK_LIST(uint32_t) Indices;
PTK_LIST_DEFINE(Vertices);
PTK_LIST_DEFINE(Indices);
PTK_LIST(Vertices) m_vertices_cache;
PTK_LIST(Indices) m_indices_cache;
PTK_LIST(Vertex) g_vertices; PTK_LIST(Vertex) g_vertices;
PTK_LIST(uint32_t) g_indices; PTK_LIST(uint32_t) g_indices;
@ -31,11 +40,17 @@ static const PtkVec2 uvs[] = {
void vk_init_vertices(void) { void vk_init_vertices(void) {
m_update = PTK_LIST_NEW(bool, 1); m_update = PTK_LIST_NEW(bool, 1);
m_vertices_cache = PTK_LIST_NEW(Vertices, 1);
m_indices_cache = PTK_LIST_NEW(Indices, 1);
g_vertices = PTK_LIST_NEW(Vertex, 0); g_vertices = PTK_LIST_NEW(Vertex, 0);
g_indices = PTK_LIST_NEW(uint32_t, 0); g_indices = PTK_LIST_NEW(uint32_t, 0);
} }
void triangle(const PtkTriangle *triangle) { void triangle(const PtkTriangle *triangle) {
PTK_LIST_SET(Vertices, m_vertices_cache, triangle->id, PTK_LIST_NEW(Vertex, 3));
PTK_LIST_SET(Indices, m_indices_cache, triangle->id, PTK_LIST_NEW(uint32_t, 3));
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
Vertex v = { Vertex v = {
.pos = triangle->vertices[i], .pos = triangle->vertices[i],
@ -47,10 +62,16 @@ void triangle(const PtkTriangle *triangle) {
uint32_t old_vertex_count = g_vertices.size; uint32_t old_vertex_count = g_vertices.size;
PTK_LIST_ADD(Vertex, g_vertices, v); PTK_LIST_ADD(Vertex, g_vertices, v);
PTK_LIST_ADD(uint32_t, g_indices, old_vertex_count); PTK_LIST_ADD(uint32_t, g_indices, old_vertex_count);
PTK_LIST_ADD(Vertex, m_vertices_cache.data[triangle->id], v);
PTK_LIST_ADD(uint32_t, m_indices_cache.data[triangle->id], old_vertex_count);
} }
} }
void rect(const PtkRect *rect) { void rect(const PtkRect *rect) {
PTK_LIST_SET(Vertices, m_vertices_cache, rect->id, PTK_LIST_NEW(Vertex, 4));
PTK_LIST_SET(Indices, m_indices_cache, rect->id, PTK_LIST_NEW(uint32_t, 6));
const float x = rect->top_left.x; const float x = rect->top_left.x;
const float y = rect->top_left.y; const float y = rect->top_left.y;
const float w = rect->size.w; const float w = rect->size.w;
@ -105,6 +126,19 @@ void rect(const PtkRect *rect) {
PTK_LIST_ADD(uint32_t, g_indices, top_right_index); PTK_LIST_ADD(uint32_t, g_indices, top_right_index);
PTK_LIST_ADD(uint32_t, g_indices, bottom_left_index); PTK_LIST_ADD(uint32_t, g_indices, bottom_left_index);
PTK_LIST_ADD(uint32_t, g_indices, bottom_right_index); PTK_LIST_ADD(uint32_t, g_indices, bottom_right_index);
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], top_right);
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], bottom_left);
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], top_left);
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], bottom_right);
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], top_left_index);
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], top_right_index);
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], bottom_left_index);
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], top_right_index);
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], bottom_left_index);
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], bottom_right_index);
} }
void ellipse(const PtkEllipse *ellipse) { void ellipse(const PtkEllipse *ellipse) {
@ -125,19 +159,26 @@ void ellipse(const PtkEllipse *ellipse) {
} }
void component(PtkHandle c) { void component(PtkHandle c) {
PTK_LIST_SET(bool, m_update, c->id, false); if (!m_update.data[c->id]) {
Vertices vcache = m_vertices_cache.data[c->id];
Indices icache = m_indices_cache.data[c->id];
PTK_LIST_ADD_ALL_P(Vertex, g_vertices, vcache.data, vcache.size);
PTK_LIST_ADD_ALL_P(uint32_t, g_indices, icache.data, icache.size);
} else {
PTK_LIST_SET(bool, m_update, c->id, false);
switch (c->type) { switch (c->type) {
case PTK_COMPONENT_TYPE_TRIANGLE: { case PTK_COMPONENT_TYPE_TRIANGLE: {
triangle((PtkTriangle *)c); triangle((PtkTriangle *)c);
} break; } break;
case PTK_COMPONENT_TYPE_RECT: { case PTK_COMPONENT_TYPE_RECT: {
rect((PtkRect *)c); rect((PtkRect *)c);
} break; } break;
case PTK_COMPONENT_TYPE_ELLIPSE: { case PTK_COMPONENT_TYPE_ELLIPSE: {
ellipse((PtkEllipse *)c); ellipse((PtkEllipse *)c);
} break; } break;
default: break; default: break;
}
} }
PTK_LIST_FOR_EACH(PtkHandle, c->children, child, { PTK_LIST_FOR_EACH(PtkHandle, c->children, child, {
child->parent = c; child->parent = c;
@ -209,10 +250,10 @@ bool intersects(const PtkHandle component, const PtkPos point) {
} }
} }
void update_component(PtkHandle c) { void set_component_updated(PtkHandle c) {
PTK_LIST_SET(bool, m_update, c->id, true); PTK_LIST_SET(bool, m_update, c->id, true);
if (c->parent != PTK_NULL_HANDLE) { if (c->parent != PTK_NULL_HANDLE) {
update_component(c->parent); set_component_updated(c->parent);
} }
} }
@ -228,7 +269,12 @@ void handle_mouse(PtkHandle c, const PtkPos cursor_pos, const int button, const
if (intersects((PtkHandle)clickable, cursor_pos)) { if (intersects((PtkHandle)clickable, cursor_pos)) {
clickable->on_press(clickable, button, mods); clickable->on_press(clickable, button, mods);
update_component((PtkHandle)clickable); // TODO: make some proper updating system
// currently if I just updated clickable it would mark
// its parents up to the root for an update
// but not its child - the actual hitbox; this is very ugly
// and should probably done in another way
set_component_updated(clickable->children.data[0]);
vk_update_components(); vk_update_components();
} }
} }