339a708590845d343ed2b4c25eaad8a6ebffefd4
[mesa.git] / src / mesa / drivers / ggi / ggimesa.c
1 /* GGI-Driver for MESA
2 *
3 * Copyright (C) 1997-1998 Uwe Maurer - uwe_maurer@t-online.de
4 * 2002 Filip Spacek
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * ---------------------------------------------------------------------
20 * This code was derived from the following source of information:
21 *
22 * svgamesa.c and ddsample.c by Brian Paul
23 *
24 */
25
26 #ifdef HAVE_CONFIG_H
27 #include "conf.h"
28 #endif
29
30 #include <ggi/mesa/ggimesa_int.h>
31 #include <ggi/mesa/debug.h>
32 #include "extensions.h"
33 #include "imports.h"
34 #include "matrix.h"
35 #include "swrast/swrast.h"
36 #include "swrast_setup/swrast_setup.h"
37 #include "tnl/tnl.h"
38 #include "tnl/t_context.h"
39 #include "tnl/t_pipeline.h"
40 #include "array_cache/acache.h"
41 #include "texformat.h"
42 #include "texstore.h"
43
44 ggi_extid ggiMesaID = -1;
45 static int _ggimesaLibIsUp = 0;
46 static void *_ggimesaConfigHandle;
47
48 static char ggimesaconffile[] = GGIMESACONFFILE;
49
50 int _ggimesaDebugSync = 0;
51 uint32 _ggimesaDebugState = 0;
52
53 static void gl_ggiUpdateState(GLcontext *ctx, GLuint new_state);
54 static int changed(ggi_visual_t vis, int whatchanged);
55
56
57 static int _ggi_error(void)
58 {
59 GGIMESADPRINT_CORE("_ggi_error() called\n");
60
61 return -1;
62 }
63
64 static void gl_ggiGetSize(GLframebuffer *fb, GLuint *width, GLuint *height)
65 {
66 /* FIXME: this is a hack to work around the new interface */
67 GLcontext *ctx;
68 ggi_mesa_context_t ggi_ctx;
69 ctx = _mesa_get_current_context();
70 ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
71
72 GGIMESADPRINT_CORE("gl_ggiGetSize() called\n");
73
74 *width = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.x;
75 *height = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
76 printf("returning %d, %d\n", *width, *height);
77 }
78
79 static void gl_ggiSetIndex(GLcontext *ctx, GLuint ci)
80 {
81 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
82
83 GGIMESADPRINT_CORE("gl_ggiSetIndex() called\n");
84
85 ggiSetGCForeground(ggi_ctx->ggi_visual, ci);
86 ggi_ctx->color = (ggi_pixel)ci;
87 }
88
89 static void gl_ggiSetClearIndex(GLcontext *ctx, GLuint ci)
90 {
91 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
92
93 GGIMESADPRINT_CORE("gl_ggiSetClearIndex() called\n");
94
95 ggiSetGCForeground(ggi_ctx->ggi_visual, ci);
96 ggi_ctx->clearcolor = (ggi_pixel)ci;
97 }
98
99 static void gl_ggiSetClearColor(GLcontext *ctx, const GLchan color[4])
100 {
101 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
102 ggi_color rgb;
103 ggi_pixel col;
104
105 GGIMESADPRINT_CORE("gl_ggiSetClearColor() called\n");
106
107 rgb.r = (uint16)color[0] << SHIFT;
108 rgb.g = (uint16)color[1] << SHIFT;
109 rgb.b = (uint16)color[2] << SHIFT;
110 col = ggiMapColor(ggi_ctx->ggi_visual, &rgb);
111 ggiSetGCForeground(ggi_ctx->ggi_visual, col);
112 ggi_ctx->clearcolor = col;
113 }
114
115 static void gl_ggiClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
116 GLint x, GLint y, GLint width, GLint height)
117 {
118 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
119
120 GGIMESADPRINT_CORE("gl_ggiClear() called\n");
121
122 if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT))
123 {
124 ggiSetGCForeground(ggi_ctx->ggi_visual, ggi_ctx->clearcolor);
125
126 if (all)
127 {
128 int w, h;
129 w = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.x;
130 h = LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y;
131 ggiDrawBox(ggi_ctx->ggi_visual, 0, 0, w, h);
132 }
133 else
134 {
135 ggiDrawBox(ggi_ctx->ggi_visual, x, y, //FLIP(y),
136 width, height);
137 }
138 ggiSetGCForeground(ggi_ctx->ggi_visual, ggi_ctx->color);
139
140 mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
141 }
142 _swrast_Clear(ctx, mask, all, x, y, width, height);
143
144 }
145
146 /* Set the buffer used for drawing */
147 static GLboolean gl_ggiSetDrawBuffer(GLcontext *ctx, GLenum mode)
148 {
149 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
150
151 printf("set draw %d\n", mode);
152 GGIMESADPRINT_CORE("gl_ggiSetDrawBuffer() called\n");
153
154 if (mode == GL_FRONT_LEFT)
155 {
156 ggiSetWriteFrame(ggi_ctx->ggi_visual,
157 ggiGetDisplayFrame(ggi_ctx->ggi_visual));
158 return GL_TRUE;
159 }
160 else if (mode == GL_BACK_LEFT)
161 {
162 ggiSetWriteFrame(ggi_ctx->ggi_visual,
163 ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
164 return GL_TRUE;
165 }
166 else
167 {
168 return GL_FALSE;
169 }
170 }
171
172
173 /* Set the buffer used for reading */
174 /* XXX support for separate read/draw buffers hasn't been tested */
175 static GLboolean gl_ggiSetReadBuffer(GLcontext *ctx, GLframebuffer *buffer, GLenum mode)
176 {
177 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
178
179 printf("set read %d\n", mode);
180 GGIMESADPRINT_CORE("gl_ggiSetReadBuffer() called\n");
181
182 if (mode == GL_FRONT_LEFT)
183 {
184 ggiSetReadFrame(ggi_ctx->ggi_visual,
185 ggiGetDisplayFrame(ggi_ctx->ggi_visual));
186 return GL_TRUE;
187 }
188 else if (mode == GL_BACK_LEFT)
189 {
190 ggiSetReadFrame(ggi_ctx->ggi_visual,
191 ggiGetDisplayFrame(ggi_ctx->ggi_visual)?0 : 1);
192 return GL_TRUE;
193 }
194 else
195 return GL_FALSE;
196 }
197
198
199 static const GLubyte * gl_ggiGetString(GLcontext *ctx, GLenum name)
200 {
201 GGIMESADPRINT_CORE("gl_ggiGetString() called\n");
202
203 if (name == GL_RENDERER)
204 return (GLubyte *) "Mesa GGI";
205 else
206 return NULL;
207 }
208
209 static void gl_ggiFlush(GLcontext *ctx)
210 {
211 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
212
213 GGIMESADPRINT_CORE("gl_ggiFlush() called\n");
214
215 ggiFlush(ggi_ctx->ggi_visual);
216 }
217
218 static void gl_ggiIndexMask(GLcontext *ctx, GLuint mask)
219 {
220 GGIMESADPRINT_CORE("gl_ggiIndexMask() called\n");
221 }
222
223 static void gl_ggiColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
224 GLboolean bmask, GLboolean amask)
225 {
226 GGIMESADPRINT_CORE("gl_ggiColorMask() called\n");
227 }
228
229 static void gl_ggiEnable(GLcontext *ctx, GLenum pname, GLboolean state)
230 {
231 GGIMESADPRINT_CORE("gl_ggiEnable() called\n");
232 }
233
234 static void gl_ggiSetupPointers(GLcontext *ctx)
235 {
236 TNLcontext *tnl;
237
238 GGIMESADPRINT_CORE("gl_ggiSetupPointers() called\n");
239
240 /* General information */
241 ctx->Driver.GetString = gl_ggiGetString;
242 ctx->Driver.GetBufferSize = gl_ggiGetSize;
243 ctx->Driver.Finish = gl_ggiFlush;
244 ctx->Driver.Flush = gl_ggiFlush;
245
246 /* Software rasterizer pixel paths */
247 ctx->Driver.Accum = _swrast_Accum;
248 ctx->Driver.Bitmap = _swrast_Bitmap;
249 ctx->Driver.Clear = gl_ggiClear;
250 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
251 ctx->Driver.CopyPixels = _swrast_CopyPixels;
252 ctx->Driver.DrawPixels = _swrast_DrawPixels;
253 ctx->Driver.ReadPixels = _swrast_ReadPixels;
254
255 /* Software texturing */
256 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
257 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
258 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
259 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
260 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
261 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
262 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
263 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
264
265 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
266 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
267 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
268 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
269 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
270
271 ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
272 ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
273 ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
274
275 /* Imaging extensions */
276 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
277 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
278 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
279 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
280
281 /* State change callbacks */
282 ctx->Driver.SetDrawBuffer = gl_ggiSetDrawBuffer;
283 ctx->Driver.ClearIndex = gl_ggiSetClearIndex;
284 ctx->Driver.ClearColor = gl_ggiSetClearColor;
285 ctx->Driver.IndexMask = gl_ggiIndexMask;
286 ctx->Driver.ColorMask = gl_ggiColorMask;
287 ctx->Driver.Enable = gl_ggiEnable;
288
289 ctx->Driver.UpdateState = gl_ggiUpdateState;
290
291 /* Initialize TNL driver interface */
292 tnl = TNL_CONTEXT(ctx);
293 tnl->Driver.RunPipeline = _tnl_run_pipeline;
294
295 /* Install setup for tnl */
296 _swsetup_Wakeup(ctx);
297 }
298
299 static void get_mode_info(ggi_visual_t vis, int *r, int *g, int *b,
300 GLboolean *rgb, GLboolean *db, int *ci)
301 {
302 int i;
303
304 *r = 0;
305 *g = 0;
306 *b = 0;
307
308 for(i = 0; i < sizeof(ggi_pixel)*8; ++i){
309 int mask = 1 << i;
310 if(LIBGGI_PIXFMT(vis)->red_mask & mask)
311 ++(*r);
312 if(LIBGGI_PIXFMT(vis)->green_mask & mask)
313 ++(*g);
314 if(LIBGGI_PIXFMT(vis)->blue_mask & mask)
315 ++(*b);
316 }
317
318 *rgb = GT_SCHEME(LIBGGI_MODE(vis)->graphtype) == GT_TRUECOLOR;
319 *db = LIBGGI_MODE(vis)->frames > 1;
320 *ci = GT_SIZE(LIBGGI_MODE(vis)->graphtype);
321
322 printf("rgb (%d, %d, %d) db %d, rgb %d ci %d\n",*r,*g,*b,*db,*rgb,*ci);
323 }
324
325 int ggiMesaInit()
326 {
327 int err;
328 char *str;
329
330 GGIMESADPRINT_CORE("ggiMesaInit() called\n");
331
332 str = getenv("GGIMESA_DEBUG");
333 if (str != NULL) {
334 _ggimesaDebugState = atoi(str);
335 GGIMESADPRINT_CORE("Debugging=%d\n", _ggimesaDebugState);
336 }
337
338 str = getenv("GGIMESA_DEBUGSYNC");
339 if (str != NULL) {
340 _ggimesaDebugSync = 1;
341 }
342
343 GGIMESADPRINT_CORE("ggiMesaInit()\n");
344
345 _ggimesaLibIsUp++;
346 if (_ggimesaLibIsUp > 1)
347 return 0; /* Initialize only at first call */
348
349 err = ggLoadConfig(ggimesaconffile, &_ggimesaConfigHandle);
350 if (err != GGI_OK)
351 {
352 GGIMESADPRINT_CORE("GGIMesa: Couldn't open %s\n",
353 ggimesaconffile);
354 _ggimesaLibIsUp--;
355 return err;
356 }
357
358 ggiMesaID = ggiExtensionRegister("GGIMesa",
359 sizeof(struct ggi_mesa_ext), changed);
360
361 if (ggiMesaID < 0)
362 {
363 GGIMESADPRINT_CORE("GGIMesa: failed to register as extension\n");
364 _ggimesaLibIsUp--;
365 ggFreeConfig(_ggimesaConfigHandle);
366 return ggiMesaID;
367 }
368
369 return 0;
370 }
371
372 int ggiMesaExit(void)
373 {
374 int rc;
375
376 GGIMESADPRINT_CORE("ggiMesaExit() called\n");
377
378 if (!_ggimesaLibIsUp)
379 return -1;
380
381 if (_ggimesaLibIsUp > 1)
382 {
383 /* Exit only at last call */
384 _ggimesaLibIsUp--;
385 return 0;
386 }
387
388 rc = ggiExtensionUnregister(ggiMesaID);
389 ggFreeConfig(_ggimesaConfigHandle);
390
391 _ggimesaLibIsUp = 0;
392
393 return rc;
394 }
395
396 int ggiMesaAttach(ggi_visual_t vis)
397 {
398 int rc;
399
400 GGIMESADPRINT_CORE("ggiMesaAttach() called\n");
401
402 rc = ggiExtensionAttach(vis, ggiMesaID);
403 if (rc == 0)
404 {
405 int r, g, b, ci;
406 GLboolean rgb, db;
407 GLvisual *gl_visual;
408 GLframebuffer *gl_fb;
409
410 /* We are creating the primary instance */
411 memset(LIBGGI_MESAEXT(vis), 0, sizeof(struct ggi_mesa_ext));
412 LIBGGI_MESAEXT(vis)->update_state = (void *)_ggi_error;
413 LIBGGI_MESAEXT(vis)->setup_driver = (void *)_ggi_error;
414
415 /* Initialize default mesa visual */
416 get_mode_info(vis, &r, &g, &b, &rgb, &db, &ci);
417 gl_visual = &(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
418 _mesa_initialize_visual(gl_visual,
419 rgb, db, 0 /* No stereo */,
420 r, g, b, 0 /* No alpha */, ci,
421 0 /* No depth */, 0 /* No stencil */,
422 0, 0, 0, 0 /* No accum */, 0);
423
424 /* Now fake an "API change" so the right libs get loaded */
425 changed(vis, GGI_CHG_APILIST);
426 }
427
428 return rc;
429 }
430
431 int ggiMesaDetach(ggi_visual_t vis)
432 {
433 GGIMESADPRINT_CORE("ggiMesaDetach() called\n");
434
435 return ggiExtensionDetach(vis, ggiMesaID);
436 }
437
438 int ggiMesaExtendVisual(ggi_visual_t vis, GLboolean alpha_flag,
439 GLboolean stereo_flag, GLint depth_size,
440 GLint stencil_size, GLint accum_red_size,
441 GLint accum_green_size, GLint accum_blue_size,
442 GLint accum_alpha_size, GLint num_samples)
443 {
444 GLvisual *gl_vis = &(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
445 int r, g, b, ci;
446 GLboolean db, rgb;
447
448 get_mode_info(vis, &r, &g, &b, &rgb, &db, &ci);
449
450 /* Initialize the visual with the provided information */
451 _mesa_initialize_visual(&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual),
452 rgb, db, stereo_flag,
453 r, g, b, 0 /* FIXME */, ci,
454 depth_size, stencil_size,
455 accum_red_size, accum_green_size,
456 accum_blue_size, accum_alpha_size, 0);
457
458 /* Now fake an "API change" so the right libs get loaded. After all,
459 extending the visual by all these new buffers could be considered
460 a "mode change" which requires an "API change".
461 */
462 changed(vis, GGI_CHG_APILIST);
463
464 return 0;
465 }
466
467
468 ggi_mesa_context_t ggiMesaCreateContext(ggi_visual_t vis)
469 {
470 ggi_mesa_context_t ctx;
471 int err;
472 ggi_color pal[256];
473 int i;
474 __GLimports imports;
475
476 GGIMESADPRINT_CORE("ggiMesaCreateContext() called\n");
477
478 ctx = (ggi_mesa_context_t)malloc(sizeof(struct ggi_mesa_context));
479 if (!ctx)
480 return NULL;
481
482 ctx->ggi_visual = vis;
483 ctx->color = 0;
484
485 _mesa_init_default_imports( &imports, (void *) ctx);
486 ctx->gl_ctx =
487 _mesa_create_context(&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual),
488 NULL, &imports);
489 if (!ctx->gl_ctx)
490 goto free_context;
491
492 _mesa_enable_sw_extensions(ctx->gl_ctx);
493
494 _swrast_CreateContext(ctx->gl_ctx);
495 _ac_CreateContext(ctx->gl_ctx);
496 _tnl_CreateContext(ctx->gl_ctx);
497 _swsetup_CreateContext(ctx->gl_ctx);
498
499 gl_ggiSetupPointers(ctx->gl_ctx);
500
501 /* Make sure that an appropriate sublib has been loaded */
502 if (!LIBGGI_MESAEXT(ctx->ggi_visual)->setup_driver){
503 GGIMESADPRINT_CORE("setup_driver==NULL!\n");
504 GGIMESADPRINT_CORE("Please check your config files!\n");
505 goto free_context;
506 }
507
508 /* Set up the sublib driver */
509 err = LIBGGI_MESAEXT(ctx->ggi_visual)->setup_driver(ctx);
510 if (err){
511 GGIMESADPRINT_CORE("setup_driver failed (err = %d)", err);
512 goto free_gl_context;
513 }
514
515 return ctx;
516
517 free_gl_context:
518 _mesa_destroy_context(ctx->gl_ctx);
519 free_context:
520 free(ctx);
521
522 return NULL;
523 }
524
525 void ggiMesaDestroyContext(ggi_mesa_context_t ctx)
526 {
527 GGIMESADPRINT_CORE("ggiMesaDestroyContext() called\n");
528
529 if(!ctx)
530 return;
531
532 _mesa_destroy_context(ctx->gl_ctx);
533 free(ctx);
534 }
535
536 void ggiMesaMakeCurrent(ggi_mesa_context_t ctx, ggi_visual_t vis)
537 {
538 GGIMESADPRINT_CORE("ggiMesaMakeCurrent(ctx = %p) called\n", ctx);
539
540 /* FIXME: clean up where are ggi_vis */
541 if (ctx->ggi_visual != vis) {
542 GGIMESADPRINT_CORE("Cannot migrate GL contexts\n");
543 return;
544 }
545
546 _mesa_make_current(ctx->gl_ctx, &LIBGGI_MESAEXT(vis)->mesa_buffer);
547
548 if (ctx->gl_ctx->Viewport.Width == 0)
549 {
550 _mesa_Viewport(0, 0,
551 LIBGGI_MODE(vis)->visible.x,
552 LIBGGI_MODE(vis)->visible.y);
553 ctx->gl_ctx->Scissor.Width = LIBGGI_MODE(vis)->visible.x;
554 ctx->gl_ctx->Scissor.Height = LIBGGI_MODE(vis)->visible.y;
555 }
556 }
557
558
559 /*
560 * Swap front/back buffers for current context if double buffered.
561 */
562 void ggiMesaSwapBuffers(void)
563 {
564 GLcontext *ctx;
565 ggi_mesa_context_t ggi_ctx;
566 ctx = _mesa_get_current_context();
567 ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
568
569 GGIMESADPRINT_CORE("ggiMesaSwapBuffers() called\n");
570
571 _mesa_swapbuffers(ctx);
572 gl_ggiFlush(ctx);
573
574 ggiSetDisplayFrame(ggi_ctx->ggi_visual,
575 !ggiGetDisplayFrame(ggi_ctx->ggi_visual));
576 ggiSetWriteFrame(ggi_ctx->ggi_visual,
577 !ggiGetWriteFrame(ggi_ctx->ggi_visual));
578 ggiSetReadFrame(ggi_ctx->ggi_visual,
579 !ggiGetReadFrame(ggi_ctx->ggi_visual));
580
581 GGIMESADPRINT_CORE("swap disp: %d, write %d\n",
582 ggiGetDisplayFrame(ggi_ctx->ggi_visual),
583 ggiGetWriteFrame(ggi_ctx->ggi_visual));
584 }
585
586 static void gl_ggiUpdateState(GLcontext *ctx, GLuint new_state)
587 {
588 ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx;
589
590 GGIMESADPRINT_CORE("gl_ggiUpdateState() called\n");
591
592 /* Propogate statechange information to swrast and swrast_setup
593 * modules. The GGI driver has no internal GL-dependent state.
594 */
595 _swrast_InvalidateState(ctx, new_state);
596 _swsetup_InvalidateState(ctx, new_state);
597 _tnl_InvalidateState(ctx, new_state);
598
599 if (!LIBGGI_MESAEXT(ggi_ctx->ggi_visual)->update_state) {
600 GGIMESADPRINT_CORE("update_state == NULL!\n");
601 GGIMESADPRINT_CORE("Please check your config files!\n");
602 ggiPanic("");
603 }
604
605 LIBGGI_MESAEXT(ggi_ctx->ggi_visual)->update_state(ggi_ctx);
606 }
607
608 static int changed(ggi_visual_t vis, int whatchanged)
609 {
610 GLcontext *ctx;
611 ctx = _mesa_get_current_context();
612
613 GGIMESADPRINT_CORE("changed() called\n");
614
615 switch (whatchanged)
616 {
617 case GGI_CHG_APILIST:
618 {
619 char api[256];
620 char args[256];
621 int i;
622 const char *fname;
623 ggi_dlhandle *lib;
624 GLvisual *gl_vis=&(LIBGGI_MESAEXT(vis)->mesa_visual.gl_visual);
625 GLframebuffer *gl_fb = &(LIBGGI_MESAEXT(vis)->mesa_buffer);
626
627 /* Initialize the framebuffer to provide all necessary
628 buffers in software. The target libraries that are loaded
629 next are free to modify this according to their
630 capabilities.
631 */
632 /* FIXME: if the target changes capabilities we'll leak
633 swrast's memory !!! Need to deallocate first */
634 _mesa_initialize_framebuffer(gl_fb, gl_vis,
635 gl_vis->depthBits > 0,
636 gl_vis->stencilBits > 0,
637 gl_vis->accumRedBits > 0,
638 gl_vis->alphaBits > 0);
639
640 for (i = 0; ggiGetAPI(vis, i, api, args) == 0; i++)
641 {
642 strcat(api, "-mesa");
643 fname = ggMatchConfig(_ggimesaConfigHandle, api, NULL);
644 if (fname == NULL)
645 {
646 /* No special implementation for this sublib */
647 continue;
648 }
649 lib = ggiExtensionLoadDL(vis, fname, args, NULL,
650 GGI_SYMNAME_PREFIX);
651 }
652
653 /* The targets have cleared everything they can do from
654 the framebuffer structure so we provide the rest in sw
655 */
656 _swrast_alloc_buffers(gl_fb);
657
658 break;
659 }
660 }
661 return 0;
662 }
663