diff options
author | Jens Arnold <amiconn@rockbox.org> | 2007-10-13 22:32:35 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2007-10-13 22:32:35 +0000 |
commit | cb4186c989d74696c77518e7e53d4bc02d587eec (patch) | |
tree | ffb5dd68a87e50db0e69e244aa41baa9aba22ca9 /apps/plugins/test_fps.c | |
parent | a0f15c64baf30bde63267d52bdac0c00efdcbf0d (diff) | |
download | rockbox-cb4186c989d74696c77518e7e53d4bc02d587eec.tar.gz rockbox-cb4186c989d74696c77518e7e53d4bc02d587eec.zip |
Improved FPS test plugin: * Better precision for low frame rates (take extra ticks into account). * Measure YUV blit framerate on colour targets.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15099 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/test_fps.c')
-rw-r--r-- | apps/plugins/test_fps.c | 283 |
1 files changed, 208 insertions, 75 deletions
diff --git a/apps/plugins/test_fps.c b/apps/plugins/test_fps.c index 9188d96ba4..2da1d92d99 100644 --- a/apps/plugins/test_fps.c +++ b/apps/plugins/test_fps.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #include "plugin.h" | 19 | #include "plugin.h" |
20 | #include "helper.h" | ||
20 | 21 | ||
21 | #ifdef HAVE_LCD_BITMAP | 22 | #ifdef HAVE_LCD_BITMAP |
22 | 23 | ||
@@ -29,135 +30,267 @@ | |||
29 | #define FPS_QUIT BUTTON_POWER | 30 | #define FPS_QUIT BUTTON_POWER |
30 | #endif | 31 | #endif |
31 | 32 | ||
33 | #define DURATION (2*HZ) /* longer duration gives more precise results */ | ||
34 | |||
32 | PLUGIN_HEADER | 35 | PLUGIN_HEADER |
33 | 36 | ||
34 | static struct plugin_api* rb; | 37 | static struct plugin_api* rb; |
35 | 38 | ||
36 | /* plugin entry point */ | 39 | /* Screen logging */ |
37 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 40 | static int line; |
38 | { | 41 | static int max_line; |
39 | char str[64]; /* text buffer */ | ||
40 | int time_start; /* start tickcount */ | ||
41 | int frame_count; /* frame counter */ | ||
42 | #ifndef SIMULATOR | ||
43 | int cpu_freq; | ||
44 | #endif | ||
45 | int line = 0; | ||
46 | int part14_x = LCD_WIDTH/4; /* x-offset for 1/4 update test */ | ||
47 | int part14_w = LCD_WIDTH/2; /* x-size for 1/4 update test */ | ||
48 | int part14_y = LCD_HEIGHT/4; /* y-offset for 1/4 update test */ | ||
49 | int part14_h = LCD_HEIGHT/2; /* y-size for 1/4 update test */ | ||
50 | #ifdef HAVE_REMOTE_LCD | 42 | #ifdef HAVE_REMOTE_LCD |
51 | int r_line = 0; | 43 | static int remote_line; |
52 | int r_part14_x = LCD_REMOTE_WIDTH/4; /* x-offset for 1/4 update test */ | 44 | static int remote_max_line; |
53 | int r_part14_w = LCD_REMOTE_WIDTH/2; /* x-size for 1/4 update test */ | ||
54 | int r_part14_y = LCD_REMOTE_HEIGHT/4; /* y-offset for 1/4 update test */ | ||
55 | int r_part14_h = LCD_REMOTE_HEIGHT/2; /* y-size for 1/4 update test */ | ||
56 | #endif | 45 | #endif |
57 | 46 | ||
58 | /* standard stuff */ | 47 | static void log_init(void) |
59 | (void)parameter; | 48 | { |
60 | rb = api; | 49 | int h; |
61 | 50 | ||
51 | rb->lcd_setmargins(0, 0); | ||
52 | rb->lcd_getstringsize("A", NULL, &h); | ||
53 | max_line = LCD_HEIGHT / h; | ||
54 | line = 0; | ||
62 | rb->lcd_clear_display(); | 55 | rb->lcd_clear_display(); |
63 | rb->lcd_puts(0, line++, "FPS Measurement"); | 56 | rb->lcd_update(); |
64 | #ifdef HAVE_REMOTE_LCD | 57 | #ifdef HAVE_REMOTE_LCD |
65 | rb->lcd_puts(0, line++, "Main LCD"); | 58 | rb->lcd_remote_setmargins(0, 0); |
66 | rb->lcd_remote_puts(0, r_line++, "FPS Measurement"); | 59 | rb->lcd_remote_getstringsize("A", NULL, &h); |
67 | rb->lcd_remote_puts(0, r_line++, "Main LCD"); | 60 | remote_max_line = LCD_REMOTE_HEIGHT / h; |
61 | remote_line = 0; | ||
62 | rb->lcd_remote_clear_display(); | ||
68 | rb->lcd_remote_update(); | 63 | rb->lcd_remote_update(); |
69 | #endif | 64 | #endif |
70 | rb->lcd_update(); | 65 | } |
71 | 66 | ||
72 | #ifndef SIMULATOR | 67 | static void log_text(char *text) |
73 | cpu_freq = *rb->cpu_frequency; /* remember CPU frequency */ | 68 | { |
69 | rb->lcd_puts(0, line, text); | ||
70 | if (++line >= max_line) | ||
71 | line = 0; | ||
72 | rb->lcd_update(); | ||
73 | #ifdef HAVE_REMOTE_LCD | ||
74 | rb->lcd_remote_puts(0, remote_line, text); | ||
75 | if (++remote_line >= remote_max_line) | ||
76 | remote_line = 0; | ||
77 | rb->lcd_remote_update(); | ||
74 | #endif | 78 | #endif |
79 | } | ||
80 | |||
81 | static int calc_tenth_fps(int framecount, long ticks) | ||
82 | { | ||
83 | return (10*HZ) * framecount / ticks; | ||
84 | } | ||
75 | 85 | ||
76 | /* TEST 1: FULL LCD UPDATE */ | 86 | static void time_main_update(void) |
87 | { | ||
88 | char str[32]; /* text buffer */ | ||
89 | long time_start; /* start tickcount */ | ||
90 | long time_end; /* end tickcount */ | ||
91 | int frame_count; | ||
92 | int fps; | ||
93 | |||
94 | const int part14_x = LCD_WIDTH/4; /* x-offset for 1/4 update test */ | ||
95 | const int part14_w = LCD_WIDTH/2; /* x-size for 1/4 update test */ | ||
96 | const int part14_y = LCD_HEIGHT/4; /* y-offset for 1/4 update test */ | ||
97 | const int part14_h = LCD_HEIGHT/2; /* y-size for 1/4 update test */ | ||
98 | |||
99 | /* Test 1: full LCD update */ | ||
77 | frame_count = 0; | 100 | frame_count = 0; |
101 | rb->sleep(0); /* sync to tick */ | ||
78 | time_start = *rb->current_tick; | 102 | time_start = *rb->current_tick; |
79 | while(*rb->current_tick - time_start < 2*HZ) | 103 | while((time_end = *rb->current_tick) - time_start < DURATION) |
80 | { | 104 | { |
81 | rb->lcd_update(); | 105 | rb->lcd_update(); |
82 | frame_count++; | 106 | frame_count++; |
83 | } | 107 | } |
108 | fps = calc_tenth_fps(frame_count, time_end - time_start); | ||
109 | rb->snprintf(str, sizeof(str), "1/1: %d.%d fps", fps / 10, fps % 10); | ||
110 | log_text(str); | ||
84 | 111 | ||
85 | rb->snprintf(str, sizeof(str), "1/1: %d.%d fps", frame_count / 2, | 112 | /* Test 2: quarter LCD update */ |
86 | (frame_count % 2) * 5); | ||
87 | rb->lcd_puts(0, line++, str); | ||
88 | rb->lcd_update(); | ||
89 | |||
90 | /* TEST 2: QUARTER LCD UPDATE */ | ||
91 | frame_count = 0; | 113 | frame_count = 0; |
114 | rb->sleep(0); /* sync to tick */ | ||
92 | time_start = *rb->current_tick; | 115 | time_start = *rb->current_tick; |
93 | while(*rb->current_tick - time_start < 2*HZ) | 116 | while((time_end = *rb->current_tick) - time_start < DURATION) |
94 | { | 117 | { |
95 | rb->lcd_update_rect(part14_x, part14_y, part14_w, part14_h); | 118 | rb->lcd_update_rect(part14_x, part14_y, part14_w, part14_h); |
96 | frame_count++; | 119 | frame_count++; |
97 | } | 120 | } |
121 | fps = calc_tenth_fps(frame_count, time_end - time_start); | ||
122 | rb->snprintf(str, sizeof(str), "1/4: %d.%d fps", fps / 10, fps % 10); | ||
123 | log_text(str); | ||
124 | } | ||
98 | 125 | ||
99 | rb->snprintf(str, sizeof(str), "1/4: %d.%d fps", frame_count/2, | 126 | #ifdef HAVE_LCD_COLOR |
100 | (frame_count%2)*5); | 127 | |
101 | rb->lcd_puts(0, line++, str); | 128 | #if LCD_WIDTH >= LCD_HEIGHT |
129 | #define YUV_WIDTH LCD_WIDTH | ||
130 | #define YUV_HEIGHT LCD_HEIGHT | ||
131 | #else /* Assume the screen is rotated on portrait LCDs */ | ||
132 | #define YUV_WIDTH LCD_HEIGHT | ||
133 | #define YUV_HEIGHT LCD_WIDTH | ||
134 | #endif | ||
135 | |||
136 | static unsigned char ydata[YUV_HEIGHT][YUV_WIDTH]; | ||
137 | static unsigned char udata[YUV_HEIGHT/2][YUV_WIDTH/2]; | ||
138 | static unsigned char vdata[YUV_HEIGHT/2][YUV_WIDTH/2]; | ||
139 | |||
140 | static unsigned char * const yuvbuf[3] = { | ||
141 | (void*)ydata, | ||
142 | (void*)udata, | ||
143 | (void*)vdata | ||
144 | }; | ||
145 | |||
146 | static void make_gradient_rect(width, height) | ||
147 | { | ||
148 | unsigned char vline[YUV_WIDTH/2]; | ||
149 | int x, y; | ||
150 | |||
151 | width /= 2; | ||
152 | height /= 2; | ||
153 | |||
154 | for (x = 0; x < width; x++) | ||
155 | vline[x] = (x << 8) / width; | ||
156 | for (y = 0; y < height; y++) | ||
157 | { | ||
158 | rb->memset(udata[y], (y << 8) / height, width); | ||
159 | rb->memcpy(vdata[y], vline, width); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static void time_main_yuv(void) | ||
164 | { | ||
165 | char str[32]; /* text buffer */ | ||
166 | long time_start; /* start tickcount */ | ||
167 | long time_end; /* end tickcount */ | ||
168 | int frame_count; | ||
169 | int fps; | ||
170 | |||
171 | const int part14_x = YUV_WIDTH/4; /* x-offset for 1/4 update test */ | ||
172 | const int part14_w = YUV_WIDTH/2; /* x-size for 1/4 update test */ | ||
173 | const int part14_y = YUV_HEIGHT/4; /* y-offset for 1/4 update test */ | ||
174 | const int part14_h = YUV_HEIGHT/2; /* y-size for 1/4 update test */ | ||
102 | 175 | ||
103 | #ifndef SIMULATOR | 176 | int x, y; |
104 | if (*rb->cpu_frequency != cpu_freq) | ||
105 | rb->snprintf(str, sizeof(str), "CPU: frequency changed!"); | ||
106 | else | ||
107 | rb->snprintf(str, sizeof(str), "CPU: %d Hz", cpu_freq); | ||
108 | 177 | ||
109 | rb->lcd_puts(0, line++, str); | 178 | rb->memset(ydata, 128, sizeof(ydata)); /* medium grey */ |
179 | |||
180 | /* Test 1: full LCD update */ | ||
181 | make_gradient_rect(YUV_WIDTH, YUV_HEIGHT); | ||
182 | |||
183 | frame_count = 0; | ||
184 | rb->sleep(0); /* sync to tick */ | ||
185 | time_start = *rb->current_tick; | ||
186 | while((time_end = *rb->current_tick) - time_start < DURATION) | ||
187 | { | ||
188 | rb->lcd_yuv_blit(yuvbuf, 0, 0, YUV_WIDTH, | ||
189 | 0, 0, YUV_WIDTH, YUV_HEIGHT); | ||
190 | frame_count++; | ||
191 | } | ||
192 | fps = calc_tenth_fps(frame_count, time_end - time_start); | ||
193 | rb->snprintf(str, sizeof(str), "1/1: %d.%d fps", fps / 10, fps % 10); | ||
194 | log_text(str); | ||
195 | |||
196 | /* Test 2: quarter LCD update */ | ||
197 | make_gradient_rect(YUV_WIDTH/2, YUV_HEIGHT/2); | ||
198 | |||
199 | frame_count = 0; | ||
200 | rb->sleep(0); /* sync to tick */ | ||
201 | time_start = *rb->current_tick; | ||
202 | while((time_end = *rb->current_tick) - time_start < DURATION) | ||
203 | { | ||
204 | rb->lcd_yuv_blit(yuvbuf, 0, 0, YUV_WIDTH, | ||
205 | part14_x, part14_y, part14_w, part14_h); | ||
206 | frame_count++; | ||
207 | } | ||
208 | fps = calc_tenth_fps(frame_count, time_end - time_start); | ||
209 | rb->snprintf(str, sizeof(str), "1/4: %d.%d fps", fps / 10, fps % 10); | ||
210 | log_text(str); | ||
211 | } | ||
110 | #endif | 212 | #endif |
111 | rb->lcd_update(); | ||
112 | 213 | ||
113 | #ifdef HAVE_REMOTE_LCD | 214 | #ifdef HAVE_REMOTE_LCD |
114 | rb->lcd_puts(0, line++, "Remote LCD"); | 215 | static void time_remote_update(void) |
115 | rb->lcd_update(); | 216 | { |
116 | rb->lcd_remote_puts(0, r_line++, "Remote LCD"); | 217 | char str[32]; /* text buffer */ |
117 | rb->lcd_remote_update(); | 218 | long time_start; /* start tickcount */ |
219 | long time_end; /* end tickcount */ | ||
220 | int frame_count; | ||
221 | int fps; | ||
118 | 222 | ||
119 | #ifndef SIMULATOR | 223 | const int part14_x = LCD_REMOTE_WIDTH/4; /* x-offset for 1/4 update test */ |
120 | cpu_freq = *rb->cpu_frequency; /* remember CPU frequency */ | 224 | const int part14_w = LCD_REMOTE_WIDTH/2; /* x-size for 1/4 update test */ |
121 | #endif | 225 | const int part14_y = LCD_REMOTE_HEIGHT/4; /* y-offset for 1/4 update test */ |
226 | const int part14_h = LCD_REMOTE_HEIGHT/2; /* y-size for 1/4 update test */ | ||
122 | 227 | ||
123 | /* TEST 1: FULL LCD UPDATE */ | 228 | /* Test 1: full LCD update */ |
124 | frame_count = 0; | 229 | frame_count = 0; |
230 | rb->sleep(0); /* sync to tick */ | ||
125 | time_start = *rb->current_tick; | 231 | time_start = *rb->current_tick; |
126 | while(*rb->current_tick - time_start < 2*HZ) | 232 | while((time_end = *rb->current_tick) - time_start < DURATION) |
127 | { | 233 | { |
128 | rb->lcd_remote_update(); | 234 | rb->lcd_remote_update(); |
129 | frame_count++; | 235 | frame_count++; |
130 | } | 236 | } |
237 | fps = calc_tenth_fps(frame_count, time_end - time_start); | ||
238 | rb->snprintf(str, sizeof(str), "1/1: %d.%d fps", fps / 10, fps % 10); | ||
239 | log_text(str); | ||
131 | 240 | ||
132 | rb->snprintf(str, sizeof(str), "1/1: %d.%d fps", frame_count / 2, | 241 | /* Test 2: quarter LCD update */ |
133 | (frame_count % 2) * 5); | ||
134 | rb->lcd_puts(0, line++, str); | ||
135 | rb->lcd_update(); | ||
136 | |||
137 | /* TEST 2: QUARTER LCD UPDATE */ | ||
138 | frame_count = 0; | 242 | frame_count = 0; |
243 | rb->sleep(0); /* sync to tick */ | ||
139 | time_start = *rb->current_tick; | 244 | time_start = *rb->current_tick; |
140 | while(*rb->current_tick - time_start < 2*HZ) | 245 | while((time_end = *rb->current_tick) - time_start < DURATION) |
141 | { | 246 | { |
142 | rb->lcd_remote_update_rect(r_part14_x, r_part14_y, r_part14_w, | 247 | rb->lcd_remote_update_rect(part14_x, part14_y, part14_w, part14_h); |
143 | r_part14_h); | ||
144 | frame_count++; | 248 | frame_count++; |
145 | } | 249 | } |
250 | fps = calc_tenth_fps(frame_count, time_end - time_start); | ||
251 | rb->snprintf(str, sizeof(str), "1/4: %d.%d fps", fps / 10, fps % 10); | ||
252 | log_text(str); | ||
253 | } | ||
254 | #endif | ||
255 | |||
256 | /* plugin entry point */ | ||
257 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
258 | { | ||
259 | #ifndef SIMULATOR | ||
260 | char str[32]; | ||
261 | int cpu_freq; | ||
262 | #endif | ||
146 | 263 | ||
147 | rb->snprintf(str, sizeof(str), "1/4: %d.%d fps", frame_count/2, | 264 | /* standard stuff */ |
148 | (frame_count%2)*5); | 265 | (void)parameter; |
149 | rb->lcd_puts(0, line++, str); | 266 | rb = api; |
150 | 267 | ||
268 | log_init(); | ||
151 | #ifndef SIMULATOR | 269 | #ifndef SIMULATOR |
152 | if (*rb->cpu_frequency != cpu_freq) | 270 | cpu_freq = *rb->cpu_frequency; /* remember CPU frequency */ |
153 | rb->snprintf(str, sizeof(str), "CPU: frequency changed!"); | 271 | #endif |
154 | else | 272 | backlight_force_on(rb); /* backlight control in lib/helper.c */ |
155 | rb->snprintf(str, sizeof(str), "CPU: %d Hz", cpu_freq); | ||
156 | 273 | ||
157 | rb->lcd_puts(0, line++, str); | 274 | log_text("Main LCD Update"); |
275 | time_main_update(); | ||
276 | #ifdef HAVE_LCD_COLOR | ||
277 | log_text("Main LCD YUV"); | ||
278 | time_main_yuv(); | ||
158 | #endif | 279 | #endif |
159 | rb->lcd_update(); | 280 | #ifdef HAVE_REMOTE_LCD |
281 | log_text("Remote LCD Update"); | ||
282 | time_remote_update(); | ||
283 | #endif | ||
284 | |||
285 | #ifndef SIMULATOR | ||
286 | if (*rb->cpu_frequency != cpu_freq) | ||
287 | rb->snprintf(str, sizeof(str), "CPU clock changed!"); | ||
288 | else | ||
289 | rb->snprintf(str, sizeof(str), "CPU: %d MHz", | ||
290 | (cpu_freq + 500000) / 1000000); | ||
291 | log_text(str); | ||
160 | #endif | 292 | #endif |
293 | backlight_use_settings(rb); /* backlight control in lib/helper.c */ | ||
161 | 294 | ||
162 | /* wait until user closes plugin */ | 295 | /* wait until user closes plugin */ |
163 | while (rb->button_get(true) != FPS_QUIT); | 296 | while (rb->button_get(true) != FPS_QUIT); |