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 #include "gdi_private.h"
27 #include "wine/library.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(dib
);
32 #ifdef SONAME_LIBOSMESA
35 #include "wine/wgl_driver.h"
37 #define OSMESA_COLOR_INDEX GL_COLOR_INDEX
38 #define OSMESA_RGBA GL_RGBA
39 #define OSMESA_BGRA 0x1
40 #define OSMESA_ARGB 0x2
41 #define OSMESA_RGB GL_RGB
42 #define OSMESA_BGR 0x4
43 #define OSMESA_RGB_565 0x5
44 #define OSMESA_ROW_LENGTH 0x10
45 #define OSMESA_Y_UP 0x11
47 typedef struct osmesa_context
*OSMesaContext
;
49 extern BOOL WINAPI
GdiSetPixelFormat( HDC hdc
, INT fmt
, const PIXELFORMATDESCRIPTOR
*pfd
);
53 OSMesaContext context
;
57 static struct opengl_funcs opengl_funcs
;
59 #define USE_GL_FUNC(name) #name,
60 static const char *opengl_func_names
[] = { ALL_WGL_FUNCS
};
63 static OSMesaContext (*pOSMesaCreateContextExt
)( GLenum format
, GLint depthBits
, GLint stencilBits
,
64 GLint accumBits
, OSMesaContext sharelist
);
65 static void (*pOSMesaDestroyContext
)( OSMesaContext ctx
);
66 static void * (*pOSMesaGetProcAddress
)( const char *funcName
);
67 static GLboolean (*pOSMesaMakeCurrent
)( OSMesaContext ctx
, void *buffer
, GLenum type
,
68 GLsizei width
, GLsizei height
);
69 static void (*pOSMesaPixelStore
)( GLint pname
, GLint value
);
75 BYTE red_bits
, red_shift
;
76 BYTE green_bits
, green_shift
;
77 BYTE blue_bits
, blue_shift
;
78 BYTE alpha_bits
, alpha_shift
;
84 { OSMESA_BGRA
, 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 32, 8 },
85 { OSMESA_BGRA
, 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 16, 8 },
86 { OSMESA_RGBA
, 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 32, 8 },
87 { OSMESA_RGBA
, 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 16, 8 },
88 { OSMESA_ARGB
, 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 32, 8 },
89 { OSMESA_ARGB
, 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 16, 8 },
90 { OSMESA_RGB
, 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 32, 8 },
91 { OSMESA_RGB
, 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 16, 8 },
92 { OSMESA_BGR
, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 },
93 { OSMESA_BGR
, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 },
94 { OSMESA_RGB_565
, 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 32, 8 },
95 { OSMESA_RGB_565
, 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 16, 8 },
97 static const int nb_formats
= sizeof(pixel_formats
) / sizeof(pixel_formats
[0]);
99 static BOOL
init_opengl(void)
101 static BOOL init_done
= FALSE
;
102 static void *osmesa_handle
;
106 if (init_done
) return (osmesa_handle
!= NULL
);
109 osmesa_handle
= wine_dlopen( SONAME_LIBOSMESA
, RTLD_NOW
, buffer
, sizeof(buffer
) );
110 if (osmesa_handle
== NULL
)
112 ERR( "Failed to load OSMesa: %s\n", buffer
);
116 for (i
= 0; i
< sizeof(opengl_func_names
)/sizeof(opengl_func_names
[0]); i
++)
118 if (!(((void **)&opengl_funcs
.gl
)[i
] = wine_dlsym( osmesa_handle
, opengl_func_names
[i
], buffer
, sizeof(buffer
) )))
120 ERR( "%s not found in %s (%s), disabling.\n", opengl_func_names
[i
], SONAME_LIBOSMESA
, buffer
);
124 #define LOAD_FUNCPTR(f) do if (!(p##f = wine_dlsym( osmesa_handle, #f, buffer, sizeof(buffer) ))) \
126 ERR( "%s not found in %s (%s), disabling.\n", #f, SONAME_LIBOSMESA, buffer ); \
130 LOAD_FUNCPTR(OSMesaCreateContextExt
);
131 LOAD_FUNCPTR(OSMesaDestroyContext
);
132 LOAD_FUNCPTR(OSMesaGetProcAddress
);
133 LOAD_FUNCPTR(OSMesaMakeCurrent
);
134 LOAD_FUNCPTR(OSMesaPixelStore
);
140 wine_dlclose( osmesa_handle
, NULL
, 0 );
141 osmesa_handle
= NULL
;
145 /**********************************************************************
146 * dibdrv_wglDescribePixelFormat
148 static int dibdrv_wglDescribePixelFormat( HDC hdc
, int fmt
, UINT size
, PIXELFORMATDESCRIPTOR
*descr
)
150 int ret
= sizeof(pixel_formats
) / sizeof(pixel_formats
[0]);
152 if (!descr
) return ret
;
153 if (fmt
<= 0 || fmt
> ret
) return 0;
154 if (size
< sizeof(*descr
)) return 0;
156 memset( descr
, 0, sizeof(*descr
) );
157 descr
->nSize
= sizeof(*descr
);
159 descr
->dwFlags
= PFD_SUPPORT_GDI
| PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_BITMAP
| PFD_GENERIC_FORMAT
;
160 descr
->iPixelType
= PFD_TYPE_RGBA
;
161 descr
->cColorBits
= pixel_formats
[fmt
- 1].color_bits
;
162 descr
->cRedBits
= pixel_formats
[fmt
- 1].red_bits
;
163 descr
->cRedShift
= pixel_formats
[fmt
- 1].red_shift
;
164 descr
->cGreenBits
= pixel_formats
[fmt
- 1].green_bits
;
165 descr
->cGreenShift
= pixel_formats
[fmt
- 1].green_shift
;
166 descr
->cBlueBits
= pixel_formats
[fmt
- 1].blue_bits
;
167 descr
->cBlueShift
= pixel_formats
[fmt
- 1].blue_shift
;
168 descr
->cAlphaBits
= pixel_formats
[fmt
- 1].alpha_bits
;
169 descr
->cAlphaShift
= pixel_formats
[fmt
- 1].alpha_shift
;
170 descr
->cAccumBits
= pixel_formats
[fmt
- 1].accum_bits
;
171 descr
->cAccumRedBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
172 descr
->cAccumGreenBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
173 descr
->cAccumBlueBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
174 descr
->cAccumAlphaBits
= pixel_formats
[fmt
- 1].accum_bits
/ 4;
175 descr
->cDepthBits
= pixel_formats
[fmt
- 1].depth_bits
;
176 descr
->cStencilBits
= pixel_formats
[fmt
- 1].stencil_bits
;
177 descr
->cAuxBuffers
= 0;
178 descr
->iLayerType
= PFD_MAIN_PLANE
;
182 /***********************************************************************
183 * dibdrv_wglCopyContext
185 static BOOL
dibdrv_wglCopyContext( struct wgl_context
*src
, struct wgl_context
*dst
, UINT mask
)
187 FIXME( "not supported yet\n" );
191 /***********************************************************************
192 * dibdrv_wglCreateContext
194 static struct wgl_context
*dibdrv_wglCreateContext( HDC hdc
)
196 struct wgl_context
*context
;
198 if (!(context
= HeapAlloc( GetProcessHeap(), 0, sizeof( *context
)))) return NULL
;
199 context
->format
= GetPixelFormat( hdc
);
200 if (!context
->format
|| context
->format
> nb_formats
) context
->format
= 1;
202 if (!(context
->context
= pOSMesaCreateContextExt( pixel_formats
[context
->format
- 1].mesa
,
203 pixel_formats
[context
->format
- 1].depth_bits
,
204 pixel_formats
[context
->format
- 1].stencil_bits
,
205 pixel_formats
[context
->format
- 1].accum_bits
, 0 )))
207 HeapFree( GetProcessHeap(), 0, context
);
213 /***********************************************************************
214 * dibdrv_wglDeleteContext
216 static void dibdrv_wglDeleteContext( struct wgl_context
*context
)
218 pOSMesaDestroyContext( context
->context
);
219 HeapFree( GetProcessHeap(), 0, context
);
222 /***********************************************************************
223 * dibdrv_wglGetPixelFormat
225 static int dibdrv_wglGetPixelFormat( HDC hdc
)
227 DC
*dc
= get_dc_ptr( hdc
);
232 ret
= dc
->pixel_format
;
233 release_dc_ptr( dc
);
238 /***********************************************************************
239 * dibdrv_wglGetProcAddress
241 static PROC
dibdrv_wglGetProcAddress( const char *proc
)
243 if (!strncmp( proc
, "wgl", 3 )) return NULL
;
244 return (PROC
)pOSMesaGetProcAddress( proc
);
247 /***********************************************************************
248 * dibdrv_wglMakeCurrent
250 static BOOL
dibdrv_wglMakeCurrent( HDC hdc
, struct wgl_context
*context
)
260 pOSMesaMakeCurrent( NULL
, NULL
, GL_UNSIGNED_BYTE
, 0, 0 );
264 if (GetPixelFormat( hdc
) != context
->format
)
265 FIXME( "mismatched pixel formats %u/%u not supported yet\n",
266 GetPixelFormat( hdc
), context
->format
);
268 bitmap
= GetCurrentObject( hdc
, OBJ_BITMAP
);
269 bmp
= GDI_GetObjPtr( bitmap
, OBJ_BITMAP
);
270 if (!bmp
) return FALSE
;
272 if (init_dib_info_from_bitmapobj( &dib
, bmp
))
275 int width
= dib
.rect
.right
- dib
.rect
.left
;
276 int height
= dib
.rect
.bottom
- dib
.rect
.top
;
279 bits
= (char *)dib
.bits
.ptr
+ (dib
.rect
.bottom
- 1) * dib
.stride
;
281 bits
= (char *)dib
.bits
.ptr
+ dib
.rect
.top
* dib
.stride
;
282 bits
+= dib
.rect
.left
* dib
.bit_count
/ 8;
284 TRACE( "context %p bits %p size %ux%u\n", context
, bits
, width
, height
);
286 if (pixel_formats
[context
->format
- 1].mesa
== OSMESA_RGB_565
)
287 type
= GL_UNSIGNED_SHORT_5_6_5
;
289 type
= GL_UNSIGNED_BYTE
;
291 ret
= pOSMesaMakeCurrent( context
->context
, bits
, type
, width
, height
);
294 pOSMesaPixelStore( OSMESA_ROW_LENGTH
, abs( dib
.stride
) * 8 / dib
.bit_count
);
295 pOSMesaPixelStore( OSMESA_Y_UP
, 1 ); /* Windows seems to assume bottom-up */
298 GDI_ReleaseObj( bitmap
);
302 /**********************************************************************
303 * dibdrv_wglSetPixelFormat
305 static BOOL
dibdrv_wglSetPixelFormat( HDC hdc
, int fmt
, const PIXELFORMATDESCRIPTOR
*descr
)
307 if (fmt
<= 0 || fmt
> nb_formats
) return FALSE
;
308 return GdiSetPixelFormat( hdc
, fmt
, descr
);
311 /***********************************************************************
312 * dibdrv_wglShareLists
314 static BOOL
dibdrv_wglShareLists( struct wgl_context
*org
, struct wgl_context
*dest
)
316 FIXME( "not supported yet\n" );
320 /***********************************************************************
321 * dibdrv_wglSwapBuffers
323 static BOOL
dibdrv_wglSwapBuffers( HDC hdc
)
328 static struct opengl_funcs opengl_funcs
=
331 dibdrv_wglCopyContext
, /* p_wglCopyContext */
332 dibdrv_wglCreateContext
, /* p_wglCreateContext */
333 dibdrv_wglDeleteContext
, /* p_wglDeleteContext */
334 dibdrv_wglDescribePixelFormat
,/* p_wglDescribePixelFormat */
335 dibdrv_wglGetPixelFormat
, /* p_wglGetPixelFormat */
336 dibdrv_wglGetProcAddress
, /* p_wglGetProcAddress */
337 dibdrv_wglMakeCurrent
, /* p_wglMakeCurrent */
338 dibdrv_wglSetPixelFormat
, /* p_wglSetPixelFormat */
339 dibdrv_wglShareLists
, /* p_wglShareLists */
340 dibdrv_wglSwapBuffers
, /* p_wglSwapBuffers */
344 /**********************************************************************
345 * dibdrv_wine_get_wgl_driver
347 struct opengl_funcs
*dibdrv_wine_get_wgl_driver( PHYSDEV dev
, UINT version
)
349 if (version
!= WINE_WGL_DRIVER_VERSION
)
351 ERR( "version mismatch, opengl32 wants %u but dibdrv has %u\n", version
, WINE_WGL_DRIVER_VERSION
);
355 if (!init_opengl()) return (void *)-1;
357 return &opengl_funcs
;
360 #else /* SONAME_LIBOSMESA */
362 /**********************************************************************
363 * dibdrv_wine_get_wgl_driver
365 struct opengl_funcs
*dibdrv_wine_get_wgl_driver( PHYSDEV dev
, UINT version
)
368 if (!warned
++) ERR( "OSMesa not compiled in, no OpenGL bitmap support\n" );
372 #endif /* SONAME_LIBOSMESA */