a few little optimizations to take the edge off, 4.0.18 ready for publishing (barring problems durring test drive session)
parent
6c1ebcf06e
commit
5217d015be
|
@ -290,8 +290,14 @@ static i32_4tech
|
|||
general_memory_check(General_Memory *general){}
|
||||
#endif
|
||||
|
||||
#if !defined(PRFL_FUNC_GROUP)
|
||||
#define PRFL_FUNC_GROUP()
|
||||
#endif
|
||||
|
||||
static void*
|
||||
general_memory_allocate(General_Memory *general, i32_4tech size){
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
void *result = 0;
|
||||
if (size < BUBBLE_MIN_SIZE) size = BUBBLE_MIN_SIZE;
|
||||
for (Bubble *bubble = general->free_sentinel.next2;
|
||||
|
|
84
4ed.cpp
84
4ed.cpp
|
@ -549,12 +549,11 @@ command_caller(Coroutine *coroutine){
|
|||
Generic_Command generic;
|
||||
if (cmd_in->bind.function == command_user_callback){
|
||||
generic.command = cmd_in->bind.custom;
|
||||
models->command_caller(&models->app_links, generic);
|
||||
}
|
||||
else{
|
||||
generic.cmdid = (Command_ID)cmd_in->bind.custom_id;
|
||||
models->command_caller(&models->app_links, generic);
|
||||
}
|
||||
models->command_caller(&models->app_links, generic);
|
||||
}
|
||||
else{
|
||||
cmd_in->bind.function(command->system, command, cmd_in->bind);
|
||||
|
@ -1171,56 +1170,46 @@ extern "C" SCROLL_RULE_SIG(fallback_scroll_rule){
|
|||
}
|
||||
|
||||
App_Init_Sig(app_init){
|
||||
Partition *partition;
|
||||
Panel *panels, *panel;
|
||||
Panel_Divider *dividers, *div;
|
||||
i32 panel_max_count;
|
||||
i32 divider_max_count;
|
||||
|
||||
App_Vars *vars = (App_Vars*)memory->vars_memory;
|
||||
Models *models = &vars->models;
|
||||
models->keep_playing = 1;
|
||||
models->keep_playing = true;
|
||||
|
||||
app_links_init(system, &models->app_links, memory->user_memory, memory->user_memory_size);
|
||||
|
||||
models->config_api = api;
|
||||
models->app_links.cmd_context = &vars->command_data;
|
||||
|
||||
partition = &models->mem.part;
|
||||
Partition *partition = &models->mem.part;
|
||||
|
||||
{
|
||||
panel_max_count = models->layout.panel_max_count = MAX_VIEWS;
|
||||
divider_max_count = panel_max_count - 1;
|
||||
models->layout.panel_count = 0;
|
||||
|
||||
panels = push_array(partition, Panel, panel_max_count);
|
||||
models->layout.panels = panels;
|
||||
|
||||
dll_init_sentinel(&models->layout.free_sentinel);
|
||||
dll_init_sentinel(&models->layout.used_sentinel);
|
||||
|
||||
panel = panels;
|
||||
for (i32 i = 0; i < panel_max_count; ++i, ++panel){
|
||||
dll_insert(&models->layout.free_sentinel, panel);
|
||||
}
|
||||
|
||||
dividers = push_array(partition, Panel_Divider, divider_max_count);
|
||||
models->layout.dividers = dividers;
|
||||
|
||||
div = dividers;
|
||||
for (i32 i = 0; i < divider_max_count-1; ++i, ++div){
|
||||
div->next = (div + 1);
|
||||
}
|
||||
div->next = 0;
|
||||
models->layout.free_divider = dividers;
|
||||
PRFL_INIT(memory->debug_memory, memory->debug_memory_size);
|
||||
|
||||
i32 panel_max_count = models->layout.panel_max_count = MAX_VIEWS;
|
||||
i32 divider_max_count = panel_max_count - 1;
|
||||
models->layout.panel_count = 0;
|
||||
|
||||
Panel *panels = push_array(partition, Panel, panel_max_count);
|
||||
models->layout.panels = panels;
|
||||
|
||||
dll_init_sentinel(&models->layout.free_sentinel);
|
||||
dll_init_sentinel(&models->layout.used_sentinel);
|
||||
|
||||
Panel *panel = panels;
|
||||
for (i32 i = 0; i < panel_max_count; ++i, ++panel){
|
||||
dll_insert(&models->layout.free_sentinel, panel);
|
||||
}
|
||||
|
||||
Panel_Divider *dividers = push_array(partition, Panel_Divider, divider_max_count);
|
||||
models->layout.dividers = dividers;
|
||||
|
||||
Panel_Divider *div = dividers;
|
||||
for (i32 i = 0; i < divider_max_count-1; ++i, ++div){
|
||||
div->next = (div + 1);
|
||||
}
|
||||
div->next = 0;
|
||||
models->layout.free_divider = dividers;
|
||||
|
||||
|
||||
{
|
||||
View *view = 0;
|
||||
View_Persistent *persistent = 0;
|
||||
i32 i = 0;
|
||||
i32 max = 0;
|
||||
|
||||
models->live_set = &vars->live_set;
|
||||
|
||||
vars->live_set.count = 0;
|
||||
|
@ -1230,12 +1219,12 @@ App_Init_Sig(app_init){
|
|||
|
||||
dll_init_sentinel(&vars->live_set.free_sentinel);
|
||||
|
||||
max = vars->live_set.max;
|
||||
view = vars->live_set.views;
|
||||
for (i = 0; i < max; ++i, ++view){
|
||||
i32 max = vars->live_set.max;
|
||||
View *view = vars->live_set.views;
|
||||
for (i32 i = 0; i < max; ++i, ++view){
|
||||
dll_insert(&vars->live_set.free_sentinel, view);
|
||||
|
||||
persistent = &view->persistent;
|
||||
View_Persistent *persistent = &view->persistent;
|
||||
persistent->id = i;
|
||||
persistent->models = models;
|
||||
}
|
||||
|
@ -1515,8 +1504,7 @@ App_Init_Sig(app_init){
|
|||
}
|
||||
|
||||
internal i32
|
||||
update_cli_handle_without_file(System_Functions *system, Models *models,
|
||||
CLI_Handles *cli, char *dest, i32 max){
|
||||
update_cli_handle_without_file(System_Functions *system, Models *models, CLI_Handles *cli, char *dest, i32 max){
|
||||
i32 result = 0;
|
||||
u32 amount = 0;
|
||||
|
||||
|
@ -1567,6 +1555,8 @@ update_cli_handle_with_file(System_Functions *system, Models *models, CLI_Handle
|
|||
|
||||
|
||||
App_Step_Sig(app_step){
|
||||
PRFL_BEGIN_FRAME();
|
||||
|
||||
Application_Step_Result app_result = *app_result_;
|
||||
app_result.animating = 0;
|
||||
|
||||
|
@ -2632,6 +2622,8 @@ App_Step_Sig(app_step){
|
|||
*app_result_ = app_result;
|
||||
|
||||
// end-of-app_step
|
||||
|
||||
PRFL_END_FRAME("profile.data");
|
||||
}
|
||||
|
||||
extern "C" App_Get_Functions_Sig(app_get_functions){
|
||||
|
|
2
4ed.h
2
4ed.h
|
@ -21,6 +21,8 @@ struct Application_Memory{
|
|||
i32 target_memory_size;
|
||||
void *user_memory;
|
||||
i32 user_memory_size;
|
||||
void *debug_memory;
|
||||
i32 debug_memory_size;
|
||||
};
|
||||
|
||||
#define KEY_INPUT_BUFFER_SIZE 8
|
||||
|
|
|
@ -606,6 +606,8 @@ range is not within the bounds of the buffer.
|
|||
)
|
||||
DOC_SEE(4coder_Buffer_Positioning_System)
|
||||
*/{
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(cmd, buffer);
|
||||
|
||||
|
@ -1114,6 +1116,8 @@ DOC_RETURN(returns a summary of the newly created buffer or of the existing buff
|
|||
|
||||
DOC_SEE(begin_buffer_creation)
|
||||
*/{
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
Models *models = cmd->models;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "4ed_math.h"
|
||||
#include "4ed_system.h"
|
||||
#include "4ed_profile.h"
|
||||
|
||||
//#define USE_DEBUG_MEMORY
|
||||
|
||||
|
|
|
@ -669,6 +669,8 @@ buffer_measure_starts(Buffer_Measure_Starts *state, Gap_Buffer *buffer){
|
|||
|
||||
internal void
|
||||
buffer_measure_character_starts(System_Functions *system, Render_Font *font, Gap_Buffer *buffer, i32 *character_starts, i32 mode, i32 virtual_white){
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
assert(mode == 0);
|
||||
|
||||
Gap_Buffer_Stream stream = {0};
|
||||
|
|
|
@ -106,6 +106,11 @@ struct Editing_File_Settings{
|
|||
};
|
||||
global_const Editing_File_Settings null_editing_file_settings = {0};
|
||||
|
||||
struct Editing_Hacks{
|
||||
b32 suppression_mode;
|
||||
b32 needs_wraps_and_fix_cursor;
|
||||
};
|
||||
|
||||
struct Editing_File_State{
|
||||
Gap_Buffer buffer;
|
||||
|
||||
|
@ -140,6 +145,8 @@ struct Editing_File_State{
|
|||
File_Edit_Positions edit_pos_space[16];
|
||||
File_Edit_Positions *edit_poss[16];
|
||||
i32 edit_poss_count;
|
||||
|
||||
Editing_Hacks hacks;
|
||||
};
|
||||
global_const Editing_File_State null_editing_file_state = {0};
|
||||
|
||||
|
|
|
@ -899,6 +899,8 @@ file_update_cursor_positions(System_Functions *system, Models *models, Editing_F
|
|||
|
||||
internal void
|
||||
file_measure_starts(General_Memory *general, Gap_Buffer *buffer){
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
if (!buffer->line_starts){
|
||||
i32 max = buffer->line_max = KB(1);
|
||||
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32));
|
||||
|
@ -1453,6 +1455,8 @@ get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start){
|
|||
|
||||
internal void
|
||||
file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
General_Memory *general = &models->mem.general;
|
||||
Partition *part = &models->mem.part;
|
||||
|
||||
|
@ -1509,12 +1513,20 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
i32 potential_count = 0;
|
||||
i32 stage = 0;
|
||||
|
||||
PRFL_BEGIN_RESUMABLE(buffer_measure_wrap_y);
|
||||
PRFL_BEGIN_RESUMABLE(NeedWrapDetermination);
|
||||
PRFL_BEGIN_RESUMABLE(NeedLineShift);
|
||||
PRFL_BEGIN_RESUMABLE(LongTokenParsing);
|
||||
|
||||
do{
|
||||
PRFL_START_RESUMABLE(buffer_measure_wrap_y);
|
||||
stop = buffer_measure_wrap_y(&state, params, current_line_shift, do_wrap, wrap_unit_end);
|
||||
PRFL_STOP_RESUMABLE(buffer_measure_wrap_y);
|
||||
|
||||
switch (stop.status){
|
||||
case BLStatus_NeedWrapDetermination:
|
||||
{
|
||||
PRFL_START_RESUMABLE(NeedWrapDetermination);
|
||||
if (use_tokens){
|
||||
if (stage == 0){
|
||||
do_wrap = 0;
|
||||
|
@ -1539,7 +1551,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
f32 self_x = 0;
|
||||
i32 wrap_end_result = size;
|
||||
if (buffer_stringify_loop(&stream, params.buffer, i, size)){
|
||||
b32 still_looping = 0;
|
||||
b32 still_looping = false;
|
||||
do{
|
||||
for (; i < stream.end; ++i){
|
||||
{
|
||||
|
@ -1594,11 +1606,13 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
do_wrap = 0;
|
||||
}
|
||||
}
|
||||
PRFL_STOP_RESUMABLE(NeedWrapDetermination);
|
||||
}break;
|
||||
|
||||
case BLStatus_NeedWrapLineShift:
|
||||
case BLStatus_NeedLineShift:
|
||||
{
|
||||
PRFL_START_RESUMABLE(NeedLineShift);
|
||||
f32 current_width = width;
|
||||
|
||||
if (use_tokens){
|
||||
|
@ -1636,8 +1650,8 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
b32 emit_comment_position = 0;
|
||||
b32 first_word = 1;
|
||||
|
||||
if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT ||
|
||||
wrap_state.token_ptr->type == CPP_TOKEN_STRING_CONSTANT){
|
||||
if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT || wrap_state.token_ptr->type == CPP_TOKEN_STRING_CONSTANT){
|
||||
PRFL_START_RESUMABLE(LongTokenParsing);
|
||||
i32 i = wrap_state.token_ptr->start;
|
||||
i32 end_i = i + wrap_state.token_ptr->size;
|
||||
|
||||
|
@ -1758,6 +1772,8 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
potential_marks[potential_count] = potential_wrap;
|
||||
++potential_count;
|
||||
}
|
||||
|
||||
PRFL_STOP_RESUMABLE(LongTokenParsing);
|
||||
}
|
||||
|
||||
if (!emit_comment_position){
|
||||
|
@ -1928,10 +1944,17 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
|
||||
file->state.line_indents[stop.wrap_line_index] = current_line_shift;
|
||||
file->state.wrap_line_count = stop.wrap_line_index;
|
||||
|
||||
PRFL_STOP_RESUMABLE(NeedLineShift);
|
||||
}break;
|
||||
}
|
||||
}while(stop.status != BLStatus_Finished);
|
||||
|
||||
PRFL_END_RESUMABLE(buffer_measure_wrap_y);
|
||||
PRFL_END_RESUMABLE(NeedWrapDetermination);
|
||||
PRFL_END_RESUMABLE(NeedLineShift);
|
||||
PRFL_END_RESUMABLE(LongTokenParsing);
|
||||
|
||||
++file->state.wrap_line_count;
|
||||
|
||||
file_allocate_wrap_positions_as_needed(general, file, wrap_position_index);
|
||||
|
@ -1939,12 +1962,23 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
file->state.wrap_position_count = wrap_position_index;
|
||||
|
||||
end_temp_memory(temp);
|
||||
|
||||
if (file->state.hacks.needs_wraps_and_fix_cursor){
|
||||
file->state.hacks.needs_wraps_and_fix_cursor = false;
|
||||
file_update_cursor_positions(system, models, file);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
file_measure_wraps_and_fix_cursor(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){
|
||||
file_measure_wraps(system, models, file, font);
|
||||
file_update_cursor_positions(system, models, file);
|
||||
if (file->state.hacks.suppression_mode){
|
||||
file->state.hacks.needs_wraps_and_fix_cursor = true;
|
||||
}
|
||||
else{
|
||||
file->state.hacks.needs_wraps_and_fix_cursor = false;
|
||||
file_measure_wraps(system, models, file, font);
|
||||
file_update_cursor_positions(system, models, file);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -1965,6 +1999,7 @@ file_set_min_base_width(System_Functions *system, Models *models, Editing_File *
|
|||
|
||||
internal void
|
||||
file_create_from_string(System_Functions *system, Models *models, Editing_File *file, String val, b8 read_only = 0){
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
General_Memory *general = &models->mem.general;
|
||||
Partition *part = &models->mem.part;
|
||||
|
@ -1997,12 +2032,15 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
|
|||
file->settings.font_id = font_id;
|
||||
Render_Font *font = system->font.get_render_data_by_id(font_id);
|
||||
|
||||
file_measure_starts(general, &file->state.buffer);
|
||||
|
||||
file_allocate_character_starts_as_needed(general, file);
|
||||
buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
|
||||
|
||||
file_measure_wraps(system, models, file, font);
|
||||
{
|
||||
PRFL_SCOPE_GROUP(measurements);
|
||||
file_measure_starts(general, &file->state.buffer);
|
||||
|
||||
file_allocate_character_starts_as_needed(general, file);
|
||||
buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
|
||||
|
||||
file_measure_wraps(system, models, file, font);
|
||||
}
|
||||
|
||||
file->settings.read_only = read_only;
|
||||
if (!read_only){
|
||||
|
@ -2034,7 +2072,13 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
|
|||
}
|
||||
|
||||
if (hook_open_file){
|
||||
PRFL_SCOPE_GROUP(open_hook);
|
||||
file->state.hacks.suppression_mode = true;
|
||||
hook_open_file(app_links, file->id.id);
|
||||
file->state.hacks.suppression_mode = false;
|
||||
if (file->state.hacks.needs_wraps_and_fix_cursor){
|
||||
file_measure_wraps_and_fix_cursor(system, models, file, font);
|
||||
}
|
||||
}
|
||||
file->settings.is_initialized = true;
|
||||
}
|
||||
|
@ -3218,9 +3262,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil
|
|||
scroll.scroll_y = y_position;
|
||||
}
|
||||
|
||||
view_set_cursor_and_scroll(view, new_cursor,
|
||||
1, view->file_data.file->settings.unwrapped_lines,
|
||||
scroll);
|
||||
view_set_cursor_and_scroll(view, new_cursor, 1, view->file_data.file->settings.unwrapped_lines, scroll);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3319,8 +3361,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file
|
|||
}
|
||||
|
||||
internal void
|
||||
file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
|
||||
Edit_Spec spec, History_Mode history_mode, i32 batch_type){
|
||||
file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode, i32 batch_type){
|
||||
|
||||
Mem_Options *mem = &models->mem;
|
||||
General_Memory *general = &mem->general;
|
||||
|
@ -3771,6 +3812,8 @@ make_string_terminated(Partition *part, char *str, i32 len){
|
|||
|
||||
internal void
|
||||
init_normal_file(System_Functions *system, Models *models, Editing_File *file, char *buffer, i32 size){
|
||||
PRFL_FUNC_GROUP();
|
||||
|
||||
String val = make_string(buffer, size);
|
||||
file_create_from_string(system, models, file, val);
|
||||
|
||||
|
|
|
@ -45,6 +45,14 @@ struct Render_Font{
|
|||
u32 name_len;
|
||||
char filename[256];
|
||||
char name[256];
|
||||
|
||||
// Hack optimizations
|
||||
struct Page_Cache{
|
||||
u32 page_number;
|
||||
Glyph_Page *page;
|
||||
};
|
||||
|
||||
Page_Cache cache[16];
|
||||
};
|
||||
|
||||
struct Glyph_Data{
|
||||
|
|
|
@ -79,7 +79,21 @@ font_get_glyph_advance(System_Functions *system, Render_Font *font, u32 codepoin
|
|||
f32 result = 0.f;
|
||||
u32 page_number = (codepoint >> 8);
|
||||
u32 glyph_index = codepoint & 0xFF;
|
||||
Glyph_Page *page = font_get_or_make_page(system, font, page_number);
|
||||
|
||||
Glyph_Page *page = 0;
|
||||
|
||||
// Hack optimizations
|
||||
u32 cache_index = page_number % ArrayCount(font->cache);
|
||||
if (font->cache[cache_index].page_number == page_number){
|
||||
page = font->cache[cache_index].page;
|
||||
}
|
||||
|
||||
if (page == 0){
|
||||
page = font_get_or_make_page(system, font, page_number);
|
||||
font->cache[cache_index].page = page;
|
||||
font->cache[cache_index].page_number = page_number;
|
||||
}
|
||||
|
||||
if (page != 0 && page->advance[glyph_index] > 0.f){
|
||||
result = page->advance[glyph_index];
|
||||
}
|
||||
|
@ -91,7 +105,21 @@ font_get_glyph(System_Functions *system, Render_Font *font, u32 codepoint){
|
|||
Glyph_Data result = {0};
|
||||
u32 page_number = (codepoint >> 8);
|
||||
u32 glyph_index = codepoint & 0xFF;
|
||||
Glyph_Page *page = font_get_or_make_page(system, font, page_number);
|
||||
|
||||
Glyph_Page *page = 0;
|
||||
|
||||
// Hack optimizations
|
||||
u32 cache_index = page_number % ArrayCount(font->cache);
|
||||
if (font->cache[cache_index].page_number == page_number){
|
||||
page = font->cache[cache_index].page;
|
||||
}
|
||||
|
||||
if (page == 0){
|
||||
page = font_get_or_make_page(system, font, page_number);
|
||||
font->cache[cache_index].page = page;
|
||||
font->cache[cache_index].page_number = page_number;
|
||||
}
|
||||
|
||||
if (page != 0 && page->advance[glyph_index] > 0.f){
|
||||
result.bounds = page->glyphs[glyph_index];
|
||||
result.tex = page->tex;
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 29.03.2017
|
||||
*
|
||||
* Really basic profiling primitives. (not meant to stay for long)
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#define FRED_INTERNAL 1
|
||||
|
||||
#include "4tech_defines.h"
|
||||
#include "4ed_profile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
global f32 frame_target = 58000000.f;
|
||||
|
||||
internal void
|
||||
usage(){
|
||||
fprintf(stderr, "No! Like this, you moron:\n"
|
||||
"\t<PROFILE-EXE> <PROFILE-DATA> [min-time-filter]\n");
|
||||
}
|
||||
|
||||
internal u32
|
||||
parse_frame_count(u8 *ptr, u8 *end){
|
||||
u32 count = 0;
|
||||
|
||||
for (;ptr < end;){
|
||||
u8 *frame_base = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
u8 *frame_end = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
umem skip_size = frame_end - frame_base;
|
||||
ptr += skip_size;
|
||||
++count;
|
||||
}
|
||||
|
||||
if (ptr != end){
|
||||
count = 0;
|
||||
}
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
struct Parse_Frame_Result{
|
||||
u8 *next_read_ptr;
|
||||
u8 *output_chunk;
|
||||
b32 still_looping;
|
||||
b32 bad_parse;
|
||||
f32 frame_time;
|
||||
};
|
||||
|
||||
internal Parse_Frame_Result
|
||||
parse_frame(u8 *ptr, u8 *end_ptr){
|
||||
Parse_Frame_Result result = {0};
|
||||
|
||||
u8 *frame_base = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
u8 *frame_end = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
umem frame_size = frame_end - frame_base;
|
||||
u8 *frame_start_ptr = ptr;
|
||||
u8 *frame_end_ptr = ptr + frame_size;
|
||||
|
||||
u8 *out_chunk = (u8*)malloc(frame_size*2);
|
||||
u8 *out_ptr = out_chunk;
|
||||
|
||||
Profile_Group *group = (Profile_Group*)frame_start_ptr;
|
||||
Profile_Group *group_end = (Profile_Group*)frame_end_ptr;
|
||||
|
||||
Profile_Group *stack[64];
|
||||
u32 top = 0;
|
||||
|
||||
stack[top++] = group;
|
||||
|
||||
result.frame_time = group->cycle_count / frame_target;
|
||||
|
||||
for (;group < group_end;){
|
||||
for (u32 i = 1; i < top; ++i){
|
||||
*out_ptr++ = ' ';
|
||||
}
|
||||
|
||||
char *name = group->name;
|
||||
for (u32 i = 0; name[i]; ++i){
|
||||
*out_ptr++ = name[i];
|
||||
}
|
||||
|
||||
*out_ptr++ = ':';
|
||||
*out_ptr++ = ' ';
|
||||
|
||||
char str[64];
|
||||
sprintf(str, "%f", group->cycle_count / frame_target);
|
||||
for (u32 i = 0; str[i]; ++i){
|
||||
*out_ptr++ = str[i];
|
||||
}
|
||||
*out_ptr++ = '\n';
|
||||
|
||||
++group;
|
||||
|
||||
for(;top > 0;){
|
||||
Profile_Group *group_top = stack[top-1];
|
||||
umem end_offset = (u8*)group_top->end - frame_base;
|
||||
u8 *this_group_end_ptr = frame_start_ptr + end_offset;
|
||||
Profile_Group *this_group_end = (Profile_Group*)this_group_end_ptr;
|
||||
|
||||
if (group == this_group_end){
|
||||
--top;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stack[top++] = group;
|
||||
}
|
||||
|
||||
if (top != 1){
|
||||
result.bad_parse = true;
|
||||
}
|
||||
else{
|
||||
*out_ptr++ = 0;
|
||||
result.next_read_ptr = frame_end_ptr;
|
||||
result.output_chunk = out_chunk;
|
||||
if (frame_end_ptr != end_ptr){
|
||||
result.still_looping = true;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
print_profile(char *filename, f32 min_filter){
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (!file){
|
||||
fprintf(stderr, "There ain't no file sittin' around called %s.\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
u32 size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
u8 *buffer = (u8*)malloc(size);
|
||||
|
||||
fread(buffer, 1, size, file);
|
||||
fclose(file);
|
||||
|
||||
u8 *read_ptr = buffer;
|
||||
u8 *end_ptr = buffer + size;
|
||||
|
||||
// Frame Count Parse
|
||||
u32 frame_count = parse_frame_count(read_ptr, end_ptr);
|
||||
|
||||
if (frame_count == 0){
|
||||
fprintf(stderr, "There's some fricken problem. I didn't get a good frame count!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Full Parse
|
||||
u8 **output_chunks = (u8**)malloc(frame_count*sizeof(u8*));
|
||||
u32 chunk_i = 0;
|
||||
|
||||
Parse_Frame_Result result = {0};
|
||||
do{
|
||||
if (chunk_i >= frame_count){
|
||||
fprintf(stderr, "The parse ain't lined up! You're fired!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
result = parse_frame(read_ptr, end_ptr);
|
||||
|
||||
if (result.bad_parse){
|
||||
fprintf(stderr, "You've pickled the data nimwit!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
read_ptr = result.next_read_ptr;
|
||||
if (result.frame_time >= min_filter){
|
||||
output_chunks[chunk_i++] = result.output_chunk;
|
||||
}
|
||||
}while(result.still_looping);
|
||||
|
||||
// Print
|
||||
fprintf(stdout, "Frames: %u (%u)\n", chunk_i, frame_count);
|
||||
for (u32 i = 0; i < chunk_i; ++i){
|
||||
fprintf(stdout, "%s", output_chunks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
if (argc < 2){
|
||||
usage();
|
||||
}
|
||||
else{
|
||||
f32 min_filter = 0.f;
|
||||
if (argc == 3){
|
||||
min_filter = (f32)atof(argv[2]);
|
||||
}
|
||||
|
||||
print_profile(argv[1], min_filter);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 29.03.2017
|
||||
*
|
||||
* Really basic profiling primitives. (not meant to stay for long)
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FRED_PROFILE_H)
|
||||
#define FRED_PROFILE_H
|
||||
|
||||
#if FRED_INTERNAL
|
||||
|
||||
#include <intrin.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct Profile_Group{
|
||||
char name[104];
|
||||
u64 cycle_start;
|
||||
u64 cycle_count;
|
||||
void *end;
|
||||
};
|
||||
|
||||
struct Profile{
|
||||
u8 *buffer;
|
||||
u32 pos, max;
|
||||
|
||||
Profile_Group *stack[64];
|
||||
u32 stack_top;
|
||||
};
|
||||
global Profile global_profile = {0};
|
||||
|
||||
internal Profile_Group*
|
||||
push_group(char *name){
|
||||
Profile_Group *result = 0;
|
||||
if (global_profile.pos + sizeof(Profile_Group) <= global_profile.max){
|
||||
result = (Profile_Group*)(global_profile.buffer + global_profile.pos);
|
||||
global_profile.pos += sizeof(Profile_Group);
|
||||
u32 i = 0;
|
||||
for (; name[i] && i < sizeof(result->name)-1; ++i){
|
||||
result->name[i] = name[i];
|
||||
}
|
||||
result->name[i] = 0;
|
||||
result->cycle_start = __rdtsc();
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_init(void *mem, u32 max){
|
||||
global_profile.buffer = (u8*)mem;
|
||||
global_profile.max = max;
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_begin_group(char *name){
|
||||
u32 stack_pos = global_profile.stack_top;
|
||||
if (stack_pos < ArrayCount(global_profile.stack)){
|
||||
global_profile.stack[stack_pos] = push_group(name);
|
||||
Assert(global_profile.stack[stack_pos] != 0);
|
||||
++global_profile.stack_top;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_end_group(){
|
||||
Assert(global_profile.stack_top > 0);
|
||||
u32 stack_pos = --global_profile.stack_top;
|
||||
if (stack_pos < ArrayCount(global_profile.stack)){
|
||||
Profile_Group *group = global_profile.stack[stack_pos];
|
||||
Assert(group != 0);
|
||||
group->cycle_count = __rdtsc() - group->cycle_start;
|
||||
group->end = global_profile.buffer + global_profile.pos;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_begin_frame(){
|
||||
global_profile.pos = 0;
|
||||
global_profile.stack_top = 0;
|
||||
profile_begin_group("*frame*");
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_end_frame(char *filename){
|
||||
profile_end_group();
|
||||
Assert(global_profile.stack_top == 0);
|
||||
|
||||
FILE *file = fopen(filename, "ab");
|
||||
Assert(file != 0);
|
||||
fwrite(&global_profile.buffer, 8, 1, file);
|
||||
|
||||
Profile_Group *first_group = (Profile_Group*)global_profile.buffer;
|
||||
fwrite(&first_group->end, 8, 1, file);
|
||||
|
||||
fwrite(global_profile.buffer, 1, global_profile.pos, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
internal Profile_Group*
|
||||
profile_begin_resumable(char *name){
|
||||
Profile_Group *result = push_group(name);
|
||||
Assert(result != 0);
|
||||
result->cycle_count = 0;
|
||||
result->end = result + 1;
|
||||
return(result);
|
||||
}
|
||||
|
||||
struct profile_scope{
|
||||
profile_scope(char *name){
|
||||
profile_begin_group(name);
|
||||
}
|
||||
|
||||
~profile_scope(){
|
||||
profile_end_group();
|
||||
}
|
||||
};
|
||||
|
||||
#define PRFL_INIT(m,s) profile_init(m,s)
|
||||
|
||||
#define PRFL_BEGIN_FRAME() profile_begin_frame()
|
||||
#define PRFL_END_FRAME(n) profile_end_frame(n)
|
||||
|
||||
#define PRFL_BEGIN_GROUP(n) profile_begin_group(#n)
|
||||
#define PRFL_END_GROUP() profile_end_group()
|
||||
#define PRFL_SCOPE_GROUP(n) profile_scope SCOPE_##n(#n)
|
||||
|
||||
#define PRFL_FUNC_GROUP() profile_scope SCOPE_FUNC(__FUNCTION__)
|
||||
|
||||
#define PRFL_BEGIN_RESUMABLE(n) Profile_Group *PRFLGRP_##n = profile_begin_resumable(#n)
|
||||
#define PRFL_START_RESUMABLE(n) PRFLGRP_##n->cycle_start = __rdtsc()
|
||||
#define PRFL_STOP_RESUMABLE(n) PRFLGRP_##n->cycle_count += __rdtsc() - PRFLGRP_##n->cycle_start
|
||||
#define PRFL_END_RESUMABLE(n)
|
||||
|
||||
#else
|
||||
|
||||
#define PRFL_INIT(m,s)
|
||||
|
||||
#define PRFL_BEGIN_FRAME()
|
||||
#define PRFL_END_FRAME(n)
|
||||
|
||||
#define PRFL_BEGIN_GROUP(n)
|
||||
#define PRFL_END_GROUP()
|
||||
#define PRFL_SCOPE_GROUP(n)
|
||||
|
||||
#define PRFL_FUNC_GROUP()
|
||||
|
||||
#define PRFL_BEGIN_RESUMABLE(n)
|
||||
#define PRFL_START_RESUMABLE(n)
|
||||
#define PRFL_STOP_RESUMABLE(n)
|
||||
#define PRFL_END_RESUMABLE(n)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
@ -629,7 +629,6 @@ package(char *cdir){
|
|||
copy_file(build_dir, "4ed" EXE, dir, 0, 0);
|
||||
copy_file(build_dir, "4ed_app" DLL, dir, 0, 0);
|
||||
copy_all (pack_data_dir, "*", dir);
|
||||
//copy_file(0, "TODO.txt", dir, 0, 0);
|
||||
copy_file(data_dir, "release-config.4coder", dir, 0, "config.4coder");
|
||||
|
||||
get_4coder_dist_name(&str, true, zip_dir, tier, arch, "zip");
|
||||
|
|
|
@ -6,6 +6,7 @@ fkey_command_win[2] = {"site\\build.bat", "*compilation*", true , true };
|
|||
fkey_command_win[3] = {"string\\build.bat", "*compilation*", true , true };
|
||||
fkey_command_win[4] = {"echo build: x86 & build.bat /DDEV_BUILD_X86", "*compilation*", true , true };
|
||||
fkey_command_win[5] = {"..\\misc\\run.bat", "*run*", false, false };
|
||||
fkey_command_win[6] = {"run_profile.bat", "*profile*", false, true };
|
||||
fkey_command_win[12] = {"package.bat", "*package*", false, true };
|
||||
|
||||
fkey_command_linux[1] = {"echo build: x64 & ./build.sh", "*compilation*", true , true };
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
@echo off
|
||||
|
||||
SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX
|
||||
SET OPTS=%OPTS% /GR- /EHa- /nologo /FC
|
||||
|
||||
pushd ..\build
|
||||
cl %OPTS% ..\code\4ed_profile.cpp /Zi /Feprofile
|
||||
popd
|
||||
|
||||
pushd ..\data\test
|
||||
..\..\build\profile profile.data 0.4
|
||||
popd
|
|
@ -2032,9 +2032,11 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
memory_vars.target_memory_size = MB(512);
|
||||
memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
base = (LPVOID)0;
|
||||
memory_vars.user_memory_size = MB(2);
|
||||
memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
memory_vars.user_memory = system_memory_allocate(memory_vars.user_memory_size);
|
||||
|
||||
memory_vars.debug_memory_size = MB(512);
|
||||
memory_vars.debug_memory = system_memory_allocate(memory_vars.debug_memory_size);
|
||||
|
||||
win32vars.target.max = MB(1);
|
||||
win32vars.target.push_buffer = (char*)system_memory_allocate(win32vars.target.max);
|
||||
|
|
Loading…
Reference in New Issue