2 * DIB driver OpenGL support
4 * Copyright 2012 Alexandre Julliard
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
22 #include "wine/port.h"
24 #ifdef HAVE_GL_OSMESA_H
25 #include <GL/osmesa.h>
31 #include "gdi_private.h"
34 #include "wine/library.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(dib);
39 #ifdef SONAME_LIBOSMESA
41 #include "wine/wgl_driver.h"
45 OSMesaContext context;
49 static struct opengl_funcs opengl_funcs;
51 #define USE_GL_FUNC(name) #name,
52 static const char *opengl_func_names[] = { ALL_WGL_FUNCS };
55 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
56 MAKE_FUNCPTR(OSMesaCreateContextExt)
57 MAKE_FUNCPTR(OSMesaDestroyContext)
58 MAKE_FUNCPTR(OSMesaGetProcAddress)
59 MAKE_FUNCPTR(OSMesaMakeCurrent)
60 MAKE_FUNCPTR(OSMesaPixelStore)
67 BYTE red_bits, red_shift;
68 BYTE green_bits, green_shift;
69 BYTE blue_bits, blue_shift;
70 BYTE alpha_bits, alpha_shift;
76 { OSMESA_BGRA, 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 32, 8 },
77 { OSMESA_BGRA, 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 16, 8 },
78 { OSMESA_RGBA, 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 32, 8 },
79 { OSMESA_RGBA, 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 16, 8 },
80 { OSMESA_ARGB, 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 32, 8 },
81 { OSMESA_ARGB, 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 16, 8 },
82 { OSMESA_RGB, 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 32, 8 },
83 { OSMESA_RGB, 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 16, 8 },
84 { OSMESA_BGR, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 },
85 { OSMESA_BGR, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 },
86 { OSMESA_RGB_565, 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 32, 8 },
87 { OSMESA_RGB_565, 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 16, 8 },
89 static const int nb_formats = sizeof(pixel_formats) / sizeof(pixel_formats[0]);
91 static BOOL init_opengl(void)
94 static void *osmesa_handle;
98 if (init_done) return (osmesa_handle != NULL);
101 osmesa_handle = wine_dlopen( SONAME_LIBOSMESA, RTLD_NOW, buffer, sizeof(buffer) );
102 if (osmesa_handle == NULL)
104 ERR( "Failed to load OSMesa: %s\n", buffer );
108 for (i = 0; i < sizeof(opengl_func_names)/sizeof(opengl_func_names[0]); i++)
110 if (!(((void **)&opengl_funcs.gl)[i] = wine_dlsym( osmesa_handle, opengl_func_names[i], NULL, 0 )))
112 ERR( "%s not found in %s, disabling.\n", opengl_func_names[i], SONAME_LIBOSMESA );
116 #define LOAD_FUNCPTR(f) do if (!(p##f = (void *)wine_dlsym( osmesa_handle, #f, NULL, 0 ))) \
118 ERR( "%s not found in %s, disabling.\n", #f, SONAME_LIBOSMESA ); \
122 LOAD_FUNCPTR(OSMesaCreateContextExt);
123 LOAD_FUNCPTR(OSMesaDestroyContext);
124 LOAD_FUNCPTR(OSMesaGetProcAddress);
125 LOAD_FUNCPTR(OSMesaMakeCurrent);
126 LOAD_FUNCPTR(OSMesaPixelStore);
132 wine_dlclose( osmesa_handle, NULL, 0 );
133 osmesa_handle = NULL;
137 /**********************************************************************
138 * dibdrv_DescribePixelFormat
140 int dibdrv_DescribePixelFormat( PHYSDEV dev, int fmt, UINT size, PIXELFORMATDESCRIPTOR *descr )
142 int ret = sizeof(pixel_formats) / sizeof(pixel_formats[0]);
144 if (fmt <= 0 || fmt > ret) return ret;
145 if (size < sizeof(*descr)) return 0;
147 memset( descr, 0, sizeof(*descr) );
148 descr->nSize = sizeof(*descr);
150 descr->dwFlags = PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP | PFD_GENERIC_FORMAT;
151 descr->iPixelType = PFD_TYPE_RGBA;
152 descr->cColorBits = pixel_formats[fmt - 1].color_bits;
153 descr->cRedBits = pixel_formats[fmt - 1].red_bits;
154 descr->cRedShift = pixel_formats[fmt - 1].red_shift;
155 descr->cGreenBits = pixel_formats[fmt - 1].green_bits;
156 descr->cGreenShift = pixel_formats[fmt - 1].green_shift;
157 descr->cBlueBits = pixel_formats[fmt - 1].blue_bits;
158 descr->cBlueShift = pixel_formats[fmt - 1].blue_shift;
159 descr->cAlphaBits = pixel_formats[fmt - 1].alpha_bits;
160 descr->cAlphaShift = pixel_formats[fmt - 1].alpha_shift;
161 descr->cAccumBits = pixel_formats[fmt - 1].accum_bits;
162 descr->cAccumRedBits = pixel_formats[fmt - 1].accum_bits / 4;
163 descr->cAccumGreenBits = pixel_formats[fmt - 1].accum_bits / 4;
164 descr->cAccumBlueBits = pixel_formats[fmt - 1].accum_bits / 4;
165 descr->cAccumAlphaBits = pixel_formats[fmt - 1].accum_bits / 4;
166 descr->cDepthBits = pixel_formats[fmt - 1].depth_bits;
167 descr->cStencilBits = pixel_formats[fmt - 1].stencil_bits;
168 descr->cAuxBuffers = 0;
169 descr->iLayerType = PFD_MAIN_PLANE;
173 /**********************************************************************
174 * dibdrv_SetPixelFormat
176 BOOL dibdrv_SetPixelFormat( PHYSDEV dev, int fmt, const PIXELFORMATDESCRIPTOR *descr )
181 if (fmt <= 0 || fmt > nb_formats) return FALSE;
182 dc = get_dc_ptr( dev->hdc );
183 if (!dc->pixel_format) dc->pixel_format = fmt;
184 else ret = (dc->pixel_format == fmt);
185 release_dc_ptr( dc );
189 /***********************************************************************
190 * dibdrv_wglCopyContext
192 static BOOL dibdrv_wglCopyContext( struct wgl_context *src, struct wgl_context *dst, UINT mask )
194 FIXME( "not supported yet\n" );
198 /***********************************************************************
199 * dibdrv_wglCreateContext
201 static struct wgl_context *dibdrv_wglCreateContext( HDC hdc )
203 struct wgl_context *context;
205 if (!(context = HeapAlloc( GetProcessHeap(), 0, sizeof( *context )))) return NULL;
206 context->format = GetPixelFormat( hdc );
207 if (!context->format || context->format > nb_formats) context->format = 1;
209 if (!(context->context = pOSMesaCreateContextExt( pixel_formats[context->format - 1].mesa,
210 pixel_formats[context->format - 1].depth_bits,
211 pixel_formats[context->format - 1].stencil_bits,
212 pixel_formats[context->format - 1].accum_bits, 0 )))
214 HeapFree( GetProcessHeap(), 0, context );
220 /***********************************************************************
221 * dibdrv_wglDeleteContext
223 static void dibdrv_wglDeleteContext( struct wgl_context *context )
225 pOSMesaDestroyContext( context->context );
226 HeapFree( GetProcessHeap(), 0, context );
229 /***********************************************************************
230 * dibdrv_wglGetPixelFormat
232 static int dibdrv_wglGetPixelFormat( HDC hdc )
234 DC *dc = get_dc_ptr( hdc );
239 ret = dc->pixel_format;
240 release_dc_ptr( dc );
245 /***********************************************************************
246 * dibdrv_wglGetProcAddress
248 static PROC dibdrv_wglGetProcAddress( const char *proc )
250 if (!strncmp( proc, "wgl", 3 )) return NULL;
251 return (PROC)pOSMesaGetProcAddress( proc );
254 /***********************************************************************
255 * dibdrv_wglMakeCurrent
257 static BOOL dibdrv_wglMakeCurrent( HDC hdc, struct wgl_context *context )
266 pOSMesaMakeCurrent( NULL, NULL, GL_UNSIGNED_BYTE, 0, 0 );
270 if (GetPixelFormat( hdc ) != context->format)
271 FIXME( "mismatched pixel formats %u/%u not supported yet\n",
272 GetPixelFormat( hdc ), context->format );
274 bitmap = GetCurrentObject( hdc, OBJ_BITMAP );
275 bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
276 if (!bmp) return FALSE;
278 if (init_dib_info_from_bitmapobj( &dib, bmp ))
281 int width = dib.rect.right - dib.rect.left;
282 int height = dib.rect.bottom - dib.rect.top;
285 bits = (char *)dib.bits.ptr + (dib.rect.bottom - 1) * dib.stride;
287 bits = (char *)dib.bits.ptr + dib.rect.top * dib.stride;
288 bits += dib.rect.left * dib.bit_count / 8;
290 TRACE( "context %p bits %p size %ux%u\n", context, bits, width, height );
292 ret = pOSMesaMakeCurrent( context->context, bits, GL_UNSIGNED_BYTE, width, height );
295 pOSMesaPixelStore( OSMESA_ROW_LENGTH, abs( dib.stride ) * 8 / dib.bit_count );
296 pOSMesaPixelStore( OSMESA_Y_UP, 1 ); /* Windows seems to assume bottom-up */
299 GDI_ReleaseObj( bitmap );
303 /***********************************************************************
304 * dibdrv_wglShareLists
306 static BOOL dibdrv_wglShareLists( struct wgl_context *org, struct wgl_context *dest )
308 FIXME( "not supported yet\n" );
312 static struct opengl_funcs opengl_funcs =
315 dibdrv_wglCopyContext, /* p_wglCopyContext */
316 dibdrv_wglCreateContext, /* p_wglCreateContext */
317 dibdrv_wglDeleteContext, /* p_wglDeleteContext */
318 dibdrv_wglGetPixelFormat, /* p_wglGetPixelFormat */
319 dibdrv_wglGetProcAddress, /* p_wglGetProcAddress */
320 dibdrv_wglMakeCurrent, /* p_wglMakeCurrent */
321 dibdrv_wglShareLists, /* p_wglShareLists */
325 /**********************************************************************
326 * dibdrv_wine_get_wgl_driver
328 struct opengl_funcs *dibdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
330 if (version != WINE_WGL_DRIVER_VERSION)
332 ERR( "version mismatch, opengl32 wants %u but dibdrv has %u\n", version, WINE_WGL_DRIVER_VERSION );
336 if (!init_opengl()) return (void *)-1;
338 return &opengl_funcs;
341 #else /* SONAME_LIBOSMESA */
343 /**********************************************************************
344 * dibdrv_DescribePixelFormat
346 int dibdrv_DescribePixelFormat( PHYSDEV dev, int fmt, UINT size, PIXELFORMATDESCRIPTOR *descr )
351 /**********************************************************************
352 * dibdrv_SetPixelFormat
354 BOOL dibdrv_SetPixelFormat( PHYSDEV dev, int fmt, const PIXELFORMATDESCRIPTOR *descr )
359 /**********************************************************************
360 * dibdrv_wine_get_wgl_driver
362 struct opengl_funcs *dibdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
364 ERR( "OSMesa not compiled in, no OpenGL bitmap support\n" );
368 #endif /* SONAME_LIBOSMESA */