Add memory allocation tracking data to debug state

This commit is contained in:
Doyle Thai 2016-07-09 21:42:36 +10:00
parent 54ecddad2f
commit d82afe49d0
8 changed files with 74 additions and 37 deletions

View File

@ -143,8 +143,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
v2i codepointRange = font->codepointRange; v2i codepointRange = font->codepointRange;
const i32 numGlyphs = codepointRange.y - codepointRange.x; const i32 numGlyphs = codepointRange.y - codepointRange.x;
GlyphBitmap *glyphBitmaps = GlyphBitmap *glyphBitmaps = PLATFORM_MEM_ALLOC(numGlyphs, GlyphBitmap);
CAST(GlyphBitmap *) calloc(numGlyphs, sizeof(GlyphBitmap));
v2i largestGlyphDimension = V2i(0, 0); v2i largestGlyphDimension = V2i(0, 0);
const f32 targetFontHeight = 20.0f; const f32 targetFontHeight = 20.0f;
@ -159,8 +158,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
font->metrics = CAST(FontMetrics){ascent, descent, lineGap}; font->metrics = CAST(FontMetrics){ascent, descent, lineGap};
font->charMetrics = font->charMetrics = PLATFORM_MEM_ALLOC(numGlyphs, CharMetrics);
CAST(CharMetrics *) calloc(numGlyphs, sizeof(CharMetrics));
/* Use STB_TrueType to generate a series of bitmap characters */ /* Use STB_TrueType to generate a series of bitmap characters */
i32 glyphIndex = 0; i32 glyphIndex = 0;
@ -175,7 +173,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
&height, &xOffset, &yOffset); &height, &xOffset, &yOffset);
u8 *source = monoBitmap; u8 *source = monoBitmap;
u32 *colorBitmap = calloc(width * height, sizeof(u32)); u32 *colorBitmap = PLATFORM_MEM_ALLOC(width * height, u32);
u32 *dest = colorBitmap; u32 *dest = colorBitmap;
// NOTE(doyle): STB generates 1 byte per pixel bitmaps, we use 4bpp, so // NOTE(doyle): STB generates 1 byte per pixel bitmaps, we use 4bpp, so
@ -250,8 +248,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
} }
#endif #endif
u32 *fontBitmap = CAST(u32 *)calloc( i32 bitmapSize = squared(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL;
squared(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL, sizeof(u32)); u32 *fontBitmap = PLATFORM_MEM_ALLOC(bitmapSize, u32);
const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL; const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL;
// Check value to determine when a row of glyphs is completely printed // Check value to determine when a row of glyphs is completely printed
@ -349,14 +347,19 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
stbi_write_png("out.png", MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4, fontBitmap, stbi_write_png("out.png", MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4, fontBitmap,
MAX_TEXTURE_SIZE * 4); MAX_TEXTURE_SIZE * 4);
#endif #endif
PLATFORM_MEM_FREE(fontBitmap, bitmapSize);
font->tex = &assetManager->textures[texlist_font]; font->tex = &assetManager->textures[texlist_font];
font->atlas = &assetManager->texAtlas[texlist_font]; font->atlas = &assetManager->texAtlas[texlist_font];
for (i32 i = 0; i < numGlyphs; i++) for (i32 i = 0; i < numGlyphs; i++)
free(glyphBitmaps[i].pixels); {
i32 glyphBitmapSizeInBytes = glyphBitmaps[i].dimensions.w *
glyphBitmaps[i].dimensions.h * sizeof(u32);
PLATFORM_MEM_FREE(glyphBitmaps[i].pixels, glyphBitmapSizeInBytes);
}
free(glyphBitmaps); PLATFORM_MEM_FREE(glyphBitmaps, numGlyphs * sizeof(GlyphBitmap));
platform_closeFileRead(&fontFileRead); platform_closeFileRead(&fontFileRead);
return 0; return 0;

View File

@ -1,18 +1,18 @@
#include "Dengine/Platform.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include <stdlib.h>
DebugState GLOBAL_debugState; DebugState GLOBAL_debugState;
void debug_init() void debug_init()
{ {
GLOBAL_debugState.totalMemoryAllocated = 0;
GLOBAL_debugState.callCount = PLATFORM_MEM_ALLOC(debugcallcount_num, i32);
GLOBAL_debugState.numDebugStrings = 0; GLOBAL_debugState.numDebugStrings = 0;
GLOBAL_debugState.stringUpdateTimer = 0.0f; GLOBAL_debugState.stringUpdateTimer = 0.0f;
GLOBAL_debugState.stringUpdateRate = 0.15f; GLOBAL_debugState.stringUpdateRate = 0.15f;
GLOBAL_debugState.stringLineGap = -1; GLOBAL_debugState.stringLineGap = -1;
GLOBAL_debugState.callCount =
CAST(i32 *) calloc(debugcallcount_num, sizeof(i32));
} }
void debug_pushString(char *formatString, void *data, char *dataType) void debug_pushString(char *formatString, void *data, char *dataType)

View File

@ -22,7 +22,7 @@ i32 platform_readFileToBuffer(const char *const filePath,
} }
// TODO(doyle): Warning we assume files less than 4GB // TODO(doyle): Warning we assume files less than 4GB
file->buffer = (void *)calloc(fileSize.LowPart, sizeof(char)); file->buffer = PLATFORM_MEM_ALLOC(fileSize.LowPart, char);
file->size = fileSize.LowPart; file->size = fileSize.LowPart;
DWORD numBytesRead = 0; DWORD numBytesRead = 0;
@ -33,7 +33,7 @@ i32 platform_readFileToBuffer(const char *const filePath,
{ {
printf("ReadFile() failed: %d error number\n", printf("ReadFile() failed: %d error number\n",
status); status);
free(file->buffer); PLATFORM_MEM_FREE(file->buffer, file->size);
return status; return status;
} }
else if (numBytesRead != file->size) else if (numBytesRead != file->size)
@ -41,7 +41,7 @@ i32 platform_readFileToBuffer(const char *const filePath,
printf( printf(
"ReadFile() failed: Number of bytes read doesn't match file " "ReadFile() failed: Number of bytes read doesn't match file "
"size\n"); "size\n");
free(file->buffer); PLATFORM_MEM_FREE(file->buffer, file->size);
return -1; return -1;
} }

View File

@ -24,7 +24,7 @@ void renderer_string(Renderer *const renderer, Font *const font,
{ {
i32 quadIndex = 0; i32 quadIndex = 0;
i32 strLen = common_strlen(string); i32 strLen = common_strlen(string);
RenderQuad *stringQuads = CAST(RenderQuad *)calloc(strLen, sizeof(RenderQuad)); RenderQuad *stringQuads = PLATFORM_MEM_ALLOC(strLen, RenderQuad);
f32 baseline = pos.y; f32 baseline = pos.y;
for (i32 i = 0; i < strLen; i++) for (i32 i = 0; i < strLen; i++)
@ -56,7 +56,7 @@ void renderer_string(Renderer *const renderer, Font *const font,
updateBufferObject(renderer, stringQuads, quadIndex); updateBufferObject(renderer, stringQuads, quadIndex);
renderer_object(renderer, V2(0.0f, 0.0f), renderer->size, rotate, color, renderer_object(renderer, V2(0.0f, 0.0f), renderer->size, rotate, color,
font->tex); font->tex);
free(stringQuads); PLATFORM_MEM_FREE(stringQuads, strLen * sizeof(RenderQuad));
} }

View File

@ -1,14 +1,14 @@
#include "Dengine/Platform.h"
#include "Dengine/AssetManager.h" #include "Dengine/AssetManager.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "WorldTraveller/WorldTraveller.h" #include "WorldTraveller/WorldTraveller.h"
//TODO(doyle): This is temporary! Maybe abstract into our platform layer, or // TODO(doyle): This is temporary! Maybe abstract into our platform layer, or
//choose to load assets outside of WorldTraveller! // choose to load assets outside of WorldTraveller !
#include <stdlib.h>
INTERNAL Entity *addEntity(World *world, v2 pos, v2 size, INTERNAL Entity *addEntity(World *world, v2 pos, v2 size, enum EntityType type,
enum EntityType type, enum Direction direction, enum Direction direction, Texture *tex, b32 collides)
Texture *tex, b32 collides)
{ {
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
@ -130,8 +130,7 @@ void worldTraveller_gameInit(GameState *state, v2i windowSize)
{ {
World *const world = &state->world[i]; World *const world = &state->world[i];
world->maxEntities = 8192; world->maxEntities = 8192;
world->entities = world->entities = PLATFORM_MEM_ALLOC(world->maxEntities, Entity);
CAST(Entity *) calloc(world->maxEntities, sizeof(Entity));
world->texType = texlist_terrain; world->texType = texlist_terrain;
v2 worldDimensionInTilesf = V2(CAST(f32) worldDimensionInTiles.x, v2 worldDimensionInTilesf = V2(CAST(f32) worldDimensionInTiles.x,
@ -163,7 +162,7 @@ void worldTraveller_gameInit(GameState *state, v2i windowSize)
f32 duration = 1.0f; f32 duration = 1.0f;
i32 numRects = 1; i32 numRects = 1;
v4 *animRects = CAST(v4 *)calloc(numRects, sizeof(v4)); v4 *animRects = PLATFORM_MEM_ALLOC(numRects, v4);
animRects[0] = atlas->texRect[terraincoords_ground]; animRects[0] = atlas->texRect[terraincoords_ground];
addAnim(tile, animRects, numRects, duration); addAnim(tile, animRects, numRects, duration);
} }
@ -189,14 +188,14 @@ void worldTraveller_gameInit(GameState *state, v2i windowSize)
/* Add idle animation */ /* Add idle animation */
f32 duration = 1.0f; f32 duration = 1.0f;
i32 numRects = 1; i32 numRects = 1;
v4 *heroIdleRects = CAST(v4 *) calloc(numRects, sizeof(v4)); v4 *heroIdleRects = PLATFORM_MEM_ALLOC(numRects, v4);
heroIdleRects[0] = V4(746.0f, 1018.0f, 804.0f, 920.0f); heroIdleRects[0] = V4(746.0f, 1018.0f, 804.0f, 920.0f);
addAnim(hero, heroIdleRects, numRects, duration); addAnim(hero, heroIdleRects, numRects, duration);
/* Add walking animation */ /* Add walking animation */
duration = 0.10f; duration = 0.10f;
numRects = 3; numRects = 3;
v4 *heroWalkRects = CAST(v4 *) calloc(numRects, sizeof(v4)); v4 *heroWalkRects = PLATFORM_MEM_ALLOC(numRects, v4);
heroWalkRects[0] = V4(641.0f, 1018.0f, 699.0f, 920.0f); heroWalkRects[0] = V4(641.0f, 1018.0f, 699.0f, 920.0f);
heroWalkRects[1] = V4(746.0f, 1018.0f, 804.0f, 920.0f); heroWalkRects[1] = V4(746.0f, 1018.0f, 804.0f, 920.0f);
heroWalkRects[2] = V4(849.0f, 1018.0f, 904.0f, 920.0f); heroWalkRects[2] = V4(849.0f, 1018.0f, 904.0f, 920.0f);
@ -224,7 +223,7 @@ void worldTraveller_gameInit(GameState *state, v2i windowSize)
/* Add npc waving animation */ /* Add npc waving animation */
duration = 0.30f; duration = 0.30f;
numRects = 2; numRects = 2;
v4 *npcWavingRects = CAST(v4 *) calloc(numRects, sizeof(v4)); v4 *npcWavingRects = PLATFORM_MEM_ALLOC(numRects, v4);
npcWavingRects[0] = V4(944.0f, 918.0f, 1010.0f, 816.0f); npcWavingRects[0] = V4(944.0f, 918.0f, 1010.0f, 816.0f);
npcWavingRects[1] = V4(944.0f, 812.0f, 1010.0f, 710.0f); npcWavingRects[1] = V4(944.0f, 812.0f, 1010.0f, 710.0f);
addAnim(npc, npcWavingRects, numRects, duration); addAnim(npc, npcWavingRects, numRects, duration);
@ -427,6 +426,9 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
DEBUG_PUSH_STRING("glDrawArray Calls: %d", DEBUG_PUSH_STRING("glDrawArray Calls: %d",
&GLOBAL_debugState.callCount[debugcallcount_drawArrays], &GLOBAL_debugState.callCount[debugcallcount_drawArrays],
"i32"); "i32");
i32 debug_kbAllocated = GLOBAL_debugState.totalMemoryAllocated / 1024;
DEBUG_PUSH_STRING("TotalMemoryAllocated: %dkb", &debug_kbAllocated, "i32");
debug_stringUpdateAndRender(&state->renderer, font, dt); debug_stringUpdateAndRender(&state->renderer, font, dt);
debug_clearCallCounter(); debug_clearCallCounter();
#endif #endif

View File

@ -15,7 +15,9 @@ enum DebugCallCount
typedef struct DebugState typedef struct DebugState
{ {
i32 totalMemoryAllocated;
i32 *callCount; i32 *callCount;
/* Debug strings rendered in top left corner */ /* Debug strings rendered in top left corner */
char debugStrings[256][64]; char debugStrings[256][64];
i32 numDebugStrings; i32 numDebugStrings;

View File

@ -2,7 +2,6 @@
#define DENGINE_MATH_H #define DENGINE_MATH_H
#include <math.h> #include <math.h>
#include "Dengine/Common.h" #include "Dengine/Common.h"
#define squared(x) (x * x) #define squared(x) (x * x)

View File

@ -3,8 +3,16 @@
#include <Windows.h> #include <Windows.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "Dengine/Common.h" #include "Dengine/Common.h"
#include "Dengine/Debug.h"
// TODO(doyle): Create own custom memory allocator
#define PLATFORM_MEM_ALLOC(num, type) \
CAST(type *) platform_memoryAlloc(num * sizeof(type))
#define PLATFORM_MEM_FREE(ptr, bytes) \
platform_memoryFree(CAST(void *) ptr, bytes)
typedef struct typedef struct
{ {
@ -12,15 +20,38 @@ typedef struct
i32 size; i32 size;
} PlatformFileRead; } PlatformFileRead;
i32 platform_readFileToBuffer(const char *const filePath, // TODO(doyle): numBytes in mem free is temporary until we create custom
PlatformFileRead *file); // allocator since we haven't put in a system to track memory usage per
// allocation
inline void platform_memoryFree(void *data, i32 numBytes)
{
if (data) free(data);
#ifdef DENGINE_DEBUG
GLOBAL_debugState.totalMemoryAllocated -= numBytes;
#endif
}
inline void *platform_memoryAlloc(i32 numBytes)
{
void *result = calloc(1, numBytes);
#ifdef DENGINE_DEBUG
if (result)
GLOBAL_debugState.totalMemoryAllocated += numBytes;
#endif
return result;
}
inline void platform_closeFileRead(PlatformFileRead *file) inline void platform_closeFileRead(PlatformFileRead *file)
{ {
if (file->buffer) PLATFORM_MEM_FREE(file->buffer, file->size);
{
free(file->buffer);
}
} }
i32 platform_readFileToBuffer(const char *const filePath,
PlatformFileRead *file);
#endif #endif