egl: Some per-driver data should be per-display.

Move some fields of _EGLDriver to _EGLDisplay.  It also becomes
unnecessary to pass _EGLDisplay to drivers when _eglMain is called.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
This commit is contained in:
Chia-I Wu
2009-08-13 13:38:24 +08:00
committed by Brian Paul
parent 0eaa02c836
commit 5a2c9372a0
13 changed files with 138 additions and 95 deletions

View File

@@ -84,7 +84,9 @@ demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
_eglAddConfig(disp, config); _eglAddConfig(disp, config);
} }
drv->Initialized = EGL_TRUE; /* enable supported extensions */
disp->Extensions.MESA_screen_surface = EGL_TRUE;
disp->Extensions.MESA_copy_context = EGL_TRUE;
*major = 1; *major = 1;
*minor = 0; *minor = 0;
@@ -97,7 +99,6 @@ static EGLBoolean
demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy) demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{ {
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/ /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
free(drv);
return EGL_TRUE; return EGL_TRUE;
} }
@@ -247,12 +248,19 @@ demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSu
} }
static void
demoUnload(_EGLDriver *drv)
{
free(drv);
}
/** /**
* The bootstrap function. Return a new DemoDriver object and * The bootstrap function. Return a new DemoDriver object and
* plug in API functions. * plug in API functions.
*/ */
_EGLDriver * _EGLDriver *
_eglMain(_EGLDisplay *dpy, const char *args) _eglMain(const char *args)
{ {
DemoDriver *demo; DemoDriver *demo;
@@ -274,9 +282,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
demo->Base.API.DestroySurface = demoDestroySurface; demo->Base.API.DestroySurface = demoDestroySurface;
demo->Base.API.DestroyContext = demoDestroyContext; demo->Base.API.DestroyContext = demoDestroyContext;
/* enable supported extensions */ demo->Base.Name = "egl/demo";
demo->Base.Extensions.MESA_screen_surface = EGL_TRUE; demo->Base.Unload = demoUnload;
demo->Base.Extensions.MESA_copy_context = EGL_TRUE;
return &demo->Base; return &demo->Base;
} }

View File

@@ -462,9 +462,9 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
} }
} }
glXQueryVersion(disp->Xdpy, &GLX_drv->glx_maj, &GLX_drv->glx_min); disp->ClientAPIsMask = all_apis;
GLX_drv->Base.Initialized = EGL_TRUE; glXQueryVersion(disp->Xdpy, &GLX_drv->glx_maj, &GLX_drv->glx_min);
GLX_drv->Base.Name = "GLX"; GLX_drv->Base.Name = "GLX";
@@ -513,7 +513,9 @@ GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp)
{ {
_eglLog(_EGL_DEBUG, "GLX: eglTerminate"); _eglLog(_EGL_DEBUG, "GLX: eglTerminate");
_eglReleaseDisplayResources(drv, disp);
FreeDisplayExt(disp->Xdpy); FreeDisplayExt(disp->Xdpy);
_eglCleanupDisplay(disp);
return EGL_TRUE; return EGL_TRUE;
} }
@@ -797,12 +799,20 @@ GLX_eglGetProcAddress(const char *procname)
} }
static void
GLX_Unload(_EGLDriver *drv)
{
struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
free(GLX_drv);
}
/** /**
* This is the main entrypoint into the driver, called by libEGL. * This is the main entrypoint into the driver, called by libEGL.
* Create a new _EGLDriver object and init its dispatch table. * Create a new _EGLDriver object and init its dispatch table.
*/ */
_EGLDriver * _EGLDriver *
_eglMain(_EGLDisplay *disp, const char *args) _eglMain(const char *args)
{ {
struct GLX_egl_driver *GLX_drv = CALLOC_STRUCT(GLX_egl_driver); struct GLX_egl_driver *GLX_drv = CALLOC_STRUCT(GLX_egl_driver);
char *env; char *env;
@@ -831,8 +841,8 @@ _eglMain(_EGLDisplay *disp, const char *args)
GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers; GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers;
GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress; GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress;
GLX_drv->Base.ClientAPIsMask = all_apis;
GLX_drv->Base.Name = "GLX"; GLX_drv->Base.Name = "GLX";
GLX_drv->Base.Unload = GLX_Unload;
_eglLog(_EGL_DEBUG, "GLX: main(%s)", args); _eglLog(_EGL_DEBUG, "GLX: main(%s)", args);

View File

@@ -87,15 +87,18 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
} }
drv->APImajor = major_int; disp->APImajor = major_int;
drv->APIminor = minor_int; disp->APIminor = minor_int;
snprintf(drv->Version, sizeof(drv->Version), snprintf(disp->Version, sizeof(disp->Version),
"%d.%d (%s)", major_int, minor_int, drv->Name); "%d.%d (%s)", major_int, minor_int, drv->Name);
/* update the global notion of supported APIs */
_eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask;
disp->Driver = drv; disp->Driver = drv;
} else { } else {
major_int = drv->APImajor; major_int = disp->APImajor;
minor_int = drv->APIminor; minor_int = disp->APIminor;
} }
/* Update applications version of major and minor if not NULL */ /* Update applications version of major and minor if not NULL */

View File

@@ -7,6 +7,19 @@
#include "egltypedefs.h" #include "egltypedefs.h"
#include "eglhash.h" #include "eglhash.h"
#include "egldefines.h"
/**
* Optional EGL extensions info.
*/
struct _egl_extensions
{
EGLBoolean MESA_screen_surface;
EGLBoolean MESA_copy_context;
char String[_EGL_MAX_EXTENSIONS_LEN];
};
struct _egl_display struct _egl_display
@@ -16,6 +29,18 @@ struct _egl_display
const char *DriverName; const char *DriverName;
_EGLDriver *Driver; _EGLDriver *Driver;
void *DriverData; /* private to driver */
int APImajor, APIminor; /**< as returned by eglInitialize() */
char Version[1000]; /**< initialized from APImajor/minor, DriverName */
/** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
EGLint ClientAPIsMask;
char ClientAPIs[1000]; /**< updated by eglQueryString */
_EGLExtensions Extensions;
int LargestPbuffer;
EGLint NumScreens; EGLint NumScreens;
_EGLScreen **Screens; /* array [NumScreens] */ _EGLScreen **Screens; /* array [NumScreens] */

View File

@@ -245,7 +245,7 @@ _eglOpenLibrary(const char *driverName, lib_handle *handle)
* owned by the driver and freed. * owned by the driver and freed.
*/ */
static _EGLDriver * static _EGLDriver *
_eglLoadDriver(_EGLDisplay *dpy, char *path, char *args) _eglLoadDriver(char *path, char *args)
{ {
_EGLMain_t mainFunc; _EGLMain_t mainFunc;
lib_handle lib; lib_handle lib;
@@ -255,7 +255,7 @@ _eglLoadDriver(_EGLDisplay *dpy, char *path, char *args)
if (!mainFunc) if (!mainFunc)
return NULL; return NULL;
drv = mainFunc(dpy, args); drv = mainFunc(args);
if (!drv) { if (!drv) {
if (lib) if (lib)
close_library(lib); close_library(lib);
@@ -332,13 +332,10 @@ _eglPreloadDriver(_EGLDisplay *dpy)
} }
} }
drv = _eglLoadDriver(dpy, path, args); drv = _eglLoadDriver(path, args);
if (!drv) if (!drv)
return NULL; return NULL;
/* update the global notion of supported APIs */
_eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
_eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
return drv->Name; return drv->Name;

View File

@@ -4,19 +4,6 @@
#include "egltypedefs.h" #include "egltypedefs.h"
#include "eglapi.h" #include "eglapi.h"
#include "egldefines.h"
/**
* Optional EGL extensions info.
*/
struct _egl_extensions
{
EGLBoolean MESA_screen_surface;
EGLBoolean MESA_copy_context;
char String[_EGL_MAX_EXTENSIONS_LEN];
};
/** /**
@@ -24,8 +11,6 @@ struct _egl_extensions
*/ */
struct _egl_driver struct _egl_driver
{ {
EGLBoolean Initialized; /**< set by driver after initialized */
void *LibHandle; /**< dlopen handle */ void *LibHandle; /**< dlopen handle */
const char *Path; /**< path to this driver */ const char *Path; /**< path to this driver */
const char *Args; /**< args to load this driver */ const char *Args; /**< args to load this driver */
@@ -36,21 +21,11 @@ struct _egl_driver
/**< called before dlclose to release this driver */ /**< called before dlclose to release this driver */
void (*Unload)(_EGLDriver *drv); void (*Unload)(_EGLDriver *drv);
int APImajor, APIminor; /**< as returned by eglInitialize() */
char Version[1000]; /**< initialized from APImajor/minor, Name */
/** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
EGLint ClientAPIsMask;
_EGLAPI API; /**< EGL API dispatch table */ _EGLAPI API; /**< EGL API dispatch table */
_EGLExtensions Extensions;
int LargestPbuffer;
}; };
extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args); extern _EGLDriver *_eglMain(const char *args);
extern const char * extern const char *

View File

@@ -15,7 +15,6 @@ struct _egl_global _eglGlobal =
&_eglGlobalMutex, /* Mutex */ &_eglGlobalMutex, /* Mutex */
1, /* FreeScreenHandle */ 1, /* FreeScreenHandle */
0x0, /* ClientAPIsMask */ 0x0, /* ClientAPIsMask */
{ 0x0 }, /* ClientAPIs */
0, /* NumDrivers */ 0, /* NumDrivers */
{ NULL }, /* Drivers */ { NULL }, /* Drivers */
1, /* NumAtExitCalls */ 1, /* NumAtExitCalls */

View File

@@ -18,8 +18,6 @@ struct _egl_global
/* bitmaks of supported APIs (supported by _some_ driver) */ /* bitmaks of supported APIs (supported by _some_ driver) */
EGLint ClientAPIsMask; EGLint ClientAPIsMask;
char ClientAPIs[1000]; /**< updated by eglQueryString */
EGLint NumDrivers; EGLint NumDrivers;
_EGLDriver *Drivers[10]; _EGLDriver *Drivers[10];

View File

@@ -35,6 +35,7 @@
#include <string.h> #include <string.h>
#include "eglglobals.h" #include "eglglobals.h"
#include "eglmisc.h" #include "eglmisc.h"
#include "egldisplay.h"
/** /**
@@ -42,40 +43,45 @@
* the driver's Extensions string. * the driver's Extensions string.
*/ */
static void static void
_eglUpdateExtensionsString(_EGLDriver *drv) _eglUpdateExtensionsString(_EGLDisplay *dpy)
{ {
drv->Extensions.String[0] = 0; char *exts = dpy->Extensions.String;
if (drv->Extensions.MESA_screen_surface) if (exts[0])
strcat(drv->Extensions.String, "EGL_MESA_screen_surface "); return;
if (drv->Extensions.MESA_copy_context)
strcat(drv->Extensions.String, "EGL_MESA_copy_context "); if (dpy->Extensions.MESA_screen_surface)
assert(strlen(drv->Extensions.String) < _EGL_MAX_EXTENSIONS_LEN); strcat(exts, "EGL_MESA_screen_surface ");
if (dpy->Extensions.MESA_copy_context)
strcat(exts, "EGL_MESA_copy_context ");
assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN);
} }
static void static void
_eglUpdateAPIsString(_EGLDriver *drv) _eglUpdateAPIsString(_EGLDisplay *dpy)
{ {
_eglGlobal.ClientAPIs[0] = 0; char *apis = dpy->ClientAPIs;
if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) if (apis[0] || !dpy->ClientAPIsMask)
strcat(_eglGlobal.ClientAPIs, "OpenGL "); return;
if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES_BIT) if (dpy->ClientAPIsMask & EGL_OPENGL_BIT)
strcat(_eglGlobal.ClientAPIs, "OpenGL_ES "); strcat(apis, "OpenGL ");
if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES2_BIT) if (dpy->ClientAPIsMask & EGL_OPENGL_ES_BIT)
strcat(_eglGlobal.ClientAPIs, "OpenGL_ES2 "); strcat(apis, "OpenGL_ES ");
if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) if (dpy->ClientAPIsMask & EGL_OPENGL_ES2_BIT)
strcat(_eglGlobal.ClientAPIs, "OpenVG "); strcat(apis, "OpenGL_ES2 ");
assert(strlen(_eglGlobal.ClientAPIs) < sizeof(_eglGlobal.ClientAPIs)); if (dpy->ClientAPIsMask & EGL_OPENVG_BIT)
strcat(apis, "OpenVG ");
assert(strlen(apis) < sizeof(dpy->ClientAPIs));
} }
const char * const char *
_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name) _eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name)
{ {
@@ -85,14 +91,14 @@ _eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name)
case EGL_VENDOR: case EGL_VENDOR:
return _EGL_VENDOR_STRING; return _EGL_VENDOR_STRING;
case EGL_VERSION: case EGL_VERSION:
return drv->Version; return dpy->Version;
case EGL_EXTENSIONS: case EGL_EXTENSIONS:
_eglUpdateExtensionsString(drv); _eglUpdateExtensionsString(dpy);
return drv->Extensions.String; return dpy->Extensions.String;
#ifdef EGL_VERSION_1_2 #ifdef EGL_VERSION_1_2
case EGL_CLIENT_APIS: case EGL_CLIENT_APIS:
_eglUpdateAPIsString(drv); _eglUpdateAPIsString(dpy);
return _eglGlobal.ClientAPIs; return dpy->ClientAPIs;
#endif #endif
default: default:
_eglError(EGL_BAD_PARAMETER, "eglQueryString"); _eglError(EGL_BAD_PARAMETER, "eglQueryString");

View File

@@ -243,7 +243,7 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
*value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID); *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
return EGL_TRUE; return EGL_TRUE;
case EGL_LARGEST_PBUFFER: case EGL_LARGEST_PBUFFER:
*value = drv->LargestPbuffer; *value = dpy->LargestPbuffer;
return EGL_TRUE; return EGL_TRUE;
case EGL_SURFACE_TYPE: case EGL_SURFACE_TYPE:
*value = surface->Type; *value = surface->Type;

View File

@@ -29,7 +29,7 @@ typedef struct _egl_surface _EGLSurface;
typedef struct _egl_thread_info _EGLThreadInfo; typedef struct _egl_thread_info _EGLThreadInfo;
typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy, const char *args); typedef _EGLDriver *(*_EGLMain_t)(const char *args);
#endif /* EGLTYPEDEFS_INCLUDED */ #endif /* EGLTYPEDEFS_INCLUDED */

View File

@@ -21,12 +21,20 @@ extern const struct dri_extension card_extensions[];
* Exported functions * Exported functions
*/ */
static void
drm_unload(_EGLDriver *drv)
{
struct drm_device *dev = (struct drm_device *)drv;
dev->api->destroy(dev->api);
free(dev);
}
/** /**
* The bootstrap function. Return a new drm_driver object and * The bootstrap function. Return a new drm_driver object and
* plug in API functions. * plug in API functions.
*/ */
_EGLDriver * _EGLDriver *
_eglMain(_EGLDisplay *dpy, const char *args) _eglMain(const char *args)
{ {
struct drm_device *drm; struct drm_device *drm;
@@ -53,12 +61,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
drm->base.API.SwapBuffers = drm_swap_buffers; drm->base.API.SwapBuffers = drm_swap_buffers;
drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
drm->base.Name = "DRM/Gallium/Win"; drm->base.Name = "DRM/Gallium/Win";
drm->base.Unload = drm_unload;
/* enable supported extensions */
drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
drm->base.Extensions.MESA_copy_context = EGL_TRUE;
return &drm->base; return &drm->base;
} }
@@ -199,7 +203,10 @@ drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
_eglAddConfig(disp, config); _eglAddConfig(disp, config);
drv->Initialized = EGL_TRUE; disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
/* enable supported extensions */
disp->Extensions.MESA_screen_surface = EGL_TRUE;
disp->Extensions.MESA_copy_context = EGL_TRUE;
*major = 1; *major = 1;
*minor = 4; *minor = 4;
@@ -219,6 +226,8 @@ drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
struct drm_screen *screen; struct drm_screen *screen;
int i = 0; int i = 0;
_eglReleaseDisplayResources(drv, dpy);
drmFreeVersion(dev->version); drmFreeVersion(dev->version);
for (i = 0; i < dev->count_screens; i++) { for (i = 0; i < dev->count_screens; i++) {
@@ -235,12 +244,10 @@ drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
dev->screen->destroy(dev->screen); dev->screen->destroy(dev->screen);
dev->winsys = NULL; dev->winsys = NULL;
dev->api->destroy(dev->api);
drmClose(dev->drmFD); drmClose(dev->drmFD);
_eglCleanupDisplay(dpy); _eglCleanupDisplay(dpy);
free(dev);
return EGL_TRUE; return EGL_TRUE;
} }

View File

@@ -62,6 +62,7 @@ struct xlib_egl_driver
{ {
_EGLDriver Base; /**< base class */ _EGLDriver Base; /**< base class */
EGLint apis;
struct pipe_winsys *winsys; struct pipe_winsys *winsys;
struct pipe_screen *screen; struct pipe_screen *screen;
}; };
@@ -194,9 +195,15 @@ static EGLBoolean
xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
EGLint *minor, EGLint *major) EGLint *minor, EGLint *major)
{ {
struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
create_configs(drv, dpy); create_configs(drv, dpy);
drv->Initialized = EGL_TRUE; if (!dpy->Xdpy) {
dpy->Xdpy = XOpenDisplay(NULL);
}
dpy->ClientAPIsMask = xdrv->apis;
/* we're supporting EGL 1.4 */ /* we're supporting EGL 1.4 */
*minor = 1; *minor = 1;
@@ -212,6 +219,8 @@ xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
static EGLBoolean static EGLBoolean
xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{ {
_eglReleaseDisplayResources(drv, dpy);
_eglCleanupDisplay(dpy);
return EGL_TRUE; return EGL_TRUE;
} }
@@ -744,12 +753,22 @@ find_supported_apis(void)
} }
static void
xlib_Unload(_EGLDriver *drv)
{
struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
xdrv->screen->destroy(xdrv->screen);
free(xdrv->winsys);
free(xdrv);
}
/** /**
* This is the main entrypoint into the driver. * This is the main entrypoint into the driver.
* Called by libEGL to instantiate an _EGLDriver object. * Called by libEGL to instantiate an _EGLDriver object.
*/ */
_EGLDriver * _EGLDriver *
_eglMain(_EGLDisplay *dpy, const char *args) _eglMain(const char *args)
{ {
struct xlib_egl_driver *xdrv; struct xlib_egl_driver *xdrv;
@@ -759,10 +778,6 @@ _eglMain(_EGLDisplay *dpy, const char *args)
if (!xdrv) if (!xdrv)
return NULL; return NULL;
if (!dpy->Xdpy) {
dpy->Xdpy = XOpenDisplay(NULL);
}
_eglInitDriverFallbacks(&xdrv->Base); _eglInitDriverFallbacks(&xdrv->Base);
xdrv->Base.API.Initialize = xlib_eglInitialize; xdrv->Base.API.Initialize = xlib_eglInitialize;
xdrv->Base.API.Terminate = xlib_eglTerminate; xdrv->Base.API.Terminate = xlib_eglTerminate;
@@ -777,16 +792,17 @@ _eglMain(_EGLDisplay *dpy, const char *args)
xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
xdrv->Base.ClientAPIsMask = find_supported_apis(); xdrv->apis = find_supported_apis();
if (xdrv->Base.ClientAPIsMask == 0x0) { if (xdrv->apis == 0x0) {
/* the app isn't directly linked with any EGL-supprted APIs /* the app isn't directly linked with any EGL-supprted APIs
* (such as libGLESv2.so) so use an EGL utility to see what * (such as libGLESv2.so) so use an EGL utility to see what
* APIs might be loaded dynamically on this system. * APIs might be loaded dynamically on this system.
*/ */
xdrv->Base.ClientAPIsMask = _eglFindAPIs(); xdrv->apis = _eglFindAPIs();
} }
xdrv->Base.Name = "Xlib/softpipe"; xdrv->Base.Name = "Xlib/softpipe";
xdrv->Base.Unload = xlib_Unload;
/* create one winsys and use it for all contexts/surfaces */ /* create one winsys and use it for all contexts/surfaces */
xdrv->winsys = create_sw_winsys(); xdrv->winsys = create_sw_winsys();