From 40c2329b3c8591d275f725333682575131ea8224 Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Mon, 9 Sep 2024 22:25:22 +0200 Subject: [PATCH] implement vertex and index caches hopefully these work and actually help with performance --- include/ptk.h | 2 ++ src/ptk.c | 13 +++++++ src/ptk_vk/components.c | 76 +++++++++++++++++++++++++++++++++-------- 3 files changed, 76 insertions(+), 15 deletions(-) diff --git a/include/ptk.h b/include/ptk.h index 091eaef..d6e6e06 100644 --- a/include/ptk.h +++ b/include/ptk.h @@ -28,6 +28,8 @@ typedef enum { PTK_COMPONENT_TYPE_CLICKABLE = 4, } PtkComponentType; +const char *ptk_component_type_to_str(PtkComponentType type); + PTK_LIST_DEFINE(PtkHandle); #define PTK_COMPONENT_DEFINE(name, ...) \ diff --git a/src/ptk.c b/src/ptk.c index 01ba2d8..1eabce2 100644 --- a/src/ptk.c +++ b/src/ptk.c @@ -142,6 +142,19 @@ bool ptk_init(const size_t width, const size_t height, const char *title, const 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; PtkHandle ptk_box(const size_t child_count, PtkHandle *children) { diff --git a/src/ptk_vk/components.c b/src/ptk_vk/components.c index 6be97a3..5651b90 100644 --- a/src/ptk_vk/components.c +++ b/src/ptk_vk/components.c @@ -18,6 +18,15 @@ static PtkHandle m_root_component; // so we have to use _Bool here 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(uint32_t) g_indices; @@ -31,11 +40,17 @@ static const PtkVec2 uvs[] = { void vk_init_vertices(void) { 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_indices = PTK_LIST_NEW(uint32_t, 0); } 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) { Vertex v = { .pos = triangle->vertices[i], @@ -47,10 +62,16 @@ void triangle(const PtkTriangle *triangle) { uint32_t old_vertex_count = g_vertices.size; PTK_LIST_ADD(Vertex, g_vertices, v); 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) { + 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 y = rect->top_left.y; 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, bottom_left_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) { @@ -125,19 +159,26 @@ void ellipse(const PtkEllipse *ellipse) { } 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) { - case PTK_COMPONENT_TYPE_TRIANGLE: { - triangle((PtkTriangle *)c); - } break; - case PTK_COMPONENT_TYPE_RECT: { - rect((PtkRect *)c); - } break; - case PTK_COMPONENT_TYPE_ELLIPSE: { - ellipse((PtkEllipse *)c); - } break; - default: break; + switch (c->type) { + case PTK_COMPONENT_TYPE_TRIANGLE: { + triangle((PtkTriangle *)c); + } break; + case PTK_COMPONENT_TYPE_RECT: { + rect((PtkRect *)c); + } break; + case PTK_COMPONENT_TYPE_ELLIPSE: { + ellipse((PtkEllipse *)c); + } break; + default: break; + } } PTK_LIST_FOR_EACH(PtkHandle, c->children, child, { 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); 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)) { 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(); } }