From 316d4952fa24a8a612323aa2e0c5ddf3541811bc Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Mon, 26 Feb 2024 22:11:30 +0000 Subject: [PATCH] GUI: Added a new Display tab that only updates when the cpu finished producing a new frame and made massive performance improvements with the help of the new profiler --- Makefile | 1 + gui.c | 172 +++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 125 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 3abe627..26dcf23 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,7 @@ callgrind.out:first ${MAIN_ROM} ${QUIET_VALGRIND} ${Q}if ldd first |grep asan > /dev/null;\ then\ + rm -f "$@";\ echo ERROR: Binary build with libasan, please rebuild without address sanitiser;\ else\ valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes --callgrind-out-file=callgrind.out ./first -i programs/3d_renderer.rom;\ diff --git a/gui.c b/gui.c index 4ff163f..e307511 100644 --- a/gui.c +++ b/gui.c @@ -49,6 +49,8 @@ WINDOW *pipeline_disas; WINDOW *debug_simdata; +WINDOW *display_terminal_output; + int monochrome; int get_terminal_size(){ @@ -61,7 +63,7 @@ int get_terminal_size(){ } -char *tab_name[]={"Overview","Memory","Pipeline","Debug"}; +char *tab_name[]={"Overview","Memory","Pipeline","Debug","Display"}; unsigned int CURRENT_TAB=1; @@ -92,12 +94,16 @@ int gui_ncurses_refresh(){ }else if(CURRENT_TAB==4){ if(wrefresh(debug_simdata)==ERR) return 1; + }else if(CURRENT_TAB==5){ + if(wrefresh(display_terminal_output)==ERR) + return 1; } return 0; } enum GUI_CPU_STATE_t GUI_CPU_STATE=GUI_CPU_SINGLE_STEPPING; + void update_tabs(){ wattron(tabs,A_BOLD); wattron(tabs,COLOR_PAIR(2)); @@ -225,6 +231,8 @@ int start_gui(){ pipeline_pipeline=newwin(terminal_height-1-border*2,terminal_width-border*3-GENERAL_DISAS_WIDTH,1+border,border); pipeline_disas=newwin(terminal_height-1-border*2,GENERAL_DISAS_WIDTH,1+border,border+terminal_width-border*3-GENERAL_DISAS_WIDTH); + display_terminal_output=newwin(terminal_height-1,terminal_width,1,0); + gui_settings=malloc(sizeof(struct gui_settings_t)); gui_settings->cycles_per_frame=100; @@ -604,7 +612,7 @@ L'⢀',L'⢁',L'⢂',L'⢃',L'⢄',L'⢅',L'⢆',L'⢇',L'⢈',L'⢉',L'⢊',L' L'⣀',L'⣁',L'⣂',L'⣃',L'⣄',L'⣅',L'⣆',L'⣇',L'⣈',L'⣉',L'⣊',L'⣋',L'⣌',L'⣍',L'⣎',L'⣏',L'⣐',L'⣑',L'⣒',L'⣓',L'⣔',L'⣕',L'⣖',L'⣗',L'⣘',L'⣙',L'⣚',L'⣛',L'⣜',L'⣝',L'⣞',L'⣟',L'⣠',L'⣡',L'⣢',L'⣣',L'⣤',L'⣥',L'⣦',L'⣧',L'⣨',L'⣩',L'⣪',L'⣫',L'⣬',L'⣭',L'⣮',L'⣯',L'⣰',L'⣱',L'⣲',L'⣳',L'⣴',L'⣵',L'⣶',L'⣷',L'⣸',L'⣹',L'⣺',L'⣻',L'⣼',L'⣽',L'⣾',L'⣿', }; -int print_braille_frame_buffer(WINDOW* win,uint8_t *buffer,int width,int height){ +int print_braille_frame_buffer(WINDOW* win,uint8_t *buffer,int width,int height,int fullscreen){ for(int h=0;hterminal_output_size/4;i++){ uint32_t c=simdata->terminal_output[i]; @@ -675,9 +693,9 @@ int update_general_terminal_output(struct simdata_t *simdata){ if(c==0x00000001) vector=0; else if(c==0x00000002) - memset(vector_working_frame_buffer,0,(height*4)*(width*2)); + memset(vector_working_frame_buffer,0,vfb_height*vfb_width); else if(c==0x00000003) - memcpy(vector_display_frame_buffer,vector_working_frame_buffer,(height*4)*(width*2)); + memcpy(vector_display_frame_buffer,vector_working_frame_buffer,vfb_height*vfb_width); else vstate++; break; @@ -709,17 +727,17 @@ int update_general_terminal_output(struct simdata_t *simdata){ } }else{ if(c>=' '&&c<='~'){ - mvwprintw(general_terminal_output,term_curs_y+1,term_curs_x+1,"%c",c); + mvwprintw(win,term_curs_y+1,term_curs_x+1,"%c",c); term_curs_x++; - if(term_curs_x>=width-2){ + if(term_curs_x>=width){ term_curs_x=0; term_curs_y++; } - if(term_curs_y>=height-2){ - wscrl(general_terminal_output,1); + if(term_curs_y>=height){ + wscrl(win,1); term_curs_y--; for(int i=0;i=height-2){ - wscrl(general_terminal_output,1); + if(term_curs_y>=vfb_height){ + wscrl(win,1); term_curs_y--; - box(general_terminal_output, 0 , 0); - mvwprintw(general_terminal_output,0,width/2-7,"[ TERM OUTPUT ]"); + box(win, 0 , 0); + mvwprintw(win,0,width/2-7,"[ TERM OUTPUT ]"); } break; default: - werase(general_terminal_output); - box(general_terminal_output, 0 , 0); - mvwprintw(general_terminal_output,0,width/2-7,"[ TERM OUTPUT ]"); - mvwprintw(general_terminal_output,1,1,"Invalid output"); + werase(win); + box(win, 0 , 0); + mvwprintw(win,0,width/2-7,"[ TERM OUTPUT ]"); + mvwprintw(win,1,1,"Invalid output"); return 0; } } } } - box(general_terminal_output, 0 , 0); - if(!vector){ - mvwchgat(general_terminal_output,term_curs_y+1,term_curs_x+1, 1, A_REVERSE, 0, NULL); - mvwprintw(general_terminal_output,0,width/2-7,"[ TERM OUTPUT ]"); - }else{ - print_braille_frame_buffer(general_terminal_output,vector_display_frame_buffer,(width-2)*2,(height-2)*4); - mvwprintw(general_terminal_output,0,width/2-9,"[ VECTOR DISPLAY ]"); - } + if(!fullscreen){ + box(win, 0 , 0); + if(!vector){ + mvwchgat(win,term_curs_y+1,term_curs_x+1, 1, A_REVERSE, 0, NULL); + mvwprintw(win,0,width/2-7,"[ TERM OUTPUT ]"); + }else{ + print_braille_frame_buffer(win,vector_display_frame_buffer,vfb_width,vfb_height,0); + mvwprintw(win,0,width/2-9,"[ VECTOR DISPLAY ]"); + } + }else + if(vector) + print_braille_frame_buffer(win,vector_display_frame_buffer,vfb_width,vfb_height,1); free(vector_working_frame_buffer); free(vector_display_frame_buffer); return 0; } +int update_general_terminal_output(WINDOW *win, struct simdata_t *simdata){ + return update_terminal_output(win,simdata,0); +} + +int update_display_terminal_output(WINDOW *win, struct simdata_t *simdata){ + return update_terminal_output(win,simdata,1); +} + int update_debug_simdata(struct simdata_t *simdata){ int width,height; werase(debug_simdata); @@ -856,18 +886,34 @@ int update_pipeline(WINDOW *win,struct simdata_t *simdata){ return 0; } +int force_disp_terminal_output_update(struct simdata_t *simdata){ + if(update_display_terminal_output(display_terminal_output,simdata)) + return 1; + if(gui_ncurses_refresh()) + return 1; +if(simdata) + return 0; +else return 0; +} int clear_back_window=1; +int write_tabs=1; int update_gui(struct simdata_t *simdata){ - if(simdata->cpu_state==CPU_HALTED) + if(simdata->cpu_state==CPU_HALTED){ GUI_CPU_STATE=GUI_CPU_STOPPED; + if(CURRENT_TAB==5) + force_disp_terminal_output_update(simdata); + } if(clear_back_window){ clear(); clear_back_window=0; } - if((simdata->current_clock)%(gui_settings->cycles_per_frame)==0 || GUI_CPU_STATE!=GUI_CPU_RUNNING ){ + if(write_tabs){ update_tabs(); + write_tabs=0; + } + if((simdata->current_clock)%(gui_settings->cycles_per_frame)==0 || GUI_CPU_STATE!=GUI_CPU_RUNNING ){ if(CURRENT_TAB==1){ if(update_general_memdump(simdata)) return 1; @@ -877,7 +923,7 @@ int update_gui(struct simdata_t *simdata){ return 1; if(update_general_registers(simdata)) return 1; - if(update_general_terminal_output(simdata)) + if(update_general_terminal_output(general_terminal_output,simdata)) return 1; }else if(CURRENT_TAB==2){ if(update_memory_memdump(simdata)) @@ -890,10 +936,15 @@ int update_gui(struct simdata_t *simdata){ }else if(CURRENT_TAB==4){ if(update_debug_simdata(simdata)) return 1; + }else if(CURRENT_TAB==5){ + if(GUI_CPU_STATE!=GUI_CPU_RUNNING) + force_disp_terminal_output_update(simdata); } + + if(CURRENT_TAB!=5) + if(gui_ncurses_refresh()) + return 1; } - if(gui_ncurses_refresh()) - return 1; return 0; } @@ -901,18 +952,23 @@ int gui_continue_request(struct simdata_t *simdata){ int inch; int release=0; while(release==0){ - if(((inch=getch())==ERR)){ - if(GUI_CPU_STATE==GUI_CPU_SINGLE_STEPPING) - return 1; - else - release=1; - } + inch=ERR; + if(((simdata->current_clock)%(gui_settings->cycles_per_frame))==0 || GUI_CPU_STATE!=GUI_CPU_RUNNING ){ + if(((inch=getch())==ERR)){ + if(GUI_CPU_STATE==GUI_CPU_SINGLE_STEPPING) + return 1; + else + release=1; + } + }else + release=1; switch(inch){ case 'r': if(simdata->cpu_state!=CPU_HALTED){ if(GUI_CPU_STATE==GUI_CPU_RUNNING){ GUI_CPU_STATE=GUI_CPU_SINGLE_STEPPING; - update_gui(simdata); + if(CURRENT_TAB!=5) + update_gui(simdata); nodelay(stdscr, FALSE); }else{ GUI_CPU_STATE=GUI_CPU_RUNNING; @@ -929,6 +985,7 @@ int gui_continue_request(struct simdata_t *simdata){ if(CURRENT_TAB!=1){ CURRENT_TAB=1; clear(); + update_tabs(); update_gui(simdata); } break; @@ -936,6 +993,7 @@ int gui_continue_request(struct simdata_t *simdata){ if(CURRENT_TAB!=2){ CURRENT_TAB=2; clear(); + update_tabs(); update_gui(simdata); } break; @@ -943,6 +1001,7 @@ int gui_continue_request(struct simdata_t *simdata){ if(CURRENT_TAB!=3){ CURRENT_TAB=3; clear(); + update_tabs(); update_gui(simdata); } break; @@ -950,9 +1009,18 @@ int gui_continue_request(struct simdata_t *simdata){ if(CURRENT_TAB!=4){ CURRENT_TAB=4; clear(); + update_tabs(); update_gui(simdata); } break; + case '5': + if(CURRENT_TAB!=5){ + CURRENT_TAB=5; + clear(); + update_tabs(); + force_disp_terminal_output_update(simdata); + } + break; case 'j': if(CURRENT_TAB==2){ memory_window_address++; @@ -976,6 +1044,7 @@ int gui_continue_request(struct simdata_t *simdata){ return 0; } +uint32_t highest_disps=0;//XXX: remember that if we create a clear screen command it should zero this out too int clean_cpu_output(struct simdata_t *simdata){ uint32_t last_vect_disp=0; uint32_t second_last_vect_disp=simdata->terminal_output_size/4;//TODO: I shouldn't have to initialise this. GCC gives a warning erroneously @@ -1015,12 +1084,19 @@ int clean_cpu_output(struct simdata_t *simdata){ } } } + if(highest_disps=2){ int final_data_size=simdata->terminal_output_size-(second_last_vect_disp+4); memmove((uint8_t*)simdata->terminal_output+4,(uint8_t*)simdata->terminal_output+simdata->terminal_output_size-final_data_size,final_data_size); simdata->terminal_output[0]=0xFFFFFFFF; simdata->terminal_output=realloc(simdata->terminal_output,final_data_size+4); simdata->terminal_output_size=final_data_size+4; + if(CURRENT_TAB==5) + force_disp_terminal_output_update(simdata); } return 0; }