x11drv/opengl: Pixel format rewrite.
[wine/wine64.git] / dlls / winex11.drv / opengl.c
blob1793a093bea5daa48824d60afa6ea5ed5f47221b
1 /*
2 * X11DRV OpenGL functions
4 * Copyright 2000 Lionel Ulmer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdlib.h>
25 #include <string.h>
27 #include "x11drv.h"
28 #include "wine/library.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
32 WINE_DECLARE_DEBUG_CHANNEL(opengl);
33 WINE_DECLARE_DEBUG_CHANNEL(fps);
35 #if defined(HAVE_GL_GL_H) && defined(HAVE_GL_GLX_H)
37 #undef APIENTRY
38 #undef CALLBACK
39 #undef WINAPI
41 #ifdef HAVE_GL_GL_H
42 # include <GL/gl.h>
43 #endif
44 #ifdef HAVE_GL_GLX_H
45 # include <GL/glx.h>
46 #endif
47 #ifdef HAVE_GL_GLEXT_H
48 # include <GL/glext.h>
49 #endif
51 #undef APIENTRY
52 #undef CALLBACK
53 #undef WINAPI
55 /* Redefines the constants */
56 #define CALLBACK __stdcall
57 #define WINAPI __stdcall
58 #define APIENTRY WINAPI
61 static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
62 TRACE(" - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
63 TRACE(" - dwFlags : ");
64 #define TEST_AND_DUMP(t,tv) if ((t) & (tv)) TRACE(#tv " ")
65 TEST_AND_DUMP(ppfd->dwFlags, PFD_DEPTH_DONTCARE);
66 TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER);
67 TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER_DONTCARE);
68 TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_WINDOW);
69 TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_BITMAP);
70 TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_ACCELERATED);
71 TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_FORMAT);
72 TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_PALETTE);
73 TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_SYSTEM_PALETTE);
74 TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO);
75 TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO_DONTCARE);
76 TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_GDI);
77 TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_OPENGL);
78 TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_COPY);
79 TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_EXCHANGE);
80 TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_LAYER_BUFFERS);
81 #undef TEST_AND_DUMP
82 TRACE("\n");
84 TRACE(" - iPixelType : ");
85 switch (ppfd->iPixelType) {
86 case PFD_TYPE_RGBA: TRACE("PFD_TYPE_RGBA"); break;
87 case PFD_TYPE_COLORINDEX: TRACE("PFD_TYPE_COLORINDEX"); break;
89 TRACE("\n");
91 TRACE(" - Color : %d\n", ppfd->cColorBits);
92 TRACE(" - Red : %d\n", ppfd->cRedBits);
93 TRACE(" - Green : %d\n", ppfd->cGreenBits);
94 TRACE(" - Blue : %d\n", ppfd->cBlueBits);
95 TRACE(" - Alpha : %d\n", ppfd->cAlphaBits);
96 TRACE(" - Accum : %d\n", ppfd->cAccumBits);
97 TRACE(" - Depth : %d\n", ppfd->cDepthBits);
98 TRACE(" - Stencil : %d\n", ppfd->cStencilBits);
99 TRACE(" - Aux : %d\n", ppfd->cAuxBuffers);
101 TRACE(" - iLayerType : ");
102 switch (ppfd->iLayerType) {
103 case PFD_MAIN_PLANE: TRACE("PFD_MAIN_PLANE"); break;
104 case PFD_OVERLAY_PLANE: TRACE("PFD_OVERLAY_PLANE"); break;
105 case (BYTE)PFD_UNDERLAY_PLANE: TRACE("PFD_UNDERLAY_PLANE"); break;
107 TRACE("\n");
110 /* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and
111 include all dependencies
113 #ifndef SONAME_LIBGL
114 #define SONAME_LIBGL "libGL.so"
115 #endif
117 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
118 MAKE_FUNCPTR(glGetError)
119 MAKE_FUNCPTR(glXChooseVisual)
120 MAKE_FUNCPTR(glXGetConfig)
121 MAKE_FUNCPTR(glXSwapBuffers)
122 MAKE_FUNCPTR(glXQueryExtension)
124 MAKE_FUNCPTR(glXGetFBConfigs)
125 MAKE_FUNCPTR(glXChooseFBConfig)
126 MAKE_FUNCPTR(glXGetFBConfigAttrib)
127 MAKE_FUNCPTR(glXCreateGLXPixmap)
128 MAKE_FUNCPTR(glXDestroyGLXPixmap)
129 /* MAKE_FUNCPTR(glXQueryDrawable) */
130 #undef MAKE_FUNCPTR
132 static BOOL has_opengl(void)
134 static int init_done;
135 static void *opengl_handle;
137 int error_base, event_base;
139 if (init_done) return (opengl_handle != NULL);
140 init_done = 1;
142 opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, NULL, 0);
143 if (opengl_handle == NULL) return FALSE;
145 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(RTLD_DEFAULT, #f, NULL, 0)) == NULL) goto sym_not_found;
146 LOAD_FUNCPTR(glGetError)
147 LOAD_FUNCPTR(glXChooseVisual)
148 LOAD_FUNCPTR(glXGetConfig)
149 LOAD_FUNCPTR(glXSwapBuffers)
150 LOAD_FUNCPTR(glXQueryExtension)
152 LOAD_FUNCPTR(glXGetFBConfigs)
153 LOAD_FUNCPTR(glXChooseFBConfig)
154 LOAD_FUNCPTR(glXGetFBConfigAttrib)
155 LOAD_FUNCPTR(glXCreateGLXPixmap)
156 LOAD_FUNCPTR(glXDestroyGLXPixmap)
157 #undef LOAD_FUNCPTR
159 wine_tsx11_lock();
160 if (pglXQueryExtension(gdi_display, &error_base, &event_base) == True) {
161 TRACE("GLX is up and running error_base = %d\n", error_base);
162 } else {
163 wine_dlclose(opengl_handle, NULL, 0);
164 opengl_handle = NULL;
166 wine_tsx11_unlock();
167 return (opengl_handle != NULL);
169 sym_not_found:
170 wine_dlclose(opengl_handle, NULL, 0);
171 opengl_handle = NULL;
172 return FALSE;
175 static BOOL get_fbconfig_from_main_visual(int *fmt_id, int *fmt_index)
177 int nCfgs = 0;
178 int tmp_fmt_id = 0;
179 int tmp_vis_id = 0;
180 int i = 0;
181 GLXFBConfig* cfgs = NULL;
183 /* Retrieve the visualid from our main visual */
184 VisualID visualid = XVisualIDFromVisual(visual);
186 cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), NULL, &nCfgs);
187 if (NULL == cfgs || 0 == nCfgs) {
188 ERR("glXChooseFBConfig returns NULL (glError: %d)\n", pglGetError());
189 if(cfgs != NULL) XFree(cfgs);
190 return FALSE;
193 /* Walk through all FB configurations to retrieve the FB configuration matching our visual */
194 for(i=0; i<nCfgs; i++) {
195 pglXGetFBConfigAttrib(gdi_display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id);
196 pglXGetFBConfigAttrib(gdi_display, cfgs[i], GLX_VISUAL_ID, &tmp_vis_id);
197 if(tmp_vis_id == visualid) {
198 *fmt_id = tmp_fmt_id;
199 *fmt_index = i + 1; /* Use a one based index, iPixelFormat uses that too */
200 TRACE("Found FBCONFIG_ID 0x%x at index %d for VISUAL_ID 0x%x\n", *fmt_id, *fmt_index, tmp_vis_id);
201 if(cfgs != NULL) XFree(cfgs);
202 return TRUE;
206 ERR("Can't find a matching FBCONFIG_ID for VISUAL_ID 0x%lx!\n", visualid);
208 if(cfgs != NULL) XFree(cfgs);
209 return FALSE;
213 * X11DRV_ChoosePixelFormat
215 * Equivalent of glXChooseVisual
217 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
218 const PIXELFORMATDESCRIPTOR *ppfd) {
219 GLXFBConfig* cfgs = NULL;
220 int ret = 0;
221 int nCfgs = 0;
222 int fmt_id = 0;
223 int fmt_index = 0;
225 if (!has_opengl()) {
226 ERR("No libGL on this box - disabling OpenGL support !\n");
227 return 0;
230 if (TRACE_ON(opengl)) {
231 TRACE("(%p,%p)\n", physDev, ppfd);
233 dump_PIXELFORMATDESCRIPTOR((const PIXELFORMATDESCRIPTOR *) ppfd);
236 wine_tsx11_lock();
237 if(!visual) {
238 ERR("Can't get an opengl visual!\n");
239 goto choose_exit;
242 /* Get a list containing all supported FB configurations */
243 cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), NULL, &nCfgs);
244 if (NULL == cfgs || 0 == nCfgs) {
245 ERR("glXChooseFBConfig returns NULL (glError: %d)\n", pglGetError());
246 goto choose_exit;
249 /* In case an fbconfig was found, check if it matches to the requirements of the ppfd */
250 if(!get_fbconfig_from_main_visual(&fmt_id, &fmt_index)) {
251 ERR("Can't find a matching FBCONFIG_ID for VISUAL_ID 0x%lx!\n", visual->visualid);
252 } else {
253 int dwFlags = 0;
254 int iPixelType = 0;
255 int value = 0;
257 /* Pixel type */
258 pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_RENDER_TYPE, &value);
259 if (value & GLX_RGBA_BIT)
260 iPixelType = PFD_TYPE_RGBA;
261 else
262 iPixelType = PFD_TYPE_COLORINDEX;
264 if (ppfd->iPixelType != iPixelType) {
265 goto choose_exit;
268 /* Doublebuffer */
269 pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_DOUBLEBUFFER, &value); if (value) dwFlags |= PFD_DOUBLEBUFFER;
270 if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE)) {
271 if ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (dwFlags & PFD_DOUBLEBUFFER)) {
272 goto choose_exit;
276 /* Stereo */
277 pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_STEREO, &value); if (value) dwFlags |= PFD_STEREO;
278 if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE)) {
279 if ((ppfd->dwFlags & PFD_STEREO) != (dwFlags & PFD_STEREO)) {
280 goto choose_exit;
284 /* Alpha bits */
285 pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_ALPHA_SIZE, &value);
286 if (ppfd->iPixelType==PFD_TYPE_RGBA && ppfd->cAlphaBits && !value) {
287 goto choose_exit;
290 /* Depth bits */
291 pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_DEPTH_SIZE, &value);
292 if (ppfd->cDepthBits && !value) {
293 goto choose_exit;
296 /* Stencil bits */
297 pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_STENCIL_SIZE, &value);
298 if (ppfd->cStencilBits && !value) {
299 goto choose_exit;
302 /* Aux buffers */
303 pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_AUX_BUFFERS, &value);
304 if (ppfd->cAuxBuffers && !value) {
305 goto choose_exit;
308 /* When we pass all the checks we have found a matching format :) */
309 ret = 1;
310 TRACE("Succesfully found a matching mode, returning index: %d\n", ret);
313 choose_exit:
314 if(!ret)
315 TRACE("No matching mode was found returning 0\n");
317 if (NULL != cfgs) XFree(cfgs);
318 wine_tsx11_unlock();
319 return ret;
323 * X11DRV_DescribePixelFormat
325 * Get the pixel-format descriptor associated to the given id
327 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
328 int iPixelFormat,
329 UINT nBytes,
330 PIXELFORMATDESCRIPTOR *ppfd) {
331 /*XVisualInfo *vis;*/
332 int value;
333 int rb,gb,bb,ab;
335 GLXFBConfig* cfgs = NULL;
336 GLXFBConfig cur;
337 int nCfgs = 0;
338 int ret = 0;
340 if (!has_opengl()) {
341 ERR("No libGL on this box - disabling OpenGL support !\n");
342 return 0;
345 TRACE("(%p,%d,%d,%p)\n", physDev, iPixelFormat, nBytes, ppfd);
347 wine_tsx11_lock();
348 cfgs = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs);
349 wine_tsx11_unlock();
351 if (NULL == cfgs || 0 == nCfgs) {
352 ERR("unexpected iPixelFormat(%d), returns NULL\n", iPixelFormat);
353 return 0; /* unespected error */
356 /* This function allways reports the total number of supported pixel formats.
357 * At the moment we only support the pixel format corresponding to the main
358 * visual which got created at x11drv initialization. More formats could be
359 * supported if there was a way to recreate x11 windows in x11drv.
360 * Because we only support one format nCfgs needs to be set to 1.
362 nCfgs = 1;
364 if (ppfd == NULL) {
365 /* The application is only querying the number of visuals */
366 wine_tsx11_lock();
367 if (NULL != cfgs) XFree(cfgs);
368 wine_tsx11_unlock();
369 return nCfgs;
372 if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) {
373 ERR("Wrong structure size !\n");
374 /* Should set error */
375 return 0;
378 if (nCfgs < iPixelFormat || 1 > iPixelFormat) {
379 WARN("unexpected iPixelFormat(%d): not >=1 and <=nFormats(%d), returning NULL\n", iPixelFormat, nCfgs);
380 return 0;
383 /* Retrieve the index in the FBConfig table corresponding to the visual ID from the main visual */
384 if(!get_fbconfig_from_main_visual(&value, &iPixelFormat)) {
385 ERR("Can't find a valid pixel format index from the main visual, expect problems!\n");
386 return 0;
389 ret = nCfgs;
390 cur = cfgs[iPixelFormat - 1];
392 memset(ppfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
393 ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
394 ppfd->nVersion = 1;
396 /* These flags are always the same... */
397 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
398 /* Now the flags extracted from the Visual */
400 wine_tsx11_lock();
402 pglXGetFBConfigAttrib(gdi_display, cur, GLX_CONFIG_CAVEAT, &value);
403 if(value == GLX_SLOW_CONFIG)
404 ppfd->dwFlags |= PFD_GENERIC_ACCELERATED;
406 pglXGetFBConfigAttrib(gdi_display, cur, GLX_DOUBLEBUFFER, &value); if (value) ppfd->dwFlags |= PFD_DOUBLEBUFFER;
407 pglXGetFBConfigAttrib(gdi_display, cur, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
409 /* Pixel type */
410 pglXGetFBConfigAttrib(gdi_display, cur, GLX_RENDER_TYPE, &value);
411 if (value & GLX_RGBA_BIT)
412 ppfd->iPixelType = PFD_TYPE_RGBA;
413 else
414 ppfd->iPixelType = PFD_TYPE_COLORINDEX;
416 /* Color bits */
417 pglXGetFBConfigAttrib(gdi_display, cur, GLX_BUFFER_SIZE, &value);
418 ppfd->cColorBits = value;
420 /* Red, green, blue and alpha bits / shifts */
421 if (ppfd->iPixelType == PFD_TYPE_RGBA) {
422 pglXGetFBConfigAttrib(gdi_display, cur, GLX_RED_SIZE, &rb);
423 pglXGetFBConfigAttrib(gdi_display, cur, GLX_GREEN_SIZE, &gb);
424 pglXGetFBConfigAttrib(gdi_display, cur, GLX_BLUE_SIZE, &bb);
425 pglXGetFBConfigAttrib(gdi_display, cur, GLX_ALPHA_SIZE, &ab);
427 ppfd->cRedBits = rb;
428 ppfd->cRedShift = gb + bb + ab;
429 ppfd->cBlueBits = bb;
430 ppfd->cBlueShift = ab;
431 ppfd->cGreenBits = gb;
432 ppfd->cGreenShift = bb + ab;
433 ppfd->cAlphaBits = ab;
434 ppfd->cAlphaShift = 0;
435 } else {
436 ppfd->cRedBits = 0;
437 ppfd->cRedShift = 0;
438 ppfd->cBlueBits = 0;
439 ppfd->cBlueShift = 0;
440 ppfd->cGreenBits = 0;
441 ppfd->cGreenShift = 0;
442 ppfd->cAlphaBits = 0;
443 ppfd->cAlphaShift = 0;
445 /* Accums : to do ... */
447 /* Depth bits */
448 pglXGetFBConfigAttrib(gdi_display, cur, GLX_DEPTH_SIZE, &value);
449 ppfd->cDepthBits = value;
451 /* stencil bits */
452 pglXGetFBConfigAttrib(gdi_display, cur, GLX_STENCIL_SIZE, &value);
453 ppfd->cStencilBits = value;
455 wine_tsx11_unlock();
457 /* Aux : to do ... */
459 ppfd->iLayerType = PFD_MAIN_PLANE;
461 if (TRACE_ON(opengl)) {
462 dump_PIXELFORMATDESCRIPTOR(ppfd);
465 wine_tsx11_lock();
466 if (NULL != cfgs) XFree(cfgs);
467 wine_tsx11_unlock();
469 return ret;
473 * X11DRV_GetPixelFormat
475 * Get the pixel-format id used by this DC
477 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
478 TRACE("(%p): returns %d\n", physDev, physDev->current_pf);
480 return physDev->current_pf;
484 * X11DRV_SetPixelFormat
486 * Set the pixel-format id used by this DC
488 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
489 int iPixelFormat,
490 const PIXELFORMATDESCRIPTOR *ppfd) {
491 TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
493 /* At the moment we only support the pixelformat corresponding to the main
494 * x11drv visual which got created at x11drv initialization. More formats
495 * can be supported if there was a way to recreate x11 windows in x11drv
497 if(iPixelFormat != 1) {
498 TRACE("Invalid iPixelFormat: %d\n", iPixelFormat);
499 return 0;
502 physDev->current_pf = iPixelFormat;
504 if (TRACE_ON(opengl)) {
505 int nCfgs_fmt = 0;
506 GLXFBConfig* cfgs_fmt = NULL;
507 GLXFBConfig cur_cfg;
508 int value;
509 int gl_test = 0;
511 if(!get_fbconfig_from_main_visual(&value, &iPixelFormat)) {
512 ERR("Can't find a valid pixel format index from the main visual, expect problems!\n");
513 return TRUE; /* Return true because the SetPixelFormat stuff itself passed */
517 * How to test if hdc current drawable is compatible (visual/FBConfig) ?
519 * in case of root window created HDCs we crash here :(
521 Drawable drawable = get_drawable( physDev->hdc );
522 TRACE(" drawable (%p,%p) have :\n", drawable, root_window);
523 pglXQueryDrawable(gdi_display, drawable, GLX_FBCONFIG_ID, (unsigned int*) &value);
524 TRACE(" - FBCONFIG_ID as 0x%x\n", tmp);
525 pglXQueryDrawable(gdi_display, drawable, GLX_VISUAL_ID, (unsigned int*) &value);
526 TRACE(" - VISUAL_ID as 0x%x\n", tmp);
527 pglXQueryDrawable(gdi_display, drawable, GLX_WIDTH, (unsigned int*) &value);
528 TRACE(" - WIDTH as %d\n", tmp);
529 pglXQueryDrawable(gdi_display, drawable, GLX_HEIGHT, (unsigned int*) &value);
530 TRACE(" - HEIGHT as %d\n", tmp);
532 cfgs_fmt = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs_fmt);
533 cur_cfg = cfgs_fmt[iPixelFormat - 1];
534 gl_test = pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_FBCONFIG_ID, &value);
535 if (gl_test) {
536 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
537 } else {
538 TRACE(" FBConfig have :\n");
539 TRACE(" - FBCONFIG_ID 0x%x\n", value);
540 pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_VISUAL_ID, &value);
541 TRACE(" - VISUAL_ID 0x%x\n", value);
542 pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_DRAWABLE_TYPE, &value);
543 TRACE(" - DRAWABLE_TYPE 0x%x\n", value);
545 XFree(cfgs_fmt);
547 return TRUE;
550 static XID create_glxpixmap(X11DRV_PDEVICE *physDev)
552 GLXPixmap ret;
553 XVisualInfo *vis;
554 XVisualInfo template;
555 int num;
557 wine_tsx11_lock();
559 /* Retrieve the visualid from our main visual which is the only visual we can use */
560 template.visualid = XVisualIDFromVisual(visual);
561 vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
563 ret = pglXCreateGLXPixmap(gdi_display, vis, physDev->bitmap->pixmap);
564 XFree(vis);
565 wine_tsx11_unlock();
566 TRACE("return %lx\n", ret);
567 return ret;
570 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
572 Drawable ret;
574 if(physDev->bitmap)
576 if (physDev->bitmap->hbitmap == BITMAP_stock_phys_bitmap.hbitmap)
577 ret = physDev->drawable; /* PBuffer */
578 else
580 if(!physDev->bitmap->glxpixmap)
581 physDev->bitmap->glxpixmap = create_glxpixmap(physDev);
582 ret = physDev->bitmap->glxpixmap;
585 else
586 ret = physDev->drawable;
587 return ret;
590 BOOL destroy_glxpixmap(XID glxpixmap)
592 wine_tsx11_lock();
593 pglXDestroyGLXPixmap(gdi_display, glxpixmap);
594 wine_tsx11_unlock();
595 return TRUE;
599 * X11DRV_SwapBuffers
601 * Swap the buffers of this DC
603 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev)
605 GLXDrawable drawable;
606 if (!has_opengl()) {
607 ERR("No libGL on this box - disabling OpenGL support !\n");
608 return 0;
611 TRACE_(opengl)("(%p)\n", physDev);
613 drawable = get_glxdrawable(physDev);
614 wine_tsx11_lock();
615 pglXSwapBuffers(gdi_display, drawable);
616 wine_tsx11_unlock();
618 /* FPS support */
619 if (TRACE_ON(fps))
621 static long prev_time, frames;
623 DWORD time = GetTickCount();
624 frames++;
625 /* every 1.5 seconds */
626 if (time - prev_time > 1500) {
627 TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
628 prev_time = time;
629 frames = 0;
633 return TRUE;
636 /***********************************************************************
637 * X11DRV_setup_opengl_visual
639 * Setup the default visual used for OpenGL and Direct3D, and the desktop
640 * window (if it exists). If OpenGL isn't available, the visual is simply
641 * set to the default visual for the display
643 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
645 XVisualInfo *visual = NULL;
646 /* In order to support OpenGL or D3D, we require a double-buffered visual and stencil buffer support, */
647 int dblBuf[] = {GLX_RGBA,GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DOUBLEBUFFER, None};
648 if (!has_opengl()) return NULL;
650 wine_tsx11_lock();
651 visual = pglXChooseVisual(display, DefaultScreen(display), dblBuf);
652 wine_tsx11_unlock();
653 if (visual == NULL) {
654 /* fallback to 16 bits depth, no alpha */
655 int dblBuf2[] = {GLX_RGBA,GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, GLX_DOUBLEBUFFER, None};
656 WARN("Failed to get a visual with at least 24 bits depth\n");
658 wine_tsx11_lock();
659 visual = pglXChooseVisual(display, DefaultScreen(display), dblBuf2);
660 wine_tsx11_unlock();
661 if (visual == NULL) {
662 /* fallback to no stencil */
663 int dblBuf2[] = {GLX_RGBA,GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
664 WARN("Failed to get a visual with at least 8 bits of stencil\n");
666 wine_tsx11_lock();
667 visual = pglXChooseVisual(display, DefaultScreen(display), dblBuf2);
668 wine_tsx11_unlock();
669 if (visual == NULL) {
670 /* This should only happen if we cannot find a match with a depth size 16 */
671 FIXME("Failed to find a suitable visual\n");
672 return visual;
676 TRACE("Visual ID %lx Chosen\n",visual->visualid);
677 return visual;
680 #else /* no OpenGL includes */
682 void X11DRV_OpenGL_Init(Display *display)
686 /***********************************************************************
687 * ChoosePixelFormat (X11DRV.@)
689 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
690 const PIXELFORMATDESCRIPTOR *ppfd) {
691 ERR("No OpenGL support compiled in.\n");
693 return 0;
696 /***********************************************************************
697 * DescribePixelFormat (X11DRV.@)
699 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
700 int iPixelFormat,
701 UINT nBytes,
702 PIXELFORMATDESCRIPTOR *ppfd) {
703 ERR("No OpenGL support compiled in.\n");
705 return 0;
708 /***********************************************************************
709 * GetPixelFormat (X11DRV.@)
711 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
712 ERR("No OpenGL support compiled in.\n");
714 return 0;
717 /***********************************************************************
718 * SetPixelFormat (X11DRV.@)
720 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
721 int iPixelFormat,
722 const PIXELFORMATDESCRIPTOR *ppfd) {
723 ERR("No OpenGL support compiled in.\n");
725 return FALSE;
728 /***********************************************************************
729 * SwapBuffers (X11DRV.@)
731 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) {
732 ERR_(opengl)("No OpenGL support compiled in.\n");
734 return FALSE;
737 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
739 return NULL;
742 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
744 return 0;
747 BOOL destroy_glxpixmap(XID glxpixmap)
749 return FALSE;
752 #endif /* defined(HAVE_OPENGL) */