[Xquartz-changes] [296] AppleSGLX/trunk

source_changes at macosforge.org source_changes at macosforge.org
Sun Mar 8 13:48:54 PDT 2009


Revision: 296
          http://trac.macosforge.org/projects/xquartz/changeset/296
Author:   gstaplin at apple.com
Date:     2009-03-08 13:48:53 -0700 (Sun, 08 Mar 2009)
Log Message:
-----------
Work around a surface destruction issue on withdraw/unmap, by recreating
the surface in 2 possible paths (glViewport and glXSwapBuffers).  This isn't
ideal, but it fixes the test case, and should resolve the issue with most apps.
There may be an app or 2 that have redraw issues even after this.

The old libGL had black windows after a withdraw/unmap remap pattern,
due to surfaces being destroyed, and the old libGL didn't recreate them.  The 
old libGL also leaked surfaces in some cases.

Modified Paths:
--------------
    AppleSGLX/trunk/apple_glx.c
    AppleSGLX/trunk/apple_glx_context.c
    AppleSGLX/trunk/apple_glx_context.h
    AppleSGLX/trunk/apple_xgl_api_viewport.c
    AppleSGLX/trunk/glxcmds.c

Modified: AppleSGLX/trunk/apple_glx.c
===================================================================
--- AppleSGLX/trunk/apple_glx.c	2009-03-08 04:08:32 UTC (rev 295)
+++ AppleSGLX/trunk/apple_glx.c	2009-03-08 20:48:53 UTC (rev 296)
@@ -141,6 +141,8 @@
 
 void apple_glx_swap_buffers(void *ptr) {
     struct apple_glx_context *ac = ptr;
+
+    /* This may not be needed with CGLFlushDrawable: */
     glFlush();
     apple_cgl.flush_drawable(ac->context_obj);
 }

Modified: AppleSGLX/trunk/apple_glx_context.c
===================================================================
--- AppleSGLX/trunk/apple_glx_context.c	2009-03-08 04:08:32 UTC (rev 295)
+++ AppleSGLX/trunk/apple_glx_context.c	2009-03-08 20:48:53 UTC (rev 296)
@@ -142,6 +142,7 @@
     ac->need_update = false;
     ac->is_current = false;
     ac->made_current = false;
+    ac->last_surface_window = None;
     
     apple_visual_create_pfobj(&ac->pixel_format_obj, mode, 
 			      &ac->double_buffered, /*offscreen*/ false);
@@ -291,7 +292,7 @@
 	oldac->is_current = false;
 
     if(NULL == ac) {
-	/*Clear the current context.*/
+	/*Clear the current context for this thread.*/
 	apple_cgl.set_current_context(NULL);
 
 	if(oldac) {
@@ -301,6 +302,9 @@
 		oldac->drawable->destroy(oldac->drawable);
 		oldac->drawable = NULL;
 	    }
+
+	    /* Invalidate this to prevent surface recreation. */
+	    oldac->last_surface_window = None;
 	}
 	
 	return false;
@@ -321,6 +325,9 @@
 	    ac->drawable->destroy(ac->drawable);
 	    ac->drawable = NULL;
 	}
+
+	/* Invalidate this to prevent surface recreation. */
+	ac->last_surface_window = None;
 	
 	apple_glx_diagnostic("%s: drawable is None, error is: %d\n",
 			     __func__, error);
@@ -389,6 +396,9 @@
 
     ac->thread_id = pthread_self();
      
+    /* This will be set if the pending_destroy code indicates it should be: */
+    ac->last_surface_window = None;
+
     switch(ac->drawable->type) {
     case APPLE_GLX_DRAWABLE_PBUFFER:
     case APPLE_GLX_DRAWABLE_SURFACE:
@@ -408,10 +418,19 @@
     return false;
 }
 
-bool apple_glx_is_current_drawable(void *ptr, GLXDrawable drawable) {
+bool apple_glx_is_current_drawable(Display *dpy, void *ptr, 
+				   GLXDrawable drawable) {
     struct apple_glx_context *ac = ptr;
+    
+    if(ac->drawable && ac->drawable->drawable == drawable) {
+	return true;
+    } else if(NULL == ac->drawable && None != ac->last_surface_window) {
+	apple_glx_context_update(dpy, ac);
 
-    return (ac->drawable && ac->drawable->drawable == drawable);
+	return (ac->drawable && ac->drawable->drawable == drawable);
+    }
+
+    return false;
 }
 
 bool apple_glx_copy_context(void *currentptr, void *srcptr, void *destptr, 
@@ -484,9 +503,19 @@
     return updated;
 } 
 
-void apple_glx_context_update(void *ptr) {
+void apple_glx_context_update(Display *dpy, void *ptr) {
     struct apple_glx_context *ac = ptr;
 
+    if(NULL == ac->drawable && None != ac->last_surface_window) {
+	bool failed;
+
+	/* Attempt to recreate the surface for a destroyed drawable. */
+	failed = apple_glx_make_current_context(dpy, ac, ac, ac->last_surface_window);
+
+	apple_glx_diagnostic("%s: surface recreation failed? %s\n", __func__,
+			     failed ? "YES" : "NO");
+    }
+
     if(ac->need_update) {
 	xp_update_gl_context(ac->context_obj);
 	ac->need_update = false;
@@ -509,6 +538,8 @@
 
 	    d = ac->drawable;
 
+	    ac->last_surface_window = d->drawable;
+
 	    ac->drawable = NULL;
 
 	    /* 

Modified: AppleSGLX/trunk/apple_glx_context.h
===================================================================
--- AppleSGLX/trunk/apple_glx_context.h	2009-03-08 04:08:32 UTC (rev 295)
+++ AppleSGLX/trunk/apple_glx_context.h	2009-03-08 20:48:53 UTC (rev 296)
@@ -50,6 +50,13 @@
     bool need_update;
     bool is_current; /* True if the context is current in some thread. */
     bool made_current; /* True if the context has ever been made current. */
+
+    /*
+     * last_surface is set by the pending_destroy code handler for a drawable.
+     * Due to a CG difference, we have to recreate a surface if the window
+     * is unmapped and mapped again.
+     */
+    Window last_surface_window;
     struct apple_glx_context *previous, *next;
 };
 
@@ -59,7 +66,7 @@
 void apple_glx_destroy_context(void **ptr, Display *dpy);
 
 bool apple_glx_make_current_context(Display *dpy, void *oldptr, void *ptr, GLXDrawable drawable);
-bool apple_glx_is_current_drawable(void *ptr, GLXDrawable drawable);
+bool apple_glx_is_current_drawable(Display *dpy, void *ptr, GLXDrawable drawable);
 
 bool apple_glx_copy_context(void *currentptr, void *srcptr, void *destptr, 
 			    unsigned long mask, int *errorptr, 
@@ -67,6 +74,6 @@
 
 int apple_glx_context_surface_changed(unsigned int uid, pthread_t caller);
 
-void apple_glx_context_update(void *ptr);
+void apple_glx_context_update(Display *dpy, void *ptr);
 
 #endif /*APPLE_GLX_CONTEXT_H*/

Modified: AppleSGLX/trunk/apple_xgl_api_viewport.c
===================================================================
--- AppleSGLX/trunk/apple_xgl_api_viewport.c	2009-03-08 04:08:32 UTC (rev 295)
+++ AppleSGLX/trunk/apple_xgl_api_viewport.c	2009-03-08 20:48:53 UTC (rev 296)
@@ -34,9 +34,10 @@
 
 void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
     GLXContext gc = __glXGetCurrentContext();
+    Display *dpy = glXGetCurrentDisplay();
 
     if(gc && gc->apple)
-	apple_glx_context_update(gc->apple);
+	apple_glx_context_update(dpy, gc->apple);
 
     __gl_api.Viewport(x, y, width, height);
 }

Modified: AppleSGLX/trunk/glxcmds.c
===================================================================
--- AppleSGLX/trunk/glxcmds.c	2009-03-08 04:08:32 UTC (rev 295)
+++ AppleSGLX/trunk/glxcmds.c	2009-03-08 20:48:53 UTC (rev 296)
@@ -610,7 +610,7 @@
 PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) {
     GLXContext gc = glXGetCurrentContext();
     
-    if(gc && apple_glx_is_current_drawable(gc->apple, drawable)) {
+    if(gc && apple_glx_is_current_drawable(dpy, gc->apple, drawable)) {
 	apple_glx_swap_buffers(gc->apple);
     } else {
 	__glXSendError(dpy, GLXBadCurrentWindow, 0, X_GLXSwapBuffers, false);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/xquartz-changes/attachments/20090308/910f6a7a/attachment.html>


More information about the Xquartz-changes mailing list