diff options
Diffstat (limited to 'firmware/drivers/lcd-memframe.c')
-rw-r--r-- | firmware/drivers/lcd-memframe.c | 73 |
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 ***/ |
29 | bool 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) |
32 | static bool lcd_on SHAREDBSS_ATTR = false; /* Is the display turned on? */ | ||
33 | #else | ||
34 | static bool lcd_on SHAREDBSS_ATTR = true; /* Is the display turned on? */ | ||
35 | #endif | ||
36 | |||
37 | bool lcd_active(void) | 32 | bool 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) | |||
53 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, | 57 | extern 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. */ |
58 | void lcd_update(void) | 63 | void 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. */ | ||
68 | void lcd_update_rect(int x, int y, int width, int height) | 76 | void 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 | */ | ||
130 | void lcd_blit_yuv(unsigned char * const src[3], | 143 | void 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 */ | ||