Revision: 259 http://trac.macosforge.org/projects/xquartz/changeset/259 Author: gstaplin@apple.com Date: 2009-02-25 23:05:26 -0800 (Wed, 25 Feb 2009) Log Message: ----------- Make the xp_update_gl_context thread safe. When a surface notify event occurs the code will now set a need_update boolean in each affected context. Also optimize the make current path a bit to avoid setting current if already current. Do the same with the drawable search and setting. Modified Paths: -------------- AppleSGLX/trunk/Makefile AppleSGLX/trunk/apple_glx.c AppleSGLX/trunk/apple_glx_context.c AppleSGLX/trunk/gen_api_library.tcl Added Paths: ----------- AppleSGLX/trunk/apple_xgl_api_viewport.c AppleSGLX/trunk/apple_xgl_api_viewport.h Modified: AppleSGLX/trunk/Makefile =================================================================== --- AppleSGLX/trunk/Makefile 2009-02-25 21:09:24 UTC (rev 258) +++ AppleSGLX/trunk/Makefile 2009-02-26 07:05:26 UTC (rev 259) @@ -32,7 +32,8 @@ appledri.o apple_glx_context.o apple_glx.o pixel.o \ compsize.o apple_visual.o apple_cgl.o glxreply.o glcontextmodes.o \ apple_xgl_api.o apple_glx_drawable.o xfont.o apple_glx_pbuffer.o \ - apple_glx_pixmap.o apple_xgl_api_read.o glx_empty.o glx_error.o + apple_glx_pixmap.o apple_xgl_api_read.o glx_empty.o glx_error.o \ + apple_xgl_api_viewport.o #This is used for building the tests. #The tests don't require installation. @@ -50,6 +51,7 @@ apple_glx_drawable.o: apple_glx_drawable.h apple_glx_drawable.c apple_glx_pixmap.h apple_glx_pbuffer.h apple_xgl_api.o: apple_xgl_api.h apple_xgl_api.c apple_xgl_api_stereo.c apple_xgl_api_read.o: apple_xgl_api_read.h apple_xgl_api_read.c apple_xgl_api.h +apple_xgl_api_viewport.o: apple_xgl_api_viewport.h apple_xgl_api_viewport.c apple_xgl_api.h glcontextmodes.o: glcontextmodes.c glcontextmodes.h glxext.o: glxext.c glxreply.o: glxreply.c Modified: AppleSGLX/trunk/apple_glx.c =================================================================== --- AppleSGLX/trunk/apple_glx.c 2009-02-25 21:09:24 UTC (rev 258) +++ AppleSGLX/trunk/apple_glx.c 2009-02-26 07:05:26 UTC (rev 259) @@ -1,5 +1,5 @@ /* - Copyright (c) 2008 Apple Inc. + Copyright (c) 2008, 2009 Apple Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -58,22 +58,33 @@ } static void surface_notify_handler(Display *dpy, unsigned int uid, int kind) { - xp_surface_id sid; - CGLContextObj contextobj; - if(apple_glx_get_surface_from_uid(uid, &sid, &contextobj)) { - /* The surface was probably destroyed. */ - return; - } + switch(kind) { + case AppleDRISurfaceNotifyDestroyed: { + xp_surface_id sid; + CGLContextObj contextobj; - switch(kind) { - case AppleDRISurfaceNotifyDestroyed: + if(apple_glx_get_surface_from_uid(uid, &sid, &contextobj)) { + /* The surface was probably destroyed. */ + return; + } + + /* FIXME this needs more thread safety. */ + apple_cgl.clear_drawable(contextobj); xp_destroy_surface(sid); + } break; - case AppleDRISurfaceNotifyChanged: - xp_update_gl_context(contextobj); + case AppleDRISurfaceNotifyChanged: { + int updated; + + updated = apple_glx_context_surface_changed(uid, pthread_self()); + +#ifdef LIBGL_DEBUG + printf("surface notify updated %d\n", updated); +#endif + } break; default: Modified: AppleSGLX/trunk/apple_glx_context.c =================================================================== --- AppleSGLX/trunk/apple_glx_context.c 2009-02-25 21:09:24 UTC (rev 258) +++ AppleSGLX/trunk/apple_glx_context.c 2009-02-26 07:05:26 UTC (rev 259) @@ -139,6 +139,7 @@ ac->thread_id = pthread_self(); ac->screen = screen; ac->double_buffered = false; + ac->need_update = false; ac->is_current = false; ac->made_current = false; @@ -315,13 +316,14 @@ assert(NULL != dpy); /* Reset the is_current state of the old context, if non-NULL. */ - if(oldac) + if(oldac && (ac != oldac)) oldac->is_current = false; if(NULL == ac) { /*Clear the current context.*/ apple_cgl.set_current_context(NULL); - + oldac->is_current = false; + return false; } @@ -337,7 +339,12 @@ return false; } - newagd = apple_glx_find_drawable(dpy, drawable); + /* This is an optimisation to avoid searching for the drawable. */ + if(ac->drawable && ac->drawable->drawable == drawable) { + newagd = ac->drawable; + } else { + newagd = apple_glx_find_drawable(dpy, drawable); + } if(ac->drawable == newagd) same_drawable = true; @@ -371,6 +378,13 @@ } } + /* + * Avoid this costly path if this is the same drawable and the + * context is already current. + */ + if(same_drawable && ac->is_current) + return false; + cglerr = apple_cgl.set_current_context(ac->context_obj); if(kCGLNoError != cglerr) { @@ -556,3 +570,38 @@ unlock_context_list(); } + +/* + * The value returned is the total number of contexts set to update. + * It's meant for debugging/introspection. + */ +int apple_glx_context_surface_changed(unsigned int uid, pthread_t caller) { + struct apple_glx_context *ac; + int updated = 0; + + lock_context_list(); + + for(ac = context_list; ac; ac = ac->next) { + if(ac->drawable && ac->drawable->uid == uid) { + ac->need_update = true; + ++updated; + } + } + + unlock_context_list(); + + return updated; +} + +void apple_glx_context_update(void *ptr) { + struct apple_glx_context *ac = ptr; + + if(ac->need_update) { + xp_update_gl_context(ac->context_obj); + ac->need_update = false; + +#ifdef LIBGL_DEBUG + printf("updating context %p\n", ptr); +#endif + } +} Added: AppleSGLX/trunk/apple_xgl_api_viewport.c =================================================================== --- AppleSGLX/trunk/apple_xgl_api_viewport.c (rev 0) +++ AppleSGLX/trunk/apple_xgl_api_viewport.c 2009-02-26 07:05:26 UTC (rev 259) @@ -0,0 +1,42 @@ +/* + Copyright (c) 2009 Apple Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. +*/ +#include "apple_glx_context.h" +#include "apple_xgl_api.h" +#include "apple_xgl_api_viewport.h" + +extern struct apple_xgl_api __gl_api; + +void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { + GLXContext gc = __glXGetCurrentContext(); + + if(gc && gc->apple) + apple_glx_context_update(gc->apple); + + __gl_api.Viewport(x, y, width, height); +} Added: AppleSGLX/trunk/apple_xgl_api_viewport.h =================================================================== --- AppleSGLX/trunk/apple_xgl_api_viewport.h (rev 0) +++ AppleSGLX/trunk/apple_xgl_api_viewport.h 2009-02-26 07:05:26 UTC (rev 259) @@ -0,0 +1,36 @@ +/* + Copyright (c) 2009 Apple Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. +*/ +#ifndef APPLE_XGL_API_VIEWPORT_H +#define APPLE_XGL_API_VIEWPORT_H + +#include "glxclient.h" + +void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); + +#endif Modified: AppleSGLX/trunk/gen_api_library.tcl =================================================================== --- AppleSGLX/trunk/gen_api_library.tcl 2009-02-25 21:09:24 UTC (rev 258) +++ AppleSGLX/trunk/gen_api_library.tcl 2009-02-26 07:05:26 UTC (rev 259) @@ -127,8 +127,11 @@ #These are special to glXMakeContextCurrent. #See also: apple_xgl_api_read.c. - lappend exclude ReadPixels CopyPixels CopyColorTable + lappend exclude ReadPixels CopyPixels CopyColorTable + #This is excluded to work with surface updates. + lappend exclude Viewport + foreach f $sorted { if {$f in $exclude} { continue