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