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 721c40aad..007f3f0f8 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 36b45710c..1c2b209c4 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 bd0832c9c..b5f2fdbc3 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 a3d9589a2..1611ad90f 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 3d717bc51..5e1e24233 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 9cf82ba8d..2c81abc88 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 2c55b136c..c4a6ea451 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 54407939b..ef04eabb7 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 4014bf8cf..ecd6f4de8 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 cc1714f95..d073d44bf 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 231dd562c..a23049298 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 424bea538..0129fad88 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 9a304c75a..5c7cefba7 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 d9ae6fa2b..08fdabe0d 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 fe0cff2ce..46ec9c657 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 4ba114499..8da2b9839 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 c27316b52..4c834aea8 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 bdbbb3105..bfad0a0ba 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 1773f059b..b870bf957 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 c22639ab0..95ab744fd 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 4239d3f92..6f464af25 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 0f55acec4..cd493d530 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 16721e84c..0b0dc7e9d 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 5c5b968ee..13c76cbea 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",