From ccbb95634145ad5bc6362fc0bffdc63ac8a63d1d Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Mon, 7 Mar 2011 14:09:13 +0100
Subject: [PATCH] Added pluggable memory allocator and threading stub.
---
include/GL/glfw3.h | 15 +++++++++++
readme.html | 1 +
src/init.c | 55 ++++++++++++++++++++++++++++++++++++++++
src/internal.h | 7 +++++
src/win32/win32_window.c | 6 ++---
src/window.c | 4 +--
src/x11/x11_fullscreen.c | 12 ++++-----
src/x11/x11_window.c | 6 ++---
8 files changed, 92 insertions(+), 14 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 9d5ae7bd..ee622b20 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -463,6 +463,8 @@ typedef void (* GLFWmouseposfun)(GLFWwindow,int,int);
typedef void (* GLFWscrollfun)(GLFWwindow,int,int);
typedef void (* GLFWkeyfun)(GLFWwindow,int,int);
typedef void (* GLFWcharfun)(GLFWwindow,int);
+typedef void* (* GLFWmallocfun)(size_t);
+typedef void (* GLFWfreefun)(void*);
/* The video mode structure used by glfwGetVideoModes */
typedef struct
@@ -482,6 +484,18 @@ typedef struct
unsigned short blue[GLFW_GAMMA_RAMP_SIZE];
} GLFWgammaramp;
+/* Custom memory allocator interface */
+typedef struct
+{
+ GLFWmallocfun malloc;
+ GLFWfreefun free;
+} GLFWallocator;
+
+/* Custom threading model interface */
+typedef struct
+{
+} GLFWthreadmodel;
+
/*************************************************************************
* Prototypes
@@ -489,6 +503,7 @@ typedef struct
/* Initialization, termination and version querying */
GLFWAPI int glfwInit(void);
+GLFWAPI int glfwInitWithModels(GLFWthreadmodel* threading, GLFWallocator* allocator);
GLFWAPI void glfwTerminate(void);
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
GLFWAPI const char* glfwGetVersionString(void);
diff --git a/readme.html b/readme.html
index c373a4ba..6d54174f 100644
--- a/readme.html
+++ b/readme.html
@@ -272,6 +272,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 glfwGetCurrentWindow
function for retrieving the window whose OpenGL context is current
+ Added glfwInitWithModels
function and GLFWallocator
and GLFWthreadmodel
types for pluggable memory allocation and threading models
Added GLFW_OPENGL_ES2_PROFILE
profile for creating OpenGL ES 2.0 contexts using the GLX_EXT_create_context_es2_profile
and WGL_EXT_create_context_es2_profile
extensions
Added windows
simple multi-window test program
Added sharing
simple OpenGL object sharing test program
diff --git a/src/init.c b/src/init.c
index 99f0fd92..d83c19ee 100644
--- a/src/init.c
+++ b/src/init.c
@@ -45,6 +45,30 @@ static void glfw_atexit(void)
}
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Allocate memory using the allocator
+//========================================================================
+
+void* _glfwMalloc(size_t size)
+{
+ return _glfwLibrary.allocator.malloc(size);
+}
+
+
+//========================================================================
+// Free memory using the allocator
+//========================================================================
+
+void _glfwFree(void* ptr)
+{
+ _glfwLibrary.allocator.free(ptr);
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -54,12 +78,43 @@ static void glfw_atexit(void)
//========================================================================
GLFWAPI int glfwInit(void)
+{
+ return glfwInitWithModels(NULL, NULL);
+}
+
+
+//========================================================================
+// Initialize various GLFW state using custom model interfaces
+//========================================================================
+
+GLFWAPI int glfwInitWithModels(GLFWthreadmodel* threading, GLFWallocator* allocator)
{
if (_glfwInitialized)
return GL_TRUE;
memset(&_glfwLibrary, 0, sizeof(_glfwLibrary));
+ if (threading)
+ _glfwLibrary.threading = *threading;
+
+ if (allocator)
+ {
+ // Verify that the specified model is complete
+ if (!allocator->malloc || !allocator->free)
+ {
+ _glfwSetError(GLFW_INVALID_VALUE, NULL);
+ return GL_FALSE;
+ }
+
+ _glfwLibrary.allocator = *allocator;
+ }
+ else
+ {
+ // Use the libc malloc and free
+ _glfwLibrary.allocator.malloc = malloc;
+ _glfwLibrary.allocator.free = free;
+ }
+
// Not all window hints are cleared to zero, so this needs to be here
// despite the memset above
_glfwClearWindowHints();
diff --git a/src/internal.h b/src/internal.h
index b0465e1b..a9fbe16d 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -228,6 +228,9 @@ struct _GLFWlibrary
GLFWkeyfun keyCallback;
GLFWcharfun charCallback;
+ GLFWthreadmodel threading;
+ GLFWallocator allocator;
+
GLFWgammaramp currentRamp;
GLFWgammaramp originalRamp;
int originalRampSize;
@@ -310,6 +313,10 @@ void* _glfwPlatformGetProcAddress(const char* procname);
// Prototypes for platform independent internal functions
//========================================================================
+// Memory management (init.c)
+void* _glfwMalloc(size_t size);
+void _glfwFree(void* ptr);
+
// Fullscren management (fullscreen.c)
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c
index 98c4dafe..2def3a82 100644
--- a/src/win32/win32_window.c
+++ b/src/win32/win32_window.c
@@ -188,7 +188,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
return NULL;
}
- result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);
+ result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count);
if (!result)
{
_glfwSetError(GLFW_OUT_OF_MEMORY, "Win32/WGL: Failed to allocate _GLFWfbconfig array");
@@ -1182,13 +1182,13 @@ static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* fbconfig)
closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!closest)
{
- free(fbconfigs);
+ _glfwFree(fbconfigs);
return 0;
}
pixelFormat = (int) closest->platformID;
- free(fbconfigs);
+ _glfwFree(fbconfigs);
fbconfigs = NULL;
closest = NULL;
diff --git a/src/window.c b/src/window.c
index 8e16ad2c..de497f71 100644
--- a/src/window.c
+++ b/src/window.c
@@ -360,7 +360,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
return NULL;
}
- window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow));
+ window = (_GLFWwindow*) _glfwMalloc(sizeof(_GLFWwindow));
if (!window)
{
_glfwSetError(GLFW_OUT_OF_MEMORY, "glfwOpenWindow: Failed to allocate window structure");
@@ -692,7 +692,7 @@ GLFWAPI void glfwCloseWindow(GLFWwindow handle)
*prev = window->next;
}
- free(window);
+ _glfwFree(window);
}
diff --git a/src/x11/x11_fullscreen.c b/src/x11/x11_fullscreen.c
index 40b85f97..c154fe3d 100644
--- a/src/x11/x11_fullscreen.c
+++ b/src/x11/x11_fullscreen.c
@@ -356,7 +356,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
return 0;
}
- rgbarray = (int*) malloc(sizeof(int) * viscount);
+ rgbarray = (int*) _glfwMalloc(sizeof(int) * viscount);
rgbcount = 0;
// Build RGB array
@@ -400,7 +400,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
sizelist = XRRConfigSizes(sc, &sizecount);
- resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * sizecount);
+ resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * sizecount);
for (k = 0; k < sizecount; k++)
{
@@ -417,7 +417,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
#if defined(_GLFW_HAS_XF86VIDMODE)
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, &modecount, &modelist);
- resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount);
+ resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * modecount);
for (k = 0; k < modecount; k++)
{
@@ -446,7 +446,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
if (!resarray)
{
rescount = 1;
- resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount);
+ resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * rescount);
resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, screen);
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, screen);
@@ -470,8 +470,8 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
// Free visuals list
XFree(vislist);
- free(resarray);
- free(rgbarray);
+ _glfwFree(resarray);
+ _glfwFree(rgbarray);
return count;
}
diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c
index abafe39f..3ecb15a1 100644
--- a/src/x11/x11_window.c
+++ b/src/x11/x11_window.c
@@ -304,7 +304,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
}
}
- result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);
+ result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count);
if (!result)
{
_glfwSetError(GLFW_OUT_OF_MEMORY, "X11/GLX: Failed to allocate _GLFWfbconfig array");
@@ -1341,12 +1341,12 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!result)
{
- free(fbconfigs);
+ _glfwFree(fbconfigs);
return GL_FALSE;
}
closest = *result;
- free(fbconfigs);
+ _glfwFree(fbconfigs);
}
if (!createContext(window, wndconfig, (GLXFBConfigID) closest.platformID))