1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
22 * Copyright (C) 2009-2010 Cyril Hrubis <metan@ucw.cz> *
24 *****************************************************************************/
28 void GP_WritePixels8bpp(void *start
, size_t count
, uint8_t value
)
30 uint8_t *p
= (uint8_t *) start
;
31 uint8_t *end
= p
+ count
;
36 void GP_WritePixels16bpp(void *start
, size_t count
, uint16_t value
)
38 uint16_t *p
= (uint16_t *) start
;
41 /* Write as much pixels as possible in 4-pixel blocks. */
42 for (i
= count
; i
>= 4; p
+= 4, i
-= 4) {
61 void GP_WritePixels24bpp(void *start
, size_t count
, uint32_t value
)
63 uint8_t *bytep
= (uint8_t *) start
;
65 /* How much bytes we are offset against the 32-bit boundary. */
66 int shift
= ((intptr_t) bytep
) % 4;
69 * Pixels remaining to draw (one less than pixelcount because
70 * one incomplete pixel is drawn during the preparation phase.)
75 * Handle each color component separately.
76 * (Probably they are R, G, B but who knows.)
78 uint8_t a
= value
& 0xff;
79 uint8_t b
= (value
>> 8) & 0xff;
80 uint8_t c
= (value
>> 16) & 0xff;
86 * The line consists of three repeating 32-bit segments
87 * (except for the starting and ending segment:
91 uint32_t abca
= a
<< 24 | b
<< 16 | c
<< 8 | a
;
92 uint32_t bcab
= b
<< 24 | c
<< 16 | a
<< 8 | b
;
93 uint32_t cabc
= c
<< 24 | a
<< 16 | b
<< 8 | c
;
95 uint32_t abca
= a
<< 24 | c
<< 16 | b
<< 8 | a
;
96 uint32_t bcab
= b
<< 24 | a
<< 16 | c
<< 8 | b
;
97 uint32_t cabc
= c
<< 24 | b
<< 16 | a
<< 8 | c
;
101 * Handle the first few bytes (1 pixel or less) and prepare
102 * the repeating sequence.
105 default: /* shut up gcc */
110 p
= (uint32_t *) bytep
;
117 p
= (uint32_t *)(bytep
+ 1);
125 p
= (uint32_t *)(bytep
+ 2);
134 p
= (uint32_t *)(bytep
+ 3);
139 * Write as much of the line as possible as
140 * triplets of 32-bit numbers; hopefully the compiler can
141 * put some wide write instructions in.
151 /* Write the rest of the last pixel of the main part */
152 bytep
= (uint8_t *) p
;
182 void GP_WritePixels32bpp(void *start
, size_t count
, uint32_t value
)
185 * Inspired by GNU libc's wmemset() (by Ulrich Drepper, licensed under LGPL).
187 * Write the pixels in groups of four, allowing the compiler to use
188 * MMX/SSE/similar instructions if available. The last few pixels are
189 * copied normally one-by-one. (Speed gain is about 15% over a naive loop
190 * on AMD Phenom CPU.)
193 uint32_t *p
= (uint32_t *) start
;