Added pluggable memory allocator and threading stub.

This commit is contained in:
Camilla Berglund 2011-03-07 14:09:13 +01:00
parent cf7819df8d
commit ccbb956341
8 changed files with 92 additions and 14 deletions

View File

@ -463,6 +463,8 @@ typedef void (* GLFWmouseposfun)(GLFWwindow,int,int);
typedef void (* GLFWscrollfun)(GLFWwindow,int,int); typedef void (* GLFWscrollfun)(GLFWwindow,int,int);
typedef void (* GLFWkeyfun)(GLFWwindow,int,int); typedef void (* GLFWkeyfun)(GLFWwindow,int,int);
typedef void (* GLFWcharfun)(GLFWwindow,int); typedef void (* GLFWcharfun)(GLFWwindow,int);
typedef void* (* GLFWmallocfun)(size_t);
typedef void (* GLFWfreefun)(void*);
/* The video mode structure used by glfwGetVideoModes */ /* The video mode structure used by glfwGetVideoModes */
typedef struct typedef struct
@ -482,6 +484,18 @@ typedef struct
unsigned short blue[GLFW_GAMMA_RAMP_SIZE]; unsigned short blue[GLFW_GAMMA_RAMP_SIZE];
} GLFWgammaramp; } GLFWgammaramp;
/* Custom memory allocator interface */
typedef struct
{
GLFWmallocfun malloc;
GLFWfreefun free;
} GLFWallocator;
/* Custom threading model interface */
typedef struct
{
} GLFWthreadmodel;
/************************************************************************* /*************************************************************************
* Prototypes * Prototypes
@ -489,6 +503,7 @@ typedef struct
/* Initialization, termination and version querying */ /* Initialization, termination and version querying */
GLFWAPI int glfwInit(void); GLFWAPI int glfwInit(void);
GLFWAPI int glfwInitWithModels(GLFWthreadmodel* threading, GLFWallocator* allocator);
GLFWAPI void glfwTerminate(void); GLFWAPI void glfwTerminate(void);
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
GLFWAPI const char* glfwGetVersionString(void); GLFWAPI const char* glfwGetVersionString(void);

View File

@ -272,6 +272,7 @@ version of GLFW.</p>
<li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li> <li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li>
<li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li> <li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li>
<li>Added <code>glfwGetCurrentWindow</code> function for retrieving the window whose OpenGL context is current</li> <li>Added <code>glfwGetCurrentWindow</code> function for retrieving the window whose OpenGL context is current</li>
<li>Added <code>glfwInitWithModels</code> function and <code>GLFWallocator</code> and <code>GLFWthreadmodel</code> types for pluggable memory allocation and threading models</li>
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li> <li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li>
<li>Added <code>windows</code> simple multi-window test program</li> <li>Added <code>windows</code> simple multi-window test program</li>
<li>Added <code>sharing</code> simple OpenGL object sharing test program</li> <li>Added <code>sharing</code> simple OpenGL object sharing test program</li>

View File

@ -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 ////// ////// GLFW public API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -54,12 +78,43 @@ static void glfw_atexit(void)
//======================================================================== //========================================================================
GLFWAPI int glfwInit(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) if (_glfwInitialized)
return GL_TRUE; return GL_TRUE;
memset(&_glfwLibrary, 0, sizeof(_glfwLibrary)); 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 // Not all window hints are cleared to zero, so this needs to be here
// despite the memset above // despite the memset above
_glfwClearWindowHints(); _glfwClearWindowHints();

View File

@ -228,6 +228,9 @@ struct _GLFWlibrary
GLFWkeyfun keyCallback; GLFWkeyfun keyCallback;
GLFWcharfun charCallback; GLFWcharfun charCallback;
GLFWthreadmodel threading;
GLFWallocator allocator;
GLFWgammaramp currentRamp; GLFWgammaramp currentRamp;
GLFWgammaramp originalRamp; GLFWgammaramp originalRamp;
int originalRampSize; int originalRampSize;
@ -310,6 +313,10 @@ void* _glfwPlatformGetProcAddress(const char* procname);
// Prototypes for platform independent internal functions // Prototypes for platform independent internal functions
//======================================================================== //========================================================================
// Memory management (init.c)
void* _glfwMalloc(size_t size);
void _glfwFree(void* ptr);
// Fullscren management (fullscreen.c) // Fullscren management (fullscreen.c)
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);

View File

@ -188,7 +188,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
return NULL; return NULL;
} }
result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count); result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count);
if (!result) if (!result)
{ {
_glfwSetError(GLFW_OUT_OF_MEMORY, "Win32/WGL: Failed to allocate _GLFWfbconfig array"); _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); closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!closest) if (!closest)
{ {
free(fbconfigs); _glfwFree(fbconfigs);
return 0; return 0;
} }
pixelFormat = (int) closest->platformID; pixelFormat = (int) closest->platformID;
free(fbconfigs); _glfwFree(fbconfigs);
fbconfigs = NULL; fbconfigs = NULL;
closest = NULL; closest = NULL;

View File

@ -360,7 +360,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
return NULL; return NULL;
} }
window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow)); window = (_GLFWwindow*) _glfwMalloc(sizeof(_GLFWwindow));
if (!window) if (!window)
{ {
_glfwSetError(GLFW_OUT_OF_MEMORY, "glfwOpenWindow: Failed to allocate window structure"); _glfwSetError(GLFW_OUT_OF_MEMORY, "glfwOpenWindow: Failed to allocate window structure");
@ -692,7 +692,7 @@ GLFWAPI void glfwCloseWindow(GLFWwindow handle)
*prev = window->next; *prev = window->next;
} }
free(window); _glfwFree(window);
} }

View File

@ -356,7 +356,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
return 0; return 0;
} }
rgbarray = (int*) malloc(sizeof(int) * viscount); rgbarray = (int*) _glfwMalloc(sizeof(int) * viscount);
rgbcount = 0; rgbcount = 0;
// Build RGB array // Build RGB array
@ -400,7 +400,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
sizelist = XRRConfigSizes(sc, &sizecount); 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++) for (k = 0; k < sizecount; k++)
{ {
@ -417,7 +417,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
#if defined(_GLFW_HAS_XF86VIDMODE) #if defined(_GLFW_HAS_XF86VIDMODE)
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, &modecount, &modelist); 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++) for (k = 0; k < modecount; k++)
{ {
@ -446,7 +446,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
if (!resarray) if (!resarray)
{ {
rescount = 1; 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].width = DisplayWidth(_glfwLibrary.X11.display, screen);
resarray[0].height = DisplayHeight(_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 // Free visuals list
XFree(vislist); XFree(vislist);
free(resarray); _glfwFree(resarray);
free(rgbarray); _glfwFree(rgbarray);
return count; return count;
} }

View File

@ -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) if (!result)
{ {
_glfwSetError(GLFW_OUT_OF_MEMORY, "X11/GLX: Failed to allocate _GLFWfbconfig array"); _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); result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!result) if (!result)
{ {
free(fbconfigs); _glfwFree(fbconfigs);
return GL_FALSE; return GL_FALSE;
} }
closest = *result; closest = *result;
free(fbconfigs); _glfwFree(fbconfigs);
} }
if (!createContext(window, wndconfig, (GLXFBConfigID) closest.platformID)) if (!createContext(window, wndconfig, (GLXFBConfigID) closest.platformID))