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
This commit is contained in:
parent
201ac2d401
commit
316d4952fa
1
Makefile
1
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;\
|
||||
|
148
gui.c
148
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;h<height/4;h++){
|
||||
for(int w=0;w<width/2;w++){
|
||||
uint8_t select=0;
|
||||
@ -624,6 +632,9 @@ int print_braille_frame_buffer(WINDOW* win,uint8_t *buffer,int width,int height)
|
||||
select|=0x20;
|
||||
if(buffer[w*2+1 +width*(h*4+3 )])
|
||||
select|=0x80;
|
||||
if(fullscreen)
|
||||
mvwprintw(win,h,w,"%lc",braille_lookup[select]);
|
||||
else
|
||||
mvwprintw(win,h+1,w+1,"%lc",braille_lookup[select]);
|
||||
}
|
||||
}
|
||||
@ -648,24 +659,31 @@ void braille_frame_buffer_line(uint8_t *buffer,int buffer_width,int buffer_heigh
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int update_general_terminal_output(struct simdata_t *simdata){
|
||||
int update_terminal_output(WINDOW *win, struct simdata_t *simdata,uint8_t fullscreen){
|
||||
int width,height;
|
||||
werase(general_terminal_output);
|
||||
getmaxyx(general_terminal_output,height,width);
|
||||
werase(win);
|
||||
getmaxyx(win,height,width);
|
||||
|
||||
term_curs_x=0;
|
||||
term_curs_y=0;
|
||||
uint8_t* vector_working_frame_buffer=malloc((height*4)*(width*2));
|
||||
uint8_t* vector_display_frame_buffer=malloc((height*4)*(width*2));
|
||||
memset(vector_working_frame_buffer,0,(height*4)*(width*2));
|
||||
memset(vector_display_frame_buffer,0,(height*4)*(width*2));
|
||||
|
||||
int vector=0;
|
||||
int vstate=0;
|
||||
|
||||
int vfb_width=(width-2)*2;
|
||||
int vfb_height=(height-2)*4;
|
||||
int vfb_width, vfb_height;
|
||||
if(fullscreen){
|
||||
vfb_width=(width)*2;
|
||||
vfb_height=(height)*4;
|
||||
}else{
|
||||
vfb_width=(width-2)*2;
|
||||
vfb_height=(height-2)*4;
|
||||
}
|
||||
|
||||
uint8_t* vector_working_frame_buffer=malloc(vfb_height*vfb_width);
|
||||
uint8_t* vector_display_frame_buffer=malloc(vfb_height*vfb_width);
|
||||
memset(vector_working_frame_buffer,0,vfb_height*vfb_width);
|
||||
memset(vector_display_frame_buffer,0,vfb_height*vfb_width);
|
||||
|
||||
float x0,y0,x1,y1;
|
||||
for(uint64_t i=0;i < simdata->terminal_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<width;i++){
|
||||
mvwprintw(general_terminal_output,term_curs_y+1,i," ");
|
||||
mvwprintw(win,term_curs_y+1,i," ");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@ -730,37 +748,49 @@ int update_general_terminal_output(struct simdata_t *simdata){
|
||||
case 0x0a:
|
||||
term_curs_x=0;
|
||||
term_curs_y++;
|
||||
if(term_curs_y>=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(!fullscreen){
|
||||
box(win, 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 ]");
|
||||
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(general_terminal_output,vector_display_frame_buffer,(width-2)*2,(height-2)*4);
|
||||
mvwprintw(general_terminal_output,0,width/2-9,"[ VECTOR DISPLAY ]");
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -901,17 +952,22 @@ int gui_continue_request(struct simdata_t *simdata){
|
||||
int inch;
|
||||
int release=0;
|
||||
while(release==0){
|
||||
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;
|
||||
if(CURRENT_TAB!=5)
|
||||
update_gui(simdata);
|
||||
nodelay(stdscr, FALSE);
|
||||
}else{
|
||||
@ -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<disps_found){
|
||||
highest_disps=disps_found;
|
||||
if(CURRENT_TAB==5)
|
||||
force_disp_terminal_output_update(simdata);
|
||||
}
|
||||
if(disps_found>=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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user