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"
43 extern BOOL WINAPI
GdiSetPixelFormat( HDC hdc
, INT fmt
, const PIXELFORMATDESCRIPTOR
*pfd
);
47 OSMesaContext context
;
51 static struct opengl_funcs opengl_funcs
;
53 #define USE_GL_FUNC(name) #name,
54 static const char *opengl_func_names
[] = { ALL_WGL_FUNCS
};
57 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
58 MAKE_FUNCPTR(OSMesaCreateContextExt
)
59 MAKE_FUNCPTR(OSMesaDestroyContext
)
60 MAKE_FUNCPTR(OSMesaGetProcAddress
)
61 MAKE_FUNCPTR(OSMesaMakeCurrent
)
62 MAKE_FUNCPTR(OSMesaPixelStore
)
69 BYTE red_bits
, red_shift
;
70 BYTE green_bits
, green_shift
;
71 BYTE blue_bits
, blue_shift
;
72 BYTE alpha_bits
, alpha_shift
;
78 { OSMESA_BGRA
, 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 32, 8 },
79 { OSMESA_BGRA
, 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 16, 8 },
80 { OSMESA_RGBA
, 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 32, 8 },
81 { OSMESA_RGBA
, 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 16, 8 },
82 { OSMESA_ARGB
, 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 32, 8 },
83 { OSMESA_ARGB
, 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 16, 8 },
84 { OSMESA_RGB
, 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 32, 8 },
85 { OSMESA_RGB
, 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 16, 8 },
86 { OSMESA_BGR
, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 },
87 { OSMESA_BGR
, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 },
88 { OSMESA_RGB_565
, 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 32, 8 },
89 { OSMESA_RGB_565
, 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 16, 8 },
91 static const int nb_formats
= sizeof(pixel_formats
) / sizeof(pixel_formats
[0]);
93 static BOOL
init_opengl(void)
96 static void *osmesa_handle
;
100 if (init_done
) return (osmesa_handle
!= NULL
);
103 osmesa_handle
= wine_dlopen( SONAME_LIBOSMESA
, RTLD_NOW
, buffer
, sizeof(buffer
) );
104 if (osmesa_handle
== NULL
)
106 ERR( "Failed to load OSMesa: %s\n", buffer
);
110 for (i
= 0; i
< sizeof(opengl_func_names
)/sizeof(opengl_func_names
[0]); i
++)
112 if (!(((void **)&opengl_funcs
.gl
)[i
] = wine_dlsym( osmesa_handle
, opengl_func_names
[i
], NULL
, 0 )))
114 ERR( "%s not found in %s, disabling.\n", opengl_func_names
[i
], SONAME_LIBOSMESA
);
118 #define LOAD_FUNCPTR(f) do if (!(p##f = (void *)wine_dlsym( osmesa_handle, #f, NULL, 0 ))) \
120 ERR( "%s not found in %s, disabling.\n", #f, SONAME_LIBOSMESA ); \
124 LOAD_FUNCPTR(OSMesaCreateContextExt
);
125 LOAD_FUNCPTR(OSMesaDestroyContext
);
126 LOAD_FUNCPTR(OSMesaGetProcAddress
);
127 LOAD_FUNCPTR(OSMesaMakeCurrent
);
128 LOAD_FUNCPTR(OSMesaPixelStore
);
134 wine_dlclose( osmesa_handle
, NULL
, 0 );
135 osmesa_handle
= NULL
;
139 /**********************************************************************
140 * dibdrv_wglDescribePixelFormat
142 int dibdrv_wglDescribePixelFormat( HDC hdc
, int fmt
, UINT size
, PIXELFORMATDESCRIPTOR
*descr
)
144 int ret
= sizeof(pixel_formats
) / sizeof(pixel_formats
[0]);
146 if (fmt
<= 0 || fmt
> ret
) return ret
;
147 if (size
< sizeof(*descr
)) return 0;
149 memset( descr
, 0, sizeof(*descr
) );
150 descr
->nSize
= sizeof(*descr
);
152 descr
->dwFlags
= PFD_SUPPORT_GDI
| PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_BITMAP
| PFD_GENERIC_FORMAT
;
153 descr
->iPixelType
= PFD_TYPE_RGBA
;
154 descr
->cColorBits
= pixel_formats
[fmt
- 1].color_bits
;
155 descr
->cRedBits
= pixel_formats
[fmt
- 1].red_bits
;
156 descr
->cRedShift
= pixel_formats
[fmt
- 1].red_shift
;
157 descr
->cGreenBits
= pixel_formats
[fmt
- 1].green_bits
;
158 descr
->cGreenShift
= pixel_formats
[fmt
- 1].green_shift
;
159 descr
->cBlueBits
= pixel_formats
[fmt
- 1].blue_bits
;
160 descr
->cBlueShift
= pixel_formats
[fmt
- 1].blue_shift
;
161 descr
->cAlphaBits
= pixel_formats
[fmt
- 1].alpha_bits
;
162 descr
->cAlphaShift
= pixel_formats
[fmt
- 1].alpha_shift
;
163 descr
->cAccumBits
= pixel_formats
[fmt
- 1].accum_bits
;
164 descr
->cAccumRedBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
165 descr
->cAccumGreenBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
166 descr
->cAccumBlueBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
167 descr
->cAccumAlphaBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
168 descr
->cDepthBits
= pixel_formats
[fmt
- 1].depth_bits
;
169 descr
->cStencilBits
= pixel_formats
[fmt
- 1].stencil_bits
;
170 descr
->cAuxBuffers
= 0;
171 descr
->iLayerType
= PFD_MAIN_PLANE
;
175 /***********************************************************************
176 * dibdrv_wglCopyContext
178 static BOOL
dibdrv_wglCopyContext( struct wgl_context
*src
, struct wgl_context
*dst
, UINT mask
)
180 FIXME( "not supported yet\n" );
184 /***********************************************************************
185 * dibdrv_wglCreateContext
187 static struct wgl_context
*dibdrv_wglCreateContext( HDC hdc
)
189 struct wgl_context
*context
;
191 if (!(context
= HeapAlloc( GetProcessHeap(), 0, sizeof( *context
)))) return NULL
;
192 context
->format
= GetPixelFormat( hdc
);
193 if (!context
->format
|| context
->format
> nb_formats
) context
->format
= 1;
195 if (!(context
->context
= pOSMesaCreateContextExt( pixel_formats
[context
->format
- 1].mesa
,
196 pixel_formats
[context
->format
- 1].depth_bits
,
197 pixel_formats
[context
->format
- 1].stencil_bits
,
198 pixel_formats
[context
->format
- 1].accum_bits
, 0 )))
200 HeapFree( GetProcessHeap(), 0, context
);
206 /***********************************************************************
207 * dibdrv_wglDeleteContext
209 static void dibdrv_wglDeleteContext( struct wgl_context
*context
)
211 pOSMesaDestroyContext( context
->context
);
212 HeapFree( GetProcessHeap(), 0, context
);
215 /***********************************************************************
216 * dibdrv_wglGetPixelFormat
218 static int dibdrv_wglGetPixelFormat( HDC hdc
)
220 DC
*dc
= get_dc_ptr( hdc
);
225 ret
= dc
->pixel_format
;
226 release_dc_ptr( dc
);
231 /***********************************************************************
232 * dibdrv_wglGetProcAddress
234 static PROC
dibdrv_wglGetProcAddress( const char *proc
)
236 if (!strncmp( proc
, "wgl", 3 )) return NULL
;
237 return (PROC
)pOSMesaGetProcAddress( proc
);
240 /***********************************************************************
241 * dibdrv_wglMakeCurrent
243 static BOOL
dibdrv_wglMakeCurrent( HDC hdc
, struct wgl_context
*context
)
252 pOSMesaMakeCurrent( NULL
, NULL
, GL_UNSIGNED_BYTE
, 0, 0 );
256 if (GetPixelFormat( hdc
) != context
->format
)
257 FIXME( "mismatched pixel formats %u/%u not supported yet\n",
258 GetPixelFormat( hdc
), context
->format
);
260 bitmap
= GetCurrentObject( hdc
, OBJ_BITMAP
);
261 bmp
= GDI_GetObjPtr( bitmap
, OBJ_BITMAP
);
262 if (!bmp
) return FALSE
;
264 if (init_dib_info_from_bitmapobj( &dib
, bmp
))
267 int width
= dib
.rect
.right
- dib
.rect
.left
;
268 int height
= dib
.rect
.bottom
- dib
.rect
.top
;
271 bits
= (char *)dib
.bits
.ptr
+ (dib
.rect
.bottom
- 1) * dib
.stride
;
273 bits
= (char *)dib
.bits
.ptr
+ dib
.rect
.top
* dib
.stride
;
274 bits
+= dib
.rect
.left
* dib
.bit_count
/ 8;
276 TRACE( "context %p bits %p size %ux%u\n", context
, bits
, width
, height
);
278 ret
= pOSMesaMakeCurrent( context
->context
, bits
, GL_UNSIGNED_BYTE
, width
, height
);
281 pOSMesaPixelStore( OSMESA_ROW_LENGTH
, abs( dib
.stride
) * 8 / dib
.bit_count
);
282 pOSMesaPixelStore( OSMESA_Y_UP
, 1 ); /* Windows seems to assume bottom-up */
285 GDI_ReleaseObj( bitmap
);
289 /**********************************************************************
290 * dibdrv_wglSetPixelFormat
292 BOOL
dibdrv_wglSetPixelFormat( HDC hdc
, int fmt
, const PIXELFORMATDESCRIPTOR
*descr
)
294 if (fmt
<= 0 || fmt
> nb_formats
) return FALSE
;
295 return GdiSetPixelFormat( hdc
, fmt
, descr
);
298 /***********************************************************************
299 * dibdrv_wglShareLists
301 static BOOL
dibdrv_wglShareLists( struct wgl_context
*org
, struct wgl_context
*dest
)
303 FIXME( "not supported yet\n" );
307 static struct opengl_funcs opengl_funcs
=
310 dibdrv_wglCopyContext
, /* p_wglCopyContext */
311 dibdrv_wglCreateContext
, /* p_wglCreateContext */
312 dibdrv_wglDeleteContext
, /* p_wglDeleteContext */
313 dibdrv_wglDescribePixelFormat
,/* p_wglDescribePixelFormat */
314 dibdrv_wglGetPixelFormat
, /* p_wglGetPixelFormat */
315 dibdrv_wglGetProcAddress
, /* p_wglGetProcAddress */
316 dibdrv_wglMakeCurrent
, /* p_wglMakeCurrent */
317 dibdrv_wglSetPixelFormat
, /* p_wglSetPixelFormat */
318 dibdrv_wglShareLists
, /* p_wglShareLists */
322 /**********************************************************************
323 * dibdrv_wine_get_wgl_driver
325 struct opengl_funcs
*dibdrv_wine_get_wgl_driver( PHYSDEV dev
, UINT version
)
327 if (version
!= WINE_WGL_DRIVER_VERSION
)
329 ERR( "version mismatch, opengl32 wants %u but dibdrv has %u\n", version
, WINE_WGL_DRIVER_VERSION
);
333 if (!init_opengl()) return (void *)-1;
335 return &opengl_funcs
;
338 #else /* SONAME_LIBOSMESA */
340 /**********************************************************************
341 * dibdrv_wine_get_wgl_driver
343 struct opengl_funcs
*dibdrv_wine_get_wgl_driver( PHYSDEV dev
, UINT version
)
346 if (!warned
++) ERR( "OSMesa not compiled in, no OpenGL bitmap support\n" );
350 #endif /* SONAME_LIBOSMESA */