diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c index 5e1110eb3d..bc391632ad 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | |||
@@ -201,8 +201,8 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | |||
201 | int stride, int x, int y, int width, | 201 | int stride, int x, int y, int width, |
202 | int height) | 202 | int height) |
203 | { | 203 | { |
204 | fb_data *dst, *dst_end; | 204 | int w, px; |
205 | unsigned int transcolor; | 205 | fb_data *dst; |
206 | 206 | ||
207 | if (x + width > LCD_WIDTH) | 207 | if (x + width > LCD_WIDTH) |
208 | width = LCD_WIDTH - x; /* Clip right */ | 208 | width = LCD_WIDTH - x; /* Clip right */ |
@@ -219,26 +219,29 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | |||
219 | return; /* nothing left to do */ | 219 | return; /* nothing left to do */ |
220 | 220 | ||
221 | src += stride * src_y + src_x; /* move starting point */ | 221 | src += stride * src_y + src_x; /* move starting point */ |
222 | dst = &lcd_framebuffer[(y)][(x)]; | 222 | dst = &lcd_framebuffer[y][x]; |
223 | dst_end = dst + height * LCD_WIDTH; | 223 | |
224 | width *= 2; | 224 | asm volatile ( |
225 | stride *= 2; | 225 | ".rowstart: \r\n" |
226 | transcolor = TRANSPARENT_COLOR; | 226 | "mov %[w], %[width] \r\n" /* Load width for inner loop */ |
227 | asm volatile( | 227 | ".nextpixel: \r\n" |
228 | "rowstart: \n" | 228 | "ldrh %[px], [%[s]], #2 \r\n" /* Load src pixel */ |
229 | "mov r0, #0 \n" | 229 | "add %[d], %[d], #2 \r\n" /* Uncoditionally increment dst */ |
230 | "nextpixel: \n" | 230 | "cmp %[px], %[transcolor] \r\n" /* Compare to transparent color */ |
231 | "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ | 231 | "strneh %[px], [%[d], #-2] \r\n" /* Store dst if not transparent */ |
232 | "cmp r1, %5 \n" /* Compare to transparent color */ | 232 | "subs %[w], %[w], #1 \r\n" /* Width counter has run down? */ |
233 | "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ | 233 | "bgt .nextpixel \r\n" /* More in this row? */ |
234 | "add r0, r0, #2 \n" | 234 | "add %[s], %[s], %[sstp], lsl #1 \r\n" /* Skip over to start of next line */ |
235 | "cmp r0, %2 \n" /* r0 == width? */ | 235 | "add %[d], %[d], %[dstp], lsl #1 \r\n" |
236 | "bne nextpixel \n" /* More in this row? */ | 236 | "subs %[h], %[h], #1 \r\n" /* Height counter has run down? */ |
237 | "add %0, %0, %4 \n" /* src += stride */ | 237 | "bgt .rowstart \r\n" /* More rows? */ |
238 | "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ | 238 | : [w]"=&r"(w), [h]"+&r"(height), [px]"=&r"(px), |
239 | "cmp %1, %3 \n" | 239 | [s]"+&r"(src), [d]"+&r"(dst) |
240 | "bne rowstart \n" /* if(dst != dst_end), keep going */ | 240 | : [width]"r"(width), |
241 | : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); | 241 | [sstp]"r"(stride - width), |
242 | [dstp]"r"(LCD_WIDTH - width), | ||
243 | [transcolor]"r"(TRANSPARENT_COLOR) | ||
244 | ); | ||
242 | } | 245 | } |
243 | 246 | ||
244 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | 247 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ |