From 09c687d14d42a8f1cb831bbd448cf1b930a7f030 Mon Sep 17 00:00:00 2001 From: vurtun Date: Sun, 20 Sep 2015 21:08:32 +0200 Subject: [PATCH] fixed dynamic buffer allocation --- demo/demo.c | 10 +++------- demo/nanovg.c | 4 ++-- demo/opengl.c | 21 +++++++++++++++++---- demo/xlib.c | 4 ++-- zahnrad.c | 6 ++++++ zahnrad.h | 23 +++++++++++------------ 6 files changed, 41 insertions(+), 27 deletions(-) diff --git a/demo/demo.c b/demo/demo.c index 470afcf..0eaf53a 100644 --- a/demo/demo.c +++ b/demo/demo.c @@ -481,7 +481,6 @@ struct state { struct demo_gui { zr_bool running; - struct zr_buffer memory; struct zr_input input; struct zr_command_queue queue; struct zr_style config; @@ -538,7 +537,7 @@ widget_panel(struct zr_context *panel, struct state *demo) } { - /* tiled widgets layout */ + /* tiled layout */ struct zr_tiled_layout tiled; enum zr_layout_format fmt = (demo->scaleable) ? ZR_DYNAMIC : ZR_STATIC; @@ -711,11 +710,8 @@ init_demo(struct demo_gui *gui) struct zr_clipboard clip; gui->running = zr_true; - memory = zr_buffer_alloc(&gui->memory, ZR_BUFFER_FRONT, MAX_COMMAND_MEMORY, 0); - zr_command_queue_init_fixed(&gui->queue, memory, MAX_COMMAND_MEMORY); - zr_style_default(config, ZR_DEFAULT_ALL, &gui->font); - /* panel */ + zr_style_default(config, ZR_DEFAULT_ALL, &gui->font); zr_window_init(&gui->panel, zr_rect(30, 30, 280, 530), ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_SCALEABLE, &gui->queue, config, &gui->input); @@ -739,7 +735,7 @@ init_demo(struct demo_gui *gui) win->slider = 2.0f; win->progressbar = 50; win->spinner = 100; - + win->widget_tab = ZR_MINIMIZED; } /* ----------------------------------------------------------------- diff --git a/demo/nanovg.c b/demo/nanovg.c index 96ceba5..6a6550e 100644 --- a/demo/nanovg.c +++ b/demo/nanovg.c @@ -274,7 +274,7 @@ main(int argc, char *argv[]) /* GUI */ memset(&gui, 0, sizeof gui); - zr_buffer_init_fixed(&gui.memory, calloc(MAX_MEMORY, 1), MAX_MEMORY); + zr_command_queue_init_fixed(&gui.queue, calloc(MAX_MEMORY, 1), MAX_MEMORY); gui.font.userdata = zr_handle_ptr(vg); gui.font.width = font_get_width; nvgTextMetrics(vg, NULL, NULL, &gui.font.height); @@ -317,7 +317,7 @@ main(int argc, char *argv[]) cleanup: /* Cleanup */ - free(zr_buffer_memory(&gui.memory)); + free(zr_buffer_memory(&gui.queue.buffer)); nvgDeleteGLES2(vg); SDL_GL_DeleteContext(glContext); SDL_DestroyWindow(win); diff --git a/demo/opengl.c b/demo/opengl.c index 4bcfeb1..66bd0d3 100644 --- a/demo/opengl.c +++ b/demo/opengl.c @@ -448,6 +448,14 @@ resize(SDL_Event *evt) glViewport(0, 0, evt->window.data1, evt->window.data2); } + +static void* mem_alloc(zr_handle unused, zr_size size) +{UNUSED(unused); return calloc(1, size);} +static void* mem_realloc(zr_handle unused, void *ptr, zr_size size) +{UNUSED(unused); return realloc(ptr, size);} +static void mem_free(zr_handle unused, void *ptr) +{UNUSED(unused); free(ptr);} + int main(int argc, char *argv[]) { @@ -462,6 +470,7 @@ main(int argc, char *argv[]) int width = 0, height = 0; /* GUI */ + struct zr_allocator alloc; struct device device; struct demo_gui gui; struct zr_font font; @@ -486,10 +495,13 @@ main(int argc, char *argv[]) die("Failed to setup GLEW\n"); /* GUI */ + alloc.userdata.ptr = NULL; + alloc.alloc = mem_alloc; + alloc.realloc = mem_realloc; + alloc.free = mem_free; memset(&gui, 0, sizeof gui); - zr_buffer_init_fixed(&gui.memory, calloc(MAX_MEMORY, 1), MAX_MEMORY); - mem = zr_buffer_alloc(&gui.memory, ZR_BUFFER_FRONT, MAX_DRAW_COMMAND_MEMORY, 0); - zr_buffer_init_fixed(&device.cmds, mem, MAX_DRAW_COMMAND_MEMORY); + zr_buffer_init(&device.cmds, &alloc, 1024, 2.0f); + zr_command_queue_init(&gui.queue, &alloc, 1024, 2.0f); gui.font = font_bake_and_upload(&device, &font, font_path, 14, zr_font_default_glyph_ranges()); @@ -536,7 +548,8 @@ main(int argc, char *argv[]) cleanup: /* Cleanup */ free(font.glyphes); - free(zr_buffer_memory(&gui.memory)); + zr_command_queue_free(&gui.queue); + zr_buffer_free(&device.cmds); device_shutdown(&device); SDL_GL_DeleteContext(glContext); SDL_DestroyWindow(win); diff --git a/demo/xlib.c b/demo/xlib.c index b3d937a..c1325f4 100644 --- a/demo/xlib.c +++ b/demo/xlib.c @@ -446,7 +446,7 @@ main(int argc, char *argv[]) /* GUI */ memset(&gui, 0, sizeof gui); - zr_buffer_init_fixed(&gui.memory, calloc(MAX_MEMORY, 1), MAX_MEMORY); + zr_command_queue_init_fixed(&gui.queue, calloc(MAX_MEMORY, 1), MAX_MEMORY); gui.font.userdata = zr_handle_ptr(xw.font); gui.font.height = (zr_float)xw.font->height; gui.font.width = font_get_text_width; @@ -485,7 +485,7 @@ main(int argc, char *argv[]) sleep_for(DTIME - dt); } - free(zr_buffer_memory(&gui.memory)); + free(zr_buffer_memory(&gui.queue.buffer)); font_del(xw.dpy, xw.font); surface_del(xw.surf); XUnmapWindow(xw.dpy, xw.win); diff --git a/zahnrad.c b/zahnrad.c index 442f4e2..5b497da 100644 --- a/zahnrad.c +++ b/zahnrad.c @@ -699,6 +699,7 @@ zr_buffer_init(struct zr_buffer *b, const struct zr_allocator *a, b->type = ZR_BUFFER_DYNAMIC; b->memory.ptr = a->alloc(a->userdata, initial_size); b->memory.size = initial_size; + b->size = initial_size; b->grow_factor = grow_factor; b->pool = *a; } @@ -806,6 +807,7 @@ zr_buffer_alloc(struct zr_buffer *b, enum zr_buffer_allocation_type type, /* buffer is full so allocate bigger buffer if dynamic */ if (b->type != ZR_BUFFER_DYNAMIC || !b->pool.realloc) return 0; cap = (zr_size)((zr_float)b->memory.size * b->grow_factor); + cap = MAX(cap, zr_round_up_pow2((zr_uint)(b->allocated + size))); b->memory.ptr = zr_buffer_realloc(b, cap, &b->memory.size); if (!b->memory.ptr) return 0; @@ -842,11 +844,13 @@ zr_buffer_reset(struct zr_buffer *buffer, enum zr_buffer_allocation_type type) if (!buffer) return; if (type == ZR_BUFFER_BACK) { /* reset back buffer either back to back marker or empty */ + buffer->needed -= (buffer->memory.size - buffer->marker[type].offset); if (buffer->marker[type].active) buffer->size = buffer->marker[type].offset; else buffer->size = buffer->memory.size; } else { /* reset front buffer either back to back marker or empty */ + buffer->needed -= (buffer->allocated - buffer->marker[type].offset); if (buffer->marker[type].active) buffer->allocated = buffer->marker[type].offset; else buffer->allocated = 0; @@ -1428,6 +1432,7 @@ zr_command_queue_free(struct zr_command_queue *queue) ZR_ASSERT(queue); if (!queue) return; zr_buffer_clear(&queue->buffer); + zr_buffer_free(&queue->buffer); } void @@ -1499,6 +1504,7 @@ zr_command_queue_next(struct zr_command_queue *queue, const struct zr_command *c next = zr_ptr_add_const(struct zr_command, buffer, cmd->next); return next; } + /* ============================================================== * * Draw List diff --git a/zahnrad.h b/zahnrad.h index 8e94b01..2c809f2 100644 --- a/zahnrad.h +++ b/zahnrad.h @@ -662,7 +662,7 @@ enum zr_command_clipping { ZR_CLIP = zr_true }; -struct zr_command_buffer_stats { +struct zr_command_stats { zr_uint lines; /* number of lines inside the buffer */ zr_uint rectangles; @@ -687,7 +687,7 @@ struct zr_command_buffer { /* current clipping rectangle */ zr_bool use_clipping; /* flag if the command buffer should clip commands */ - struct zr_command_buffer_stats stats; + struct zr_command_stats stats; /* stats about the content of the buffer */ struct zr_command_queue *queue; struct zr_command_buffer *next; @@ -1756,14 +1756,13 @@ zr_size zr_edit_box_len(struct zr_edit_box*); zr_widget_button_text_image -- button widget with image and text content zr_widget_toggle -- either a checkbox or radiobutton widget zr_widget_slider -- floating point slider widget - zr_progress -- unsigned integer progressbar widget - zr_editbox -- Editbox widget for complex user input - zr_edit -- Editbox wiget for basic user input - zr_edit_filtered -- Editbox with utf8 gylph filter capabilities - zr_spinner -- integer spinner widget - zr_selector -- string selector widget - zr_scrollbarv -- vertical scrollbar widget imeplementation - zr_scrollbarh -- horizontal scrollbar widget imeplementation + zr_widget_progress -- unsigned integer progressbar widget + zr_widget_editbox -- Editbox widget for complex user input + zr_widget_edit -- Editbox wiget for basic user input + zr_widget_edit_filtered -- Editbox with utf8 gylph filter capabilities + zr_widget_spinner -- integer spinner widget + zr_widget_scrollbarv -- vertical scrollbar widget imeplementation + zr_widget_scrollbarh -- horizontal scrollbar widget imeplementation */ enum zr_text_align { ZR_TEXT_LEFT, @@ -3247,7 +3246,7 @@ void zr_layout_pop(struct zr_context*); */ enum zr_widget_state zr_widget(struct zr_rect*, struct zr_context*); /* this function represents the base of every widget and calculates the bounds - * and allocated space for a widget inside a window. + * and allocates space for a widget inside a window. Output: - allocated space for a widget to draw into - zr_true if the widget is visible and should be updated zr_false if not @@ -3617,7 +3616,7 @@ struct zr_vec2 zr_popup_end(struct zr_context *parent, */ void zr_popup_nonblock_begin(struct zr_context *parent, struct zr_context *popup, zr_flags flags, zr_state *active, struct zr_rect body); -/* this function adds a context menu popup +/* this function adds a no-blocking context menu popup Input: - type of the popup as either growing or static - additonal popup window flags