Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / swrast / swrast_span.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.1
4  *
5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6  * Copyright 2008, 2010 George Sapountzis <gsapountzis@gmail.com>
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 #include "swrast_priv.h"
27
28 #define YFLIP(_xrb, Y) ((_xrb)->Base.Height - (Y) - 1)
29
30 /*
31  * Dithering support takes the "computation" extreme in the "computation vs.
32  * storage" trade-off. This approach is very simple to implement and any
33  * computational overhead should be acceptable. XMesa uses table lookups for
34  * around 8KB of storage overhead per visual.
35  */
36 #define DITHER 1
37
38 static const GLubyte kernel[16] = {
39     0*16,  8*16,  2*16, 10*16,
40    12*16,  4*16, 14*16,  6*16,
41     3*16, 11*16,  1*16,  9*16,
42    15*16,  7*16, 13*16,  5*16,
43 };
44
45 #if DITHER
46 #define DITHER_COMP(X, Y) kernel[((X) & 0x3) | (((Y) & 0x3) << 2)]
47
48 #define DITHER_CLAMP(X) (((X) < CHAN_MAX) ? (X) : CHAN_MAX)
49 #else
50 #define DITHER_COMP(X, Y) 0
51
52 #define DITHER_CLAMP(X) (X)
53 #endif
54
55
56 /*
57  * Pixel macros shared across front/back buffer span functions.
58  */
59
60 /* 32-bit BGRA */
61 #define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \
62    *DST = VALUE[ACOMP] << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
63 #define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \
64    *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
65 #define FETCH_PIXEL_A8R8G8B8(DST, SRC) \
66    DST[ACOMP] = *SRC >> 24;            \
67    DST[RCOMP] = (*SRC >> 16) & 0xff;   \
68    DST[GCOMP] = (*SRC >> 8) & 0xff;    \
69    DST[BCOMP] = *SRC & 0xff
70
71
72 /* 32-bit BGRX */
73 #define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \
74    *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
75 #define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \
76    *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
77 #define FETCH_PIXEL_X8R8G8B8(DST, SRC) \
78    DST[ACOMP] = 0xff;                  \
79    DST[RCOMP] = (*SRC >> 16) & 0xff;   \
80    DST[GCOMP] = (*SRC >> 8) & 0xff;    \
81    DST[BCOMP] = *SRC & 0xff
82
83
84 /* 16-bit BGR */
85 #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
86    do { \
87    int d = DITHER_COMP(X, Y) >> 6; \
88    *DST = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
89             ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
90             ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
91    } while(0)
92 #define FETCH_PIXEL_R5G6B5(DST, SRC) \
93    do { \
94    DST[ACOMP] = 0xff; \
95    DST[RCOMP] = ((*SRC >> 8) & 0xf8) * 255 / 0xf8; \
96    DST[GCOMP] = ((*SRC >> 3) & 0xfc) * 255 / 0xfc; \
97    DST[BCOMP] = ((*SRC << 3) & 0xf8) * 255 / 0xf8; \
98    } while(0)
99
100
101 /* 8-bit BGR */
102 #define STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) \
103    do { \
104    int d = DITHER_COMP(X, Y) >> 3; \
105    GLubyte *p = (GLubyte *)DST; \
106    *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xe0) >> 5) | \
107           ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xe0) >> 2) | \
108           ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xc0) >> 0) ); \
109    } while(0)
110 #define FETCH_PIXEL_R3G3B2(DST, SRC) \
111    do { \
112    GLubyte p = *(GLubyte *)SRC; \
113    DST[ACOMP] = 0xff; \
114    DST[RCOMP] = ((p << 5) & 0xe0) * 255 / 0xe0; \
115    DST[GCOMP] = ((p << 2) & 0xe0) * 255 / 0xe0; \
116    DST[BCOMP] = ((p << 0) & 0xc0) * 255 / 0xc0; \
117    } while(0)
118
119
120 /*
121  * Generate code for back-buffer span functions.
122  */
123
124 /* 32-bit BGRA */
125 #define NAME(FUNC) FUNC##_A8R8G8B8
126 #define RB_TYPE GLubyte
127 #define SPAN_VARS \
128    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
129 #define INIT_PIXEL_PTR(P, X, Y) \
130    GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X)
131 #define INC_PIXEL_PTR(P) P++
132 #define STORE_PIXEL(DST, X, Y, VALUE) \
133    STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
134 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
135    STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
136 #define FETCH_PIXEL(DST, SRC) \
137    FETCH_PIXEL_A8R8G8B8(DST, SRC)
138
139 #include "swrast/s_spantemp.h"
140
141
142 /* 32-bit BGRX */
143 #define NAME(FUNC) FUNC##_X8R8G8B8
144 #define RB_TYPE GLubyte
145 #define SPAN_VARS \
146    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
147 #define INIT_PIXEL_PTR(P, X, Y) \
148    GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X);
149 #define INC_PIXEL_PTR(P) P++
150 #define STORE_PIXEL(DST, X, Y, VALUE) \
151    STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
152 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
153    STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE)
154 #define FETCH_PIXEL(DST, SRC) \
155    FETCH_PIXEL_X8R8G8B8(DST, SRC)
156
157 #include "swrast/s_spantemp.h"
158
159
160 /* 16-bit BGR */
161 #define NAME(FUNC) FUNC##_R5G6B5
162 #define RB_TYPE GLubyte
163 #define SPAN_VARS \
164    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
165 #define INIT_PIXEL_PTR(P, X, Y) \
166    GLushort *P = (GLushort *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 2 + (X);
167 #define INC_PIXEL_PTR(P) P++
168 #define STORE_PIXEL(DST, X, Y, VALUE) \
169    STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
170 #define FETCH_PIXEL(DST, SRC) \
171    FETCH_PIXEL_R5G6B5(DST, SRC)
172
173 #include "swrast/s_spantemp.h"
174
175
176 /* 8-bit BGR */
177 #define NAME(FUNC) FUNC##_R3G3B2
178 #define RB_TYPE GLubyte
179 #define SPAN_VARS \
180    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
181 #define INIT_PIXEL_PTR(P, X, Y) \
182    GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 1;
183 #define INC_PIXEL_PTR(P) P += 1
184 #define STORE_PIXEL(DST, X, Y, VALUE) \
185    STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
186 #define FETCH_PIXEL(DST, SRC) \
187    FETCH_PIXEL_R3G3B2(DST, SRC)
188
189 #include "swrast/s_spantemp.h"
190
191
192 /*
193  * Generate code for front-buffer span functions.
194  */
195
196 /* 32-bit BGRA */
197 #define NAME(FUNC) FUNC##_A8R8G8B8_front
198 #define RB_TYPE GLubyte
199 #define SPAN_VARS \
200    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
201 #define INIT_PIXEL_PTR(P, X, Y) \
202    GLuint *P = (GLuint *)row;
203 #define INC_PIXEL_PTR(P) P++
204 #define STORE_PIXEL(DST, X, Y, VALUE) \
205    STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
206 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
207    STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
208 #define FETCH_PIXEL(DST, SRC) \
209    FETCH_PIXEL_A8R8G8B8(DST, SRC)
210
211 #include "swrast_spantemp.h"
212
213
214 /* 32-bit BGRX */
215 #define NAME(FUNC) FUNC##_X8R8G8B8_front
216 #define RB_TYPE GLubyte
217 #define SPAN_VARS \
218    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
219 #define INIT_PIXEL_PTR(P, X, Y) \
220    GLuint *P = (GLuint *)row;
221 #define INC_PIXEL_PTR(P) P++
222 #define STORE_PIXEL(DST, X, Y, VALUE) \
223    STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
224 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
225    STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE)
226 #define FETCH_PIXEL(DST, SRC) \
227    FETCH_PIXEL_X8R8G8B8(DST, SRC)
228
229 #include "swrast_spantemp.h"
230
231
232 /* 16-bit BGR */
233 #define NAME(FUNC) FUNC##_R5G6B5_front
234 #define RB_TYPE GLubyte
235 #define SPAN_VARS \
236    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
237 #define INIT_PIXEL_PTR(P, X, Y) \
238    GLushort *P = (GLushort *)row;
239 #define INC_PIXEL_PTR(P) P++
240 #define STORE_PIXEL(DST, X, Y, VALUE) \
241    STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
242 #define FETCH_PIXEL(DST, SRC) \
243    FETCH_PIXEL_R5G6B5(DST, SRC)
244
245 #include "swrast_spantemp.h"
246
247
248 /* 8-bit BGR */
249 #define NAME(FUNC) FUNC##_R3G3B2_front
250 #define RB_TYPE GLubyte
251 #define SPAN_VARS \
252    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
253 #define INIT_PIXEL_PTR(P, X, Y) \
254    GLubyte *P = (GLubyte *)row;
255 #define INC_PIXEL_PTR(P) P += 1
256 #define STORE_PIXEL(DST, X, Y, VALUE) \
257    STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
258 #define FETCH_PIXEL(DST, SRC) \
259    FETCH_PIXEL_R3G3B2(DST, SRC)
260
261 #include "swrast_spantemp.h"
262
263
264 /*
265  * Back-buffers are malloced memory and always private.
266  *
267  * BACK_PIXMAP (not supported)
268  * BACK_XIMAGE
269  */
270 void
271 swrast_set_span_funcs_back(struct swrast_renderbuffer *xrb,
272                            GLuint pixel_format)
273 {
274     switch (pixel_format) {
275     case PF_A8R8G8B8:
276         xrb->Base.GetRow = get_row_A8R8G8B8;
277         xrb->Base.GetValues = get_values_A8R8G8B8;
278         xrb->Base.PutRow = put_row_A8R8G8B8;
279         xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8;
280         xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8;
281         xrb->Base.PutValues = put_values_A8R8G8B8;
282         xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8;
283         break;
284     case PF_X8R8G8B8:
285         xrb->Base.GetRow = get_row_X8R8G8B8;
286         xrb->Base.GetValues = get_values_X8R8G8B8;
287         xrb->Base.PutRow = put_row_X8R8G8B8;
288         xrb->Base.PutRowRGB = put_row_rgb_X8R8G8B8;
289         xrb->Base.PutMonoRow = put_mono_row_X8R8G8B8;
290         xrb->Base.PutValues = put_values_X8R8G8B8;
291         xrb->Base.PutMonoValues = put_mono_values_X8R8G8B8;
292         break;
293     case PF_R5G6B5:
294         xrb->Base.GetRow = get_row_R5G6B5;
295         xrb->Base.GetValues = get_values_R5G6B5;
296         xrb->Base.PutRow = put_row_R5G6B5;
297         xrb->Base.PutRowRGB = put_row_rgb_R5G6B5;
298         xrb->Base.PutMonoRow = put_mono_row_R5G6B5;
299         xrb->Base.PutValues = put_values_R5G6B5;
300         xrb->Base.PutMonoValues = put_mono_values_R5G6B5;
301         break;
302     case PF_R3G3B2:
303         xrb->Base.GetRow = get_row_R3G3B2;
304         xrb->Base.GetValues = get_values_R3G3B2;
305         xrb->Base.PutRow = put_row_R3G3B2;
306         xrb->Base.PutRowRGB = put_row_rgb_R3G3B2;
307         xrb->Base.PutMonoRow = put_mono_row_R3G3B2;
308         xrb->Base.PutValues = put_values_R3G3B2;
309         xrb->Base.PutMonoValues = put_mono_values_R3G3B2;
310         break;
311     default:
312         assert(0);
313         return;
314     }
315 }
316
317
318 /*
319  * Front-buffers are provided by the loader, the xorg loader uses pixmaps.
320  *
321  * WINDOW,          An X window
322  * GLXWINDOW,       GLX window
323  * PIXMAP,          GLX pixmap
324  * PBUFFER          GLX Pbuffer
325  */
326 void
327 swrast_set_span_funcs_front(struct swrast_renderbuffer *xrb,
328                             GLuint pixel_format)
329 {
330     switch (pixel_format) {
331     case PF_A8R8G8B8:
332         xrb->Base.GetRow = get_row_A8R8G8B8_front;
333         xrb->Base.GetValues = get_values_A8R8G8B8_front;
334         xrb->Base.PutRow = put_row_A8R8G8B8_front;
335         xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8_front;
336         xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8_front;
337         xrb->Base.PutValues = put_values_A8R8G8B8_front;
338         xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8_front;
339         break;
340     case PF_X8R8G8B8:
341         xrb->Base.GetRow = get_row_X8R8G8B8_front;
342         xrb->Base.GetValues = get_values_X8R8G8B8_front;
343         xrb->Base.PutRow = put_row_X8R8G8B8_front;
344         xrb->Base.PutRowRGB = put_row_rgb_X8R8G8B8_front;
345         xrb->Base.PutMonoRow = put_mono_row_X8R8G8B8_front;
346         xrb->Base.PutValues = put_values_X8R8G8B8_front;
347         xrb->Base.PutMonoValues = put_mono_values_X8R8G8B8_front;
348         break;
349     case PF_R5G6B5:
350         xrb->Base.GetRow = get_row_R5G6B5_front;
351         xrb->Base.GetValues = get_values_R5G6B5_front;
352         xrb->Base.PutRow = put_row_R5G6B5_front;
353         xrb->Base.PutRowRGB = put_row_rgb_R5G6B5_front;
354         xrb->Base.PutMonoRow = put_mono_row_R5G6B5_front;
355         xrb->Base.PutValues = put_values_R5G6B5_front;
356         xrb->Base.PutMonoValues = put_mono_values_R5G6B5_front;
357         break;
358     case PF_R3G3B2:
359         xrb->Base.GetRow = get_row_R3G3B2_front;
360         xrb->Base.GetValues = get_values_R3G3B2_front;
361         xrb->Base.PutRow = put_row_R3G3B2_front;
362         xrb->Base.PutRowRGB = put_row_rgb_R3G3B2_front;
363         xrb->Base.PutMonoRow = put_mono_row_R3G3B2_front;
364         xrb->Base.PutValues = put_values_R3G3B2_front;
365         xrb->Base.PutMonoValues = put_mono_values_R3G3B2_front;
366         break;
367     default:
368         assert(0);
369         return;
370     }
371 }