added boolean extension flags to _EGLDriver
[mesa.git] / src / egl / main / egldriver.c
1 #include <assert.h>
2 #include <dlfcn.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "eglconfig.h"
6 #include "eglcontext.h"
7 #include "egldisplay.h"
8 #include "egldriver.h"
9 #include "eglglobals.h"
10 #include "eglmode.h"
11 #include "eglscreen.h"
12 #include "eglsurface.h"
13
14
15 const char *DefaultDriverName = "demodriver";
16
17
18 /**
19 * Choose and open/init the hardware driver for the given EGLDisplay.
20 * Previously, the EGLDisplay was created with _eglNewDisplay() where
21 * we recorded the user's NativeDisplayType parameter.
22 *
23 * Now we'll use the NativeDisplayType value.
24 *
25 * Currently, the native display value is treated as a string.
26 * If the first character is ':' we interpret it as a screen or card index
27 * number (i.e. ":0" or ":1", etc)
28 * Else if the first character is '!' we interpret it as specific driver name
29 * (i.e. "!r200" or "!i830".
30 */
31 _EGLDriver *
32 _eglChooseDriver(EGLDisplay display)
33 {
34 _EGLDisplay *dpy = _eglLookupDisplay(display);
35 _EGLDriver *drv;
36 const char *driverName = DefaultDriverName;
37 const char *name;
38
39 assert(dpy);
40
41 name = dpy->Name;
42 if (!name) {
43 /* use default */
44 }
45 else if (name[0] == ':' && (name[1] >= '0' && name[1] <= '9') && !name[2]) {
46 printf("EGL: Use driver for screen: %s\n", name);
47 /* XXX probe hardware here to determine which driver to open */
48 /* driverName = "something"; */
49 }
50 else if (name[0] == '!') {
51 /* use specified driver name */
52 driverName = name + 1;
53 printf("EGL: Use driver named %s\n", driverName);
54 }
55 else {
56 /* Maybe display was returned by XOpenDisplay? */
57 printf("EGL: can't parse display pointer\n");
58 }
59
60 drv = _eglOpenDriver(dpy, driverName);
61 dpy->Driver = drv;
62
63 return drv;
64 }
65
66
67 /**
68 * Open/load the named driver and call its bootstrap function: _eglMain().
69 * \return new _EGLDriver object.
70 */
71 _EGLDriver *
72 _eglOpenDriver(_EGLDisplay *dpy, const char *driverName)
73 {
74 void *lib;
75 char driverFilename[1000];
76
77 /* XXX also prepend a directory path??? */
78 sprintf(driverFilename, "%s.so", driverName);
79
80 #if 1
81 lib = dlopen(driverFilename, RTLD_NOW);
82 if (lib) {
83 _EGLDriver *drv;
84 _EGLMain_t mainFunc;
85
86 mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
87 if (!mainFunc) {
88 fprintf(stderr, "_eglMain not found in %s", (char *) driverFilename);
89 dlclose(lib);
90 return NULL;
91 }
92
93 drv = mainFunc(dpy);
94 if (!drv) {
95 dlclose(lib);
96 return NULL;
97 }
98
99 drv->LibHandle = lib;
100 drv->Display = dpy;
101 return drv;
102 }
103 else {
104 fprintf(stderr, "EGLdebug: Error opening %s: %s\n",
105 driverFilename, dlerror());
106 return NULL;
107 }
108 #else
109 /* use built-in driver */
110 return _eglDefaultMain(d);
111 #endif
112 }
113
114
115 EGLBoolean
116 _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
117 {
118 void *handle = drv->LibHandle;
119 EGLBoolean b;
120 fprintf(stderr, "EGL debug: Closing driver\n");
121
122 /*
123 * XXX check for currently bound context/surfaces and delete them?
124 */
125
126 b = drv->Terminate(drv, dpy);
127 dlclose(handle);
128 return b;
129 }
130
131
132 /**
133 * Given a display handle, return the _EGLDriver for that display.
134 */
135 _EGLDriver *
136 _eglLookupDriver(EGLDisplay dpy)
137 {
138 _EGLDisplay *d = _eglLookupDisplay(dpy);
139 if (d)
140 return d->Driver;
141 else
142 return NULL;
143 }
144
145
146 /**
147 * Plug all the available fallback routines into the given driver's
148 * dispatch table.
149 */
150 void
151 _eglInitDriverFallbacks(_EGLDriver *drv)
152 {
153 /* If a pointer is set to NULL, then the device driver _really_ has
154 * to implement it.
155 */
156 drv->Initialize = NULL;
157 drv->Terminate = NULL;
158
159 drv->GetConfigs = _eglGetConfigs;
160 drv->ChooseConfig = _eglChooseConfig;
161 drv->GetConfigAttrib = _eglGetConfigAttrib;
162
163 drv->CreateContext = _eglCreateContext;
164 drv->DestroyContext = _eglDestroyContext;
165 drv->MakeCurrent = _eglMakeCurrent;
166 drv->QueryContext = _eglQueryContext;
167
168 drv->CreateWindowSurface = _eglCreateWindowSurface;
169 drv->CreatePixmapSurface = _eglCreatePixmapSurface;
170 drv->CreatePbufferSurface = _eglCreatePbufferSurface;
171 drv->DestroySurface = _eglDestroySurface;
172 drv->QuerySurface = _eglQuerySurface;
173 drv->SurfaceAttrib = _eglSurfaceAttrib;
174 drv->BindTexImage = _eglBindTexImage;
175 drv->ReleaseTexImage = _eglReleaseTexImage;
176 drv->SwapInterval = _eglSwapInterval;
177 drv->SwapBuffers = _eglSwapBuffers;
178 drv->CopyBuffers = _eglCopyBuffers;
179
180 drv->QueryString = _eglQueryString;
181 drv->WaitGL = _eglWaitGL;
182 drv->WaitNative = _eglWaitNative;
183
184 /* EGL_MESA_screen */
185 drv->ChooseModeMESA = _eglChooseModeMESA;
186 drv->GetModesMESA = _eglGetModesMESA;
187 drv->GetModeAttribMESA = _eglGetModeAttribMESA;
188 drv->GetScreensMESA = _eglGetScreensMESA;
189 drv->CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
190 drv->ShowSurfaceMESA = _eglShowSurfaceMESA;
191 drv->ScreenPositionMESA = _eglScreenPositionMESA;
192 drv->QueryDisplayMESA = _eglQueryDisplayMESA;
193 drv->QueryScreenMESA = _eglQueryScreenMESA;
194 drv->QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
195 drv->QueryScreenModeMESA = _eglQueryScreenModeMESA;
196 drv->QueryModeStringMESA = _eglQueryModeStringMESA;
197 }
198
199
200 /**
201 * Examine the individual extension enable/disable flags and recompute
202 * the driver's Extensions string.
203 */
204 static void
205 UpdateExtensionsString(_EGLDriver *drv)
206 {
207 drv->Extensions[0] = 0;
208
209 if (drv->MESA_screen_surface)
210 strcat(drv->Extensions, "EGL_MESA_screen_surface");
211 if (drv->MESA_copy_context)
212 strcat(drv->Extensions, "EGL_MESA_copy_context");
213 assert(strlen(drv->Extensions) < MAX_EXTENSIONS_LEN);
214 }
215
216
217
218 const char *
219 _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
220 {
221 (void) drv;
222 (void) dpy;
223 switch (name) {
224 case EGL_VENDOR:
225 return "Mesa Project";
226 case EGL_VERSION:
227 return "1.0";
228 case EGL_EXTENSIONS:
229 UpdateExtensionsString(drv);
230 return drv->Extensions;
231 default:
232 _eglError(EGL_BAD_PARAMETER, "eglQueryString");
233 return NULL;
234 }
235 }
236
237
238 EGLBoolean
239 _eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
240 {
241 /* just a placeholder */
242 (void) drv;
243 (void) dpy;
244 return EGL_TRUE;
245 }
246
247
248 EGLBoolean
249 _eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
250 {
251 /* just a placeholder */
252 (void) drv;
253 (void) dpy;
254 (void) engine;
255 return EGL_TRUE;
256 }