Prepare new maemo release
[maemo-rb.git] / apps / plugins / test_fps.c
blob358ab827f358bf94f01d3c5208f6b41420fcef65
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 Peter D'Hoye
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
22 #include "lib/helper.h"
23 #include "lib/grey.h"
24 #include "lib/pluginlib_touchscreen.h"
25 #include "lib/pluginlib_exit.h"
26 #include "lib/pluginlib_actions.h"
28 /* this set the context to use with PLA */
29 static const struct button_mapping *plugin_contexts[] = { pla_main_ctx };
32 #define FPS_QUIT PLA_EXIT
33 #define FPS_QUIT2 PLA_CANCEL
35 #define DURATION (2*HZ) /* longer duration gives more precise results */
39 /* Screen logging */
40 static int line;
41 static int max_line;
42 #ifdef HAVE_REMOTE_LCD
43 static int remote_line;
44 static int remote_max_line;
45 #endif
47 static void log_init(void)
49 int h;
51 rb->lcd_getstringsize("A", NULL, &h);
52 max_line = LCD_HEIGHT / h;
53 line = 0;
54 rb->lcd_clear_display();
55 rb->lcd_update();
56 #ifdef HAVE_REMOTE_LCD
57 rb->lcd_remote_getstringsize("A", NULL, &h);
58 remote_max_line = LCD_REMOTE_HEIGHT / h;
59 remote_line = 0;
60 rb->lcd_remote_clear_display();
61 rb->lcd_remote_update();
62 #endif
65 static void log_text(char *text)
67 rb->lcd_puts(0, line, text);
68 if (++line >= max_line)
69 line = 0;
70 rb->lcd_update();
71 #ifdef HAVE_REMOTE_LCD
72 rb->lcd_remote_puts(0, remote_line, text);
73 if (++remote_line >= remote_max_line)
74 remote_line = 0;
75 rb->lcd_remote_update();
76 #endif
79 static int calc_tenth_fps(int framecount, long ticks)
81 return (10*HZ) * framecount / ticks;
84 static void time_main_update(void)
86 char str[32]; /* text buffer */
87 long time_start; /* start tickcount */
88 long time_end; /* end tickcount */
89 int frame_count;
90 int fps;
92 const int part14_x = LCD_WIDTH/4; /* x-offset for 1/4 update test */
93 const int part14_w = LCD_WIDTH/2; /* x-size for 1/4 update test */
94 const int part14_y = LCD_HEIGHT/4; /* y-offset for 1/4 update test */
95 const int part14_h = LCD_HEIGHT/2; /* y-size for 1/4 update test */
97 log_text("Main LCD Update");
99 /* Test 1: full LCD update */
100 frame_count = 0;
101 rb->sleep(0); /* sync to tick */
102 time_start = *rb->current_tick;
103 while((time_end = *rb->current_tick) - time_start < DURATION)
105 rb->lcd_update();
106 frame_count++;
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);
112 /* Test 2: quarter LCD update */
113 frame_count = 0;
114 rb->sleep(0); /* sync to tick */
115 time_start = *rb->current_tick;
116 while((time_end = *rb->current_tick) - time_start < DURATION)
118 rb->lcd_update_rect(part14_x, part14_y, part14_w, part14_h);
119 frame_count++;
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);
126 #if defined(HAVE_LCD_COLOR) && (MEMORYSIZE > 2)
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
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];
140 static unsigned char * const yuvbuf[3] = {
141 (void*)ydata,
142 (void*)udata,
143 (void*)vdata
146 static void make_gradient_rect(int width, int height)
148 unsigned char vline[YUV_WIDTH/2];
149 int x, y;
151 width /= 2;
152 height /= 2;
154 for (x = 0; x < width; x++)
155 vline[x] = (x << 8) / width;
156 for (y = 0; y < height; y++)
158 rb->memset(udata[y], (y << 8) / height, width);
159 rb->memcpy(vdata[y], vline, width);
163 static void time_main_yuv(void)
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;
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 */
176 log_text("Main LCD YUV");
178 rb->memset(ydata, 128, sizeof(ydata)); /* medium grey */
180 /* Test 1: full LCD update */
181 make_gradient_rect(YUV_WIDTH, YUV_HEIGHT);
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)
188 rb->lcd_blit_yuv(yuvbuf, 0, 0, YUV_WIDTH,
189 0, 0, YUV_WIDTH, YUV_HEIGHT);
190 frame_count++;
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);
196 /* Test 2: quarter LCD update */
197 make_gradient_rect(YUV_WIDTH/2, YUV_HEIGHT/2);
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)
204 rb->lcd_blit_yuv(yuvbuf, 0, 0, YUV_WIDTH,
205 part14_x, part14_y, part14_w, part14_h);
206 frame_count++;
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);
212 #endif
214 #ifdef HAVE_REMOTE_LCD
215 static void time_remote_update(void)
217 char str[32]; /* text buffer */
218 long time_start; /* start tickcount */
219 long time_end; /* end tickcount */
220 int frame_count;
221 int fps;
223 const int part14_x = LCD_REMOTE_WIDTH/4; /* x-offset for 1/4 update test */
224 const int part14_w = LCD_REMOTE_WIDTH/2; /* x-size for 1/4 update test */
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 */
228 log_text("Remote LCD Update");
230 /* Test 1: full LCD update */
231 frame_count = 0;
232 rb->sleep(0); /* sync to tick */
233 time_start = *rb->current_tick;
234 while((time_end = *rb->current_tick) - time_start < DURATION)
236 rb->lcd_remote_update();
237 frame_count++;
239 fps = calc_tenth_fps(frame_count, time_end - time_start);
240 rb->snprintf(str, sizeof(str), "1/1: %d.%d fps", fps / 10, fps % 10);
241 log_text(str);
243 /* Test 2: quarter LCD update */
244 frame_count = 0;
245 rb->sleep(0); /* sync to tick */
246 time_start = *rb->current_tick;
247 while((time_end = *rb->current_tick) - time_start < DURATION)
249 rb->lcd_remote_update_rect(part14_x, part14_y, part14_w, part14_h);
250 frame_count++;
252 fps = calc_tenth_fps(frame_count, time_end - time_start);
253 rb->snprintf(str, sizeof(str), "1/4: %d.%d fps", fps / 10, fps % 10);
254 log_text(str);
256 #endif
258 #if LCD_DEPTH < 4
260 GREY_INFO_STRUCT_IRAM
261 static unsigned char greydata[LCD_HEIGHT][LCD_WIDTH];
263 static void make_grey_rect(int width, int height)
265 unsigned char vline[LCD_WIDTH];
266 int x, y;
268 for (x = 0; x < width; x++)
269 vline[x] = (x << 8) / width;
270 for (y = 0; y < height; y++)
271 rb->memcpy(greydata[y], vline, width);
274 static void time_greyscale(void)
276 char str[32]; /* text buffer */
277 long time_start; /* start tickcount */
278 long time_end; /* end tickcount */
279 long time_1, time_2;
280 int frames_1, frames_2;
281 int fps, load;
282 size_t gbuf_size;
283 unsigned char *gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
285 #if NUM_CORES > 1
286 int i;
287 for (i = 0; i < NUM_CORES; i++)
289 rb->snprintf(str, sizeof(str), "Greyscale (%s)",
290 (i > 0) ? "COP" : "CPU");
291 log_text(str);
292 #else
293 const int i = 0;
294 log_text("Greyscale library");
296 #endif
298 if (!grey_init(gbuf, gbuf_size, (i > 0) ? GREY_ON_COP : 0,
299 LCD_WIDTH, LCD_HEIGHT, NULL))
301 log_text("greylib: out of memory.");
302 return;
304 make_grey_rect(LCD_WIDTH, LCD_HEIGHT);
306 /* Test 1 - greyscale overlay not yet enabled */
307 frames_1 = 0;
308 rb->sleep(0); /* sync to tick */
309 time_start = *rb->current_tick;
310 while((time_end = *rb->current_tick) - time_start < DURATION)
312 grey_ub_gray_bitmap(greydata[0], 0, 0, LCD_WIDTH, LCD_HEIGHT);
313 frames_1++;
315 time_1 = time_end - time_start;
317 /* Test 2 - greyscale overlay enabled */
318 grey_show(true);
319 frames_2 = 0;
320 rb->sleep(0); /* sync to tick */
321 time_start = *rb->current_tick;
322 while((time_end = *rb->current_tick) - time_start < DURATION)
324 grey_ub_gray_bitmap(greydata[0], 0, 0, LCD_WIDTH, LCD_HEIGHT);
325 frames_2++;
327 time_2 = time_end - time_start;
329 grey_release();
330 fps = calc_tenth_fps(frames_2, time_2);
331 load = 100 - (100 * frames_2 * time_1) / (frames_1 * time_2);
332 rb->snprintf(str, sizeof(str), "1/1: %d.%d fps", fps / 10, fps % 10);
333 log_text(str);
335 if (load > 0 && load < 100)
337 rb->snprintf(str, sizeof(str), "CPU load: %d%%", load);
338 log_text(str);
340 else
341 log_text("CPU load err (boost?)");
344 #endif
346 void plugin_quit(void)
348 #ifdef HAVE_TOUCHSCREEN
349 static struct touchbutton button[] = {{
350 .action = ACTION_STD_OK,
351 .title = "OK",
352 /* .vp runtime initialized, rest false/NULL */
354 struct viewport *vp = &button[0].vp;
355 struct screen *lcd = rb->screens[SCREEN_MAIN];
356 rb->viewport_set_defaults(vp, SCREEN_MAIN);
357 const int border = 10;
358 const int height = 50;
360 lcd->set_viewport(vp);
361 /* button matches the bottom center in the grid */
362 vp->x = lcd->lcdwidth/3;
363 vp->width = lcd->lcdwidth/3;
364 vp->height = height;
365 vp->y = lcd->lcdheight - height - border;
367 touchbutton_draw(button, ARRAYLEN(button));
368 lcd->update_viewport();
369 if (rb->touchscreen_get_mode() == TOUCHSCREEN_POINT)
371 while(touchbutton_get(button, ARRAYLEN(button)) != ACTION_STD_OK);
373 else
374 #endif
375 while (1)
377 int btn = pluginlib_getaction(TIMEOUT_BLOCK, plugin_contexts,
378 ARRAYLEN(plugin_contexts));
379 exit_on_usb(btn);
380 if ((btn == FPS_QUIT) || (btn == FPS_QUIT2))
381 break;
385 /* plugin entry point */
386 enum plugin_status plugin_start(const void* parameter)
388 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
389 char str[32];
390 int cpu_freq;
391 #endif
393 /* standard stuff */
394 (void)parameter;
396 #ifdef HAVE_TOUCHSCREEN
397 rb->touchscreen_set_mode(rb->global_settings->touch_mode);
398 #endif
400 log_init();
401 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
402 cpu_freq = *rb->cpu_frequency; /* remember CPU frequency */
403 #endif
404 backlight_ignore_timeout();
406 time_main_update();
407 rb->sleep(HZ);
408 #if defined(HAVE_LCD_COLOR) && (MEMORYSIZE > 2)
409 time_main_yuv();
410 #endif
411 #if LCD_DEPTH < 4
412 time_greyscale();
413 #endif
414 #ifdef HAVE_REMOTE_LCD
415 time_remote_update();
416 #endif
418 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
419 if (*rb->cpu_frequency != cpu_freq)
420 rb->snprintf(str, sizeof(str), "CPU clock changed!");
421 else
422 rb->snprintf(str, sizeof(str), "CPU: %d MHz",
423 (cpu_freq + 500000) / 1000000);
424 log_text(str);
425 #endif
426 backlight_use_settings();
428 /* wait until user closes plugin */
429 plugin_quit();
431 return PLUGIN_OK;