diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-07-08 17:10:22 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-07-08 17:10:22 +0000 |
commit | 897c64399196745407ff022c595ff07c07cc01bb (patch) | |
tree | 5fcf888e93aa8e51a11a2538629c148d41e0f9e3 /firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | |
parent | 3f8c075f24fdcb4c471a4a0ae149f730e339450d (diff) | |
download | rockbox-897c64399196745407ff022c595ff07c07cc01bb.tar.gz rockbox-897c64399196745407ff022c595ff07c07cc01bb.zip |
Gigabeat: properly confined framebuffer copies and a few pendantic changes to lcd_yuv_blit. No difference full screen but quite a speedup to copy only the required bit: 534->1062 fps for 1/4 screen update using test_fps.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13821 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c')
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | 86 |
1 files changed, 55 insertions, 31 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 c96e0d6d25..5e1110eb3d 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | |||
@@ -15,6 +15,12 @@ volatile bool lcd_poweroff = false; | |||
15 | extern unsigned fg_pattern; | 15 | extern unsigned fg_pattern; |
16 | extern unsigned bg_pattern; | 16 | extern unsigned bg_pattern; |
17 | 17 | ||
18 | /* Copies a rectangle from one framebuffer to another. Can be used in | ||
19 | single transfer mode with width = num pixels, and height = 1 which | ||
20 | allows a full-width rectangle to be copied more efficiently. */ | ||
21 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, | ||
22 | int width, int height); | ||
23 | |||
18 | bool lcd_enabled() | 24 | bool lcd_enabled() |
19 | { | 25 | { |
20 | return lcd_on; | 26 | return lcd_on; |
@@ -36,7 +42,6 @@ unsigned int LCDBASEL(unsigned int address) | |||
36 | return (address & ((1 << 22)-1)) >> 1; | 42 | return (address & ((1 << 22)-1)) >> 1; |
37 | } | 43 | } |
38 | 44 | ||
39 | |||
40 | /* LCD init */ | 45 | /* LCD init */ |
41 | void lcd_init_device(void) | 46 | void lcd_init_device(void) |
42 | { | 47 | { |
@@ -122,17 +127,41 @@ void lcd_init_device(void) | |||
122 | /* Update a fraction of the display. */ | 127 | /* Update a fraction of the display. */ |
123 | void lcd_update_rect(int x, int y, int width, int height) | 128 | void lcd_update_rect(int x, int y, int width, int height) |
124 | { | 129 | { |
125 | (void)x; | 130 | fb_data *dst, *src; |
126 | (void)width; | ||
127 | (void)y; | ||
128 | (void)height; | ||
129 | 131 | ||
130 | if(!lcd_on) | 132 | if (!lcd_on) |
131 | { | ||
132 | sleep(200); | ||
133 | return; | 133 | return; |
134 | |||
135 | if (x + width > LCD_WIDTH) | ||
136 | width = LCD_WIDTH - x; /* Clip right */ | ||
137 | if (x < 0) | ||
138 | width += x, x = 0; /* Clip left */ | ||
139 | if (width <= 0) | ||
140 | return; /* nothing left to do */ | ||
141 | |||
142 | if (y + height > LCD_HEIGHT) | ||
143 | height = LCD_HEIGHT - y; /* Clip bottom */ | ||
144 | if (y < 0) | ||
145 | height += y, y = 0; /* Clip top */ | ||
146 | if (height <= 0) | ||
147 | return; /* nothing left to do */ | ||
148 | |||
149 | /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer | ||
150 | * and lcd_framebuffer */ | ||
151 | dst = (fb_data *)FRAME + LCD_WIDTH*y + x; | ||
152 | src = &lcd_framebuffer[y][x]; | ||
153 | |||
154 | /* Copy part of the Rockbox framebuffer to the second framebuffer */ | ||
155 | if (width < LCD_WIDTH) | ||
156 | { | ||
157 | /* Not full width - do line-by-line */ | ||
158 | lcd_copy_buffer_rect(dst, src, width, height); | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | /* Full width - copy as one line */ | ||
163 | lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); | ||
134 | } | 164 | } |
135 | memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); | ||
136 | } | 165 | } |
137 | 166 | ||
138 | void lcd_enable(bool state) | 167 | void lcd_enable(bool state) |
@@ -144,7 +173,7 @@ void lcd_enable(bool state) | |||
144 | if(!lcd_on) | 173 | if(!lcd_on) |
145 | { | 174 | { |
146 | lcd_on = true; | 175 | lcd_on = true; |
147 | memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); | 176 | lcd_update(); |
148 | LCDCON1 |= 1; | 177 | LCDCON1 |= 1; |
149 | } | 178 | } |
150 | } | 179 | } |
@@ -161,7 +190,11 @@ void lcd_enable(bool state) | |||
161 | This must be called after all other LCD functions that change the display. */ | 190 | This must be called after all other LCD functions that change the display. */ |
162 | void lcd_update(void) | 191 | void lcd_update(void) |
163 | { | 192 | { |
164 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | 193 | if (!lcd_on) |
194 | return; | ||
195 | |||
196 | lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], | ||
197 | LCD_WIDTH*LCD_HEIGHT, 1); | ||
165 | } | 198 | } |
166 | 199 | ||
167 | void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | 200 | void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, |
@@ -171,28 +204,19 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | |||
171 | fb_data *dst, *dst_end; | 204 | fb_data *dst, *dst_end; |
172 | unsigned int transcolor; | 205 | unsigned int transcolor; |
173 | 206 | ||
174 | /* nothing to draw? */ | ||
175 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
176 | || (x + width <= 0) || (y + height <= 0)) | ||
177 | return; | ||
178 | |||
179 | /* clipping */ | ||
180 | if (x < 0) | ||
181 | { | ||
182 | width += x; | ||
183 | src_x -= x; | ||
184 | x = 0; | ||
185 | } | ||
186 | if (y < 0) | ||
187 | { | ||
188 | height += y; | ||
189 | src_y -= y; | ||
190 | y = 0; | ||
191 | } | ||
192 | if (x + width > LCD_WIDTH) | 207 | if (x + width > LCD_WIDTH) |
193 | width = LCD_WIDTH - x; | 208 | width = LCD_WIDTH - x; /* Clip right */ |
209 | if (x < 0) | ||
210 | width += x, x = 0; /* Clip left */ | ||
211 | if (width <= 0) | ||
212 | return; /* nothing left to do */ | ||
213 | |||
194 | if (y + height > LCD_HEIGHT) | 214 | if (y + height > LCD_HEIGHT) |
195 | height = LCD_HEIGHT - y; | 215 | height = LCD_HEIGHT - y; /* Clip bottom */ |
216 | if (y < 0) | ||
217 | height += y, y = 0; /* Clip top */ | ||
218 | if (height <= 0) | ||
219 | return; /* nothing left to do */ | ||
196 | 220 | ||
197 | src += stride * src_y + src_x; /* move starting point */ | 221 | src += stride * src_y + src_x; /* move starting point */ |
198 | dst = &lcd_framebuffer[(y)][(x)]; | 222 | dst = &lcd_framebuffer[(y)][(x)]; |