2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * George Sapountzis <gsap7@yahoo.gr>
30 #include "swrast_priv.h"
32 #define YFLIP(_xrb, Y) ((_xrb)->Base.Height - (Y) - 1)
35 * Dithering support takes the "computation" extreme in the "computation vs.
36 * storage" trade-off. This approach is very simple to implement and any
37 * computational overhead should be acceptable. XMesa uses table lookups for
38 * around 8KB of storage overhead per visual.
42 static const GLubyte kernel
[16] = {
43 0*16, 8*16, 2*16, 10*16,
44 12*16, 4*16, 14*16, 6*16,
45 3*16, 11*16, 1*16, 9*16,
46 15*16, 7*16, 13*16, 5*16,
50 #define DITHER_COMP(X, Y) kernel[((X) & 0x3) | (((Y) & 0x3) << 2)]
52 #define DITHER_CLAMP(X) (((X) < CHAN_MAX) ? (X) : CHAN_MAX)
54 #define DITHER_COMP(X, Y) 0
56 #define DITHER_CLAMP(X) (X)
61 * Pixel macros shared across front/back buffer span functions.
65 #define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \
66 *DST = VALUE[ACOMP] << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
67 #define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \
68 *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
69 #define FETCH_PIXEL_A8R8G8B8(DST, SRC) \
70 DST[ACOMP] = *SRC >> 24; \
71 DST[RCOMP] = (*SRC >> 16) & 0xff; \
72 DST[GCOMP] = (*SRC >> 8) & 0xff; \
73 DST[BCOMP] = *SRC & 0xff
77 #define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \
78 *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
79 #define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \
80 *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
81 #define FETCH_PIXEL_X8R8G8B8(DST, SRC) \
83 DST[RCOMP] = (*SRC >> 16) & 0xff; \
84 DST[GCOMP] = (*SRC >> 8) & 0xff; \
85 DST[BCOMP] = *SRC & 0xff
89 #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
91 int d = DITHER_COMP(X, Y) >> 6; \
92 *DST = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
93 ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
94 ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
96 #define FETCH_PIXEL_R5G6B5(DST, SRC) \
99 DST[RCOMP] = ((*SRC >> 8) & 0xf8) * 255 / 0xf8; \
100 DST[GCOMP] = ((*SRC >> 3) & 0xfc) * 255 / 0xfc; \
101 DST[BCOMP] = ((*SRC << 3) & 0xf8) * 255 / 0xf8; \
106 #define STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) \
108 int d = DITHER_COMP(X, Y) >> 3; \
109 GLubyte *p = (GLubyte *)DST; \
110 *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xe0) >> 5) | \
111 ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xe0) >> 2) | \
112 ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xc0) >> 0) ); \
114 #define FETCH_PIXEL_R3G3B2(DST, SRC) \
116 GLubyte p = *(GLubyte *)SRC; \
118 DST[RCOMP] = ((p << 5) & 0xe0) * 255 / 0xe0; \
119 DST[GCOMP] = ((p << 2) & 0xe0) * 255 / 0xe0; \
120 DST[BCOMP] = ((p << 0) & 0xc0) * 255 / 0xc0; \
125 * Generate code for back-buffer span functions.
129 #define NAME(FUNC) FUNC##_A8R8G8B8
130 #define RB_TYPE GLubyte
132 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
133 #define INIT_PIXEL_PTR(P, X, Y) \
134 GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X)
135 #define INC_PIXEL_PTR(P) P++
136 #define STORE_PIXEL(DST, X, Y, VALUE) \
137 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
138 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
139 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
140 #define FETCH_PIXEL(DST, SRC) \
141 FETCH_PIXEL_A8R8G8B8(DST, SRC)
143 #include "swrast/s_spantemp.h"
147 #define NAME(FUNC) FUNC##_X8R8G8B8
148 #define RB_TYPE GLubyte
150 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
151 #define INIT_PIXEL_PTR(P, X, Y) \
152 GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X);
153 #define INC_PIXEL_PTR(P) P++
154 #define STORE_PIXEL(DST, X, Y, VALUE) \
155 STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
156 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
157 STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE)
158 #define FETCH_PIXEL(DST, SRC) \
159 FETCH_PIXEL_X8R8G8B8(DST, SRC)
161 #include "swrast/s_spantemp.h"
165 #define NAME(FUNC) FUNC##_R5G6B5
166 #define RB_TYPE GLubyte
168 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
169 #define INIT_PIXEL_PTR(P, X, Y) \
170 GLushort *P = (GLushort *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 2 + (X);
171 #define INC_PIXEL_PTR(P) P++
172 #define STORE_PIXEL(DST, X, Y, VALUE) \
173 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
174 #define FETCH_PIXEL(DST, SRC) \
175 FETCH_PIXEL_R5G6B5(DST, SRC)
177 #include "swrast/s_spantemp.h"
181 #define NAME(FUNC) FUNC##_R3G3B2
182 #define RB_TYPE GLubyte
184 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
185 #define INIT_PIXEL_PTR(P, X, Y) \
186 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 1;
187 #define INC_PIXEL_PTR(P) P += 1
188 #define STORE_PIXEL(DST, X, Y, VALUE) \
189 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
190 #define FETCH_PIXEL(DST, SRC) \
191 FETCH_PIXEL_R3G3B2(DST, SRC)
193 #include "swrast/s_spantemp.h"
197 * Generate code for front-buffer span functions.
201 #define NAME(FUNC) FUNC##_A8R8G8B8_front
202 #define RB_TYPE GLubyte
204 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
205 #define INIT_PIXEL_PTR(P, X, Y) \
206 GLuint *P = (GLuint *)row;
207 #define INC_PIXEL_PTR(P) P++
208 #define STORE_PIXEL(DST, X, Y, VALUE) \
209 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
210 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
211 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
212 #define FETCH_PIXEL(DST, SRC) \
213 FETCH_PIXEL_A8R8G8B8(DST, SRC)
215 #include "swrast_spantemp.h"
219 #define NAME(FUNC) FUNC##_X8R8G8B8_front
220 #define RB_TYPE GLubyte
222 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
223 #define INIT_PIXEL_PTR(P, X, Y) \
224 GLuint *P = (GLuint *)row;
225 #define INC_PIXEL_PTR(P) P++
226 #define STORE_PIXEL(DST, X, Y, VALUE) \
227 STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
228 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
229 STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE)
230 #define FETCH_PIXEL(DST, SRC) \
231 FETCH_PIXEL_X8R8G8B8(DST, SRC)
233 #include "swrast_spantemp.h"
237 #define NAME(FUNC) FUNC##_R5G6B5_front
238 #define RB_TYPE GLubyte
240 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
241 #define INIT_PIXEL_PTR(P, X, Y) \
242 GLushort *P = (GLushort *)row;
243 #define INC_PIXEL_PTR(P) P += 2
244 #define STORE_PIXEL(DST, X, Y, VALUE) \
245 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
246 #define FETCH_PIXEL(DST, SRC) \
247 FETCH_PIXEL_R5G6B5(DST, SRC)
249 #include "swrast_spantemp.h"
253 #define NAME(FUNC) FUNC##_R3G3B2_front
254 #define RB_TYPE GLubyte
256 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
257 #define INIT_PIXEL_PTR(P, X, Y) \
258 GLubyte *P = (GLubyte *)row;
259 #define INC_PIXEL_PTR(P) P += 1
260 #define STORE_PIXEL(DST, X, Y, VALUE) \
261 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
262 #define FETCH_PIXEL(DST, SRC) \
263 FETCH_PIXEL_R3G3B2(DST, SRC)
265 #include "swrast_spantemp.h"
269 * Back-buffers are malloced memory and always private.
271 * BACK_PIXMAP (not supported)
275 swrast_set_span_funcs_back(struct swrast_renderbuffer
*xrb
,
278 switch (pixel_format
) {
280 xrb
->Base
.GetRow
= get_row_A8R8G8B8
;
281 xrb
->Base
.GetValues
= get_values_A8R8G8B8
;
282 xrb
->Base
.PutRow
= put_row_A8R8G8B8
;
283 xrb
->Base
.PutRowRGB
= put_row_rgb_A8R8G8B8
;
284 xrb
->Base
.PutMonoRow
= put_mono_row_A8R8G8B8
;
285 xrb
->Base
.PutValues
= put_values_A8R8G8B8
;
286 xrb
->Base
.PutMonoValues
= put_mono_values_A8R8G8B8
;
289 xrb
->Base
.GetRow
= get_row_X8R8G8B8
;
290 xrb
->Base
.GetValues
= get_values_X8R8G8B8
;
291 xrb
->Base
.PutRow
= put_row_X8R8G8B8
;
292 xrb
->Base
.PutRowRGB
= put_row_rgb_X8R8G8B8
;
293 xrb
->Base
.PutMonoRow
= put_mono_row_X8R8G8B8
;
294 xrb
->Base
.PutValues
= put_values_X8R8G8B8
;
295 xrb
->Base
.PutMonoValues
= put_mono_values_X8R8G8B8
;
298 xrb
->Base
.GetRow
= get_row_R5G6B5
;
299 xrb
->Base
.GetValues
= get_values_R5G6B5
;
300 xrb
->Base
.PutRow
= put_row_R5G6B5
;
301 xrb
->Base
.PutRowRGB
= put_row_rgb_R5G6B5
;
302 xrb
->Base
.PutMonoRow
= put_mono_row_R5G6B5
;
303 xrb
->Base
.PutValues
= put_values_R5G6B5
;
304 xrb
->Base
.PutMonoValues
= put_mono_values_R5G6B5
;
307 xrb
->Base
.GetRow
= get_row_R3G3B2
;
308 xrb
->Base
.GetValues
= get_values_R3G3B2
;
309 xrb
->Base
.PutRow
= put_row_R3G3B2
;
310 xrb
->Base
.PutRowRGB
= put_row_rgb_R3G3B2
;
311 xrb
->Base
.PutMonoRow
= put_mono_row_R3G3B2
;
312 xrb
->Base
.PutValues
= put_values_R3G3B2
;
313 xrb
->Base
.PutMonoValues
= put_mono_values_R3G3B2
;
323 * Front-buffers are provided by the loader, the xorg loader uses pixmaps.
325 * WINDOW, An X window
326 * GLXWINDOW, GLX window
328 * PBUFFER GLX Pbuffer
331 swrast_set_span_funcs_front(struct swrast_renderbuffer
*xrb
,
334 switch (pixel_format
) {
336 xrb
->Base
.GetRow
= get_row_A8R8G8B8_front
;
337 xrb
->Base
.GetValues
= get_values_A8R8G8B8_front
;
338 xrb
->Base
.PutRow
= put_row_A8R8G8B8_front
;
339 xrb
->Base
.PutRowRGB
= put_row_rgb_A8R8G8B8_front
;
340 xrb
->Base
.PutMonoRow
= put_mono_row_A8R8G8B8_front
;
341 xrb
->Base
.PutValues
= put_values_A8R8G8B8_front
;
342 xrb
->Base
.PutMonoValues
= put_mono_values_A8R8G8B8_front
;
345 xrb
->Base
.GetRow
= get_row_X8R8G8B8_front
;
346 xrb
->Base
.GetValues
= get_values_X8R8G8B8_front
;
347 xrb
->Base
.PutRow
= put_row_X8R8G8B8_front
;
348 xrb
->Base
.PutRowRGB
= put_row_rgb_X8R8G8B8_front
;
349 xrb
->Base
.PutMonoRow
= put_mono_row_X8R8G8B8_front
;
350 xrb
->Base
.PutValues
= put_values_X8R8G8B8_front
;
351 xrb
->Base
.PutMonoValues
= put_mono_values_X8R8G8B8_front
;
354 xrb
->Base
.GetRow
= get_row_R5G6B5_front
;
355 xrb
->Base
.GetValues
= get_values_R5G6B5_front
;
356 xrb
->Base
.PutRow
= put_row_R5G6B5_front
;
357 xrb
->Base
.PutRowRGB
= put_row_rgb_R5G6B5_front
;
358 xrb
->Base
.PutMonoRow
= put_mono_row_R5G6B5_front
;
359 xrb
->Base
.PutValues
= put_values_R5G6B5_front
;
360 xrb
->Base
.PutMonoValues
= put_mono_values_R5G6B5_front
;
363 xrb
->Base
.GetRow
= get_row_R3G3B2_front
;
364 xrb
->Base
.GetValues
= get_values_R3G3B2_front
;
365 xrb
->Base
.PutRow
= put_row_R3G3B2_front
;
366 xrb
->Base
.PutRowRGB
= put_row_rgb_R3G3B2_front
;
367 xrb
->Base
.PutMonoRow
= put_mono_row_R3G3B2_front
;
368 xrb
->Base
.PutValues
= put_values_R3G3B2_front
;
369 xrb
->Base
.PutMonoValues
= put_mono_values_R3G3B2_front
;