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))