1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
22 #include "lib/helper.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 */
42 #ifdef HAVE_REMOTE_LCD
43 static int remote_line
;
44 static int remote_max_line
;
47 static void log_init(void)
51 rb
->lcd_getstringsize("A", NULL
, &h
);
52 max_line
= LCD_HEIGHT
/ h
;
54 rb
->lcd_clear_display();
56 #ifdef HAVE_REMOTE_LCD
57 rb
->lcd_remote_getstringsize("A", NULL
, &h
);
58 remote_max_line
= LCD_REMOTE_HEIGHT
/ h
;
60 rb
->lcd_remote_clear_display();
61 rb
->lcd_remote_update();
65 static void log_text(char *text
)
67 rb
->lcd_puts(0, line
, text
);
68 if (++line
>= max_line
)
71 #ifdef HAVE_REMOTE_LCD
72 rb
->lcd_remote_puts(0, remote_line
, text
);
73 if (++remote_line
>= remote_max_line
)
75 rb
->lcd_remote_update();
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 */
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 */
101 rb
->sleep(0); /* sync to tick */
102 time_start
= *rb
->current_tick
;
103 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
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);
112 /* Test 2: quarter LCD update */
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
);
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);
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
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] = {
146 static void make_gradient_rect(int width
, int height
)
148 unsigned char vline
[YUV_WIDTH
/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 */
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
);
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
);
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);
196 /* Test 2: quarter LCD update */
197 make_gradient_rect(YUV_WIDTH
/2, YUV_HEIGHT
/2);
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
);
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);
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 */
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 */
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();
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);
243 /* Test 2: quarter LCD update */
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
);
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);
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
];
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 */
280 int frames_1
, frames_2
;
283 unsigned char *gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
287 for (i
= 0; i
< NUM_CORES
; i
++)
289 rb
->snprintf(str
, sizeof(str
), "Greyscale (%s)",
290 (i
> 0) ? "COP" : "CPU");
294 log_text("Greyscale library");
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.");
304 make_grey_rect(LCD_WIDTH
, LCD_HEIGHT
);
306 /* Test 1 - greyscale overlay not yet enabled */
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
);
315 time_1
= time_end
- time_start
;
317 /* Test 2 - greyscale overlay enabled */
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
);
327 time_2
= time_end
- time_start
;
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);
335 if (load
> 0 && load
< 100)
337 rb
->snprintf(str
, sizeof(str
), "CPU load: %d%%", load
);
341 log_text("CPU load err (boost?)");
346 void plugin_quit(void)
348 #ifdef HAVE_TOUCHSCREEN
349 static struct touchbutton button
[] = {{
350 .action
= ACTION_STD_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;
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
);
377 int btn
= pluginlib_getaction(TIMEOUT_BLOCK
, plugin_contexts
,
378 ARRAYLEN(plugin_contexts
));
380 if ((btn
== FPS_QUIT
) || (btn
== FPS_QUIT2
))
385 /* plugin entry point */
386 enum plugin_status
plugin_start(const void* parameter
)
388 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
396 #ifdef HAVE_TOUCHSCREEN
397 rb
->touchscreen_set_mode(rb
->global_settings
->touch_mode
);
401 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
402 cpu_freq
= *rb
->cpu_frequency
; /* remember CPU frequency */
404 backlight_ignore_timeout();
408 #if defined(HAVE_LCD_COLOR) && (MEMORYSIZE > 2)
414 #ifdef HAVE_REMOTE_LCD
415 time_remote_update();
418 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
419 if (*rb
->cpu_frequency
!= cpu_freq
)
420 rb
->snprintf(str
, sizeof(str
), "CPU clock changed!");
422 rb
->snprintf(str
, sizeof(str
), "CPU: %d MHz",
423 (cpu_freq
+ 500000) / 1000000);
426 backlight_use_settings();
428 /* wait until user closes plugin */