comparison src/video/directfb/SDL_DirectFB_opengl.c @ 4636:b196d2758026

Couriersud to Sam Hi Sam, 20100815_1.diff contains updates for the directfb driver: - more documentation, mainly on software OpenGL in README.directfb - Revised error handling leading to leaner code - Improved/fixed OpenGL handling of multiple contexts. - Made the built-in simple window manager handle OpenGL windows. - Rewrote pixelformat mapping - this was quite ugly before. Well, all software GL, but working :-)
author Sam Lantinga <slouken@libsdl.org>
date Mon, 16 Aug 2010 09:04:55 -0700
parents f7b03b6838cb
children 164f20ba08eb
comparison
equal deleted inserted replaced
4635:0a07d002f10b 4636:b196d2758026
28 struct SDL_GLDriverData 28 struct SDL_GLDriverData
29 { 29 {
30 int gl_active; /* to stop switching drivers while we have a valid context */ 30 int gl_active; /* to stop switching drivers while we have a valid context */
31 int initialized; 31 int initialized;
32 DirectFB_GLContext *firstgl; /* linked list */ 32 DirectFB_GLContext *firstgl; /* linked list */
33
34 /* OpenGL */
35 void (*glFinish) (void);
36 void (*glFlush) (void);
33 }; 37 };
34 38
35 #define OPENGL_REQUIRS_DLOPEN 39 #define OPENGL_REQUIRS_DLOPEN
36 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) 40 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
37 #include <dlfcn.h> 41 #include <dlfcn.h>
92 } 96 }
93 97
94 int 98 int
95 DirectFB_GL_LoadLibrary(_THIS, const char *path) 99 DirectFB_GL_LoadLibrary(_THIS, const char *path)
96 { 100 {
97 SDL_DFB_DEVICEDATA(_this); 101 //SDL_DFB_DEVICEDATA(_this);
98 102
99 void *handle = NULL; 103 void *handle = NULL;
100 104
101 SDL_DFB_DEBUG("Loadlibrary : %s\n", path); 105 SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
102 106
119 /* SDL_LoadObject() will call SDL_SetError() for us. */ 123 /* SDL_LoadObject() will call SDL_SetError() for us. */
120 return -1; 124 return -1;
121 } 125 }
122 126
123 SDL_DFB_DEBUG("Loaded library: %s\n", path); 127 SDL_DFB_DEBUG("Loaded library: %s\n", path);
124
125 /* Unload the old driver and reset the pointers */
126 DirectFB_GL_UnloadLibrary(_this);
127 128
128 _this->gl_config.dll_handle = handle; 129 _this->gl_config.dll_handle = handle;
129 _this->gl_config.driver_loaded = 1; 130 _this->gl_config.driver_loaded = 1;
130 if (path) { 131 if (path) {
131 SDL_strlcpy(_this->gl_config.driver_path, path, 132 SDL_strlcpy(_this->gl_config.driver_path, path,
132 SDL_arraysize(_this->gl_config.driver_path)); 133 SDL_arraysize(_this->gl_config.driver_path));
133 } else { 134 } else {
134 *_this->gl_config.driver_path = '\0'; 135 *_this->gl_config.driver_path = '\0';
135 } 136 }
136 137
137 devdata->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish"); 138 _this->gl_data->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
138 devdata->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush"); 139 _this->gl_data->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
139 140
140 return 0; 141 return 0;
141 } 142 }
142 143
143 static void 144 static void
144 DirectFB_GL_UnloadLibrary(_THIS) 145 DirectFB_GL_UnloadLibrary(_THIS)
145 { 146 {
147 #if 0
146 int ret; 148 int ret;
147 149
148 if (_this->gl_config.driver_loaded) { 150 if (_this->gl_config.driver_loaded) {
149 151
150 ret = GL_UnloadObject(_this->gl_config.dll_handle); 152 ret = GL_UnloadObject(_this->gl_config.dll_handle);
151 if (ret) 153 if (ret)
152 SDL_DFB_ERR("Error #%d trying to unload library.\n", ret); 154 SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
153 _this->gl_config.dll_handle = NULL; 155 _this->gl_config.dll_handle = NULL;
154 _this->gl_config.driver_loaded = 0; 156 _this->gl_config.driver_loaded = 0;
155 } 157 }
158 #endif
159 /* Free OpenGL memory */
160 SDL_free(_this->gl_data);
161 _this->gl_data = NULL;
156 } 162 }
157 163
158 void * 164 void *
159 DirectFB_GL_GetProcAddress(_THIS, const char *proc) 165 DirectFB_GL_GetProcAddress(_THIS, const char *proc)
160 { 166 {
165 } 171 }
166 172
167 SDL_GLContext 173 SDL_GLContext
168 DirectFB_GL_CreateContext(_THIS, SDL_Window * window) 174 DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
169 { 175 {
176 //SDL_DFB_DEVICEDATA(_this);
170 SDL_DFB_WINDOWDATA(window); 177 SDL_DFB_WINDOWDATA(window);
171 DirectFB_GLContext *context; 178 DirectFB_GLContext *context;
172 int ret; 179
173 180 SDL_DFB_CALLOC(context, 1, sizeof(DirectFB_GLContext));
174 SDL_DFB_CALLOC(context, 1, sizeof(*context));
175 181
176 SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface, 182 SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
177 &context->context)); 183 &context->context));
178 184
179 if (!context->context) 185 if (!context->context)
180 return NULL; 186 return NULL;
181 187
182 SDL_DFB_CHECKERR(context->context->Unlock(context->context)); 188 context->is_locked = 0;
183 189 context->sdl_window = window;
190
184 context->next = _this->gl_data->firstgl; 191 context->next = _this->gl_data->firstgl;
185 _this->gl_data->firstgl = context; 192 _this->gl_data->firstgl = context;
193
194 SDL_DFB_CHECK(context->context->Unlock(context->context));
186 195
187 if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) { 196 if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
188 DirectFB_GL_DeleteContext(_this, context); 197 DirectFB_GL_DeleteContext(_this, context);
189 return NULL; 198 return NULL;
190 } 199 }
196 } 205 }
197 206
198 int 207 int
199 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) 208 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
200 { 209 {
201 SDL_DFB_WINDOWDATA(window); 210 //SDL_DFB_WINDOWDATA(window);
202 DirectFB_GLContext *ctx = (DirectFB_GLContext *) context; 211 DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
203 DirectFB_GLContext *p; 212 DirectFB_GLContext *p;
204 213
205 int ret;
206
207 for (p = _this->gl_data->firstgl; p; p = p->next) 214 for (p = _this->gl_data->firstgl; p; p = p->next)
208 p->context->Unlock(p->context); 215 {
209 216 if (p->is_locked) {
210 if (windata) { 217 SDL_DFB_CHECKERR(p->context->Unlock(p->context));
211 windata->gl_context = NULL; 218 p->is_locked = 0;
212 /* Everything is unlocked, check for a resize */ 219 }
213 DirectFB_AdjustWindowSurface(window); 220
214 } 221 }
215 222
216 if (ctx != NULL) { 223 if (ctx != NULL) {
217 SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context)); 224 SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
218 } 225 ctx->is_locked = 1;
219 226 }
220 if (windata)
221 windata->gl_context = ctx;
222 227
223 return 0; 228 return 0;
224 error: 229 error:
225 return -1; 230 return -1;
226 } 231 }
240 } 245 }
241 246
242 void 247 void
243 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window) 248 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
244 { 249 {
245 SDL_DFB_DEVICEDATA(_this); 250 //SDL_DFB_DEVICEDATA(_this);
246 SDL_DFB_WINDOWDATA(window); 251 SDL_DFB_WINDOWDATA(window);
247 int ret;
248 DFBRegion region; 252 DFBRegion region;
253 DirectFB_GLContext *p;
249 254
250 region.x1 = 0; 255 region.x1 = 0;
251 region.y1 = 0; 256 region.y1 = 0;
252 region.x2 = window->w; 257 region.x2 = window->w;
253 region.y2 = window->h; 258 region.y2 = window->h;
254 259
260 #if 0
255 if (devdata->glFinish) 261 if (devdata->glFinish)
256 devdata->glFinish(); 262 devdata->glFinish();
257 else if (devdata->glFlush) 263 else if (devdata->glFlush)
258 devdata->glFlush(); 264 devdata->glFlush();
259 265 #endif
260 if (1 || windata->gl_context) { 266
261 /* SDL_DFB_CHECKERR(windata->gl_context->context->Unlock(windata->gl_context->context)); */ 267 for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
262 SDL_DFB_CHECKERR(windata->surface->Flip(windata->surface, &region, 268 if (p->sdl_window == window && p->is_locked)
263 DSFLIP_ONSYNC)); 269 {
264 /* SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context)); */ 270 SDL_DFB_CHECKERR(p->context->Unlock(p->context));
265 271 p->is_locked = 0;
266 } 272 }
273
274 SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL, DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));
275
276 //if (windata->gl_context) {
277 //SDL_DFB_CHECKERR(windata->surface->Flip(windata->surface,NULL, DSFLIP_ONSYNC));
278 //SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context));
279 //}
267 280
268 return; 281 return;
269 error: 282 error:
270 return; 283 return;
271 } 284 }
274 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context) 287 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
275 { 288 {
276 DirectFB_GLContext *ctx = (DirectFB_GLContext *) context; 289 DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
277 DirectFB_GLContext *p; 290 DirectFB_GLContext *p;
278 291
279 ctx->context->Unlock(ctx->context); 292 if (ctx->is_locked)
280 ctx->context->Release(ctx->context); 293 SDL_DFB_CHECK(ctx->context->Unlock(ctx->context));
281 294 SDL_DFB_RELEASE(ctx->context);
282 p = _this->gl_data->firstgl; 295
283 while (p && p->next != ctx) 296 for (p = _this->gl_data->firstgl; p && p->next != ctx; p = p->next)
284 p = p->next; 297 ;
285 if (p) 298 if (p)
286 p->next = ctx->next; 299 p->next = ctx->next;
287 else 300 else
288 _this->gl_data->firstgl = ctx->next; 301 _this->gl_data->firstgl = ctx->next;
289 302
290 SDL_DFB_FREE(ctx); 303 SDL_DFB_FREE(ctx);
291 304 }
305
306 void
307 DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window)
308 {
309 DirectFB_GLContext *p;
310
311 for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
312 if (p->sdl_window == window)
313 {
314 if (p->is_locked)
315 SDL_DFB_CHECK(p->context->Unlock(p->context));
316 SDL_DFB_RELEASE(p->context);
317 }
318 }
319
320 void
321 DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
322 {
323 DirectFB_GLContext *p;
324
325 for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
326 if (p->sdl_window == window)
327 {
328 SDL_DFB_WINDOWDATA(window);
329 SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
330 &p->context));
331 if (p->is_locked)
332 SDL_DFB_CHECK(p->context->Lock(p->context));
333 }
334 }
335
336 void
337 DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window)
338 {
339 DirectFB_GLContext *p;
340
341 for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
342 if (p->sdl_window == window)
343 DirectFB_GL_DeleteContext(_this, p);
292 } 344 }
293 345
294 #endif 346 #endif
295 347
296 /* vi: set ts=4 sw=4 expandtab: */ 348 /* vi: set ts=4 sw=4 expandtab: */