aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/console/bitblit.c150
-rw-r--r--drivers/video/fbmem.c10
-rw-r--r--include/linux/fb.h15
3 files changed, 109 insertions, 66 deletions
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 6550875ef9c5..9f70e512b88b 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -103,42 +103,104 @@ static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
103 info->fbops->fb_fillrect(info, &region); 103 info->fbops->fb_fillrect(info, &region);
104} 104}
105 105
106static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
107 const u16 *s, u32 attr, u32 cnt,
108 u32 d_pitch, u32 s_pitch, u32 cellsize,
109 struct fb_image *image, u8 *buf, u8 *dst)
110{
111 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
112 u32 idx = vc->vc_font.width >> 3;
113 u8 *src;
114
115 while (cnt--) {
116 src = vc->vc_font.data + (scr_readw(s++)&
117 charmask)*cellsize;
118
119 if (attr) {
120 update_attr(buf, src, attr, vc);
121 src = buf;
122 }
123
124 if (likely(idx == 1))
125 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
126 image->height);
127 else
128 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
129 image->height);
130
131 dst += s_pitch;
132 }
133
134 info->fbops->fb_imageblit(info, image);
135}
136
137static inline void bit_putcs_unaligned(struct vc_data *vc,
138 struct fb_info *info, const u16 *s,
139 u32 attr, u32 cnt, u32 d_pitch,
140 u32 s_pitch, u32 cellsize,
141 struct fb_image *image, u8 *buf,
142 u8 *dst)
143{
144 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
145 u32 shift_low = 0, mod = vc->vc_font.width % 8;
146 u32 shift_high = 8;
147 u32 idx = vc->vc_font.width >> 3;
148 u8 *src;
149
150 while (cnt--) {
151 src = vc->vc_font.data + (scr_readw(s++)&
152 charmask)*cellsize;
153
154 if (attr) {
155 update_attr(buf, src, attr, vc);
156 src = buf;
157 }
158
159 fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
160 image->height, shift_high,
161 shift_low, mod);
162 shift_low += mod;
163 dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
164 shift_low &= 7;
165 shift_high = 8 - shift_low;
166 }
167
168 info->fbops->fb_imageblit(info, image);
169
170}
171
106static void bit_putcs(struct vc_data *vc, struct fb_info *info, 172static void bit_putcs(struct vc_data *vc, struct fb_info *info,
107 const unsigned short *s, int count, int yy, int xx, 173 const unsigned short *s, int count, int yy, int xx,
108 int fg, int bg) 174 int fg, int bg)
109{ 175{
110 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
111 unsigned int width = (vc->vc_font.width + 7) >> 3;
112 unsigned int cellsize = vc->vc_font.height * width;
113 unsigned int maxcnt = info->pixmap.size/cellsize;
114 unsigned int scan_align = info->pixmap.scan_align - 1;
115 unsigned int buf_align = info->pixmap.buf_align - 1;
116 unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
117 unsigned int shift_high = 8, pitch, cnt, size, i, k;
118 unsigned int idx = vc->vc_font.width >> 3;
119 unsigned int attribute = get_attribute(info, scr_readw(s));
120 struct fb_image image; 176 struct fb_image image;
121 u8 *src, *dst, *buf = NULL; 177 u32 width = (vc->vc_font.width + 7)/8;
122 178 u32 cellsize = width * vc->vc_font.height;
123 if (attribute) { 179 u32 maxcnt = info->pixmap.size/cellsize;
124 buf = kmalloc(cellsize, GFP_KERNEL); 180 u32 scan_align = info->pixmap.scan_align - 1;
125 if (!buf) 181 u32 buf_align = info->pixmap.buf_align - 1;
126 return; 182 u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
127 } 183 u32 attribute = get_attribute(info, scr_readw(s));
184 u8 *dst, *buf = NULL;
128 185
129 image.fg_color = fg; 186 image.fg_color = fg;
130 image.bg_color = bg; 187 image.bg_color = bg;
131
132 image.dx = xx * vc->vc_font.width; 188 image.dx = xx * vc->vc_font.width;
133 image.dy = yy * vc->vc_font.height; 189 image.dy = yy * vc->vc_font.height;
134 image.height = vc->vc_font.height; 190 image.height = vc->vc_font.height;
135 image.depth = 1; 191 image.depth = 1;
136 192
193 if (attribute) {
194 buf = kmalloc(cellsize, GFP_KERNEL);
195 if (!buf)
196 return;
197 }
198
137 while (count) { 199 while (count) {
138 if (count > maxcnt) 200 if (count > maxcnt)
139 cnt = k = maxcnt; 201 cnt = maxcnt;
140 else 202 else
141 cnt = k = count; 203 cnt = count;
142 204
143 image.width = vc->vc_font.width * cnt; 205 image.width = vc->vc_font.width * cnt;
144 pitch = ((image.width + 7) >> 3) + scan_align; 206 pitch = ((image.width + 7) >> 3) + scan_align;
@@ -147,45 +209,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
147 size &= ~buf_align; 209 size &= ~buf_align;
148 dst = fb_get_buffer_offset(info, &info->pixmap, size); 210 dst = fb_get_buffer_offset(info, &info->pixmap, size);
149 image.data = dst; 211 image.data = dst;
150 if (mod) { 212
151 while (k--) { 213 if (!mod)
152 src = vc->vc_font.data + (scr_readw(s++)& 214 bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
153 charmask)*cellsize; 215 width, cellsize, &image, buf, dst);
154 216 else
155 if (attribute) { 217 bit_putcs_unaligned(vc, info, s, attribute, cnt,
156 update_attr(buf, src, attribute, vc); 218 pitch, width, cellsize, &image,
157 src = buf; 219 buf, dst);
158 } 220
159
160 fb_pad_unaligned_buffer(dst, pitch, src, idx,
161 image.height, shift_high,
162 shift_low, mod);
163 shift_low += mod;
164 dst += (shift_low >= 8) ? width : width - 1;
165 shift_low &= 7;
166 shift_high = 8 - shift_low;
167 }
168 } else {
169 while (k--) {
170 src = vc->vc_font.data + (scr_readw(s++)&
171 charmask)*cellsize;
172
173 if (attribute) {
174 update_attr(buf, src, attribute, vc);
175 src = buf;
176 }
177
178 if (idx == 1)
179 for(i=0; i < image.height; i++)
180 dst[pitch*i] = src[i];
181 else
182 fb_pad_aligned_buffer(dst, pitch, src, idx, image.height);
183 dst += width;
184 }
185 }
186 info->fbops->fb_imageblit(info, &image);
187 image.dx += cnt * vc->vc_font.width; 221 image.dx += cnt * vc->vc_font.width;
188 count -= cnt; 222 count -= cnt;
223 s += cnt;
189 } 224 }
190 225
191 /* buf is always NULL except when in monochrome mode, so in this case 226 /* buf is always NULL except when in monochrome mode, so in this case
@@ -193,6 +228,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
193 NULL pointers just fine */ 228 NULL pointers just fine */
194 if (unlikely(buf)) 229 if (unlikely(buf))
195 kfree(buf); 230 kfree(buf);
231
196} 232}
197 233
198static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, 234static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 71b55070bdb9..70be7009f8af 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -90,15 +90,7 @@ EXPORT_SYMBOL(fb_get_color_depth);
90 */ 90 */
91void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) 91void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height)
92{ 92{
93 int i, j; 93 __fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, height);
94
95 for (i = height; i--; ) {
96 /* s_pitch is a few bytes at the most, memcpy is suboptimal */
97 for (j = 0; j < s_pitch; j++)
98 dst[j] = src[j];
99 src += s_pitch;
100 dst += d_pitch;
101 }
102} 94}
103EXPORT_SYMBOL(fb_pad_aligned_buffer); 95EXPORT_SYMBOL(fb_pad_aligned_buffer);
104 96
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 9a4f035e9fdc..82e39cd0c4fb 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -833,6 +833,21 @@ extern int fb_new_modelist(struct fb_info *info);
833extern struct fb_info *registered_fb[FB_MAX]; 833extern struct fb_info *registered_fb[FB_MAX];
834extern int num_registered_fb; 834extern int num_registered_fb;
835 835
836static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
837 u8 *src, u32 s_pitch, u32 height)
838{
839 int i, j;
840
841 d_pitch -= s_pitch;
842
843 for (i = height; i--; ) {
844 /* s_pitch is a few bytes at the most, memcpy is suboptimal */
845 for (j = 0; j < s_pitch; j++)
846 *dst++ = *src++;
847 dst += d_pitch;
848 }
849}
850
836/* drivers/video/fbsysfs.c */ 851/* drivers/video/fbsysfs.c */
837extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); 852extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
838extern void framebuffer_release(struct fb_info *info); 853extern void framebuffer_release(struct fb_info *info);