summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-04-04 22:13:53 +0000
committerJens Arnold <amiconn@rockbox.org>2008-04-04 22:13:53 +0000
commit32bd0f8ab1526e32011937a827b6e44476a6743e (patch)
treec0bdfebc167a0b06daba4de23beba31027b0d693
parent391377725ea18688aa93c542a3b470df73b88f51 (diff)
downloadrockbox-32bd0f8ab1526e32011937a827b6e44476a6743e.tar.gz
rockbox-32bd0f8ab1526e32011937a827b6e44476a6743e.zip
Greyscale library: Optionally put the greyscale ISR on COP on portalplayertargets (only use with the grey_info structure in IRAM atm\!). This speeds up doom by ~50%, and makes mpegplayer work without stuttering audio on targets using it (measured on iPod 2nd Gen and Mini 2nd Gen). It needs corelocking certain functions in the LCD driver on 1st/2nd Gen.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16973 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/doom/i_video.c2
-rw-r--r--apps/plugins/lib/grey.h6
-rw-r--r--apps/plugins/lib/grey_core.c21
-rw-r--r--apps/plugins/mpegplayer/stream_mgr.c2
-rw-r--r--apps/plugins/test_fps.c2
-rw-r--r--apps/plugins/zxbox/zxbox.c5
-rw-r--r--firmware/target/arm/ipod/lcd-gray.c30
7 files changed, 52 insertions, 16 deletions
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index ce4b670583..2e98ce9f85 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -696,7 +696,7 @@ void I_InitGraphics(void)
696 696
697#ifndef HAVE_LCD_COLOR 697#ifndef HAVE_LCD_COLOR
698 gbuf=malloc(GREYBUFSIZE); 698 gbuf=malloc(GREYBUFSIZE);
699 grey_init(rb, gbuf, GREYBUFSIZE, 0, LCD_WIDTH, LCD_HEIGHT, NULL); 699 grey_init(rb, gbuf, GREYBUFSIZE, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL);
700 /* switch on greyscale overlay */ 700 /* switch on greyscale overlay */
701 grey_show(true); 701 grey_show(true);
702#endif 702#endif
diff --git a/apps/plugins/lib/grey.h b/apps/plugins/lib/grey.h
index 3f7be44522..95dca6beb6 100644
--- a/apps/plugins/lib/grey.h
+++ b/apps/plugins/lib/grey.h
@@ -45,8 +45,10 @@
45#define GREY_INFO_STRUCT_IRAM struct _grey_info _grey_info IBSS_ATTR; 45#define GREY_INFO_STRUCT_IRAM struct _grey_info _grey_info IBSS_ATTR;
46 46
47/* Features you can request on library init (ORed together): */ 47/* Features you can request on library init (ORed together): */
48#define GREY_BUFFERED 0x0001 48#define GREY_BUFFERED 0x0001 /* Use a chunky buffer */
49#define GREY_RAWMAPPED 0x0002 49#define GREY_RAWMAPPED 0x0002 /* No gamma & LCD linearisation */
50#define GREY_ON_COP 0x0004 /* Run ISR on COP (PP targets) */
51 /* TODO: only usable in conjunction with GREY_INFO_STRUCT_IRAM atm */
50 52
51/* Library initialisation and release */ 53/* Library initialisation and release */
52bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, 54bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
diff --git a/apps/plugins/lib/grey_core.c b/apps/plugins/lib/grey_core.c
index 20c33a60f4..1326599574 100644
--- a/apps/plugins/lib/grey_core.c
+++ b/apps/plugins/lib/grey_core.c
@@ -495,11 +495,12 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
495#endif 495#endif
496 496
497 plane_size = _GREY_MULUQ(width, height); 497 plane_size = _GREY_MULUQ(width, height);
498#ifdef CPU_COLDFIRE 498#if defined(CPU_COLDFIRE) /* Buffers should be line aligned */ \
499 plane_size += (-plane_size) & 0xf; /* All buffers should be line aligned */ 499 || defined(CPU_PP) && (NUM_CORES > 1) /* Buffers must be cache line aligned */
500 plane_size += (-plane_size) & 0xf;
500 buftaken = (-(long)gbuf) & 0xf; 501 buftaken = (-(long)gbuf) & 0xf;
501#else 502#else /* Buffers must be 32 bit aligned. */
502 buftaken = (-(long)gbuf) & 3; /* All buffers must be long aligned. */ 503 buftaken = (-(long)gbuf) & 3;
503#endif 504#endif
504 gbuf += buftaken; 505 gbuf += buftaken;
505 506
@@ -509,6 +510,10 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
509 gbuf += plane_size; 510 gbuf += plane_size;
510 buftaken += plane_size; 511 buftaken += plane_size;
511 } 512 }
513#if NUM_CORES > 1 /* Values and phases must be uncached when running on COP */
514 if (features & GREY_ON_COP)
515 gbuf = UNCACHED_ADDR(gbuf);
516#endif
512 _grey_info.values = gbuf; 517 _grey_info.values = gbuf;
513 gbuf += plane_size; 518 gbuf += plane_size;
514 _grey_info.phases = gbuf; 519 _grey_info.phases = gbuf;
@@ -602,8 +607,14 @@ void grey_show(bool enable)
602#ifdef NEED_BOOST 607#ifdef NEED_BOOST
603 _grey_info.rb->cpu_boost(true); 608 _grey_info.rb->cpu_boost(true);
604#endif 609#endif
610#if NUM_CORES > 1
611 _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / LCD_SCANRATE,
612 1, _timer_isr,
613 (_grey_info.flags & GREY_ON_COP) ? COP : CPU);
614#else
605 _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / LCD_SCANRATE, 1, 615 _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / LCD_SCANRATE, 1,
606 _timer_isr IF_COP(, CPU)); 616 _timer_isr);
617#endif
607#endif /* !SIMULATOR */ 618#endif /* !SIMULATOR */
608 _grey_info.rb->screen_dump_set_hook(grey_screendump_hook); 619 _grey_info.rb->screen_dump_set_hook(grey_screendump_hook);
609 } 620 }
diff --git a/apps/plugins/mpegplayer/stream_mgr.c b/apps/plugins/mpegplayer/stream_mgr.c
index b962c5b993..778ed0df83 100644
--- a/apps/plugins/mpegplayer/stream_mgr.c
+++ b/apps/plugins/mpegplayer/stream_mgr.c
@@ -1005,7 +1005,7 @@ int stream_init(void)
1005 graymem = mem; 1005 graymem = mem;
1006#endif 1006#endif
1007 1007
1008 success = grey_init(rb, graymem, memsize, GREY_BUFFERED, 1008 success = grey_init(rb, graymem, memsize, GREY_BUFFERED|GREY_ON_COP,
1009 LCD_WIDTH, LCD_HEIGHT, &graysize); 1009 LCD_WIDTH, LCD_HEIGHT, &graysize);
1010 1010
1011 /* This can run on another processor - align size */ 1011 /* This can run on another processor - align size */
diff --git a/apps/plugins/test_fps.c b/apps/plugins/test_fps.c
index a312c13662..da61a4f348 100644
--- a/apps/plugins/test_fps.c
+++ b/apps/plugins/test_fps.c
@@ -286,7 +286,7 @@ static void time_greyscale(void)
286 int fps, load; 286 int fps, load;
287 287
288 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); 288 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
289 if (!grey_init(rb, gbuf, gbuf_size, 0, LCD_WIDTH, LCD_HEIGHT, NULL)) 289 if (!grey_init(rb, gbuf, gbuf_size, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL))
290 { 290 {
291 log_text("greylib: out of memory."); 291 log_text("greylib: out of memory.");
292 return; 292 return;
diff --git a/apps/plugins/zxbox/zxbox.c b/apps/plugins/zxbox/zxbox.c
index 198aeecb37..3d94981ce5 100644
--- a/apps/plugins/zxbox/zxbox.c
+++ b/apps/plugins/zxbox/zxbox.c
@@ -74,9 +74,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
74 /* get the remainder of the plugin buffer */ 74 /* get the remainder of the plugin buffer */
75 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); 75 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
76#ifdef USE_BUFFERED_GREY 76#ifdef USE_BUFFERED_GREY
77 grey_init(rb, gbuf, gbuf_size, GREY_BUFFERED, LCD_WIDTH, LCD_HEIGHT, NULL); 77 grey_init(rb, gbuf, gbuf_size, GREY_BUFFERED|GREY_ON_COP, LCD_WIDTH,
78 LCD_HEIGHT, NULL);
78#else 79#else
79 grey_init(rb, gbuf, gbuf_size, 0, LCD_WIDTH, LCD_HEIGHT, NULL); 80 grey_init(rb, gbuf, gbuf_size, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL);
80#endif /* USE_BUFFERED_GREY */ 81#endif /* USE_BUFFERED_GREY */
81 /* switch on greyscale overlay */ 82 /* switch on greyscale overlay */
82 grey_show(true); 83 grey_show(true);
diff --git a/firmware/target/arm/ipod/lcd-gray.c b/firmware/target/arm/ipod/lcd-gray.c
index 131b52da96..5cc219162c 100644
--- a/firmware/target/arm/ipod/lcd-gray.c
+++ b/firmware/target/arm/ipod/lcd-gray.c
@@ -53,6 +53,10 @@
53/* The backlight makes the LCD appear negative on the 1st/2nd gen */ 53/* The backlight makes the LCD appear negative on the 1st/2nd gen */
54static bool lcd_inverted = false; 54static bool lcd_inverted = false;
55static bool lcd_backlit = false; 55static bool lcd_backlit = false;
56#if NUM_CORES > 1
57/* invert_display() and the lcd_blit_* functions need to be corelocked */
58static struct corelock cl IBSS_ATTR;
59#endif
56static void invert_display(void); 60static void invert_display(void);
57#endif 61#endif
58 62
@@ -112,7 +116,9 @@ static void lcd_cmd_and_data(unsigned cmd, unsigned data)
112/* LCD init */ 116/* LCD init */
113void lcd_init_device(void) 117void lcd_init_device(void)
114{ 118{
115 119#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
120 corelock_init(&cl);
121#endif
116#ifdef IPOD_MINI2G /* serial LCD hookup */ 122#ifdef IPOD_MINI2G /* serial LCD hookup */
117 lcd_wait_write(); 123 lcd_wait_write();
118 LCD1_CONTROL = 0x01730084; /* fastest setting */ 124 LCD1_CONTROL = 0x01730084; /* fastest setting */
@@ -167,7 +173,13 @@ static void invert_display(void)
167 if (new_invert != last_invert) 173 if (new_invert != last_invert)
168 { 174 {
169 int oldlevel = disable_irq_save(); 175 int oldlevel = disable_irq_save();
176#if NUM_CORES > 1
177 corelock_lock(&cl);
170 lcd_cmd_and_data(R_DISPLAY_CONTROL, new_invert? 0x0017 : 0x0015); 178 lcd_cmd_and_data(R_DISPLAY_CONTROL, new_invert? 0x0017 : 0x0015);
179 corelock_unlock(&cl);
180#else
181 lcd_cmd_and_data(R_DISPLAY_CONTROL, new_invert? 0x0017 : 0x0015);
182#endif
171 restore_irq(oldlevel); 183 restore_irq(oldlevel);
172 last_invert = new_invert; 184 last_invert = new_invert;
173 } 185 }
@@ -254,14 +266,19 @@ void lcd_mono_data(const unsigned char *data, int count);
254void lcd_blit_mono(const unsigned char *data, int bx, int y, int bwidth, 266void lcd_blit_mono(const unsigned char *data, int bx, int y, int bwidth,
255 int height, int stride) 267 int height, int stride)
256{ 268{
269#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
270 corelock_lock(&cl);
271#endif
257 while (height--) 272 while (height--)
258 { 273 {
259 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); 274 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
260 lcd_prepare_cmd(R_RAM_DATA); 275 lcd_prepare_cmd(R_RAM_DATA);
261
262 lcd_mono_data(data, bwidth); 276 lcd_mono_data(data, bwidth);
263 data += stride; 277 data += stride;
264 } 278 }
279#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
280 corelock_unlock(&cl);
281#endif
265} 282}
266 283
267/* Helper function for lcd_grey_phase_blit(). */ 284/* Helper function for lcd_grey_phase_blit(). */
@@ -272,15 +289,20 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
272void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases, 289void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
273 int bx, int y, int bwidth, int height, int stride) 290 int bx, int y, int bwidth, int height, int stride)
274{ 291{
275 while (height--) 292#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
293 corelock_lock(&cl);
294#endif
295 while (height--)
276 { 296 {
277 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); 297 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
278 lcd_prepare_cmd(R_RAM_DATA); 298 lcd_prepare_cmd(R_RAM_DATA);
279
280 lcd_grey_data(values, phases, bwidth); 299 lcd_grey_data(values, phases, bwidth);
281 values += stride; 300 values += stride;
282 phases += stride; 301 phases += stride;
283 } 302 }
303#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
304 corelock_unlock(&cl);
305#endif
284} 306}
285 307
286void lcd_update_rect(int x, int y, int width, int height) 308void lcd_update_rect(int x, int y, int width, int height)