summaryrefslogtreecommitdiff
path: root/src/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory.cpp')
-rw-r--r--src/memory.cpp386
1 files changed, 386 insertions, 0 deletions
diff --git a/src/memory.cpp b/src/memory.cpp
new file mode 100644
index 0000000..05254cb
--- /dev/null
+++ b/src/memory.cpp
@@ -0,0 +1,386 @@
+
+static void
+Memory_InitTable(global_memory *GlobalMemory, memory *Memory, uint64 Size, memory_table_list TableName, char *Name, uint64 Block_ElementSize = 0) {
+ memory_table *Table = &Memory->Slot[TableName];
+ Table->Name = Name;
+ Table->Address = (ptrsize *)((uint8 *)GlobalMemory->Address + GlobalMemory->CurrentPosition);
+ Table->Size = Size;
+ Table->Block_ElementSize = Block_ElementSize;
+ GlobalMemory->CurrentPosition += Size;
+}
+
+static uint32
+Memory_Block_AllocateNew(memory *Memory, memory_table_list TableName)
+{
+ memory_table *Table = &Memory->Slot[TableName];
+ Assert(Table->Block_ElementSize != 0);
+ bool32 Empty = 0;
+ uint32 Index = 0;
+ uint8 *Address_Playhead = (uint8 *)Table->Address;
+ while (*Address_Playhead != 0) {
+ Address_Playhead += Table->Block_ElementSize;
+ Index++;
+ }
+ Arbitrary_Zero(Address_Playhead, Table->Block_ElementSize);
+
+ return Index;
+}
+
+static void *
+Memory_Block_AddressAtIndex(memory *Memory, memory_table_list TableName, uint32 Index, bool32 AssertExists = 1)
+{
+ memory_table *Table = &Memory->Slot[TableName];
+ Assert(Table->Block_ElementSize != 0);
+ uint8 *Address = (uint8 *)Table->Address + (Table->Block_ElementSize * Index);
+ if (AssertExists)
+ Assert(*Address != 0);
+ return (void *)Address;
+}
+
+static uint16
+Memory_Block_LazyIndexAtAddress(memory *Memory, memory_table_list TableName, void *Address)
+{
+ memory_table *Table = &Memory->Slot[TableName];
+ return ((uint8 *)Address - (uint8 *)Table->Address) / Table->Block_ElementSize;
+}
+
+static void *
+Memory_Block_AllocateAddress(memory *Memory, memory_table_list TableName)
+{
+ uint16 FileIndex = Memory_Block_AllocateNew(Memory, TableName);
+ return Memory_Block_AddressAtIndex(Memory, TableName, FileIndex, 0);
+}
+
+// IMPORTANT(fox): All block data structs have to start with a uint8 Occupied variable!
+static bool32
+Block_Loop(memory *Memory, memory_table_list TableName, uint32 TotalCount, int *HasIncremented, int *CurrentCount, int *Index)
+{
+ for (;;) {
+ if (*CurrentCount == TotalCount) {
+ return 0;
+ }
+ if (*HasIncremented) {
+ *HasIncremented = 0;
+ (*Index)++;
+ }
+ uint8 *Occupied = (uint8 *)Memory_Block_AddressAtIndex(Memory, TableName, *Index, 0);
+ if (*Occupied) {
+ *HasIncremented = 1;
+ (*CurrentCount)++;
+ return 1;
+ }
+ (*Index)++;
+ Assert(*CurrentCount <= TotalCount);
+ Assert(*Index <= TotalCount*100); // This can get triggered normally if 100+ items are added and the first 99 in memory are deleted.
+ }
+ Assert(0);
+ return 0;
+}
+
+static bool32
+Block_Loop(memory *Memory, property_channel *Property, uint32 TotalCount, int *HasIncremented, int *CurrentCount, int *Index)
+{
+ for (;;) {
+ if (*CurrentCount == TotalCount) {
+ return 0;
+ }
+ if (*HasIncremented) {
+ *HasIncremented = 0;
+ (*Index)++;
+ }
+ uint8 *Occupied = (uint8 *)Bezier_LookupAddress(Memory, Property, *Index, 0);
+ if (*Occupied) {
+ *HasIncremented = 1;
+ (*CurrentCount)++;
+ return 1;
+ }
+ (*Index)++;
+ Assert(*CurrentCount <= TotalCount);
+ Assert(*Index <= TotalCount*100); // This can get triggered normally if 100+ items are added and the first 99 in memory are deleted.
+ }
+ Assert(0);
+ return 0;
+}
+
+static uint32
+Memory_Block_PrincipalBitmap_AllocateNew(project_data *File, project_state *State, memory *Memory)
+{
+ int h = 0, c = 0, i = 0;
+ int MaxBlockIndex = -1;
+ int PrincipalCount = 0;
+ while (Block_Loop(Memory, F_Sources, File->Source_Count, &h, &c, &i)) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, i);
+ if (Source->Type == source_type_principal || Source->Type == source_type_principal_temp)
+ PrincipalCount++;
+ if (Source->Bitmap_Index > MaxBlockIndex)
+ MaxBlockIndex = i;
+ }
+ if (!PrincipalCount)
+ return 0;
+
+ block_source Source = *(block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, MaxBlockIndex);
+ uint32 LastBlock = Source.Bitmap_Index;
+ uint32 BlockSize = ((Source.Width * Source.Height * Source.BytesPerPixel) / BitmapBlockSize) + 1;
+
+ uint32 Blocks_Max = Memory->Slot[B_CachedBitmaps].Size / BitmapBlockSize;
+ Assert(Blocks_Max > (LastBlock + BlockSize));
+
+ return LastBlock + BlockSize;
+
+}
+
+static uint32
+Memory_Block_Bitmap_AllocateNew(project_state *State, memory *Memory, cache_entry Entry, uint64 NewSize)
+{
+ uint32 LastVal = 0;
+ uint32 LastBlock = 0;
+ uint32 c = 0;
+ cache_entry *EntryArray = State->Render.Entry;
+ while (EntryArray[c].IsOccupied != 0) {
+ if (EntryArray[c].Block_StartIndex > LastBlock) {
+ LastBlock = EntryArray[c].Block_StartIndex;
+ LastVal = c;
+ }
+ c++;
+ }
+ cache_entry LastEntry = EntryArray[LastVal];
+ uint32 LastEntry_BlockCount = 0;
+ switch (EntryArray[LastVal].Type) {
+ case cache_entry_type_comp:
+ {
+ block_composition Comp = *(block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, LastEntry.TypeInfo);
+ uint64 Size = Comp.Width * Comp.Height * Comp.BytesPerPixel;
+ LastEntry_BlockCount = (Size / BitmapBlockSize) + 1;
+ } break;
+ case cache_entry_type_source:
+ {
+ block_source Source = *(block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, LastEntry.TypeInfo);
+ uint64 Size = Source.Width * Source.Height * Source.BytesPerPixel;
+ LastEntry_BlockCount = (Size / BitmapBlockSize) + 1;
+ } break;
+ case cache_entry_type_assert:
+ {
+ Assert(0);
+ } break;
+ default:
+ {
+ Assert(0);
+ } break;
+ }
+
+ uint32 Blocks_Max = Memory->Slot[B_CachedBitmaps].Size / BitmapBlockSize;
+ Assert(Blocks_Max > LastBlock);
+ return LastBlock + LastEntry_BlockCount;
+
+ /*
+ uint32 Blocks_Needed = (NewSize / BitmapBlockSize) + 1;
+ uint32 Block_Index_Available = 0;
+ */
+
+}
+static void
+Memory_Cache_Purge(project_data *File, project_state *State, memory *Memory, int32 SingleFrame = -1)
+{
+ cache_entry *EntryArray = State->Render.Entry;
+ int c = 0;
+ int count = Memory->EntryCount;
+ while (count != 0) {
+ bool32 ExtraCheck = (SingleFrame == -1) ? 1 : EntryArray[c].TypeInfo == SingleFrame;
+ if (EntryArray[c].Type == cache_entry_type_comp &&
+ EntryArray[c].TypeInfo == File->PrincipalCompIndex && SingleFrame) {
+ EntryArray[c].IsCached = 0;
+ }
+ c++;
+ count--;
+ }
+}
+
+static cache_entry *
+Memory_Cache_Search(project_state *State, memory *Memory, cache_entry_type Type, uint32 TypeInfo, uint32 TypeInfo_Sub)
+{
+ cache_entry *EntryArray = State->Render.Entry;
+ int c = 0;
+ int count = Memory->EntryCount;
+ while (count != 0) {
+ if (EntryArray[c].Type == Type &&
+ EntryArray[c].TypeInfo == TypeInfo &&
+ EntryArray[c].TypeInfo_Sub == TypeInfo_Sub) {
+ return &EntryArray[c];
+ }
+ c++;
+ count--;
+ }
+ if (c != 0)
+ EntryArray[c].Block_StartIndex = Memory_Block_Bitmap_AllocateNew(State, Memory, EntryArray[c], 0);
+ EntryArray[c].IsOccupied = true;
+ EntryArray[c].Type = Type;
+ EntryArray[c].TypeInfo = TypeInfo;
+ EntryArray[c].TypeInfo_Sub = TypeInfo_Sub;
+ Memory->EntryCount++;
+ return &EntryArray[c];
+}
+
+static void *
+Memory_Block_Bitmap_AddressAtIndex(memory *Memory, uint32 Index)
+{
+ memory_table *Table = &Memory->Slot[B_CachedBitmaps];
+ uint8 *Address = (uint8 *)Table->Address + Index*BitmapBlockSize;
+ return (void *)Address;
+}
+
+static void *
+Memory_PushScratch(memory *Memory, uint64 Size) {
+ memory_table *Table = &Memory->Slot[B_ScratchSpace];
+ uint8 *Address = ((uint8 *)Table->Address + Memory->ScratchPos);
+ Memory->ScratchPos += Size;
+#if DEBUG
+ Debug.ScratchSize[Debug.ScratchState] = Size;
+ Debug.ScratchState++;
+#endif
+ return (void *)Address;
+}
+
+static void
+Memory_PopScratch(memory *Memory, uint64 Size) {
+ memory_table *Table = &Memory->Slot[B_ScratchSpace];
+ Memory->ScratchPos -= Size;
+#if DEBUG
+ Debug.ScratchState--;
+ Assert(Debug.ScratchSize[Debug.ScratchState] == Size);
+#endif
+}
+
+static void *
+Memory_AddressAtOffset(memory *Memory, memory_table_list TableName, uint64 Offset)
+{
+ memory_table *Table = &Memory->Slot[TableName];
+ return (void *)((uint8 *)Table->Address + Offset);
+}
+
+void Memory_Copy(uint8 *Address_Write, uint8 *Address_Read, uint64 Size)
+{
+ uint64 i = 0;
+ while (i < Size) {
+ *(Address_Write + i) = *(Address_Read + i);
+ i++;
+ }
+}
+
+void Memory_Fill(uint8 *Address_Write, uint8 *Address_Read, uint64 WriteSize, uint64 ReadSize)
+{
+ uint64 i = 0;
+ while (i < WriteSize) {
+ *(Address_Write + i) = *(Address_Read + (i % ReadSize));
+ i++;
+ }
+}
+
+void Arbitrary_Zero(uint8 *Address_Write, uint64 Size)
+{
+ uint64 i = 0;
+ while (i < Size) {
+ *(Address_Write + i) = 0;
+ i++;
+ }
+}
+
+void Arbitrary_SwapData(memory *Memory, uint8 *Address_0, uint8 *Address_1, uint64 Size)
+{
+ uint8 *Buffer_Scratch = (uint8 *)Memory_PushScratch(Memory, Size);
+ Memory_Copy(Buffer_Scratch, Address_0, Size);
+ Memory_Copy(Address_0, Address_1, Size);
+ Memory_Copy(Address_1, Buffer_Scratch, Size);
+ Memory_PopScratch(Memory, Size);
+}
+
+
+static void
+Arbitrary_ShiftData(uint8 *Address_Start, uint8 *Address_End, uint64 ShiftAmount, int32 Direction)
+{
+ if (Direction > 0) {
+ uint8 *AddressPlayhead = Address_End;
+ while ((ptrsize)AddressPlayhead >= (ptrsize)Address_Start) {
+ *(AddressPlayhead + ShiftAmount) = *AddressPlayhead;
+ AddressPlayhead--;
+ }
+ } else {
+ uint8 *AddressPlayhead = Address_Start;
+ while ((ptrsize)AddressPlayhead < (ptrsize)Address_End) {
+ *(AddressPlayhead - ShiftAmount) = *AddressPlayhead;
+ AddressPlayhead++;
+ }
+ }
+}
+
+// TODO(fox): Just use zlib...
+extern "C" {
+#include "miniz.c"
+}
+
+static uint64
+Data_Compress(memory *Memory, void *DataSource, uint64 DataSize, void *DataBuffer, uint64 DataBufferSize, int CompressionLevel)
+{
+ z_stream stream = {};
+ stream.next_in = (uint8 *)DataSource;
+ stream.avail_in = DataSize;
+ stream.next_out = (uint8 *)DataBuffer;
+ stream.avail_out = DataBufferSize;
+
+ if (deflateInit(&stream, CompressionLevel) != Z_OK)
+ {
+ Assert(0);
+ }
+
+ int status;
+ for ( ; ; )
+ {
+ status = deflate(&stream, Z_SYNC_FLUSH);
+
+ if (status == Z_STREAM_END || !stream.avail_in)
+ break;
+ else
+ Assert(0);
+ }
+
+ uint64 CompressedSize = stream.total_out;
+
+ if (deflateEnd(&stream) != Z_OK)
+ {
+ Assert(0);
+ }
+
+ return CompressedSize;
+}
+
+static void
+Data_Decompress(memory *Memory, void *CompressedLocation, uint64 CompressedSize, void *BitmapLocation, uint64 ExpectedSize)
+{
+ z_stream stream = {};
+ stream.next_in = (uint8 *)CompressedLocation;
+ stream.avail_in = CompressedSize;
+ stream.next_out = (uint8 *)BitmapLocation;
+ stream.avail_out = 2147483648;
+
+ if (inflateInit(&stream))
+ {
+ Assert(0);
+ }
+
+ int status;
+ for ( ; ; )
+ {
+ status = inflate(&stream, Z_NO_FLUSH);
+
+ if (status == Z_STREAM_END || !stream.avail_in)
+ break;
+ else
+ Assert(0);
+ }
+
+ // Assert(stream.total_out == ExpectedSize);
+
+ if (inflateEnd(&stream) != Z_OK)
+ {
+ Assert(0);
+ }
+}