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