/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2009 by Jens Arnold * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ //#define TEST_GREYLIB /* Uncomment for testing greylib instead of core gfx */ #include "plugin.h" #ifdef TEST_GREYLIB /* otherwise, mylcd defaults to core gfx */ #include "lib/grey.h" #endif #include "lib/helper.h" #include "lib/mylcd.h" #ifdef TEST_GREYLIB GREY_INFO_STRUCT static unsigned char *gbuf; static size_t gbuf_size = 0; #endif #define DURATION (HZ) /* longer duration gives more precise results */ #define RND_SEED 0x43A678C3 /* arbirary */ static uint16_t rand_table[0x400]; static int log_fd; static int log_init(void) { char logfilename[MAX_PATH]; int fd; rb->create_numbered_filename(logfilename, HOME_DIR, "test_gfx_log_", ".txt", 2 IF_CNFN_NUM_(, NULL)); fd = rb->open(logfilename, O_RDWR|O_CREAT|O_TRUNC, 0666); return fd; } static void init_rand_table(void) { int i; rb->srand(RND_SEED); /* make it reproducable */ for (i = 0; i < 0x400; i++) rand_table[i] = rb->rand(); } static void time_drawpixel(void) { long time_start; /* start tickcount */ long time_end; /* end tickcount */ int count1, count2, count3, count4; /* Test 1: DRMODE_SOLID */ mylcd_set_drawmode(DRMODE_SOLID); count1 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count1++ & 0x3ff]; mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f); } /* Test 2: DRMODE_FG */ mylcd_set_drawmode(DRMODE_FG); count2 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count2++ & 0x3ff]; mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f); } /* Test 3: DRMODE_BG */ mylcd_set_drawmode(DRMODE_BG); count3 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count3++ & 0x3ff]; mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f); } /* Test 4: DRMODE_COMPLEMENT */ mylcd_set_drawmode(DRMODE_COMPLEMENT); count4 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count4++ & 0x3ff]; mylcd_drawpixel((rnd >> 8) & 0x3f, rnd & 0x3f); } rb->fdprintf(log_fd, "lcd_drawpixel (pixels/s): %d/%d/%d/%d\n", count1, count2, count3, count4); } static void time_drawline(void) { long time_start; /* start tickcount */ long time_end; /* end tickcount */ int count1, count2, count3, count4; /* Test 1: DRMODE_SOLID */ mylcd_set_drawmode(DRMODE_SOLID); count1 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count1++ & 0x3ff]; unsigned rnd2 = rand_table[count1++ & 0x3ff]; mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } /* Test 2: DRMODE_FG */ mylcd_set_drawmode(DRMODE_FG); count2 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count2++ & 0x3ff]; unsigned rnd2 = rand_table[count2++ & 0x3ff]; mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } /* Test 3: DRMODE_BG */ mylcd_set_drawmode(DRMODE_BG); count3 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count3++ & 0x3ff]; unsigned rnd2 = rand_table[count3++ & 0x3ff]; mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } /* Test 4: DRMODE_COMPLEMENT */ mylcd_set_drawmode(DRMODE_COMPLEMENT); count4 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count4++ & 0x3ff]; unsigned rnd2 = rand_table[count4++ & 0x3ff]; mylcd_drawline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } rb->fdprintf(log_fd, "lcd_drawline (lines/s): %d/%d/%d/%d\n", count1, count2, count3, count4); } static void time_hline(void) { long time_start; /* start tickcount */ long time_end; /* end tickcount */ int count1, count2, count3, count4; /* Test 1: DRMODE_SOLID */ mylcd_set_drawmode(DRMODE_SOLID); count1 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count1++ & 0x3ff]; unsigned rnd2 = rand_table[count1++ & 0x3ff]; mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } /* Test 2: DRMODE_FG */ mylcd_set_drawmode(DRMODE_FG); count2 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count2++ & 0x3ff]; unsigned rnd2 = rand_table[count2++ & 0x3ff]; mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } /* Test 3: DRMODE_BG */ mylcd_set_drawmode(DRMODE_BG); count3 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count3++ & 0x3ff]; unsigned rnd2 = rand_table[count3++ & 0x3ff]; mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } /* Test 4: DRMODE_COMPLEMENT */ mylcd_set_drawmode(DRMODE_COMPLEMENT); count4 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count4++ & 0x3ff]; unsigned rnd2 = rand_table[count4++ & 0x3ff]; mylcd_hline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } rb->fdprintf(log_fd, "lcd_hline (lines/s): %d/%d/%d/%d\n", count1, count2, count3, count4); } static void time_vline(void) { long time_start; /* start tickcount */ long time_end; /* end tickcount */ int count1, count2, count3, count4; /* Test 1: DRMODE_SOLID */ mylcd_set_drawmode(DRMODE_SOLID); count1 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count1++ & 0x3ff]; unsigned rnd2 = rand_table[count1++ & 0x3ff]; mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } /* Test 2: DRMODE_FG */ mylcd_set_drawmode(DRMODE_FG); count2 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count2++ & 0x3ff]; unsigned rnd2 = rand_table[count2++ & 0x3ff]; mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } /* Test 3: DRMODE_BG */ mylcd_set_drawmode(DRMODE_BG); count3 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count3++ & 0x3ff]; unsigned rnd2 = rand_table[count3++ & 0x3ff]; mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } /* Test 4: DRMODE_COMPLEMENT */ mylcd_set_drawmode(DRMODE_COMPLEMENT); count4 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count4++ & 0x3ff]; unsigned rnd2 = rand_table[count4++ & 0x3ff]; mylcd_vline((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, rnd2 & 0x3f); } rb->fdprintf(log_fd, "lcd_vline (lines/s): %d/%d/%d/%d\n", count1, count2, count3, count4); } static void time_fillrect(void) { long time_start; /* start tickcount */ long time_end; /* end tickcount */ int count1, count2, count3, count4; /* Test 1: DRMODE_SOLID */ mylcd_set_drawmode(DRMODE_SOLID); count1 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count1++ & 0x3ff]; unsigned rnd2 = rand_table[count1++ & 0x3ff]; mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } /* Test 2: DRMODE_FG */ mylcd_set_drawmode(DRMODE_FG); count2 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count2++ & 0x3ff]; unsigned rnd2 = rand_table[count2++ & 0x3ff]; mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } /* Test 3: DRMODE_BG */ mylcd_set_drawmode(DRMODE_BG); count3 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count3++ & 0x3ff]; unsigned rnd2 = rand_table[count3++ & 0x3ff]; mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } /* Test 4: DRMODE_COMPLEMENT */ mylcd_set_drawmode(DRMODE_COMPLEMENT); count4 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd1 = rand_table[count4++ & 0x3ff]; unsigned rnd2 = rand_table[count4++ & 0x3ff]; mylcd_fillrect((rnd1 >> 8) & 0x3f, rnd1 & 0x3f, (rnd2 >> 8) & 0x3f, rnd2 & 0x3f); } rb->fdprintf(log_fd, "lcd_fillrect (rects/s): %d/%d/%d/%d\n", count1, count2, count3, count4); } static void time_text(void) /* tests mono_bitmap performance */ { long time_start; /* start tickcount */ long time_end; /* end tickcount */ int count1, count2, count3, count4; rb->lcd_setfont(FONT_SYSFIXED); /* Test 1: DRMODE_SOLID */ mylcd_set_drawmode(DRMODE_SOLID); count1 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count1++ & 0x3ff]; mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!"); } /* Test 2: DRMODE_FG */ mylcd_set_drawmode(DRMODE_FG); count2 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count2++ & 0x3ff]; mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!"); } /* Test 3: DRMODE_BG */ mylcd_set_drawmode(DRMODE_BG); count3 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count3++ & 0x3ff]; mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!"); } /* Test 4: DRMODE_COMPLEMENT */ mylcd_set_drawmode(DRMODE_COMPLEMENT); count4 = 0; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count4++ & 0x3ff]; mylcd_putsxy((rnd >> 8) & 0x3f, rnd & 0x3f, "Rockbox!"); } rb->fdprintf(log_fd, "lcd_putsxy (strings/s): %d/%d/%d/%d\n", count1, count2, count3, count4); } static void time_put_line(void) /* tests put_line performance */ { long time_start, time_end; int count1, count2, count3, count4; struct screen *display = rb->screens[SCREEN_MAIN]; const char fmt[] = "$iRockbox!"; rb->lcd_setfont(FONT_SYSFIXED); count1 = count2 = count3 = count4 = 0; struct line_desc desc = LINE_DESC_DEFINIT; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count1++ & 0x3ff]; display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio); } desc.style = STYLE_INVERT; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count2++ & 0x3ff]; display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio); } desc.style = STYLE_COLORBAR; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count3++ & 0x3ff]; display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio); } desc.style = STYLE_GRADIENT; rb->sleep(0); /* sync to tick */ time_start = *rb->current_tick; while((time_end = *rb->current_tick) - time_start < DURATION) { unsigned rnd = rand_table[count4++ & 0x3ff]; display->put_line((rnd >> 8) & 0x3f, rnd & 0x3f, &desc, fmt, Icon_Audio); } rb->fdprintf(log_fd, "\nput_line (lines (icon+text)/s): \n" " default: %d\n" " inverted: %d\n" " colorbar: %d\n" " gradient: %d\n", count1, count2, count3, count4); } /* plugin entry point */ enum plugin_status plugin_start(const void* parameter) { #ifdef HAVE_ADJUSTABLE_CPU_FREQ int cpu_freq; #endif /* standard stuff */ (void)parameter; log_fd = log_init(); if (log_fd < 0) { rb->splash(HZ, "Could not create logfile"); return PLUGIN_ERROR; } rb->fdprintf(log_fd, "%s", #ifdef TEST_GREYLIB "Greylib performance test.\n" #else "LCD driver performance test.\n" #endif "----------------------------\n\n" "Results are printed in the following drawmode order:\n" "solid/foreground/background/complement\n\n"); #ifdef TEST_GREYLIB /* get the remainder of the plugin buffer */ gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); /* initialize the greyscale buffer.*/ if (!grey_init(gbuf, gbuf_size, GREY_BUFFERED|GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL)) { rb->close(log_fd); rb->splash(HZ, "Couldn't init greyscale library"); return PLUGIN_ERROR; } #elif LCD_DEPTH > 1 rb->lcd_set_backdrop(NULL); rb->lcd_clear_display(); #endif backlight_ignore_timeout(); rb->splashf(0, "LCD driver performance test, please wait %d sec", 7*4*DURATION/HZ); init_rand_table(); #ifdef HAVE_ADJUSTABLE_CPU_FREQ cpu_freq = *rb->cpu_frequency; /* remember CPU frequency */ #endif time_drawpixel(); time_drawline(); time_hline(); time_vline(); time_fillrect(); time_text(); time_put_line(); #ifdef HAVE_ADJUSTABLE_CPU_FREQ if (*rb->cpu_frequency != cpu_freq) rb->fdprintf(log_fd, "\nCPU: %s\n", "clock changed!"); else rb->fdprintf(log_fd, "\nCPU: %d MHz\n", (cpu_freq + 500000) / 1000000); #endif rb->close(log_fd); backlight_use_settings(); #ifdef TEST_GREYLIB grey_release(); #endif return PLUGIN_OK; }