egldriver.c revision a8533d54930f8fa989036c197ad20b0778ec0cac
16052af172f0241e6678cd16efac0a0f14f40146cBrian Paul/**
26052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * Functions for choosing and opening/loading device drivers.
36052af172f0241e6678cd16efac0a0f14f40146cBrian Paul */
46052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
56052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
6adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <assert.h>
711a261ef4f1d4100c46f73ad51e7e4ed57cc1b5eBrian Paul#include <string.h>
8adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <stdio.h>
90c8908c411c434eda318b41b4f2a370a1e794831Brian Paul#include <stdlib.h>
10adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "eglconfig.h"
11adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "eglcontext.h"
12e084fe54f93c9d51df99812b76d3299b0cff57a3Brian Paul#include "egldefines.h"
13adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldisplay.h"
14adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldriver.h"
15adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "eglglobals.h"
16b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul#include "egllog.h"
1711a261ef4f1d4100c46f73ad51e7e4ed57cc1b5eBrian Paul#include "eglmisc.h"
18adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "eglmode.h"
19c22990c29a5cdff89e6e3914aa565acc88a6a407Brian Paul#include "eglscreen.h"
200c8908c411c434eda318b41b4f2a370a1e794831Brian Paul#include "eglstring.h"
21adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "eglsurface.h"
22adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
23b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#if defined(_EGL_PLATFORM_X)
246b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#include <dlfcn.h>
25b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#include "eglx.h"
26b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#elif defined(_EGL_PLATFORM_WINDOWS)
27b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz/* XXX to do */
28b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#elif defined(_EGL_PLATFORM_WINCE)
29b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz/* XXX to do */
30b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#endif
31adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
32e084fe54f93c9d51df99812b76d3299b0cff57a3Brian Paul
33e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paulstatic const char *DefaultDriverName = ":0";
34e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paulstatic const char *SysFS = "/sys/class";
359843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
369843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
379843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
38a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul/**
39a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul * Wrappers for dlopen/dlclose()
40a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul */
41a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#if defined(_EGL_PLATFORM_WINDOWS)
42a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
43a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   typedef HMODULE lib_handle;
44a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
45a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   static HMODULE
46a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   open_library(const char *filename)
47a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   {
48a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      return LoadLibrary(filename);
49a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
50a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
51a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   static void
52a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   close_library(HMODULE lib)
53a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   {
54a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      FreeLibrary(lib);
55a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
56a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
57a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#elif defined(_EGL_PLATFORM_X)
58a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
59a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   typedef void * lib_handle;
60a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
61a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   static void *
62a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   open_library(const char *filename)
63a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   {
64a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      return dlopen(filename, RTLD_LAZY);
65a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
66a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
67a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   static void
68a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   close_library(void *lib)
69a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   {
70a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      dlclose(lib);
71a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
72a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
73a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#endif
74a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
75a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
769843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
779843c6420d88db0c43b831cf79a3d1872c636225Brian Paul/**
789843c6420d88db0c43b831cf79a3d1872c636225Brian Paul * Given a card number, use sysfs to determine the DRI driver name.
799843c6420d88db0c43b831cf79a3d1872c636225Brian Paul */
8047ddcd2a7144ea456fcd52b9470e4e41b878af48Brian Paulconst char *
819843c6420d88db0c43b831cf79a3d1872c636225Brian Paul_eglChooseDRMDriver(int card)
829843c6420d88db0c43b831cf79a3d1872c636225Brian Paul{
839843c6420d88db0c43b831cf79a3d1872c636225Brian Paul#if 0
849843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   return _eglstrdup("libEGLdri");
859843c6420d88db0c43b831cf79a3d1872c636225Brian Paul#else
869843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   char path[2000], driverName[2000];
879843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   FILE *f;
889843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   int length;
899843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
909843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card);
919843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
929843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   f = fopen(path, "r");
939843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   if (!f)
949843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      return NULL;
959843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
969843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   fgets(driverName, sizeof(driverName), f);
979843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   fclose(f);
989843c6420d88db0c43b831cf79a3d1872c636225Brian Paul
999843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   if ((length = strlen(driverName)) > 1) {
1009843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      /* remove the trailing newline from sysfs */
1019843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      driverName[length - 1] = '\0';
1029843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      strncat(driverName, "_dri", sizeof(driverName));
1039843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      return _eglstrdup(driverName);
1049843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   }
1059843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   else {
1069843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      return NULL;
1079843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   }
1089843c6420d88db0c43b831cf79a3d1872c636225Brian Paul#endif
1099843c6420d88db0c43b831cf79a3d1872c636225Brian Paul}
110adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
111adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
112adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul/**
113e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul * XXX this function is totally subject change!!!
114e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul *
115e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul *
1166052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * Determine/return the name of the driver to use for the given _EGLDisplay.
117adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul *
1186052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * Try to be clever and determine if nativeDisplay is an Xlib Display
1196052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * ptr or a string (naming a driver or screen number, etc).
120adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul *
121adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * If the first character is ':' we interpret it as a screen or card index
122adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * number (i.e. ":0" or ":1", etc)
123adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * Else if the first character is '!' we interpret it as specific driver name
124adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * (i.e. "!r200" or "!i830".
1256052af172f0241e6678cd16efac0a0f14f40146cBrian Paul *
1269843c6420d88db0c43b831cf79a3d1872c636225Brian Paul * Whatever follows ':' is copied and put into dpy->DriverArgs.
1279843c6420d88db0c43b831cf79a3d1872c636225Brian Paul *
1289843c6420d88db0c43b831cf79a3d1872c636225Brian Paul * The caller may free() the returned string.
129adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul */
1306052af172f0241e6678cd16efac0a0f14f40146cBrian Paulconst char *
1316052af172f0241e6678cd16efac0a0f14f40146cBrian Paul_eglChooseDriver(_EGLDisplay *dpy)
132adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{
1330c8908c411c434eda318b41b4f2a370a1e794831Brian Paul   const char *displayString = (const char *) dpy->NativeDisplay;
1346052af172f0241e6678cd16efac0a0f14f40146cBrian Paul   const char *driverName = NULL;
135adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
136e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul   (void) DefaultDriverName;
137e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
138834aa8cfbc25622256889624ee1768c10224feb2Brian Paul   /* First, if the EGL_DRIVER env var is set, use that */
139834aa8cfbc25622256889624ee1768c10224feb2Brian Paul   driverName = getenv("EGL_DRIVER");
140834aa8cfbc25622256889624ee1768c10224feb2Brian Paul   if (driverName)
141834aa8cfbc25622256889624ee1768c10224feb2Brian Paul      return _eglstrdup(driverName);
142834aa8cfbc25622256889624ee1768c10224feb2Brian Paul
143d5078b94323241a6482f54797756116b1c864327Brian Paul#if 0
1440c8908c411c434eda318b41b4f2a370a1e794831Brian Paul   if (!displayString) {
1456052af172f0241e6678cd16efac0a0f14f40146cBrian Paul      /* choose a default */
1460c8908c411c434eda318b41b4f2a370a1e794831Brian Paul      displayString = DefaultDriverName;
147adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
148d5078b94323241a6482f54797756116b1c864327Brian Paul#endif
1490c8908c411c434eda318b41b4f2a370a1e794831Brian Paul   /* extract default DriverArgs = whatever follows ':' */
150834aa8cfbc25622256889624ee1768c10224feb2Brian Paul   if (displayString &&
151834aa8cfbc25622256889624ee1768c10224feb2Brian Paul       (displayString[0] == '!' ||
152834aa8cfbc25622256889624ee1768c10224feb2Brian Paul        displayString[0] == ':')) {
1530c8908c411c434eda318b41b4f2a370a1e794831Brian Paul      const char *args = strchr(displayString, ':');
1540c8908c411c434eda318b41b4f2a370a1e794831Brian Paul      if (args)
1550c8908c411c434eda318b41b4f2a370a1e794831Brian Paul         dpy->DriverArgs = _eglstrdup(args + 1);
1560c8908c411c434eda318b41b4f2a370a1e794831Brian Paul   }
1570c8908c411c434eda318b41b4f2a370a1e794831Brian Paul
1589843c6420d88db0c43b831cf79a3d1872c636225Brian Paul   /* determine driver name now */
1590c8908c411c434eda318b41b4f2a370a1e794831Brian Paul   if (displayString && displayString[0] == ':' &&
1600c8908c411c434eda318b41b4f2a370a1e794831Brian Paul       (displayString[1] >= '0' && displayString[1] <= '9') &&
1610c8908c411c434eda318b41b4f2a370a1e794831Brian Paul       !displayString[2]) {
1629843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      int card = atoi(displayString + 1);
1639843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      driverName = _eglChooseDRMDriver(card);
164adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
1650c8908c411c434eda318b41b4f2a370a1e794831Brian Paul   else if (displayString && displayString[0] == '!') {
1669843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      /* use user-specified driver name */
1679843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      driverName = _eglstrdup(displayString + 1);
1689843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      /* truncate driverName at ':' if present */
1699843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      {
1709843c6420d88db0c43b831cf79a3d1872c636225Brian Paul         char *args = strchr(driverName, ':');
1719843c6420d88db0c43b831cf79a3d1872c636225Brian Paul         if (args) {
1729843c6420d88db0c43b831cf79a3d1872c636225Brian Paul            *args = 0;
1739843c6420d88db0c43b831cf79a3d1872c636225Brian Paul         }
1749843c6420d88db0c43b831cf79a3d1872c636225Brian Paul      }
175adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
176adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   else {
1770c8908c411c434eda318b41b4f2a370a1e794831Brian Paul      /* NativeDisplay is not a string! */
1786052af172f0241e6678cd16efac0a0f14f40146cBrian Paul#if defined(_EGL_PLATFORM_X)
1796052af172f0241e6678cd16efac0a0f14f40146cBrian Paul      driverName = _xeglChooseDriver(dpy);
1806052af172f0241e6678cd16efac0a0f14f40146cBrian Paul#elif defined(_EGL_PLATFORM_WINDOWS)
1816052af172f0241e6678cd16efac0a0f14f40146cBrian Paul      /* XXX to do */
1826052af172f0241e6678cd16efac0a0f14f40146cBrian Paul      driverName = _weglChooseDriver(dpy);
1836052af172f0241e6678cd16efac0a0f14f40146cBrian Paul#elif defined(_EGL_PLATFORM_WINCE)
1846052af172f0241e6678cd16efac0a0f14f40146cBrian Paul      /* XXX to do */
185e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul#else
186e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul      driverName = DefaultDriverName;
1876052af172f0241e6678cd16efac0a0f14f40146cBrian Paul#endif
188adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
189adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
1906052af172f0241e6678cd16efac0a0f14f40146cBrian Paul   return driverName;
191adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul}
192adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
193adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
194adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul/**
195adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * Open/load the named driver and call its bootstrap function: _eglMain().
1966052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * By the time this function is called, the dpy->DriverName should have
1976052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * been determined.
1986052af172f0241e6678cd16efac0a0f14f40146cBrian Paul *
199adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * \return  new _EGLDriver object.
200adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul */
201adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul_EGLDriver *
2020c8908c411c434eda318b41b4f2a370a1e794831Brian Paul_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
203adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{
204485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   _EGLDriver *drv;
205485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   _EGLMain_t mainFunc;
206a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   lib_handle lib;
207adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   char driverFilename[1000];
208adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
2096052af172f0241e6678cd16efac0a0f14f40146cBrian Paul   assert(driverName);
2106052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
2116b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#if defined(_EGL_PLATFORM_WINDOWS)
2126b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   /* XXX untested */
2136b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   sprintf(driverFilename, "%s.dll", driverName);
2146b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
2156b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#elif defined(_EGL_PLATFORM_X)
216adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   /* XXX also prepend a directory path??? */
2177012d01d888d482f2c6ad1180231a482026d213aJon Smirl   sprintf(driverFilename, "%s.so", driverName);
218b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
2196b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#endif
220a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   lib = open_library(driverFilename);
2216b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul
222485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   if (!lib) {
223b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul      _eglLog(_EGL_WARNING, "Could not open %s (%s)",
224b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul              driverFilename, dlerror());
225485528f2acb69940a7c757638127f716c0cb2654Jon Smirl      return NULL;
226485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   }
227adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
2286b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#if defined(_EGL_PLATFORM_WINDOWS)
2296b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
2306b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#elif defined(_EGL_PLATFORM_X)
231485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
2326b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#endif
2336b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul
234485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   if (!mainFunc) {
235b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul      _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
236a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      close_library(lib);
237485528f2acb69940a7c757638127f716c0cb2654Jon Smirl      return NULL;
238adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
239485528f2acb69940a7c757638127f716c0cb2654Jon Smirl
2400c8908c411c434eda318b41b4f2a370a1e794831Brian Paul   drv = mainFunc(dpy, args);
241485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   if (!drv) {
242a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      close_library(lib);
243adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul      return NULL;
244adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   }
2456b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul
246485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   /* with a recurvise open you want the inner most handle */
2476b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   if (!drv->LibHandle) {
248485528f2acb69940a7c757638127f716c0cb2654Jon Smirl      drv->LibHandle = lib;
2496b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   }
2506b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   else {
251a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      close_library(lib);
2526b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul   }
253485528f2acb69940a7c757638127f716c0cb2654Jon Smirl
254d5078b94323241a6482f54797756116b1c864327Brian Paul   /* update the global notion of supported APIs */
255d5078b94323241a6482f54797756116b1c864327Brian Paul   _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
256d5078b94323241a6482f54797756116b1c864327Brian Paul
257e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul   _eglSaveDriver(drv);
258e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
259485528f2acb69940a7c757638127f716c0cb2654Jon Smirl   return drv;
260adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul}
261adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
262adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
263adbff7e977c7c768e752a24fb643d68bdf961bfeBrian PaulEGLBoolean
264adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
265adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{
266adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   void *handle = drv->LibHandle;
267adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   EGLBoolean b;
268b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul
26947ddcd2a7144ea456fcd52b9470e4e41b878af48Brian Paul   _eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
270adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
271adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   /*
272adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul    * XXX check for currently bound context/surfaces and delete them?
273adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul    */
274adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
275daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   b = drv->API.Terminate(drv, dpy);
2766b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul
277a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   close_library(handle);
2786b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul
279adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   return b;
280adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul}
281adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
282adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
283adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul/**
284e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul * Save the given driver pointer in the list of all known drivers.
285e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul */
286e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paulvoid
287e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul_eglSaveDriver(_EGLDriver *drv)
288e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul{
289e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul   _eglGlobal.Drivers[ _eglGlobal.NumDrivers++ ] = drv;
290e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul}
291e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
292e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
293e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul/**
294adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * Given a display handle, return the _EGLDriver for that display.
295adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul */
296adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul_EGLDriver *
297adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul_eglLookupDriver(EGLDisplay dpy)
298adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{
299adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   _EGLDisplay *d = _eglLookupDisplay(dpy);
300adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   if (d)
301adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul      return d->Driver;
302adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   else
303adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul      return NULL;
304adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul}
305adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
306adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
307adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul/**
308adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * Plug all the available fallback routines into the given driver's
309adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul * dispatch table.
310adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul */
311adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paulvoid
312adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul_eglInitDriverFallbacks(_EGLDriver *drv)
313adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{
314adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul   /* If a pointer is set to NULL, then the device driver _really_ has
315adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul    * to implement it.
316adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul    */
317daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.Initialize = NULL;
318daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.Terminate = NULL;
319daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
320daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.GetConfigs = _eglGetConfigs;
321daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.ChooseConfig = _eglChooseConfig;
322daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.GetConfigAttrib = _eglGetConfigAttrib;
323daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
324daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.CreateContext = _eglCreateContext;
325daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.DestroyContext = _eglDestroyContext;
326daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.MakeCurrent = _eglMakeCurrent;
327daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.QueryContext = _eglQueryContext;
328daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
329daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.CreateWindowSurface = _eglCreateWindowSurface;
330daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
331daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
332daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.DestroySurface = _eglDestroySurface;
333daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.QuerySurface = _eglQuerySurface;
334daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.SurfaceAttrib = _eglSurfaceAttrib;
335daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.BindTexImage = _eglBindTexImage;
336daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.ReleaseTexImage = _eglReleaseTexImage;
337daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.SwapInterval = _eglSwapInterval;
338daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.SwapBuffers = _eglSwapBuffers;
339daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.CopyBuffers = _eglCopyBuffers;
340daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
341daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.QueryString = _eglQueryString;
342daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.WaitGL = _eglWaitGL;
343daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.WaitNative = _eglWaitNative;
344adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
345b2006a40eb22899d38cd31691640555228e36975Brian Paul#ifdef EGL_MESA_screen_surface
346daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.ChooseModeMESA = _eglChooseModeMESA;
347daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.GetModesMESA = _eglGetModesMESA;
348daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
349daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.GetScreensMESA = _eglGetScreensMESA;
350daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
35148822796339cb4a55714dc3f1abbe379562ec538Brian Paul   drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
352daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
353daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.QueryScreenMESA = _eglQueryScreenMESA;
354daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
355daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
356daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
357b2006a40eb22899d38cd31691640555228e36975Brian Paul#endif /* EGL_MESA_screen_surface */
358b2006a40eb22899d38cd31691640555228e36975Brian Paul
359b2006a40eb22899d38cd31691640555228e36975Brian Paul#ifdef EGL_VERSION_1_2
360b2006a40eb22899d38cd31691640555228e36975Brian Paul   drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
361b2006a40eb22899d38cd31691640555228e36975Brian Paul#endif /* EGL_VERSION_1_2 */
362adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul}
363a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
364a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
365a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
366a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul/**
367a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc)
368a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul * are supported on the system by looking for standard library names.
369a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul */
370a8533d54930f8fa989036c197ad20b0778ec0cacBrian PaulEGLint
371a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul_eglFindAPIs(void)
372a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul{
373a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   EGLint mask = 0x0;
374a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   lib_handle lib;
375a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#if defined(_EGL_PLATFORM_WINDOWS)
376a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   /* XXX not sure about these names */
377a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *es1_libname = "libGLESv1_CM.dll";
378a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *es2_libname = "libGLESv2.dll";
379a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *gl_libname = "OpenGL32.dll";
380a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *vg_libname = "libOpenVG.dll";
381a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#elif defined(_EGL_PLATFORM_X)
382a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *es1_libname = "libGLESv1_CM.so";
383a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *es2_libname = "libGLESv2.so";
384a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *gl_libname = "libGL.so";
385a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   const char *vg_libname = "libOpenVG.so";
386a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#endif
387a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
388a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   if ((lib = open_library(es1_libname))) {
389a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      close_library(lib);
390a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      mask |= EGL_OPENGL_ES_BIT;
391a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
392a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
393a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   if ((lib = open_library(es2_libname))) {
394a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      close_library(lib);
395a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      mask |= EGL_OPENGL_ES2_BIT;
396a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
397a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
398a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   if ((lib = open_library(gl_libname))) {
399a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      close_library(lib);
400a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      mask |= EGL_OPENGL_BIT;
401a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
402a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
403a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   if ((lib = open_library(vg_libname))) {
404a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      close_library(lib);
405a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul      mask |= EGL_OPENVG_BIT;
406a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   }
407a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul
408a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul   return mask;
409a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul}
410