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