@@ -218,7 +218,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
218
218
{
219
219
u32 fgx = fgcolor , bgx = bgcolor , bpp = p -> var .bits_per_pixel ;
220
220
u32 ppw = 32 /bpp , spitch = (image -> width + 7 )/8 ;
221
- u32 bit_mask , eorx ;
221
+ u32 bit_mask , eorx , shift ;
222
222
const char * s = image -> data , * src ;
223
223
u32 __iomem * dst ;
224
224
const u32 * tab = NULL ;
@@ -259,25 +259,31 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
259
259
260
260
for (i = image -> height ; i -- ; ) {
261
261
dst = (u32 __iomem * )dst1 ;
262
+ shift = 8 ;
262
263
src = s ;
263
264
265
+ /*
266
+ * Manually unroll the per-line copying loop for better
267
+ * performance. This works until we processed the last
268
+ * completely filled source byte (inclusive).
269
+ */
264
270
switch (ppw ) {
265
271
case 4 : /* 8 bpp */
266
- for (j = k ; j ; j -= 2 , ++ src ) {
272
+ for (j = k ; j >= 2 ; j -= 2 , ++ src ) {
267
273
FB_WRITEL (colortab [(* src >> 4 ) & bit_mask ], dst ++ );
268
274
FB_WRITEL (colortab [(* src >> 0 ) & bit_mask ], dst ++ );
269
275
}
270
276
break ;
271
277
case 2 : /* 16 bpp */
272
- for (j = k ; j ; j -= 4 , ++ src ) {
278
+ for (j = k ; j >= 4 ; j -= 4 , ++ src ) {
273
279
FB_WRITEL (colortab [(* src >> 6 ) & bit_mask ], dst ++ );
274
280
FB_WRITEL (colortab [(* src >> 4 ) & bit_mask ], dst ++ );
275
281
FB_WRITEL (colortab [(* src >> 2 ) & bit_mask ], dst ++ );
276
282
FB_WRITEL (colortab [(* src >> 0 ) & bit_mask ], dst ++ );
277
283
}
278
284
break ;
279
285
case 1 : /* 32 bpp */
280
- for (j = k ; j ; j -= 8 , ++ src ) {
286
+ for (j = k ; j >= 8 ; j -= 8 , ++ src ) {
281
287
FB_WRITEL (colortab [(* src >> 7 ) & bit_mask ], dst ++ );
282
288
FB_WRITEL (colortab [(* src >> 6 ) & bit_mask ], dst ++ );
283
289
FB_WRITEL (colortab [(* src >> 5 ) & bit_mask ], dst ++ );
@@ -290,6 +296,20 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
290
296
break ;
291
297
}
292
298
299
+ /*
300
+ * For image widths that are not a multiple of 8, there
301
+ * are trailing pixels left on the current line. Print
302
+ * them as well.
303
+ */
304
+ for (; j -- ; ) {
305
+ shift -= ppw ;
306
+ FB_WRITEL (colortab [(* src >> shift ) & bit_mask ], dst ++ );
307
+ if (!shift ) {
308
+ shift = 8 ;
309
+ ++ src ;
310
+ }
311
+ }
312
+
293
313
dst1 += p -> fix .line_length ;
294
314
s += spitch ;
295
315
}
0 commit comments