1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Peter D'Hoye
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 #ifdef HAVE_LCD_BITMAP
27 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
28 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
29 #define FPS_QUIT BUTTON_MENU
30 #elif defined(BUTTON_OFF)
31 #define FPS_QUIT BUTTON_OFF
33 #define FPS_QUIT BUTTON_POWER
36 #define DURATION (2*HZ) /* longer duration gives more precise results */
40 static struct plugin_api
* rb
;
45 #ifdef HAVE_REMOTE_LCD
46 static int remote_line
;
47 static int remote_max_line
;
50 static unsigned char *gbuf
;
51 static size_t gbuf_size
;
54 static void log_init(void)
58 rb
->lcd_setmargins(0, 0);
59 rb
->lcd_getstringsize("A", NULL
, &h
);
60 max_line
= LCD_HEIGHT
/ h
;
62 rb
->lcd_clear_display();
64 #ifdef HAVE_REMOTE_LCD
65 rb
->lcd_remote_setmargins(0, 0);
66 rb
->lcd_remote_getstringsize("A", NULL
, &h
);
67 remote_max_line
= LCD_REMOTE_HEIGHT
/ h
;
69 rb
->lcd_remote_clear_display();
70 rb
->lcd_remote_update();
74 static void log_text(char *text
)
76 rb
->lcd_puts(0, line
, text
);
77 if (++line
>= max_line
)
80 #ifdef HAVE_REMOTE_LCD
81 rb
->lcd_remote_puts(0, remote_line
, text
);
82 if (++remote_line
>= remote_max_line
)
84 rb
->lcd_remote_update();
88 static int calc_tenth_fps(int framecount
, long ticks
)
90 return (10*HZ
) * framecount
/ ticks
;
93 static void time_main_update(void)
95 char str
[32]; /* text buffer */
96 long time_start
; /* start tickcount */
97 long time_end
; /* end tickcount */
101 const int part14_x
= LCD_WIDTH
/4; /* x-offset for 1/4 update test */
102 const int part14_w
= LCD_WIDTH
/2; /* x-size for 1/4 update test */
103 const int part14_y
= LCD_HEIGHT
/4; /* y-offset for 1/4 update test */
104 const int part14_h
= LCD_HEIGHT
/2; /* y-size for 1/4 update test */
106 /* Test 1: full LCD update */
108 rb
->sleep(0); /* sync to tick */
109 time_start
= *rb
->current_tick
;
110 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
115 fps
= calc_tenth_fps(frame_count
, time_end
- time_start
);
116 rb
->snprintf(str
, sizeof(str
), "1/1: %d.%d fps", fps
/ 10, fps
% 10);
119 /* Test 2: quarter LCD update */
121 rb
->sleep(0); /* sync to tick */
122 time_start
= *rb
->current_tick
;
123 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
125 rb
->lcd_update_rect(part14_x
, part14_y
, part14_w
, part14_h
);
128 fps
= calc_tenth_fps(frame_count
, time_end
- time_start
);
129 rb
->snprintf(str
, sizeof(str
), "1/4: %d.%d fps", fps
/ 10, fps
% 10);
133 #ifdef HAVE_LCD_COLOR
135 #if LCD_WIDTH >= LCD_HEIGHT
136 #define YUV_WIDTH LCD_WIDTH
137 #define YUV_HEIGHT LCD_HEIGHT
138 #else /* Assume the screen is rotated on portrait LCDs */
139 #define YUV_WIDTH LCD_HEIGHT
140 #define YUV_HEIGHT LCD_WIDTH
143 static unsigned char ydata
[YUV_HEIGHT
][YUV_WIDTH
];
144 static unsigned char udata
[YUV_HEIGHT
/2][YUV_WIDTH
/2];
145 static unsigned char vdata
[YUV_HEIGHT
/2][YUV_WIDTH
/2];
147 static unsigned char * const yuvbuf
[3] = {
153 static void make_gradient_rect(int width
, int height
)
155 unsigned char vline
[YUV_WIDTH
/2];
161 for (x
= 0; x
< width
; x
++)
162 vline
[x
] = (x
<< 8) / width
;
163 for (y
= 0; y
< height
; y
++)
165 rb
->memset(udata
[y
], (y
<< 8) / height
, width
);
166 rb
->memcpy(vdata
[y
], vline
, width
);
170 static void time_main_yuv(void)
172 char str
[32]; /* text buffer */
173 long time_start
; /* start tickcount */
174 long time_end
; /* end tickcount */
178 const int part14_x
= YUV_WIDTH
/4; /* x-offset for 1/4 update test */
179 const int part14_w
= YUV_WIDTH
/2; /* x-size for 1/4 update test */
180 const int part14_y
= YUV_HEIGHT
/4; /* y-offset for 1/4 update test */
181 const int part14_h
= YUV_HEIGHT
/2; /* y-size for 1/4 update test */
183 rb
->memset(ydata
, 128, sizeof(ydata
)); /* medium grey */
185 /* Test 1: full LCD update */
186 make_gradient_rect(YUV_WIDTH
, YUV_HEIGHT
);
189 rb
->sleep(0); /* sync to tick */
190 time_start
= *rb
->current_tick
;
191 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
193 rb
->lcd_yuv_blit(yuvbuf
, 0, 0, YUV_WIDTH
,
194 0, 0, YUV_WIDTH
, YUV_HEIGHT
);
197 fps
= calc_tenth_fps(frame_count
, time_end
- time_start
);
198 rb
->snprintf(str
, sizeof(str
), "1/1: %d.%d fps", fps
/ 10, fps
% 10);
201 /* Test 2: quarter LCD update */
202 make_gradient_rect(YUV_WIDTH
/2, YUV_HEIGHT
/2);
205 rb
->sleep(0); /* sync to tick */
206 time_start
= *rb
->current_tick
;
207 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
209 rb
->lcd_yuv_blit(yuvbuf
, 0, 0, YUV_WIDTH
,
210 part14_x
, part14_y
, part14_w
, part14_h
);
213 fps
= calc_tenth_fps(frame_count
, time_end
- time_start
);
214 rb
->snprintf(str
, sizeof(str
), "1/4: %d.%d fps", fps
/ 10, fps
% 10);
219 #ifdef HAVE_REMOTE_LCD
220 static void time_remote_update(void)
222 char str
[32]; /* text buffer */
223 long time_start
; /* start tickcount */
224 long time_end
; /* end tickcount */
228 const int part14_x
= LCD_REMOTE_WIDTH
/4; /* x-offset for 1/4 update test */
229 const int part14_w
= LCD_REMOTE_WIDTH
/2; /* x-size for 1/4 update test */
230 const int part14_y
= LCD_REMOTE_HEIGHT
/4; /* y-offset for 1/4 update test */
231 const int part14_h
= LCD_REMOTE_HEIGHT
/2; /* y-size for 1/4 update test */
233 /* Test 1: full LCD update */
235 rb
->sleep(0); /* sync to tick */
236 time_start
= *rb
->current_tick
;
237 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
239 rb
->lcd_remote_update();
242 fps
= calc_tenth_fps(frame_count
, time_end
- time_start
);
243 rb
->snprintf(str
, sizeof(str
), "1/1: %d.%d fps", fps
/ 10, fps
% 10);
246 /* Test 2: quarter LCD update */
248 rb
->sleep(0); /* sync to tick */
249 time_start
= *rb
->current_tick
;
250 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
252 rb
->lcd_remote_update_rect(part14_x
, part14_y
, part14_w
, part14_h
);
255 fps
= calc_tenth_fps(frame_count
, time_end
- time_start
);
256 rb
->snprintf(str
, sizeof(str
), "1/4: %d.%d fps", fps
/ 10, fps
% 10);
263 GREY_INFO_STRUCT_IRAM
264 static unsigned char greydata
[LCD_HEIGHT
][LCD_WIDTH
];
266 static void make_grey_rect(int width
, int height
)
268 unsigned char vline
[LCD_WIDTH
];
271 for (x
= 0; x
< width
; x
++)
272 vline
[x
] = (x
<< 8) / width
;
273 for (y
= 0; y
< height
; y
++)
274 rb
->memcpy(greydata
[y
], vline
, width
);
277 static void time_greyscale(void)
279 char str
[32]; /* text buffer */
280 long time_start
; /* start tickcount */
281 long time_end
; /* end tickcount */
283 int frames_1
, frames_2
;
286 gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
287 if (!grey_init(rb
, gbuf
, gbuf_size
, 0, LCD_WIDTH
, LCD_HEIGHT
, NULL
))
289 log_text("greylib: out of memory.");
292 make_grey_rect(LCD_WIDTH
, LCD_HEIGHT
);
294 /* Test 1 - greyscale overlay not yet enabled */
296 rb
->sleep(0); /* sync to tick */
297 time_start
= *rb
->current_tick
;
298 while((time_end
= *rb
->current_tick
) - time_start
< DURATION
)
300 grey_ub_gray_bitmap(greydata
[0], 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
303 time_1
= time_end
- time_start
;
305 /* Test 2 - greyscale overlay 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_2
= time_end
- time_start
;
318 fps
= calc_tenth_fps(frames_2
, time_2
);
319 load
= 100 - (100 * frames_2
* time_1
) / (frames_1
* time_2
);
320 rb
->snprintf(str
, sizeof(str
), "1/1: %d.%d fps", fps
/ 10, fps
% 10);
323 if (load
> 0 && load
< 100)
325 rb
->snprintf(str
, sizeof(str
), "CPU load: %d%%", load
);
329 log_text("CPU load err (boost?)");
333 /* plugin entry point */
334 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
342 PLUGIN_IRAM_INIT(api
)
348 cpu_freq
= *rb
->cpu_frequency
; /* remember CPU frequency */
350 backlight_force_on(rb
); /* backlight control in lib/helper.c */
352 log_text("Main LCD Update");
354 #ifdef HAVE_LCD_COLOR
355 log_text("Main LCD YUV");
359 log_text("Greyscale library");
362 #ifdef HAVE_REMOTE_LCD
363 log_text("Remote LCD Update");
364 time_remote_update();
368 if (*rb
->cpu_frequency
!= cpu_freq
)
369 rb
->snprintf(str
, sizeof(str
), "CPU clock changed!");
371 rb
->snprintf(str
, sizeof(str
), "CPU: %d MHz",
372 (cpu_freq
+ 500000) / 1000000);
375 backlight_use_settings(rb
); /* backlight control in lib/helper.c */
377 /* wait until user closes plugin */
378 while (rb
->button_get(true) != FPS_QUIT
);