/** * By Billy Biggs on 20 Oct 01. * * Calculations for how bad we are with refresh rate sync * given a specific value of HZ. * * This source code is released in the public domain. */ #include #include #include /* Rates in hz */ static const double refresh_rate = 85.0; static const double display_rate = 24.0; /* Time in seconds */ static const double calculation_time = 5.0; /* Strategy */ #define STRATEGY_EXACT 0 #define STRATEGY_NEAREST_HZ 1 #define STRATEGY_NEXT_HZ 2 #define STRATEGY_PREV_HZ 3 static const int strategy = STRATEGY_EXACT; /* HZ value (shortest scheduler wait time in ms) */ static const double hz = 10.0; /* Struct to hold our stuff */ typedef struct timemark_s { double time; int type; } timemark_t; #define MARK_REFRESH 0 #define MARK_BLIT 1 static int compare_timemark( const void *time1, const void *time2 ) { return (int) ( 1000.0 * ( ((timemark_t *) time1)->time - ((timemark_t *) time2)->time ) ); } int main( int argc, char **argv ) { timemark_t *marks; double refreshtime, outputtime, curtime; int numrefreshes, numframes; int avgsum, stretchcount, numstretches, flag, min, max; int curmark = 0; int i; refreshtime = ( 1.0 / refresh_rate ) * 1000; outputtime = ( 1.0 / display_rate ) * 1000; numrefreshes = (int) ( ( calculation_time * refresh_rate ) + 5.5 ); numframes = (int) ( ( calculation_time * display_rate ) + 1.5 ); marks = (timemark_t *) malloc( ( numrefreshes + numframes + 1 ) * sizeof( timemark_t ) ); fprintf( stdout, "Refresh rate %5.2fhz.\n", refresh_rate ); fprintf( stdout, "Output display rate %5.2fhz.\n", display_rate ); fprintf( stdout, "Calculations over %5.2fs\n", calculation_time ); fprintf( stdout, "HZ value %5.2fms\n", hz ); fprintf( stdout, "Strategy " ); if( strategy == STRATEGY_EXACT ) fprintf( stdout, "Blit at correct time.\n\n" ); if( strategy == STRATEGY_NEAREST_HZ ) fprintf( stdout, "Round blit time to nearest HZ.\n\n" ); if( strategy == STRATEGY_NEXT_HZ ) fprintf( stdout, "Round blit time to next HZ (round up).\n\n" ); if( strategy == STRATEGY_PREV_HZ ) fprintf( stdout, "Round blit time to prev HZ (round down).\n\n" ); /* Calculate refresh times. */ curtime = 0.0; for( i = 0; i < numrefreshes; i++ ) { marks[ curmark ].time = curtime; marks[ curmark ].type = MARK_REFRESH; curtime += refreshtime; curmark++; } /* Calculate times. */ curtime = 5.0; for( i = 0; i < numframes; i++ ) { double going_up = ( hz - drem( curtime, hz ) ); double going_down = drem( curtime, hz ); double next_time = curtime + going_up; double prev_time = curtime - going_down; double nearest_time = ( going_up > going_down ) ? prev_time : next_time; if( strategy == STRATEGY_EXACT ) { marks[ curmark ].time = curtime; } else if( strategy == STRATEGY_NEAREST_HZ ) { marks[ curmark ].time = nearest_time; } else if( strategy == STRATEGY_NEXT_HZ ) { marks[ curmark ].time = next_time; } else if( strategy == STRATEGY_PREV_HZ ) { marks[ curmark ].time = prev_time; } marks[ curmark ].time = curtime; marks[ curmark ].type = MARK_BLIT; curtime += outputtime; curmark++; } /* Sort the array. */ qsort( marks, curmark, sizeof( timemark_t ), compare_timemark ); /* Print the array. */ fprintf( stdout, "Results:\n" ); avgsum = 0; stretchcount = 0; numstretches = 0; flag = 0; min = 0xffff; max = 0; for( i = 0; i < curmark; i++ ) { if( marks[ i ].type ) { if( !flag ) { fprintf( stdout, "%6.1f * Blit\n", marks[ i ].time ); flag = 1; stretchcount = 0; } else { avgsum += stretchcount; fprintf( stdout, "%6.1f * Blit %d\n", marks[ i ].time, stretchcount ); if( stretchcount < min ) min = stretchcount; if( stretchcount > max ) max = stretchcount; stretchcount = 0; numstretches++; } } else { fprintf( stdout, "%6.1f - Refresh\n", marks[ i ].time ); stretchcount++; } } fprintf( stdout, "\nAverage display time: %4.2f refreshes, min = %d, max = %d.\n\n", (double) avgsum / (double) numstretches, min, max ); return 0; }