From 99ddce32147957702a61a168c4168829bc0f1e56 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 4 Oct 2010 18:17:53 +0200 Subject: [PATCH] Added context sharing. --- examples/boing.c | 2 +- examples/gears.c | 2 +- examples/heightmap.c | 2 +- examples/splitview.c | 2 +- examples/triangle.c | 2 +- examples/wave.c | 2 +- include/GL/glfw3.h | 2 +- readme.html | 1 + src/cocoa/cocoa_window.m | 7 +++++- src/internal.h | 46 +++++++++++++++++++++++----------------- src/win32/win32_window.c | 37 +++++++++++++++++++++----------- src/window.c | 4 +++- src/x11/x11_window.c | 28 ++++++++++++++---------- tests/accuracy.c | 2 +- tests/defaults.c | 2 +- tests/events.c | 2 +- tests/fsaa.c | 2 +- tests/fsfocus.c | 2 +- tests/iconify.c | 2 +- tests/peter.c | 2 +- tests/reopen.c | 2 +- tests/tearing.c | 2 +- tests/version.c | 2 +- tests/windows.c | 2 +- 24 files changed, 97 insertions(+), 62 deletions(-) diff --git a/examples/boing.c b/examples/boing.c index 721c40aa..007f3f0f 100644 --- a/examples/boing.c +++ b/examples/boing.c @@ -577,7 +577,7 @@ int main( void ) glfwOpenWindowHint(GLFW_DEPTH_BITS, 16); - window = glfwOpenWindow( 400, 400, GLFW_WINDOWED, "Boing (classic Amiga demo)" ); + window = glfwOpenWindow( 400, 400, GLFW_WINDOWED, "Boing (classic Amiga demo)", NULL ); if (!window) { fprintf( stderr, "Failed to open GLFW window\n" ); diff --git a/examples/gears.c b/examples/gears.c index 36b45710..1c2b209c 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -331,7 +331,7 @@ int main(int argc, char *argv[]) glfwOpenWindowHint(GLFW_DEPTH_BITS, 16); - window = glfwOpenWindow( 300, 300, GLFW_WINDOWED, "Gears" ); + window = glfwOpenWindow( 300, 300, GLFW_WINDOWED, "Gears", NULL ); if (!window) { fprintf( stderr, "Failed to open GLFW window\n" ); diff --git a/examples/heightmap.c b/examples/heightmap.c index bd0832c9..b5f2fdbc 100644 --- a/examples/heightmap.c +++ b/examples/heightmap.c @@ -587,7 +587,7 @@ int main(int argc, char** argv) glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); - window = glfwOpenWindow(800, 600, GLFW_WINDOWED, "GLFW OpenGL3 Heightmap demo"); + window = glfwOpenWindow(800, 600, GLFW_WINDOWED, "GLFW OpenGL3 Heightmap demo", NULL); if (! window ) { fprintf(stderr, "ERROR: Unable to create the OpenGL context and associated window\n"); diff --git a/examples/splitview.c b/examples/splitview.c index a3d9589a..1611ad90 100644 --- a/examples/splitview.c +++ b/examples/splitview.c @@ -460,7 +460,7 @@ int main( void ) glfwOpenWindowHint(GLFW_DEPTH_BITS, 16); // Open OpenGL window - window = glfwOpenWindow( 500, 500, GLFW_WINDOWED, "Split view demo" ); + window = glfwOpenWindow( 500, 500, GLFW_WINDOWED, "Split view demo", NULL ); if (!window) { fprintf( stderr, "Failed to open GLFW window\n" ); diff --git a/examples/triangle.c b/examples/triangle.c index 3d717bc5..5e1e2423 100644 --- a/examples/triangle.c +++ b/examples/triangle.c @@ -23,7 +23,7 @@ int main( void ) } // Open a window and create its OpenGL context - window = glfwOpenWindow( 640, 480, GLFW_WINDOWED, "Spinning Triangle" ); + window = glfwOpenWindow( 640, 480, GLFW_WINDOWED, "Spinning Triangle", NULL ); if (!window) { fprintf( stderr, "Failed to open GLFW window\n" ); diff --git a/examples/wave.c b/examples/wave.c index 9cf82ba8..2c81abc8 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -337,7 +337,7 @@ int main(int argc, char* argv[]) glfwOpenWindowHint(GLFW_DEPTH_BITS, 16); /* Open window */ - window = glfwOpenWindow(width, height, mode, "Wave Simulation"); + window = glfwOpenWindow(width, height, mode, "Wave Simulation", NULL); if (!window) { fprintf(stderr, "Could not open window\n"); diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 2c55b136..c4a6ea45 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -413,7 +413,7 @@ GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount); GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode); /* Window handling */ -GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, int mode, const char* title); +GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, int mode, const char* title, GLFWwindow share); GLFWAPI void glfwOpenWindowHint(int target, int hint); GLFWAPI void glfwMakeWindowCurrent(GLFWwindow window); GLFWAPI int glfwIsWindow(GLFWwindow window); diff --git a/readme.html b/readme.html index 54407939..ef04eabb 100644 --- a/readme.html +++ b/readme.html @@ -271,6 +271,7 @@ version of GLFW.

  • Added glfwSetWindowFocusCallback function and GLFWwindowfocusfun type for receiving window focus events
  • Added glfwSetWindowIconifyCallback function and GLFWwindowiconifyfun type for receiving window iconification events
  • Added windows simple multi-window test program
  • +
  • Added a parameter to glfwOpenWindow for specifying a context the new window's context will share objects with
  • Added initial window title parameter to glfwOpenWindow
  • Changed buffer bit depth parameters of glfwOpenWindow to window hints
  • Renamed glfw.h to glfw3.h to avoid conflicts with 2.x series
  • diff --git a/src/cocoa/cocoa_window.m b/src/cocoa/cocoa_window.m index 4014bf8c..ecd6f4de 100644 --- a/src/cocoa/cocoa_window.m +++ b/src/cocoa/cocoa_window.m @@ -631,9 +631,14 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, return GL_FALSE; } + NSOpenGLContext* share = NULL; + + if (wndconfig->share) + share = wndconfig->share->NSGL.context; + window->NSGL.context = [[NSOpenGLContext alloc] initWithFormat:window->NSGL.pixelFormat - shareContext:nil]; + shareContext:share]; if (window->NSGL.context == nil) { _glfwSetError(GLFW_INTERNAL_ERROR); diff --git a/src/internal.h b/src/internal.h index cc1714f9..d073d44b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -60,13 +60,20 @@ #include "platform.h" +typedef struct _GLFWhints _GLFWhints; +typedef struct _GLFWwndconfig _GLFWwndconfig; +typedef struct _GLFWfbconfig _GLFWfbconfig; +typedef struct _GLFWwindow _GLFWwindow; +typedef struct _GLFWlibrary _GLFWlibrary; + + //------------------------------------------------------------------------ // Window hints, set by glfwOpenWindowHint and consumed by glfwOpenWindow // A bucket of semi-random stuff lumped together for historical reasons // This is used only by the platform independent code and only to store // parameters passed to us by glfwOpenWindowHint //------------------------------------------------------------------------ -typedef struct _GLFWhints +struct _GLFWhints { int redBits; int greenBits; @@ -88,7 +95,7 @@ typedef struct _GLFWhints int glForward; int glDebug; int glProfile; -} _GLFWhints; +}; //------------------------------------------------------------------------ @@ -97,18 +104,19 @@ typedef struct _GLFWhints // This is used to pass window and context creation parameters from the // platform independent code to the platform specific code //------------------------------------------------------------------------ -typedef struct _GLFWwndconfig +struct _GLFWwndconfig { - int mode; - const char* title; - int refreshRate; - int windowNoResize; - int glMajor; - int glMinor; - int glForward; - int glDebug; - int glProfile; -} _GLFWwndconfig; + int mode; + const char* title; + int refreshRate; + int windowNoResize; + int glMajor; + int glMinor; + int glForward; + int glDebug; + int glProfile; + _GLFWwindow* share; +}; //------------------------------------------------------------------------ @@ -118,7 +126,7 @@ typedef struct _GLFWwndconfig // code to the platform specific code, and also to enumerate and select // available framebuffer configurations //------------------------------------------------------------------------ -typedef struct _GLFWfbconfig +struct _GLFWfbconfig { int redBits; int greenBits; @@ -134,13 +142,13 @@ typedef struct _GLFWfbconfig int stereo; int samples; GLFWintptr platformID; -} _GLFWfbconfig; +}; //------------------------------------------------------------------------ // Window structure //------------------------------------------------------------------------ -typedef struct _GLFWwindow +struct _GLFWwindow { struct _GLFWwindow* next; @@ -199,13 +207,13 @@ typedef struct _GLFWwindow _GLFW_PLATFORM_WINDOW_STATE; _GLFW_PLATFORM_CONTEXT_STATE; -} _GLFWwindow; +}; //------------------------------------------------------------------------ // Library global data //------------------------------------------------------------------------ -typedef struct _GLFWlibrary +struct _GLFWlibrary { _GLFWhints hints; @@ -215,7 +223,7 @@ typedef struct _GLFWlibrary _GLFWwindow* cursorLockWindow; _GLFW_PLATFORM_LIBRARY_STATE; -} _GLFWlibrary; +}; //======================================================================== diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c index 231dd562..a2304929 100755 --- a/src/win32/win32_window.c +++ b/src/win32/win32_window.c @@ -315,20 +315,23 @@ static HGLRC createContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, int pixelFormat) { - HGLRC context; PIXELFORMATDESCRIPTOR pfd; int flags, i = 0, attribs[7]; + HGLRC share = NULL; + + if (wndconfig->share) + share = wndconfig->share->WGL.context; if (!_glfw_DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd)) { _glfwSetError(GLFW_INTERNAL_ERROR); - return NULL; + return GL_FALSE; } if (!_glfw_SetPixelFormat(window->WGL.DC, pixelFormat, &pfd)) { _glfwSetError(GLFW_INTERNAL_ERROR); - return NULL; + return GL_FALSE; } if (window->WGL.has_WGL_ARB_create_context) @@ -372,24 +375,35 @@ static HGLRC createContext(_GLFWwindow* window, attribs[i++] = 0; - context = window->WGL.CreateContextAttribsARB(window->WGL.DC, NULL, attribs); - if (!context) + window->WGL.context = window->WGL.CreateContextAttribsARB(window->WGL.DC, + share, + attribs); + if (!window->WGL.context) { _glfwSetError(GLFW_INTERNAL_ERROR); - return NULL; + return GL_FALSE; } } else { - context = wglCreateContext(window->WGL.DC); - if (!context) + window->WGL.context = wglCreateContext(window->WGL.DC); + if (!window->WGL.context) { _glfwSetError(GLFW_INTERNAL_ERROR); - return NULL; + return GL_FALSE; + } + + if (share) + { + if (!wglShareLists(share, window->WGL.context)) + { + _glfwSetError(GLFW_INTERNAL_ERROR); + return GL_FALSE; + } } } - return context; + return GL_TRUE; } @@ -1201,8 +1215,7 @@ static int createWindow(_GLFWwindow* window, if (!pixelFormat) return GL_FALSE; - window->WGL.context = createContext(window, wndconfig, pixelFormat); - if (!window->WGL.context) + if (!createContext(window, wndconfig, pixelFormat)) return GL_FALSE; glfwMakeWindowCurrent(window); diff --git a/src/window.c b/src/window.c index 424bea53..0129fad8 100644 --- a/src/window.c +++ b/src/window.c @@ -409,7 +409,8 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, //======================================================================== GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, - int mode, const char* title) + int mode, const char* title, + GLFWwindow share) { _GLFWfbconfig fbconfig; _GLFWwndconfig wndconfig; @@ -458,6 +459,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, wndconfig.glForward = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE; wndconfig.glDebug = _glfwLibrary.hints.glDebug ? GL_TRUE : GL_FALSE; wndconfig.glProfile = _glfwLibrary.hints.glProfile; + wndconfig.share = share; // Clear for next open call _glfwClearWindowHints(); diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c index 9a304c75..5c7cefba 100644 --- a/src/x11/x11_window.c +++ b/src/x11/x11_window.c @@ -483,6 +483,10 @@ static int createContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, G int attribs[40]; int flags, dummy, index; GLXFBConfig* fbconfig; + GLXContext share = NULL; + + if (wndconfig->share) + share = wndconfig->share->GLX.context; // Retrieve the previously selected GLXFBConfig { @@ -580,28 +584,30 @@ static int createContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, G setGLXattrib(attribs, index, None, None); - window->GLX.context = window->GLX.CreateContextAttribsARB(_glfwLibrary.X11.display, - *fbconfig, - NULL, - True, - attribs); + window->GLX.context = + window->GLX.CreateContextAttribsARB(_glfwLibrary.X11.display, + *fbconfig, + share, + True, + attribs); } else { if (window->GLX.has_GLX_SGIX_fbconfig) { - window->GLX.context = window->GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display, - *fbconfig, - GLX_RGBA_TYPE, - NULL, - True); + window->GLX.context = + window->GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display, + *fbconfig, + GLX_RGBA_TYPE, + share, + True); } else { window->GLX.context = glXCreateNewContext(_glfwLibrary.X11.display, *fbconfig, GLX_RGBA_TYPE, - NULL, + share, True); } } diff --git a/tests/accuracy.c b/tests/accuracy.c index d9ae6fa2..08fdabe0 100644 --- a/tests/accuracy.c +++ b/tests/accuracy.c @@ -65,7 +65,7 @@ int main(void) exit(EXIT_FAILURE); } - window = glfwOpenWindow(window_width, window_height, GLFW_WINDOWED, "Cursor Inaccuracy Detector"); + window = glfwOpenWindow(window_width, window_height, GLFW_WINDOWED, "Cursor Inaccuracy Detector", NULL); if (!window) { glfwTerminate(); diff --git a/tests/defaults.c b/tests/defaults.c index fe0cff2c..46ec9c65 100644 --- a/tests/defaults.c +++ b/tests/defaults.c @@ -75,7 +75,7 @@ int main(void) exit(1); } - window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Defaults"); + window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Defaults", NULL); if (!window) { glfwTerminate(); diff --git a/tests/events.c b/tests/events.c index 4ba11449..8da2b983 100644 --- a/tests/events.c +++ b/tests/events.c @@ -290,7 +290,7 @@ int main(void) printf("Library initialized\n"); - window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Event Linter"); + window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Event Linter", NULL); if (!window) { glfwTerminate(); diff --git a/tests/fsaa.c b/tests/fsaa.c index c27316b5..4c834aea 100644 --- a/tests/fsaa.c +++ b/tests/fsaa.c @@ -56,7 +56,7 @@ int main(void) glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); - window = glfwOpenWindow(400, 400, GLFW_WINDOWED, "Aliasing Detector"); + window = glfwOpenWindow(400, 400, GLFW_WINDOWED, "Aliasing Detector", NULL); if (!window) { glfwTerminate(); diff --git a/tests/fsfocus.c b/tests/fsfocus.c index bdbbb310..bfad0a0b 100644 --- a/tests/fsfocus.c +++ b/tests/fsfocus.c @@ -81,7 +81,7 @@ int main(void) exit(EXIT_FAILURE); } - window = glfwOpenWindow(640, 480, GLFW_FULLSCREEN, "Fullscreen focus"); + window = glfwOpenWindow(640, 480, GLFW_FULLSCREEN, "Fullscreen focus", NULL); if (!window) { glfwTerminate(); diff --git a/tests/iconify.c b/tests/iconify.c index 1773f059..b870bf95 100644 --- a/tests/iconify.c +++ b/tests/iconify.c @@ -109,7 +109,7 @@ int main(int argc, char** argv) height = 0; } - window = glfwOpenWindow(width, height, mode, "Iconify"); + window = glfwOpenWindow(width, height, mode, "Iconify", NULL); if (!window) { glfwTerminate(); diff --git a/tests/peter.c b/tests/peter.c index c22639ab..95ab744f 100644 --- a/tests/peter.c +++ b/tests/peter.c @@ -89,7 +89,7 @@ static GLboolean open_window(void) { int x, y; - window_handle = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Peter Detector"); + window_handle = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Peter Detector", NULL); if (!window_handle) return GL_FALSE; diff --git a/tests/reopen.c b/tests/reopen.c index 4239d3f9..6f464af2 100644 --- a/tests/reopen.c +++ b/tests/reopen.c @@ -84,7 +84,7 @@ static int open_window(int width, int height, int mode) { double base = glfwGetTime(); - window_handle = glfwOpenWindow(width, height, mode, "Window Re-opener"); + window_handle = glfwOpenWindow(width, height, mode, "Window Re-opener", NULL); if (!window_handle) { fprintf(stderr, "Failed to open %s mode GLFW window: %s\n", get_mode_name(mode), glfwErrorString(glfwGetError())); diff --git a/tests/tearing.c b/tests/tearing.c index 0f55acec..cd493d53 100644 --- a/tests/tearing.c +++ b/tests/tearing.c @@ -50,7 +50,7 @@ int main(void) exit(EXIT_FAILURE); } - window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Tearing Detector"); + window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Tearing Detector", NULL); if (!window) { glfwTerminate(); diff --git a/tests/version.c b/tests/version.c index 16721e84..0b0dc7e9 100644 --- a/tests/version.c +++ b/tests/version.c @@ -180,7 +180,7 @@ int main(int argc, char** argv) // We assume here that we stand a better chance of success by leaving all // possible details of pixel format selection to GLFW - window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Version"); + window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Version", NULL); if (!window) { glfwTerminate(); diff --git a/tests/windows.c b/tests/windows.c index 5c5b968e..13c76cbe 100644 --- a/tests/windows.c +++ b/tests/windows.c @@ -55,7 +55,7 @@ int main(void) for (i = 0; i < 4; i++) { - windows[i] = glfwOpenWindow(200, 200, GLFW_WINDOWED, titles[i]); + windows[i] = glfwOpenWindow(200, 200, GLFW_WINDOWED, titles[i], NULL); if (!windows[i]) { fprintf(stderr, "Failed to open GLFW window: %s\n",