Hi,
This patch series tries to clarify the roles of EGLDriver and
EGLDisplay. It was also mentioned in another thread, and depend on the
driver API overhaul.
The rationale behind the change is every driver provides only a single
EGLDriver instance. That instance is used to drive any number of
displays supported. This patch series updates the drivers such that
they still build and work with a single EGLDisplay, as they were before.
Individual updates to drivers are still required to support multiple
EGLDisplay.
The first patch changes egldriver.c. Now drivers are chosen and
preloaded at eglGetDisplay time. When eglInitialize is called, the
previously preloaded driver (EGLDriver) is matched with the display.
It is possible that multiple displays match to the same driver.
It also adds two new hooks to EGLDriver. `Unload' is called so that the
driver has a change to release any resource it uses before being
unloaded. `Probe` is used to match a display with a driver, when the
display does not specify one. It is not used yet though.
The second patch moves per-display data from EGLDriver to EGLDisplay.
It breaks builds of drivers, which is later fixed by the last patch.
The third patch removes some cleanups done in EGL core. They belong to
drivers. That last patch updates drivers (demo, egl_glx, egl_softpipe,
and EGL_i915). This patch series is tested on egl_glx, egl_softpipe,
and EGL_i915.
--
Regards,
olv
>From 79511c5965176807148c7e44b8a9b97f8bca1177 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <olva...@gmail.com>
Date: Thu, 13 Aug 2009 13:01:48 +0800
Subject: [PATCH 1/4] egl: Change the way drivers are loaded.
Driver is chosen and preloaded when eglGetDisplay is called. Later when
eglInitialize is called, the same driver is matched to initialize the
display. Also, add new, but unused, hooks to EGLDriver to allow a
driver to probe a display or unload itself.
Signed-off-by: Chia-I Wu <olva...@gmail.com>
---
src/egl/main/eglapi.c | 2 +-
src/egl/main/egldisplay.c | 7 +-
src/egl/main/egldisplay.h | 1 -
src/egl/main/egldriver.c | 269 ++++++++++++++++++++++++++++++---------------
src/egl/main/egldriver.h | 15 ++-
src/egl/main/eglglobals.c | 8 +-
6 files changed, 199 insertions(+), 103 deletions(-)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index e8a5b18..464da00 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -77,7 +77,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
drv = disp->Driver;
if (!drv) {
- drv = _eglOpenDriver(disp, disp->DriverName, disp->DriverArgs);
+ drv = _eglOpenDriver(disp);
if (!drv)
return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index c684e42..ba7e634 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -94,7 +94,7 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
_eglInitDisplay();
dpy->SurfaceHash = _eglSurfaceHash;
- dpy->DriverName = _eglChooseDriver(dpy);
+ dpy->DriverName = _eglPreloadDriver(dpy);
if (!dpy->DriverName) {
free(dpy);
return NULL;
@@ -244,11 +244,6 @@ _eglCleanupDisplay(_EGLDisplay *disp)
disp->Configs = NULL;
/* XXX incomplete */
-
- free((void *) disp->DriverName);
- disp->DriverName = NULL;
-
- /* driver deletes the _EGLDisplay object */
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 1ebc0fc..78fbf5b 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -15,7 +15,6 @@ struct _egl_display
EGLDisplay Handle;
const char *DriverName;
- const char *DriverArgs;
_EGLDriver *Driver;
EGLint NumScreens;
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index a8ac7b3..36cc294 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -114,11 +114,12 @@ _eglChooseDRMDriver(int card)
#endif
}
+
/**
* XXX this function is totally subject change!!!
*
*
- * Determine/return the name of the driver to use for the given _EGLDisplay.
+ * Determine/return the path of the driver to use for the given native display.
*
* Try to be clever and determine if nativeDisplay is an Xlib Display
* ptr or a string (naming a driver or screen number, etc).
@@ -128,89 +129,69 @@ _eglChooseDRMDriver(int card)
* Else if the first character is '!' we interpret it as specific driver name
* (i.e. "!r200" or "!i830".
*
- * Whatever follows ':' is copied and put into dpy->DriverArgs.
+ * Whatever follows ':' is interpreted as arguments.
*
- * The caller may free() the returned string.
+ * The caller may free() the returned strings.
*/
-const char *
-_eglChooseDriver(_EGLDisplay *dpy)
+static char *
+_eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
{
- /* Under Windows, the NativeDisplay is an HDC handle, therefore */
- /* it can't be interpreted as a string or a pointer. */
-#if defined(_EGL_PLATFORM_WINDOWS)
- const char *displayString = NULL;
-#else
- const char *displayString = (const char *) dpy->NativeDisplay;
-#endif
- const char *driverName = NULL;
+ char *path = NULL;
+ const char *args = NULL;
- (void) DefaultDriverName;
+ path = getenv("EGL_DRIVER");
+ if (path)
+ path = _eglstrdup(path);
#if defined(_EGL_PLATFORM_X)
- /* First, if the EGL_DRIVER env var is set, use that */
- driverName = getenv("EGL_DRIVER");
- if (driverName)
- return _eglstrdup(driverName);
-#endif
+ (void) DefaultDriverName;
-#if 0
- if (!displayString) {
- /* choose a default */
- displayString = DefaultDriverName;
- }
-#endif
- /* extract default DriverArgs = whatever follows ':' */
- if (displayString &&
- (displayString[0] == '!' ||
- displayString[0] == ':')) {
- const char *args = strchr(displayString, ':');
- if (args)
- dpy->DriverArgs = _eglstrdup(args + 1);
- }
+ if (!path && dpy->NativeDisplay) {
+ const char *dpyString = (const char *) dpy->NativeDisplay;
+ char *p;
+ /* parse the display string */
+ if (dpyString[0] == '!' || dpyString[0] == ':') {
+ if (dpyString[0] == '!') {
+ path = _eglstrdup(dpyString);
+ p = strchr(path, ':');
+ if (p)
+ *p++ = '\0';
+ } else {
+ p = strchr(dpyString, ':');
+ if (p)
+ p++;
+ }
- /* determine driver name now */
- if (displayString && displayString[0] == ':' &&
- (displayString[1] >= '0' && displayString[1] <= '9') &&
- !displayString[2]) {
- int card = atoi(displayString + 1);
- driverName = _eglChooseDRMDriver(card);
- }
- else if (displayString && displayString[0] == '!') {
- /* use user-specified driver name */
- driverName = _eglstrdup(displayString + 1);
- /* truncate driverName at ':' if present */
- {
- char *args = strchr(driverName, ':');
- if (args) {
- *args = 0;
+ if (p) {
+ if (!path && p[0] >= '0' && p[0] <= '9' && !p[1]) {
+ int card = atoi(p);
+ path = (char *) _eglChooseDRMDriver(card);
+ }
+ args = p;
}
}
+ else {
+ path = (char *) _xeglChooseDriver(dpy);
+ }
}
- else
- {
- /* NativeDisplay is not a string! */
-#if defined(_EGL_PLATFORM_X)
- driverName = _xeglChooseDriver(dpy);
-#else
- driverName = DefaultDriverName;
-#endif
- }
+#elif defined(_EGL_PLATFORM_WINDOWS)
+ if (!path)
+ path = _eglstrdup(DefaultDriverName);
+#endif /* _EGL_PLATFORM_X */
- return driverName;
+ if (path && argsRet)
+ *argsRet = (args) ? _eglstrdup(args) : NULL;
+
+ return path;
}
/**
- * Open/load the named driver and call its bootstrap function: _eglMain().
- * By the time this function is called, the dpy->DriverName should have
- * been determined.
- *
- * \return new _EGLDriver object.
+ * Open the named driver and find its bootstrap function: _eglMain().
*/
-_EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
+static _EGLMain_t
+_eglOpenLibrary(const char *driverName, lib_handle *handle)
{
- _EGLDriver *drv;
_EGLMain_t mainFunc;
lib_handle lib;
char driverFilename[1000];
@@ -249,58 +230,170 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
if (!mainFunc) {
_eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
- close_library(lib);
+ if (lib)
+ close_library(lib);
return NULL;
}
+ *handle = lib;
+ return mainFunc;
+}
+
+
+/**
+ * Load the named driver. The path and args passed will be
+ * owned by the driver and freed.
+ */
+static _EGLDriver *
+_eglLoadDriver(_EGLDisplay *dpy, char *path, char *args)
+{
+ _EGLMain_t mainFunc;
+ lib_handle lib;
+ _EGLDriver *drv = NULL;
+
+ mainFunc = _eglOpenLibrary(path, &lib);
+ if (!mainFunc)
+ return NULL;
+
drv = mainFunc(dpy, args);
if (!drv) {
- close_library(lib);
+ if (lib)
+ close_library(lib);
return NULL;
}
- /* with a recurvise open you want the inner most handle */
- if (!drv->LibHandle) {
- drv->LibHandle = lib;
+ if (!drv->Name) {
+ _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
+ drv->Name = "UNNAMED";
}
- else {
- close_library(lib);
+
+ drv->Path = path;
+ drv->Args = args;
+ drv->LibHandle = lib;
+
+ return drv;
+}
+
+
+/**
+ * Match a display to a preloaded driver.
+ */
+static _EGLDriver *
+_eglMatchDriver(_EGLDisplay *dpy)
+{
+ _EGLDriver *defaultDriver = NULL;
+ EGLint i;
+
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ _EGLDriver *drv = _eglGlobal.Drivers[i];
+
+ /* display specifies a driver */
+ if (dpy->DriverName) {
+ if (strcmp(dpy->DriverName, drv->Name) == 0)
+ return drv;
+ }
+ else if (drv->Probe) {
+ if (drv->Probe(drv, dpy))
+ return drv;
+ }
+ else {
+ if (!defaultDriver)
+ defaultDriver = drv;
+ }
}
+ return defaultDriver;
+}
+
+
+/**
+ * Load a driver and save it.
+ */
+const char *
+_eglPreloadDriver(_EGLDisplay *dpy)
+{
+ char *path, *args;
+ _EGLDriver *drv;
+ EGLint i;
+
+ path = _eglChooseDriver(dpy, &args);
+ if (!path)
+ return NULL;
+
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ drv = _eglGlobal.Drivers[i];
+ if (strcmp(drv->Path, path) == 0) {
+ _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
+ drv->Name);
+ free(path);
+ if (args)
+ free(args);
+ return drv->Name;
+ }
+ }
+
+ drv = _eglLoadDriver(dpy, path, args);
+ if (!drv)
+ return NULL;
+
/* update the global notion of supported APIs */
_eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
- _eglSaveDriver(drv);
+ _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
+ return drv->Name;
+}
+
+
+/**
+ * Open a preloaded driver.
+ */
+_EGLDriver *
+_eglOpenDriver(_EGLDisplay *dpy)
+{
+ _EGLDriver *drv = _eglMatchDriver(dpy);
return drv;
}
+/**
+ * Close a preloaded driver.
+ */
EGLBoolean
_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
{
- void *handle = drv->LibHandle;
- EGLBoolean b;
-
- _eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
-
_eglReleaseDisplayResources(drv, dpy);
-
- b = drv->API.Terminate(drv, dpy);
-
- close_library(handle);
-
- return b;
+ drv->API.Terminate(drv, dpy);
+ return EGL_TRUE;
}
/**
- * Save the given driver pointer in the list of all known drivers.
+ * Unload preloaded drivers.
*/
void
-_eglSaveDriver(_EGLDriver *drv)
+_eglUnloadDrivers(void)
{
- _eglGlobal.Drivers[ _eglGlobal.NumDrivers++ ] = drv;
+ EGLint i;
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ _EGLDriver *drv = _eglGlobal.Drivers[i];
+ lib_handle handle = drv->LibHandle;
+
+ if (drv->Path)
+ free((char *) drv->Path);
+ if (drv->Args)
+ free((char *) drv->Args);
+
+ /* destroy driver */
+ if (drv->Unload)
+ drv->Unload(drv);
+
+ if (handle)
+ close_library(handle);
+ _eglGlobal.Drivers[i] = NULL;
+ }
+
+ _eglGlobal.NumDrivers = 0;
}
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index d97a24d..430c094 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -27,8 +27,14 @@ struct _egl_driver
EGLBoolean Initialized; /**< set by driver after initialized */
void *LibHandle; /**< dlopen handle */
+ const char *Path; /**< path to this driver */
+ const char *Args; /**< args to load this driver */
const char *Name; /**< name of this driver */
+ /**< probe a display to see if it is supported */
+ EGLBoolean (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy);
+ /**< called before dlclose to release this driver */
+ void (*Unload)(_EGLDriver *drv);
int APImajor, APIminor; /**< as returned by eglInitialize() */
char Version[1000]; /**< initialized from APImajor/minor, Name */
@@ -50,20 +56,21 @@ extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args);
extern const char *
_eglChooseDRMDriver(int card);
+
extern const char *
-_eglChooseDriver(_EGLDisplay *dpy);
+_eglPreloadDriver(_EGLDisplay *dpy);
extern _EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args);
+_eglOpenDriver(_EGLDisplay *dpy);
extern EGLBoolean
_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy);
-extern void
-_eglSaveDriver(_EGLDriver *drv);
+void
+_eglUnloadDrivers(void);
extern _EGLDriver *
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index e93b48e..a532f14 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -1,7 +1,7 @@
#include <stdlib.h>
#include <assert.h>
#include "eglglobals.h"
-#include "egldisplay.h"
+#include "egldriver.h"
#include "egllog.h"
#include "eglmutex.h"
@@ -18,8 +18,10 @@ struct _egl_global _eglGlobal =
{ 0x0 }, /* ClientAPIs */
0, /* NumDrivers */
{ NULL }, /* Drivers */
- 0, /* NumAtExitCalls */
- { NULL }, /* AtExitCalls */
+ 1, /* NumAtExitCalls */
+ { /* AtExitCalls */
+ _eglUnloadDrivers
+ },
};
--
1.6.2.4
>From 6a301c2e13c13a946cc6e07f0f28dad0aebcc362 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <olva...@gmail.com>
Date: Thu, 13 Aug 2009 13:38:24 +0800
Subject: [PATCH 2/4] 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.
This commit breaks builds of drivers.
Signed-off-by: Chia-I Wu <olva...@gmail.com>
---
src/egl/main/eglapi.c | 13 ++++++----
src/egl/main/egldisplay.h | 25 ++++++++++++++++++++
src/egl/main/egldriver.c | 9 ++-----
src/egl/main/egldriver.h | 27 +---------------------
src/egl/main/eglglobals.c | 1 -
src/egl/main/eglglobals.h | 2 -
src/egl/main/eglmisc.c | 54 ++++++++++++++++++++++++-------------------
src/egl/main/eglsurface.c | 2 +-
src/egl/main/egltypedefs.h | 2 +-
9 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 464da00..a23b571 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -87,15 +87,18 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
}
- drv->APImajor = major_int;
- drv->APIminor = minor_int;
- snprintf(drv->Version, sizeof(drv->Version),
+ disp->APImajor = major_int;
+ disp->APIminor = minor_int;
+ snprintf(disp->Version, sizeof(disp->Version),
"%d.%d (%s)", major_int, minor_int, drv->Name);
+ /* update the global notion of supported APIs */
+ _eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask;
+
disp->Driver = drv;
} else {
- major_int = drv->APImajor;
- minor_int = drv->APIminor;
+ major_int = disp->APImajor;
+ minor_int = disp->APIminor;
}
/* Update applications version of major and minor if not NULL */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 78fbf5b..e1cbbac 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -7,6 +7,19 @@
#include "egltypedefs.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
@@ -16,6 +29,18 @@ struct _egl_display
const char *DriverName;
_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;
_EGLScreen **Screens; /* array [NumScreens] */
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index 36cc294..0e6b294 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -245,7 +245,7 @@ _eglOpenLibrary(const char *driverName, lib_handle *handle)
* owned by the driver and freed.
*/
static _EGLDriver *
-_eglLoadDriver(_EGLDisplay *dpy, char *path, char *args)
+_eglLoadDriver(char *path, char *args)
{
_EGLMain_t mainFunc;
lib_handle lib;
@@ -255,7 +255,7 @@ _eglLoadDriver(_EGLDisplay *dpy, char *path, char *args)
if (!mainFunc)
return NULL;
- drv = mainFunc(dpy, args);
+ drv = mainFunc(args);
if (!drv) {
if (lib)
close_library(lib);
@@ -332,13 +332,10 @@ _eglPreloadDriver(_EGLDisplay *dpy)
}
}
- drv = _eglLoadDriver(dpy, path, args);
+ drv = _eglLoadDriver(path, args);
if (!drv)
return NULL;
- /* update the global notion of supported APIs */
- _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
-
_eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
return drv->Name;
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 430c094..7fba938 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -4,19 +4,6 @@
#include "egltypedefs.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
{
- EGLBoolean Initialized; /**< set by driver after initialized */
-
void *LibHandle; /**< dlopen handle */
const char *Path; /**< path to this driver */
const char *Args; /**< args to load this driver */
@@ -36,21 +21,11 @@ struct _egl_driver
/**< called before dlclose to release this driver */
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 */
-
- _EGLExtensions Extensions;
-
- int LargestPbuffer;
};
-extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args);
+extern _EGLDriver *_eglMain(const char *args);
extern const char *
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index a532f14..8c14f9c 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -15,7 +15,6 @@ struct _egl_global _eglGlobal =
&_eglGlobalMutex, /* Mutex */
1, /* FreeScreenHandle */
0x0, /* ClientAPIsMask */
- { 0x0 }, /* ClientAPIs */
0, /* NumDrivers */
{ NULL }, /* Drivers */
1, /* NumAtExitCalls */
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index 1e2c674..d00d12a 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -18,8 +18,6 @@ struct _egl_global
/* bitmaks of supported APIs (supported by _some_ driver) */
EGLint ClientAPIsMask;
- char ClientAPIs[1000]; /**< updated by eglQueryString */
-
EGLint NumDrivers;
_EGLDriver *Drivers[10];
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 3440b77..b37213f 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -35,6 +35,7 @@
#include <string.h>
#include "eglglobals.h"
#include "eglmisc.h"
+#include "egldisplay.h"
/**
@@ -42,38 +43,43 @@
* the driver's Extensions string.
*/
static void
-_eglUpdateExtensionsString(_EGLDriver *drv)
+_eglUpdateExtensionsString(_EGLDisplay *dpy)
{
- drv->Extensions.String[0] = 0;
+ char *exts = dpy->Extensions.String;
- if (drv->Extensions.MESA_screen_surface)
- strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
- if (drv->Extensions.MESA_copy_context)
- strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
- assert(strlen(drv->Extensions.String) < _EGL_MAX_EXTENSIONS_LEN);
+ if (exts[0])
+ return;
+
+ if (dpy->Extensions.MESA_screen_surface)
+ 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
-_eglUpdateAPIsString(_EGLDriver *drv)
+_eglUpdateAPIsString(_EGLDisplay *dpy)
{
- _eglGlobal.ClientAPIs[0] = 0;
+ char *apis = dpy->ClientAPIs;
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL ");
+ if (apis[0] || !dpy->ClientAPIsMask)
+ return;
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL_ES ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_BIT)
+ strcat(apis, "OpenGL ");
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES2_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL_ES2 ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_ES_BIT)
+ strcat(apis, "OpenGL_ES ");
- if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenVG ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_ES2_BIT)
+ 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 *
@@ -85,14 +91,14 @@ _eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name)
case EGL_VENDOR:
return _EGL_VENDOR_STRING;
case EGL_VERSION:
- return drv->Version;
+ return dpy->Version;
case EGL_EXTENSIONS:
- _eglUpdateExtensionsString(drv);
- return drv->Extensions.String;
+ _eglUpdateExtensionsString(dpy);
+ return dpy->Extensions.String;
#ifdef EGL_VERSION_1_2
case EGL_CLIENT_APIS:
- _eglUpdateAPIsString(drv);
- return _eglGlobal.ClientAPIs;
+ _eglUpdateAPIsString(dpy);
+ return dpy->ClientAPIs;
#endif
default:
_eglError(EGL_BAD_PARAMETER, "eglQueryString");
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 056288c..adf125f 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -243,7 +243,7 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
*value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
return EGL_TRUE;
case EGL_LARGEST_PBUFFER:
- *value = drv->LargestPbuffer;
+ *value = dpy->LargestPbuffer;
return EGL_TRUE;
case EGL_SURFACE_TYPE:
*value = surface->Type;
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index 0a770de..4461440 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -29,7 +29,7 @@ typedef struct _egl_surface _EGLSurface;
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 */
--
1.6.2.4
>From ed7c2b471f321bdf52578cc0319d46700c9a77d0 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <olva...@gmail.com>
Date: Thu, 13 Aug 2009 13:39:51 +0800
Subject: [PATCH 3/4] egl: Do not release resources for drivers.
It is drivers' responsibility to release its resources.
Signed-off-by: Chia-I Wu <olva...@gmail.com>
---
src/egl/main/eglapi.c | 2 +-
src/egl/main/egldisplay.c | 11 ++++++-----
src/egl/main/egldriver.c | 2 --
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index a23b571..29617b7 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -122,7 +122,7 @@ eglTerminate(EGLDisplay dpy)
drv = disp->Driver;
if (drv) {
- /* TODO drv->API.Terminate should be called here */
+ drv->API.Terminate(drv, disp);
_eglCloseDriver(drv, disp);
disp->Driver = NULL;
}
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index ba7e634..0693f25 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -40,7 +40,6 @@ _eglFiniDisplay(void)
if (dpy->ContextList || dpy->SurfaceList)
_eglLog(_EGL_DEBUG, "Display %u is destroyed with resources", key);
- _eglCleanupDisplay(dpy);
free(dpy);
key = _eglHashNextEntry(_eglDisplayHash, key);
@@ -237,11 +236,13 @@ _eglCleanupDisplay(_EGLDisplay *disp)
{
EGLint i;
- for (i = 0; i < disp->NumConfigs; i++) {
- free(disp->Configs[i]);
+ if (disp->Configs) {
+ for (i = 0; i < disp->NumConfigs; i++)
+ free(disp->Configs[i]);
+ free(disp->Configs);
+ disp->Configs = NULL;
+ disp->NumConfigs = 0;
}
- free(disp->Configs);
- disp->Configs = NULL;
/* XXX incomplete */
}
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index 0e6b294..a252a9a 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -359,8 +359,6 @@ _eglOpenDriver(_EGLDisplay *dpy)
EGLBoolean
_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
{
- _eglReleaseDisplayResources(drv, dpy);
- drv->API.Terminate(drv, dpy);
return EGL_TRUE;
}
--
1.6.2.4
>From fa34d5141167354f691b476a6aa36f82b6e2a7e2 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <olva...@gmail.com>
Date: Thu, 13 Aug 2009 13:39:41 +0800
Subject: [PATCH 4/4] egl: Unbreak builds of drivers.
The last two commits moved some fields from _EGLDriver to _EGLDisplay,
and changed the prototype of _eglMain. Update drivers so that they
build again, and implement unload hooks to destroy the drivers.
Signed-off-by: Chia-I Wu <olva...@gmail.com>
---
src/egl/drivers/demo/demo.c | 19 +++++++++----
src/egl/drivers/glx/egl_glx.c | 18 ++++++++++---
src/gallium/state_trackers/egl/egl_tracker.c | 25 +++++++++++------
src/gallium/winsys/egl_xlib/egl_xlib.c | 36 ++++++++++++++++++-------
4 files changed, 69 insertions(+), 29 deletions(-)
diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c
index e9e6bac..aea4894 100644
--- a/src/egl/drivers/demo/demo.c
+++ b/src/egl/drivers/demo/demo.c
@@ -84,7 +84,9 @@ demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
_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;
*minor = 0;
@@ -97,7 +99,6 @@ static EGLBoolean
demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/
- free(drv);
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
* plug in API functions.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
{
DemoDriver *demo;
@@ -274,9 +282,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
demo->Base.API.DestroySurface = demoDestroySurface;
demo->Base.API.DestroyContext = demoDestroyContext;
- /* enable supported extensions */
- demo->Base.Extensions.MESA_screen_surface = EGL_TRUE;
- demo->Base.Extensions.MESA_copy_context = EGL_TRUE;
+ demo->Base.Name = "egl/demo";
+ demo->Base.Unload = demoUnload;
return &demo->Base;
}
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index 607e649..9d80bc1 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -462,10 +462,10 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
}
}
+ disp->ClientAPIsMask = all_apis;
+
glXQueryVersion(disp->Xdpy, &GLX_drv->glx_maj, &GLX_drv->glx_min);
- GLX_drv->Base.Initialized = EGL_TRUE;
-
GLX_drv->Base.Name = "GLX";
/* we're supporting EGL 1.4 */
@@ -513,7 +513,9 @@ GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp)
{
_eglLog(_EGL_DEBUG, "GLX: eglTerminate");
+ _eglReleaseDisplayResources(drv, disp);
FreeDisplayExt(disp->Xdpy);
+ _eglCleanupDisplay(disp);
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.
* Create a new _EGLDriver object and init its dispatch table.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *disp, const char *args)
+_eglMain(const char *args)
{
struct GLX_egl_driver *GLX_drv = CALLOC_STRUCT(GLX_egl_driver);
char *env;
@@ -831,8 +841,8 @@ _eglMain(_EGLDisplay *disp, const char *args)
GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers;
GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress;
- GLX_drv->Base.ClientAPIsMask = all_apis;
GLX_drv->Base.Name = "GLX";
+ GLX_drv->Base.Unload = GLX_Unload;
_eglLog(_EGL_DEBUG, "GLX: main(%s)", args);
diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c
index 107f45c..ced002c 100644
--- a/src/gallium/state_trackers/egl/egl_tracker.c
+++ b/src/gallium/state_trackers/egl/egl_tracker.c
@@ -21,12 +21,20 @@ extern const struct dri_extension card_extensions[];
* 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
* plug in API functions.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
{
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.SwapBuffers = drm_swap_buffers;
- drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
drm->base.Name = "DRM/Gallium/Win";
-
- /* enable supported extensions */
- drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
- drm->base.Extensions.MESA_copy_context = EGL_TRUE;
+ drm->base.Unload = drm_unload;
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);
_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;
*minor = 4;
@@ -219,6 +226,8 @@ drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
struct drm_screen *screen;
int i = 0;
+ _eglReleaseDisplayResources(drv, dpy);
+
drmFreeVersion(dev->version);
for (i = 0; i < dev->count_screens; i++) {
@@ -235,12 +244,10 @@ drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
dev->screen->destroy(dev->screen);
dev->winsys = NULL;
- dev->api->destroy(dev->api);
drmClose(dev->drmFD);
_eglCleanupDisplay(dpy);
- free(dev);
return EGL_TRUE;
}
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index ed7eab5..7a66756 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -62,6 +62,7 @@ struct xlib_egl_driver
{
_EGLDriver Base; /**< base class */
+ EGLint apis;
struct pipe_winsys *winsys;
struct pipe_screen *screen;
};
@@ -194,9 +195,15 @@ static EGLBoolean
xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
EGLint *minor, EGLint *major)
{
+ struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+
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 */
*minor = 1;
@@ -212,6 +219,8 @@ xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
static EGLBoolean
xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
+ _eglReleaseDisplayResources(drv, dpy);
+ _eglCleanupDisplay(dpy);
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.
* Called by libEGL to instantiate an _EGLDriver object.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
{
struct xlib_egl_driver *xdrv;
@@ -759,10 +778,6 @@ _eglMain(_EGLDisplay *dpy, const char *args)
if (!xdrv)
return NULL;
- if (!dpy->Xdpy) {
- dpy->Xdpy = XOpenDisplay(NULL);
- }
-
_eglInitDriverFallbacks(&xdrv->Base);
xdrv->Base.API.Initialize = xlib_eglInitialize;
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.SwapBuffers = xlib_eglSwapBuffers;
- xdrv->Base.ClientAPIsMask = find_supported_apis();
- if (xdrv->Base.ClientAPIsMask == 0x0) {
+ xdrv->apis = find_supported_apis();
+ if (xdrv->apis == 0x0) {
/* the app isn't directly linked with any EGL-supprted APIs
* (such as libGLESv2.so) so use an EGL utility to see what
* APIs might be loaded dynamically on this system.
*/
- xdrv->Base.ClientAPIsMask = _eglFindAPIs();
- }
+ xdrv->apis = _eglFindAPIs();
+ }
xdrv->Base.Name = "Xlib/softpipe";
+ xdrv->Base.Unload = xlib_Unload;
/* create one winsys and use it for all contexts/surfaces */
xdrv->winsys = create_sw_winsys();
--
1.6.2.4
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev