summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-memframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-memframe.c')
-rw-r--r--firmware/drivers/lcd-memframe.c73
1 files changed, 53 insertions, 20 deletions
diff --git a/firmware/drivers/lcd-memframe.c b/firmware/drivers/lcd-memframe.c
index 304f0a7e9e..dd878876bf 100644
--- a/firmware/drivers/lcd-memframe.c
+++ b/firmware/drivers/lcd-memframe.c
@@ -20,20 +20,15 @@
20 * KIND, either express or implied. 20 * KIND, either express or implied.
21 * 21 *
22 ****************************************************************************/ 22 ****************************************************************************/
23#include <sys/types.h> /* off_t */
24#include "config.h" 23#include "config.h"
25#include "system.h" 24#include "system.h"
26#include "lcd.h" 25#include "lcd.h"
27#include "lcd-target.h" 26#include "lcd-target.h"
28 27
29/*** Misc. functions ***/ 28/*** Misc. functions ***/
29bool lcd_on SHAREDBSS_ATTR = false;
30 30
31#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) 31#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
32static bool lcd_on SHAREDBSS_ATTR = false; /* Is the display turned on? */
33#else
34static bool lcd_on SHAREDBSS_ATTR = true; /* Is the display turned on? */
35#endif
36
37bool lcd_active(void) 32bool lcd_active(void)
38{ 33{
39 return lcd_on; 34 return lcd_on;
@@ -45,6 +40,15 @@ void lcd_set_active(bool active)
45 lcd_on = active; 40 lcd_on = active;
46} 41}
47 42
43#else
44#define lcd_on true
45#endif
46
47#ifndef lcd_write_enabled
48#define lcd_write_enabled() lcd_on
49#endif
50
51
48/*** Blitting functions ***/ 52/*** Blitting functions ***/
49 53
50/* Copies a rectangle from one framebuffer to another. Can be used in 54/* Copies a rectangle from one framebuffer to another. Can be used in
@@ -53,23 +57,27 @@ void lcd_set_active(bool active)
53extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, 57extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src,
54 int width, int height); 58 int width, int height);
55 59
60#ifndef LCD_OPTIMIZED_UPDATE
56/* Update the display. 61/* Update the display.
57 This must be called after all other LCD functions that change the display. */ 62 This must be called after all other LCD functions that change the display. */
58void lcd_update(void) 63void lcd_update(void)
59{ 64{
60 if (!lcd_on) 65 if (!lcd_write_enabled())
61 return; 66 return;
62 67
63 /* Copy the Rockbox framebuffer to the second framebuffer */ 68 /* Copy the Rockbox framebuffer to the second framebuffer */
64 lcd_copy_buffer_rect(LCD_FRAMEBUF_ADDR(0, 0), &lcd_framebuffer[0][0], 69 lcd_copy_buffer_rect(LCD_FRAMEBUF_ADDR(0, 0), &lcd_framebuffer[0][0],
65 LCD_WIDTH*LCD_HEIGHT, 1); 70 LCD_WIDTH*LCD_HEIGHT, 1);
66} 71}
72#endif /* LCD_OPTIMIZED_UPDATE */
67 73
74#ifndef LCD_OPTIMIZED_UPDATE_RECT
75/* Update a fraction of the display. */
68void lcd_update_rect(int x, int y, int width, int height) 76void lcd_update_rect(int x, int y, int width, int height)
69{ 77{
70 fb_data *dst, *src; 78 fb_data *dst, *src;
71 79
72 if (!lcd_on) 80 if (!lcd_write_enabled())
73 return; 81 return;
74 82
75 if (x + width > LCD_WIDTH) 83 if (x + width > LCD_WIDTH)
@@ -101,6 +109,7 @@ void lcd_update_rect(int x, int y, int width, int height)
101 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); 109 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
102 } 110 }
103} 111}
112#endif /* LCD_OPTIMIZED_UPDATE_RECT */
104 113
105 114
106/*** YUV functions ***/ 115/*** YUV functions ***/
@@ -124,27 +133,50 @@ void lcd_yuv_set_options(unsigned options)
124 lcd_yuv_options = options; 133 lcd_yuv_options = options;
125} 134}
126 135
127/* Performance function to blit a YUV bitmap directly to the LCD */ 136#ifndef LCD_OPTIMIZED_BLIT_YUV
128/* For the e200 - show it rotated */ 137/* Performance function to blit a YUV bitmap directly to the LCD
129/* So the LCD_WIDTH is now the height */ 138 * src_x, src_y, width and height should be even and within the LCD's
139 * boundaries.
140 *
141 * For portrait LCDs, show it rotated counterclockwise by 90 degrees
142 */
130void lcd_blit_yuv(unsigned char * const src[3], 143void lcd_blit_yuv(unsigned char * const src[3],
131 int src_x, int src_y, int stride, 144 int src_x, int src_y, int stride,
132 int x, int y, int width, int height) 145 int x, int y, int width, int height)
133{ 146{
134 unsigned char const * yuv_src[3]; 147 /* Macrofy the bits that change between orientations */
135 off_t z; 148#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
149 #define LCD_FRAMEBUF_ADDR_ORIENTED(col, row) \
150 LCD_FRAMEBUF_ADDR(row, col)
151 #define lcd_write_yuv420_lines_odither_oriented(dst, src, w, s, col, row) \
152 lcd_write_yuv420_lines_odither(dst, src, w, s, row, col)
153 #define YUV_NEXTLINE() dst -= 2
154 #define YUV_DITHER_NEXTLINE() dst -= 2, y -= 2
155#else
156 #define LCD_FRAMEBUF_ADDR_ORIENTED(col, row) \
157 LCD_FRAMEBUF_ADDR(col, row)
158 #define lcd_write_yuv420_lines_odither_oriented(dst, src, w, s, col, row) \
159 lcd_write_yuv420_lines_odither(dst, src, w, s, col, row)
160 #define YUV_NEXTLINE() dst += 2*LCD_FBWIDTH
161 #define YUV_DITHER_NEXTLINE() dst += 2*LCD_FBWIDTH, y += 2
162#endif
136 163
137 if (!lcd_on) 164 if (!lcd_write_enabled())
138 return; 165 return;
139 166
140 /* Sorry, but width and height must be >= 2 or else */ 167 /* Sorry, but width and height must be >= 2 or else */
141 width &= ~1; 168 width &= ~1;
142 height >>= 1; 169 height >>= 1;
143 170
171#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
172 /* Adjust portrait coordinates to make (0, 0) the upper right corner */
144 y = LCD_WIDTH - 1 - y; 173 y = LCD_WIDTH - 1 - y;
145 fb_data *dst = LCD_FRAMEBUF_ADDR(y, x); 174#endif
146 175
147 z = stride*src_y; 176 fb_data *dst = LCD_FRAMEBUF_ADDR_ORIENTED(x, y);
177 int z = stride*src_y;
178
179 unsigned char const * yuv_src[3];
148 yuv_src[0] = src[0] + z + src_x; 180 yuv_src[0] = src[0] + z + src_x;
149 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); 181 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
150 yuv_src[2] = src[2] + (yuv_src[1] - src[1]); 182 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
@@ -153,12 +185,12 @@ void lcd_blit_yuv(unsigned char * const src[3],
153 { 185 {
154 do 186 do
155 { 187 {
156 lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); 188 lcd_write_yuv420_lines_odither_oriented(dst, yuv_src, width,
189 stride, x, y);
157 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 190 yuv_src[0] += stride << 1; /* Skip down two luma lines */
158 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 191 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
159 yuv_src[2] += stride >> 1; 192 yuv_src[2] += stride >> 1;
160 dst -= 2; 193 YUV_DITHER_NEXTLINE();
161 y -= 2;
162 } 194 }
163 while (--height > 0); 195 while (--height > 0);
164 } 196 }
@@ -170,8 +202,9 @@ void lcd_blit_yuv(unsigned char * const src[3],
170 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 202 yuv_src[0] += stride << 1; /* Skip down two luma lines */
171 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 203 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
172 yuv_src[2] += stride >> 1; 204 yuv_src[2] += stride >> 1;
173 dst -= 2; 205 YUV_NEXTLINE();
174 } 206 }
175 while (--height > 0); 207 while (--height > 0);
176 } 208 }
177} 209}
210#endif /* LCD_OPTIMIZED_BLIT_YUV */