[GRASS5] PNG driver problem

Glynn Clements glynn.clements at virgin.net
Tue Aug 24 15:58:26 EDT 2004

Hamish wrote:

> > > does dumping a max. res PPM work for anyone on MacOSX from NVIZ? not
> > > me, I just get the bits.
> > 
> > Can you elaborate?

> Then, next time I change a knob and redraw the NVIZ display, it breaks:
> X Error of failed request:  GLXBadContextTag
>   Major opcode of failed request:  144 (GLX)
>   Minor opcode of failed request:  1 (X_GLXRender)

I get exactly the same thing, but right away.

I'm pretty sure I know what's causing it.

Create_OS_Ctx() stores the current drawable an GLX context, and
Destroy_OS_Ctx() restores them. The problem is that the code in
do_zoom.c opens another connection to the X display itself. From the
perspective of the X server, do_zoom.c is a separate client to the
rest of NVIZ. And from the perspective of Xlib, the Display used by
do_zoom.c is a different display to the one which is used by the rest
of NVIZ.

IOW, do_zoom.c shouldn't be trying to do anything with NVIZ' X
resources, because they belong to a different client and a different

If do_zoom.c wants to create its own X connection (even to a different
X server), its own GLX context, and its own X/GLX resources, that's
fine, and it should all work.

If I change the glXMakeCurrent() call which attempts to restore the
old context to simply release the existing context, then it doesn't
crash. However, subsequently moving the viewpoint etc doesn't result
in the display being redrawn (because there isn't a current context). 
But if you resize the view window, everything then works again
(presumably, Togl explicitly restores the context as part of the
resize handling).

AFAICT, the correct solution is to force Togl to restore the context
before each redraw, and for do_zoom.c to not to access X resources
(window, GLX context) which belong to a different client and a
different display.

Try the attached patch.

Glynn Clements <glynn.clements at virgin.net>

-------------- next part --------------
Index: src/do_zoom.c
RCS file: /grassrepository/grass/src.contrib/GMSL/NVIZ2.2/src/do_zoom.c,v
retrieving revision 1.6
diff -u -r1.6 do_zoom.c
--- src/do_zoom.c	10 Aug 2004 15:32:27 -0000	1.6
+++ src/do_zoom.c	24 Aug 2004 19:58:36 -0000
@@ -29,7 +29,6 @@
 static Display *dpy;
 static Window root;
-static GLXDrawable xdraw;
 static GLXContext ctx_orig;
 static GLXPbuffer pbuffer;
@@ -260,11 +259,6 @@
     scr = DefaultScreen(dpy);
     root = RootWindow(dpy, scr);
-    xdraw = glXGetCurrentDrawable();
-    if (xdraw == None) {
-	fprintf(stderr, "Unable to get current drawable\n");
-	return (-1);
-    }
     ctx_orig = glXGetCurrentContext();
     if (ctx_orig == NULL) {
 	fprintf(stderr, "Unable to get current context\n");
@@ -358,12 +352,9 @@
     if (pbuffer)
 	fprintf(stderr, "GLX -- destroy pbuffer\n");
+	glXMakeCurrent(dpy, None, NULL);
 	glXDestroyPbuffer(dpy, pbuffer);
 	pbuffer = None;
-	glXMakeCurrent(dpy, xdraw, ctx_orig);
-	/*
-	  glXMakeContextCurrent(dpy, xdraw, xdraw, ctx_orig);
-	*/
 	return (1);
@@ -372,11 +363,11 @@
     if (glxpixmap)
 	fprintf(stderr, "Destroy Pixmap and GLXPixmap\n");
-	XFreePixmap(dpy, pixmap);
-	pixmap = None;
+	glXMakeCurrent(dpy, None, NULL);
 	glXDestroyGLXPixmap(dpy, glxpixmap);
 	glxpixmap = None;
-	glXMakeCurrent(dpy, xdraw, ctx_orig);
+	XFreePixmap(dpy, pixmap);
+	pixmap = None;
 	return (1);
Index: scripts/nviz2.2_script
RCS file: /grassrepository/grass/src.contrib/GMSL/NVIZ2.2/scripts/nviz2.2_script,v
retrieving revision 1.13
diff -u -r1.13 nviz2.2_script
--- scripts/nviz2.2_script	10 Nov 2003 14:42:49 -0000	1.13
+++ scripts/nviz2.2_script	24 Aug 2004 19:58:36 -0000
@@ -309,6 +309,7 @@
 	if {$fname != -1} then {
          Nstart_zoom $fname [winfo screenwidth .] [winfo screenheight .]
+	 .top.canvas makecurrent
 	} -underline 0 -label "Save Max. Resolution PPM(s)"

More information about the grass-dev mailing list