vg_queue api
authorhgn <hgodden00@gmail.com>
Wed, 26 Mar 2025 04:03:41 +0000 (04:03 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 26 Mar 2025 04:03:41 +0000 (04:03 +0000)
src/fonts/vg_font_thin_3.xcf
vg_io.c
vg_mem_queue.c
vg_mem_queue.h

index 3e2c1cb0960cea81812f152100ba5d826198794a..a62e594fca34530d24c42b8721bc2346e4e0c8e2 100644 (file)
Binary files a/src/fonts/vg_font_thin_3.xcf and b/src/fonts/vg_font_thin_3.xcf differ
diff --git a/vg_io.c b/vg_io.c
index a061d0fead02be726ac5ebdd6867eccb81021f0f..027daa53f7e76873badb0c1667b2804d0afeeff9 100644 (file)
--- a/vg_io.c
+++ b/vg_io.c
@@ -191,8 +191,7 @@ void *vg_file_read( void *lin_alloc, const char *path, u32 *size )
        FILE *f = fopen( path, "rb" );
        if( f )
    {
-      void *buffer = lin_alloc? vg_linear_alloc( lin_alloc, 0 ):
-                                NULL;
+      void *buffer = lin_alloc? vg_linear_alloc( lin_alloc, 0 ): NULL;
       u64 current = 0;
 
       /* read in chunks */
index 3b1a9d64ccf80fab6b306a7370ea5cf30310ab16..cc410d84ab03f7d4d71c90c27c7951570e69d88b 100644 (file)
 #include <string.h>
 
 /*
- * Allocate memory on the queue. Returns NULL if allocation failed for any
- * any reason.
+ * Copy q1 to q2, and reorganize the memory to correct for q2's new size
  */
-vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size )
+void vg_queue_copy_upgrade( vg_queue *q1, vg_queue *q2 )
 {
-   u32 total = vg_align8(size) + sizeof(vg_queue_frame);
-   vg_queue_frame *frame = NULL;
+   VG_ASSERT( q2->size >= q1->size );
 
+   if( q1->allocation_count == 0 )
+   {
+      q2->head_offset = 0;
+      q2->tail_offset = 0;
+      q2->allocation_count = 0;
+      return;
+   }
+
+   vg_queue_item *head = q1->buffer + q1->head_offset;
+   u32 end = q1->head_offset + head->alloc_size,
+       start = q1->tail_offset;
+
+   q2->allocation_count = q1->allocation_count;
+   q2->tail_offset = 0;
+   if( start < end )
+   {
+      u32 r0 = end-start;
+      memcpy( q2->buffer, q1->buffer+start, r0 );
+      q2->head_offset = r0 - head->alloc_size;
+   }
+   else
+   {
+      u32 r0 = q1->size - start;
+      memcpy( q2->buffer, q1->buffer+start, r0 );
+      memcpy( q2->buffer + r0, q1->buffer, end );
+      q2->head_offset = r0 + end - head->alloc_size;
+   }
+}
+
+void *vg_queue_data( vg_queue *q, u32 offset )
+{
+   vg_queue_item *item = q->buffer + offset;
+   return item->data;
+}
+
+void *vg_queue_tail_data( vg_queue *q )
+{
+   if( q->allocation_count )
+   {
+      return vg_queue_data( q, q->tail_offset );
+   }
+   else
+      return NULL;
+}
+
+/*
+ * Allocate memory on the queue. Returns NULL if allocation failed for any reason & out_offset undefined
+ */
+void *vg_queue_alloc( vg_queue *q, u32 size, u32 *out_offset )
+{
+   u32 total = vg_align8(size) + sizeof(vg_queue_item);
    if( total > q->size )
       return NULL;
 
-   if( q->head )
+   u32 new_item_offset;
+   if( q->allocation_count )
    {
-      u32 end   = ((u8 *)q->head - q->buffer) + q->head->alloc_size,
-          start = ((u8 *)q->tail - q->buffer),
+      vg_queue_item *head = q->buffer + q->head_offset;
+      u32 end   = q->head_offset + head->alloc_size,
+          start = q->tail_offset,
           r0    = 0,
           r1    = 0;
 
-      if( start < end ){
-         r0 = q->size-end;
+      if( start < end )
+      {
+         r0 = q->size - end;
          r1 = start;
       }
       else 
          r0 = start - end;
 
-      if( total < r0 ){
-         frame = (vg_queue_frame *)(q->buffer + end);
-      }
-      else {
-         if( total < r1 ){
-            q->head->alloc_size += r0;
-            frame = (vg_queue_frame *)q->buffer;
+      if( total < r0 )
+         new_item_offset = end;
+      else 
+      {
+         if( total < r1 )
+         {
+            head->alloc_size += r0;
+            new_item_offset = 0;
+         }
+         else
+         {
+            /* Full */
+            return NULL;
          }
       }
-
-      if( !frame ) return NULL;
    }
-   else{
-      frame = (vg_queue_frame *)q->buffer;
-      q->tail = frame;
+   else
+   {
+      new_item_offset = 0;
+      q->tail_offset = 0;
    }
 
-   memset( frame, 0, sizeof(vg_queue_frame) );
+   vg_queue_item *item = (vg_queue_item *)(q->buffer + new_item_offset);
+   memset( item, 0, sizeof(vg_queue_item) );
+   item->alloc_size = total;
+   item->size = size;
 
-   q->head = frame;
-   frame->alloc_size = total;
-   frame->size = size;
+   q->head_offset = new_item_offset;
+   q->allocation_count ++;
 
-   return frame;
+   if( out_offset )
+      *out_offset = new_item_offset;
+   return item->data;
 }
 
 /*
@@ -61,17 +122,21 @@ vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size )
  */
 void vg_queue_pop( vg_queue *q )
 {
-   if( q->head == q->tail ){
-      q->head = NULL;
-      q->tail = NULL;
+   VG_ASSERT( q->allocation_count );
+   q->allocation_count --;
+
+   if( q->head_offset == q->tail_offset )
+   {
+      q->head_offset = 0;
+      q->tail_offset = 0;
       return;
    }
 
-   u32 start = ((u8 *)q->tail - q->buffer);
-   start += q->tail->alloc_size;
+   vg_queue_item *tail = q->buffer + q->tail_offset;
+   u32 start = q->tail_offset + tail->alloc_size;
 
    if( start == q->size )
       start = 0;
 
-   q->tail = (vg_queue_frame *)(q->buffer + start);
+   q->tail_offset = start;
 }
index f898ada2b7fb0da1139ac4cbe69d65b79c80cee7..3e14ae59272b2f319cfd72d1d37f7299fb5dbb02 100644 (file)
@@ -1,9 +1,11 @@
 #pragma once
 
+#define VG_MEM_QUEUE_INVALID 0xffffffff
+
 typedef struct vg_queue vg_queue;
-typedef struct vg_queue_frame vg_queue_frame;
+typedef struct vg_queue_item vg_queue_item;
 
-struct vg_queue_frame 
+struct vg_queue_item
 {
    u32 alloc_size,size;
    u8 data[];
@@ -11,11 +13,16 @@ struct vg_queue_frame
 
 struct vg_queue 
 {
-   u8 *buffer;
+   void *buffer;
    u32 size;
-   
-   vg_queue_frame *head, *tail;
+   u32 head_offset, tail_offset;
+   u32 allocation_count;
 };
 
-vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size );
+void *vg_queue_alloc( vg_queue *q, u32 size, u32 *out_offset );
+
+void *vg_queue_data( vg_queue *q, u32 offset );
+void *vg_queue_tail_data( vg_queue *q );
+
 void vg_queue_pop( vg_queue *q );
+void vg_queue_copy_upgrade( vg_queue *q1, vg_queue *q2 );