push/pop color table state (Eric Plante)
[mesa.git] / src / mesa / drivers / ggi / default / linear.c
1 /* GGI-Driver for MESA
2 *
3 * Copyright (C) 1997 Uwe Maurer
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * ---------------------------------------------------------------------
19 * This code was derived from the following source of information:
20 *
21 * svgamesa.c and ddsample.c by Brian Paul
22 *
23 */
24
25 #include <ggi/mesa/ggimesa.h>
26 #include <ggi/mesa/ggimesa_int.h>
27 #include <ggi/mesa/debug.h>
28 #include "swrast/swrast.h"
29
30 #define RMASK ((1<<R)-1)
31 #define GMASK ((1<<G)-1)
32 #define BMASK ((1<<B)-1)
33
34 #define RS (8-R)
35 #define GS (8-G)
36 #define BS (8-B)
37
38 #define PACK(color) (((color[RCOMP]>>RS) << (G+B)) | \
39 ((color[GCOMP]>>GS) << B) | \
40 ((color[BCOMP]>>BS)))
41
42 #define FLIP(coord) (LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y-(coord) - 1)
43
44
45 /**********************************************************************/
46 /***** Write spans of pixels *****/
47 /**********************************************************************/
48
49 void GGIwrite_ci32_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
50 const GLuint ci[], const GLubyte mask[])
51 {
52 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
53 FB_TYPE *fb;
54 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
55 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
56
57 if (mask)
58 {
59 while (n--) {
60 if (*mask++)
61 *fb = *ci;
62 fb++;
63 ci++;
64 }
65 }
66 else
67 {
68 while (n--) *fb++ = *ci++;
69 }
70 }
71
72 void GGIwrite_ci8_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
73 const GLubyte ci[], const GLubyte mask[])
74 {
75 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
76 FB_TYPE *fb;
77 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
78 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
79
80 if (mask)
81 {
82 while (n--) {
83 if (*mask++)
84 *fb = *ci;
85 fb++;
86 ci++;
87 }
88 }
89 else
90 {
91 while (n--) *fb++ = *ci++;
92 }
93 }
94
95
96 void GGIwrite_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
97 const GLchan rgba[][4], const GLubyte mask[])
98 {
99 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
100 FB_TYPE *fb;
101 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
102 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
103
104 if (mask)
105 {
106 while (n--) {
107 if (*mask++)
108 *fb = PACK(rgba[0]);
109 fb++;
110 rgba++;
111 }
112 }
113 else
114 {
115 while (n--) {
116 *fb++ = PACK(rgba[0]);
117 rgba++;
118 }
119 }
120 }
121
122 void GGIwrite_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
123 const GLchan rgba[][3], const GLubyte mask[])
124 {
125 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
126 FB_TYPE *fb;
127 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
128 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
129
130 if (mask)
131 {
132 while (n--) {
133 if (*mask++)
134 *fb = PACK(rgba[0]);
135 fb++;
136 rgba++;
137 }
138 }
139 else
140 {
141 while (n--) {
142 *fb++ = PACK(rgba[0]);
143 rgba++;
144 }
145 }
146 }
147
148
149 void GGIwrite_mono_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
150 const GLchan color[4], const GLubyte mask[])
151 {
152 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
153 FB_TYPE *fb;
154 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
155 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
156
157 if (mask){
158 while (n--){
159 if (*mask++)
160 *fb = PACK(color);
161 ++fb;
162 }
163 }
164 else {
165 while (n--)
166 *fb++ = PACK(color);
167
168 /* Alternatively we could write a potentialy faster HLine
169 ggiSetGCForeground(ggi_ctx->ggi_visual, color);
170 ggiDrawHLine(ggi_ctx->ggi_visual,x,FLIP(y),n);
171 */
172 }
173 }
174
175 void GGIwrite_mono_ci_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
176 const GLuint ci, const GLubyte mask[])
177 {
178 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
179 FB_TYPE *fb;
180 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
181 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
182
183 if (mask){
184 while (n--){
185 if (*mask++)
186 *fb = ci;
187 ++fb;
188 }
189 }
190 else {
191 while (n--)
192 *fb++ = ci;
193
194 /* Alternatively we could write a potentialy faster HLine
195 ggiSetGCForeground(ggi_ctx->ggi_visual, ci);
196 ggiDrawHLine(ggi_ctx->ggi_visual, x, FLIP(y), n);
197 */
198 }
199 }
200
201
202 /**********************************************************************/
203 /***** Read spans of pixels *****/
204 /**********************************************************************/
205
206
207 void GGIread_ci32_span(const GLcontext *ctx,
208 GLuint n, GLint x, GLint y, GLuint ci[])
209 {
210 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
211 FB_TYPE *fb;
212 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
213 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
214
215 while (n--)
216 *ci++ = (GLuint)*fb++;
217 }
218
219 void GGIread_rgba_span(const GLcontext *ctx,
220 GLuint n, GLint x, GLint y, GLchan rgba[][4])
221 {
222 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
223 FB_TYPE color;
224 FB_TYPE *fb;
225 fb = (FB_TYPE *)(LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
226 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
227
228 while (n--)
229 {
230 color = *fb++;
231 rgba[0][RCOMP] = (GLubyte) (color>>(G+B))<<RS;
232 rgba[0][GCOMP] = (GLubyte) ((color>>B)& ((1<<G)-1))<<GS;
233 rgba[0][BCOMP] = (GLubyte) (color & ((1<<B)-1))<<BS;
234 rgba[0][ACOMP] = 0;
235 rgba++;
236 }
237 }
238
239 /**********************************************************************/
240 /***** Write arrays of pixels *****/
241 /**********************************************************************/
242
243 void GGIwrite_ci32_pixels(const GLcontext *ctx,
244 GLuint n, const GLint x[], const GLint y[],
245 const GLuint ci[], const GLubyte mask[])
246 {
247 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
248 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
249 void *fb = LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
250
251 while (n--) {
252 if (*mask++){
253 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
254 *dst = *ci;
255 }
256 ci++;
257 x++;
258 y++;
259 }
260 }
261
262 void GGIwrite_mono_ci_pixels(const GLcontext *ctx,
263 GLuint n, const GLint x[], const GLint y[],
264 GLuint ci, const GLubyte mask[])
265 {
266 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
267 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
268 void *fb = LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
269
270 while (n--) {
271 if (*mask++){
272 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
273 *dst = ci;
274 }
275 x++;
276 y++;
277 }
278 }
279
280 void GGIwrite_rgba_pixels(const GLcontext *ctx,
281 GLuint n, const GLint x[], const GLint y[],
282 const GLchan rgba[][4], const GLubyte mask[])
283 {
284 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
285 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
286 void *fb = LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
287
288 while (n--) {
289 if (*mask++){
290 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
291 *dst = PACK(rgba[0]);
292 }
293 x++;
294 y++;
295 rgba++;
296 }
297 }
298
299 void GGIwrite_mono_rgba_pixels(const GLcontext *ctx,
300 GLuint n, const GLint x[], const GLint y[],
301 const GLchan rgba[4], const GLubyte mask[])
302 {
303 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
304 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
305 void *fb = LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
306
307 while (n--) {
308 if (*mask++){
309 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
310 *dst = PACK(rgba);
311 }
312
313 x++;
314 y++;
315 }
316 }
317
318 /**********************************************************************/
319 /***** Read arrays of pixels *****/
320 /**********************************************************************/
321
322 void GGIread_ci32_pixels(const GLcontext *ctx,
323 GLuint n, const GLint x[], const GLint y[],
324 GLuint ci[], const GLubyte mask[])
325 {
326 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
327 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
328 void *fb = LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
329
330 while (n--) {
331 if (*mask++){
332 FB_TYPE *src = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
333 *ci = *src;
334 }
335 ci++;
336 x++;
337 y++;
338 }
339 }
340
341 void GGIread_rgba_pixels(const GLcontext *ctx,
342 GLuint n, const GLint x[], const GLint y[],
343 GLubyte rgba[][4], const GLubyte mask[])
344 {
345 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
346 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
347 void *fb = LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
348 FB_TYPE color;
349
350 while (n--)
351 {
352 if (*mask++)
353 {
354 FB_TYPE *src = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
355 color = *src;
356
357 rgba[0][RCOMP] = (GLubyte)(color>>(G+B))<<RS;
358 rgba[0][GCOMP] = (GLubyte)((color>>B)& ((1<<G)-1))<<GS;
359 rgba[0][BCOMP] = (GLubyte) (color & ((1<<B)-1))<<BS;
360 rgba[0][ACOMP] = 0;
361 }
362 x++;
363 y++;
364 rgba++;
365 }
366 }
367
368 void GGIset_buffer(GLcontext *ctx, GLframebuffer *buffer, GLenum mode)
369 {
370 }
371
372 int GGIsetup_driver(ggi_mesa_context_t ggi_ctx)
373 {
374 struct swrast_device_driver *swdd =
375 _swrast_GetDeviceDriverReference(ggi_ctx->gl_ctx);
376
377 GGIMESADPRINT_LIBS("linear_%d: GGIsetup_driver\n", sizeof(FB_TYPE)*8);
378
379 swdd->WriteRGBASpan = GGIwrite_rgba_span;
380 swdd->WriteRGBSpan = GGIwrite_rgb_span;
381 swdd->WriteMonoRGBASpan = GGIwrite_mono_rgba_span;
382 swdd->WriteRGBAPixels = GGIwrite_rgba_pixels;
383 swdd->WriteMonoRGBAPixels = GGIwrite_mono_rgba_pixels;
384
385 swdd->WriteCI32Span = GGIwrite_ci32_span;
386 swdd->WriteCI8Span = GGIwrite_ci8_span;
387 swdd->WriteMonoCISpan = GGIwrite_mono_ci_span;
388 swdd->WriteCI32Pixels = GGIwrite_ci32_pixels;
389 swdd->WriteMonoCIPixels = GGIwrite_mono_ci_pixels;
390
391 swdd->ReadCI32Span = GGIread_ci32_span;
392 swdd->ReadRGBASpan = GGIread_rgba_span;
393 swdd->ReadCI32Pixels = GGIread_ci32_pixels;
394 swdd->ReadRGBAPixels = GGIread_rgba_pixels;
395
396 swdd->SetBuffer = GGIset_buffer;
397
398 return 0;
399 }
400
401 static int GGIopen(ggi_visual_t vis,struct ggi_dlhandle *dlh,
402 const char *args,void *argptr, uint32 *dlret)
403 {
404 GGIMESADPRINT_CORE("linear_%d: GGIOpen\n", sizeof(FB_TYPE)*8);
405 LIBGGI_MESAEXT(vis)->setup_driver = GGIsetup_driver;
406
407 *dlret = GGI_DL_OPDRAW;
408 return 0;
409 }
410
411 int DLOPENFUNC(int func, void **funcptr)
412 {
413 switch (func) {
414 case GGIFUNC_open:
415 *funcptr = GGIopen;
416 return 0;
417 case GGIFUNC_exit:
418 case GGIFUNC_close:
419 *funcptr = NULL;
420 return 0;
421 default:
422 *funcptr = NULL;
423 }
424 return GGI_ENOTFOUND;
425 }
426