9d29761ad5b45336b16ac529ba009950f083acd3
[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_VIRTY(ggi_ctx->ggi_visual) - (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 *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
55 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
56
57 if (mask) {
58 while (n--) {
59 if (*mask++)
60 *fb = *ci;
61 fb++;
62 ci++;
63 }
64 } else {
65 while (n--) *fb++ = *ci++;
66 }
67 }
68
69 void GGIwrite_ci8_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
70 const GLubyte ci[], const GLubyte mask[])
71 {
72 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
73 FB_TYPE *fb;
74 fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
75 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
76
77 if (mask) {
78 while (n--) {
79 if (*mask++)
80 *fb = *ci;
81 fb++;
82 ci++;
83 }
84 } else {
85 while (n--) *fb++ = *ci++;
86 }
87 }
88
89
90 void GGIwrite_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
91 const GLchan rgba[][4], const GLubyte mask[])
92 {
93 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
94 FB_TYPE *fb;
95 fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
96 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
97
98 if (mask) {
99 while (n--) {
100 if (*mask++)
101 *fb = PACK(rgba[0]);
102 fb++;
103 rgba++;
104 }
105 } else {
106 while (n--) {
107 *fb++ = PACK(rgba[0]);
108 rgba++;
109 }
110 }
111 }
112
113 void GGIwrite_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
114 const GLchan rgba[][3], const GLubyte mask[])
115 {
116 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
117 FB_TYPE *fb;
118 fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
119 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
120
121 if (mask) {
122 while (n--) {
123 if (*mask++)
124 *fb = PACK(rgba[0]);
125 fb++;
126 rgba++;
127 }
128 } else {
129 while (n--) {
130 *fb++ = PACK(rgba[0]);
131 rgba++;
132 }
133 }
134 }
135
136
137 void GGIwrite_mono_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
138 const GLchan color[4], const GLubyte mask[])
139 {
140 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
141 FB_TYPE *fb;
142 fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
143 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
144
145 if (mask) {
146 while (n--){
147 if (*mask++)
148 *fb = PACK(color);
149 ++fb;
150 }
151 } else {
152 while (n--)
153 *fb++ = PACK(color);
154
155 /* Alternatively we could write a potentialy faster HLine
156 ggiSetGCForeground(ggi_ctx->ggi_visual, color);
157 ggiDrawHLine(ggi_ctx->ggi_visual,x,FLIP(y),n);
158 */
159 }
160 }
161
162 void GGIwrite_mono_ci_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
163 const GLuint ci, const GLubyte mask[])
164 {
165 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
166 FB_TYPE *fb;
167 fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
168 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
169
170 if (mask){
171 while (n--){
172 if (*mask++)
173 *fb = ci;
174 ++fb;
175 }
176 } else {
177 while (n--)
178 *fb++ = ci;
179
180 /* Alternatively we could write a potentialy faster HLine
181 ggiSetGCForeground(ggi_ctx->ggi_visual, ci);
182 ggiDrawHLine(ggi_ctx->ggi_visual, x, FLIP(y), n);
183 */
184 }
185 }
186
187
188 /**********************************************************************/
189 /***** Read spans of pixels *****/
190 /**********************************************************************/
191
192
193 void GGIread_ci32_span(const GLcontext *ctx,
194 GLuint n, GLint x, GLint y, GLuint ci[])
195 {
196 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
197 FB_TYPE *fb;
198 fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
199 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
200
201 while (n--)
202 *ci++ = (GLuint)*fb++;
203 }
204
205 void GGIread_rgba_span(const GLcontext *ctx,
206 GLuint n, GLint x, GLint y, GLchan rgba[][4])
207 {
208 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
209 FB_TYPE color;
210 FB_TYPE *fb;
211 fb = (FB_TYPE *)((char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual) +
212 FLIP(y)*LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual)) + x;
213
214 while (n--) {
215 color = *fb++;
216 rgba[0][RCOMP] = (GLubyte) (color>>(G+B))<<RS;
217 rgba[0][GCOMP] = (GLubyte) ((color>>B)& ((1<<G)-1))<<GS;
218 rgba[0][BCOMP] = (GLubyte) (color & ((1<<B)-1))<<BS;
219 rgba[0][ACOMP] = 0;
220 rgba++;
221 }
222 }
223
224 /**********************************************************************/
225 /***** Write arrays of pixels *****/
226 /**********************************************************************/
227
228 void GGIwrite_ci32_pixels(const GLcontext *ctx,
229 GLuint n, const GLint x[], const GLint y[],
230 const GLuint ci[], const GLubyte mask[])
231 {
232 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
233 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
234 char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
235
236 while (n--) {
237 if (*mask++){
238 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
239 *dst = *ci;
240 }
241 ci++;
242 x++;
243 y++;
244 }
245 }
246
247 void GGIwrite_mono_ci_pixels(const GLcontext *ctx,
248 GLuint n, const GLint x[], const GLint y[],
249 GLuint ci, const GLubyte mask[])
250 {
251 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
252 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
253 char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
254
255 while (n--) {
256 if (*mask++){
257 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
258 *dst = ci;
259 }
260 x++;
261 y++;
262 }
263 }
264
265 void GGIwrite_rgba_pixels(const GLcontext *ctx,
266 GLuint n, const GLint x[], const GLint y[],
267 const GLchan rgba[][4], const GLubyte mask[])
268 {
269 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
270 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
271 char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
272
273 while (n--) {
274 if (*mask++){
275 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
276 *dst = PACK(rgba[0]);
277 }
278 x++;
279 y++;
280 rgba++;
281 }
282 }
283
284 void GGIwrite_mono_rgba_pixels(const GLcontext *ctx,
285 GLuint n, const GLint x[], const GLint y[],
286 const GLchan rgba[4], const GLubyte mask[])
287 {
288 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
289 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
290 char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
291
292 while (n--) {
293 if (*mask++){
294 FB_TYPE *dst = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
295 *dst = PACK(rgba);
296 }
297
298 x++;
299 y++;
300 }
301 }
302
303 /**********************************************************************/
304 /***** Read arrays of pixels *****/
305 /**********************************************************************/
306
307 void GGIread_ci32_pixels(const GLcontext *ctx,
308 GLuint n, const GLint x[], const GLint y[],
309 GLuint ci[], const GLubyte mask[])
310 {
311 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
312 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
313 char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
314
315 while (n--) {
316 if (*mask++){
317 FB_TYPE *src = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
318 *ci = *src;
319 }
320 ci++;
321 x++;
322 y++;
323 }
324 }
325
326 void GGIread_rgba_pixels(const GLcontext *ctx,
327 GLuint n, const GLint x[], const GLint y[],
328 GLubyte rgba[][4], const GLubyte mask[])
329 {
330 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
331 int stride = LIBGGI_FB_W_STRIDE(ggi_ctx->ggi_visual);
332 char *fb = (char *)LIBGGI_CURWRITE(ggi_ctx->ggi_visual);
333 FB_TYPE color;
334
335 while (n--) {
336 if (*mask++) {
337 FB_TYPE *src = (FB_TYPE*)(fb + FLIP(*y)*stride) + *x;
338 color = *src;
339
340 rgba[0][RCOMP] = (GLubyte)(color>>(G+B))<<RS;
341 rgba[0][GCOMP] = (GLubyte)((color>>B)& ((1<<G)-1))<<GS;
342 rgba[0][BCOMP] = (GLubyte) (color & ((1<<B)-1))<<BS;
343 rgba[0][ACOMP] = 0;
344 }
345 x++;
346 y++;
347 rgba++;
348 }
349 }
350
351 void GGIset_buffer(GLcontext *ctx, GLframebuffer *buffer, GLenum mode)
352 {
353 }
354
355 int GGIsetup_driver(ggi_mesa_context_t ggi_ctx)
356 {
357 struct swrast_device_driver *swdd =
358 _swrast_GetDeviceDriverReference(ggi_ctx->gl_ctx);
359
360 GGIMESADPRINT_LIBS("linear_%d: GGIsetup_driver\n", sizeof(FB_TYPE)*8);
361
362 swdd->WriteRGBASpan = GGIwrite_rgba_span;
363 swdd->WriteRGBSpan = GGIwrite_rgb_span;
364 swdd->WriteMonoRGBASpan = GGIwrite_mono_rgba_span;
365 swdd->WriteRGBAPixels = GGIwrite_rgba_pixels;
366 swdd->WriteMonoRGBAPixels = GGIwrite_mono_rgba_pixels;
367
368 swdd->WriteCI32Span = GGIwrite_ci32_span;
369 swdd->WriteCI8Span = GGIwrite_ci8_span;
370 swdd->WriteMonoCISpan = GGIwrite_mono_ci_span;
371 swdd->WriteCI32Pixels = GGIwrite_ci32_pixels;
372 swdd->WriteMonoCIPixels = GGIwrite_mono_ci_pixels;
373
374 swdd->ReadCI32Span = GGIread_ci32_span;
375 swdd->ReadRGBASpan = GGIread_rgba_span;
376 swdd->ReadCI32Pixels = GGIread_ci32_pixels;
377 swdd->ReadRGBAPixels = GGIread_rgba_pixels;
378
379 swdd->SetBuffer = GGIset_buffer;
380
381 return 0;
382 }
383
384 static int GGIopen(ggi_visual_t vis,struct ggi_dlhandle *dlh,
385 const char *args,void *argptr, uint32 *dlret)
386 {
387 GGIMESADPRINT_CORE("linear_%d: GGIOpen\n", sizeof(FB_TYPE)*8);
388 LIBGGI_MESAEXT(vis)->setup_driver = GGIsetup_driver;
389
390 *dlret = GGI_DL_OPDRAW;
391 return 0;
392 }
393
394 int DLOPENFUNC(int func, void **funcptr)
395 {
396 switch (func) {
397 case GGIFUNC_open:
398 *funcptr = GGIopen;
399 return 0;
400 case GGIFUNC_exit:
401 case GGIFUNC_close:
402 *funcptr = NULL;
403 return 0;
404 default:
405 *funcptr = NULL;
406 }
407 return GGI_ENOTFOUND;
408 }
409