2 * Android OpenGL functions
4 * Copyright 2000 Lionel Ulmer
5 * Copyright 2005 Alex Woods
6 * Copyright 2005 Raphael Junqueira
7 * Copyright 2006-2009 Roderick Colenbrander
8 * Copyright 2006 Tomas Carnecky
9 * Copyright 2013 Matteo Bruni
10 * Copyright 2012, 2013, 2014, 2017 Alexandre Julliard
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/port.h"
41 #define GLAPIENTRY /* nothing */
44 #include "wine/wgl_driver.h"
45 #include "wine/wglext.h"
46 #include "wine/library.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(android
);
51 #define DECL_FUNCPTR(f) typeof(f) * p_##f = NULL
52 DECL_FUNCPTR( eglCreateContext
);
53 DECL_FUNCPTR( eglCreateWindowSurface
);
54 DECL_FUNCPTR( eglCreatePbufferSurface
);
55 DECL_FUNCPTR( eglDestroyContext
);
56 DECL_FUNCPTR( eglDestroySurface
);
57 DECL_FUNCPTR( eglGetConfigAttrib
);
58 DECL_FUNCPTR( eglGetConfigs
);
59 DECL_FUNCPTR( eglGetDisplay
);
60 DECL_FUNCPTR( eglGetProcAddress
);
61 DECL_FUNCPTR( eglInitialize
);
62 DECL_FUNCPTR( eglMakeCurrent
);
63 DECL_FUNCPTR( eglSwapBuffers
);
64 DECL_FUNCPTR( eglSwapInterval
);
67 static const int egl_client_version
= 2;
69 struct wgl_pixel_format
90 ANativeWindow
*window
;
95 static void *egl_handle
;
96 static void *opengl_handle
;
97 static struct wgl_pixel_format
*pixel_formats
;
98 static int nb_pixel_formats
, nb_onscreen_formats
;
99 static EGLDisplay display
;
100 static int swap_interval
;
101 static char wgl_extensions
[4096];
102 static struct opengl_funcs egl_funcs
;
104 static struct list gl_contexts
= LIST_INIT( gl_contexts
);
105 static struct list gl_drawables
= LIST_INIT( gl_drawables
);
107 static void (*pglFinish
)(void);
108 static void (*pglFlush
)(void);
110 static CRITICAL_SECTION drawable_section
;
111 static CRITICAL_SECTION_DEBUG critsect_debug
=
113 0, 0, &drawable_section
,
114 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
115 0, 0, { (DWORD_PTR
)(__FILE__
": drawable_section") }
117 static CRITICAL_SECTION drawable_section
= { &critsect_debug
, -1, 0, 0, 0, 0 };
119 static inline BOOL
is_onscreen_pixel_format( int format
)
121 return format
> 0 && format
<= nb_onscreen_formats
;
124 static struct gl_drawable
*create_gl_drawable( HWND hwnd
, HDC hdc
, int format
)
126 static const int attribs
[] = { EGL_WIDTH
, 1, EGL_HEIGHT
, 1, EGL_NONE
};
127 struct gl_drawable
*gl
= HeapAlloc( GetProcessHeap(), 0, sizeof(*gl
) );
132 gl
->window
= create_ioctl_window( hwnd
, TRUE
);
134 gl
->pbuffer
= p_eglCreatePbufferSurface( display
, pixel_formats
[gl
->format
- 1].config
, attribs
);
135 EnterCriticalSection( &drawable_section
);
136 list_add_head( &gl_drawables
, &gl
->entry
);
140 static struct gl_drawable
*get_gl_drawable( HWND hwnd
, HDC hdc
)
142 struct gl_drawable
*gl
;
144 EnterCriticalSection( &drawable_section
);
145 LIST_FOR_EACH_ENTRY( gl
, &gl_drawables
, struct gl_drawable
, entry
)
147 if (hwnd
&& gl
->hwnd
== hwnd
) return gl
;
148 if (hdc
&& gl
->hdc
== hdc
) return gl
;
150 LeaveCriticalSection( &drawable_section
);
154 static void release_gl_drawable( struct gl_drawable
*gl
)
156 if (gl
) LeaveCriticalSection( &drawable_section
);
159 void destroy_gl_drawable( HWND hwnd
)
161 struct gl_drawable
*gl
;
163 EnterCriticalSection( &drawable_section
);
164 LIST_FOR_EACH_ENTRY( gl
, &gl_drawables
, struct gl_drawable
, entry
)
166 if (gl
->hwnd
!= hwnd
) continue;
167 list_remove( &gl
->entry
);
168 if (gl
->surface
) p_eglDestroySurface( display
, gl
->surface
);
169 if (gl
->pbuffer
) p_eglDestroySurface( display
, gl
->pbuffer
);
170 release_ioctl_window( gl
->window
);
171 HeapFree( GetProcessHeap(), 0, gl
);
174 LeaveCriticalSection( &drawable_section
);
177 static BOOL
refresh_context( struct wgl_context
*ctx
)
179 BOOL ret
= InterlockedExchange( &ctx
->refresh
, FALSE
);
183 TRACE( "refreshing hwnd %p context %p surface %p\n", ctx
->hwnd
, ctx
->context
, ctx
->surface
);
184 p_eglMakeCurrent( display
, ctx
->surface
, ctx
->surface
, ctx
->context
);
185 RedrawWindow( ctx
->hwnd
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
);
190 void update_gl_drawable( HWND hwnd
)
192 struct gl_drawable
*gl
;
193 struct wgl_context
*ctx
;
195 if ((gl
= get_gl_drawable( hwnd
, 0 )))
198 (gl
->surface
= p_eglCreateWindowSurface( display
, pixel_formats
[gl
->format
- 1].config
, gl
->window
, NULL
)))
200 LIST_FOR_EACH_ENTRY( ctx
, &gl_contexts
, struct wgl_context
, entry
)
202 if (ctx
->hwnd
!= hwnd
) continue;
203 TRACE( "hwnd %p refreshing %p %scurrent\n", hwnd
, ctx
, NtCurrentTeb()->glContext
== ctx
? "" : "not " );
204 ctx
->surface
= gl
->surface
;
205 if (NtCurrentTeb()->glContext
== ctx
)
206 p_eglMakeCurrent( display
, ctx
->surface
, ctx
->surface
, ctx
->context
);
208 InterlockedExchange( &ctx
->refresh
, TRUE
);
211 release_gl_drawable( gl
);
212 RedrawWindow( hwnd
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
);
216 static BOOL
set_pixel_format( HDC hdc
, int format
, BOOL allow_change
)
218 struct gl_drawable
*gl
;
219 HWND hwnd
= WindowFromDC( hdc
);
222 if (!hwnd
|| hwnd
== GetDesktopWindow())
224 WARN( "not a proper window DC %p/%p\n", hdc
, hwnd
);
227 if (!is_onscreen_pixel_format( format
))
229 WARN( "Invalid format %d\n", format
);
232 TRACE( "%p/%p format %d\n", hdc
, hwnd
, format
);
234 if ((gl
= get_gl_drawable( hwnd
, 0 )))
240 p_eglGetConfigAttrib( display
, pixel_formats
[format
- 1].config
, EGL_NATIVE_VISUAL_ID
, &pf
);
241 gl
->window
->perform( gl
->window
, NATIVE_WINDOW_SET_BUFFERS_FORMAT
, pf
);
245 else gl
= create_gl_drawable( hwnd
, 0, format
);
247 release_gl_drawable( gl
);
249 if (prev
&& prev
!= format
&& !allow_change
) return FALSE
;
250 if (__wine_set_pixel_format( hwnd
, format
)) return TRUE
;
251 destroy_gl_drawable( hwnd
);
255 static struct wgl_context
*create_context( HDC hdc
, struct wgl_context
*share
, const int *attribs
)
257 struct gl_drawable
*gl
;
258 struct wgl_context
*ctx
;
260 if (!(gl
= get_gl_drawable( WindowFromDC( hdc
), hdc
))) return NULL
;
262 ctx
= HeapAlloc( GetProcessHeap(), 0, sizeof(*ctx
) );
264 ctx
->config
= pixel_formats
[gl
->format
- 1].config
;
266 ctx
->refresh
= FALSE
;
267 ctx
->context
= p_eglCreateContext( display
, ctx
->config
,
268 share
? share
->context
: EGL_NO_CONTEXT
, attribs
);
269 TRACE( "%p fmt %d ctx %p\n", hdc
, gl
->format
, ctx
->context
);
270 list_add_head( &gl_contexts
, &ctx
->entry
);
271 release_gl_drawable( gl
);
275 /***********************************************************************
276 * android_wglGetExtensionsStringARB
278 static const char *android_wglGetExtensionsStringARB( HDC hdc
)
280 TRACE( "() returning \"%s\"\n", wgl_extensions
);
281 return wgl_extensions
;
284 /***********************************************************************
285 * android_wglGetExtensionsStringEXT
287 static const char *android_wglGetExtensionsStringEXT(void)
289 TRACE( "() returning \"%s\"\n", wgl_extensions
);
290 return wgl_extensions
;
293 /***********************************************************************
294 * android_wglCreateContextAttribsARB
296 static struct wgl_context
*android_wglCreateContextAttribsARB( HDC hdc
, struct wgl_context
*share
,
299 int count
= 0, egl_attribs
[3];
300 BOOL opengl_es
= FALSE
;
302 while (attribs
&& *attribs
&& count
< 2)
306 case WGL_CONTEXT_PROFILE_MASK_ARB
:
307 if (attribs
[1] == WGL_CONTEXT_ES2_PROFILE_BIT_EXT
)
310 case WGL_CONTEXT_MAJOR_VERSION_ARB
:
311 egl_attribs
[count
++] = EGL_CONTEXT_CLIENT_VERSION
;
312 egl_attribs
[count
++] = attribs
[1];
315 FIXME("Unhandled attributes: %#x %#x\n", attribs
[0], attribs
[1]);
321 WARN("Requested creation of an OpenGL (non ES) context, that's not supported.\n");
324 if (!count
) /* FIXME: force version if not specified */
326 egl_attribs
[count
++] = EGL_CONTEXT_CLIENT_VERSION
;
327 egl_attribs
[count
++] = egl_client_version
;
329 egl_attribs
[count
] = EGL_NONE
;
331 return create_context( hdc
, share
, egl_attribs
);
334 /***********************************************************************
335 * android_wglMakeContextCurrentARB
337 static BOOL
android_wglMakeContextCurrentARB( HDC draw_hdc
, HDC read_hdc
, struct wgl_context
*ctx
)
340 struct gl_drawable
*draw_gl
, *read_gl
= NULL
;
341 EGLSurface draw_surface
, read_surface
;
344 TRACE( "%p %p %p\n", draw_hdc
, read_hdc
, ctx
);
348 p_eglMakeCurrent( display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
349 NtCurrentTeb()->glContext
= NULL
;
353 draw_hwnd
= WindowFromDC( draw_hdc
);
354 if ((draw_gl
= get_gl_drawable( draw_hwnd
, draw_hdc
)))
356 read_gl
= get_gl_drawable( WindowFromDC( read_hdc
), read_hdc
);
357 draw_surface
= draw_gl
->surface
? draw_gl
->surface
: draw_gl
->pbuffer
;
358 read_surface
= read_gl
->surface
? read_gl
->surface
: read_gl
->pbuffer
;
359 TRACE( "%p/%p context %p surface %p/%p\n",
360 draw_hdc
, read_hdc
, ctx
->context
, draw_surface
, read_surface
);
361 ret
= p_eglMakeCurrent( display
, draw_surface
, read_surface
, ctx
->context
);
364 ctx
->surface
= draw_gl
->surface
;
365 ctx
->hwnd
= draw_hwnd
;
366 ctx
->refresh
= FALSE
;
367 NtCurrentTeb()->glContext
= ctx
;
371 SetLastError( ERROR_INVALID_HANDLE
);
374 release_gl_drawable( read_gl
);
375 release_gl_drawable( draw_gl
);
379 /***********************************************************************
380 * android_wglSwapIntervalEXT
382 static BOOL
android_wglSwapIntervalEXT( int interval
)
386 TRACE("(%d)\n", interval
);
390 SetLastError(ERROR_INVALID_DATA
);
394 ret
= p_eglSwapInterval( display
, interval
);
397 swap_interval
= interval
;
399 SetLastError( ERROR_DC_NOT_FOUND
);
404 /***********************************************************************
405 * android_wglGetSwapIntervalEXT
407 static int android_wglGetSwapIntervalEXT(void)
409 return swap_interval
;
412 /***********************************************************************
413 * android_wglSetPixelFormatWINE
415 static BOOL
android_wglSetPixelFormatWINE( HDC hdc
, int format
)
417 return set_pixel_format( hdc
, format
, TRUE
);
420 /***********************************************************************
421 * android_wglCopyContext
423 static BOOL
android_wglCopyContext( struct wgl_context
*src
, struct wgl_context
*dst
, UINT mask
)
425 FIXME( "%p -> %p mask %#x unsupported\n", src
, dst
, mask
);
429 /***********************************************************************
430 * android_wglCreateContext
432 static struct wgl_context
*android_wglCreateContext( HDC hdc
)
434 int egl_attribs
[3] = { EGL_CONTEXT_CLIENT_VERSION
, egl_client_version
, EGL_NONE
};
436 return create_context( hdc
, NULL
, egl_attribs
);
439 /***********************************************************************
440 * android_wglDeleteContext
442 static void android_wglDeleteContext( struct wgl_context
*ctx
)
444 EnterCriticalSection( &drawable_section
);
445 list_remove( &ctx
->entry
);
446 LeaveCriticalSection( &drawable_section
);
447 p_eglDestroyContext( display
, ctx
->context
);
448 HeapFree( GetProcessHeap(), 0, ctx
);
451 /***********************************************************************
452 * android_wglDescribePixelFormat
454 static int android_wglDescribePixelFormat( HDC hdc
, int fmt
, UINT size
, PIXELFORMATDESCRIPTOR
*pfd
)
459 if (!pfd
) return nb_onscreen_formats
;
460 if (!is_onscreen_pixel_format( fmt
)) return 0;
461 if (size
< sizeof(*pfd
)) return 0;
462 config
= pixel_formats
[fmt
- 1].config
;
464 memset( pfd
, 0, sizeof(*pfd
) );
465 pfd
->nSize
= sizeof(*pfd
);
467 pfd
->dwFlags
= PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_WINDOW
| PFD_DOUBLEBUFFER
;
468 pfd
->iPixelType
= PFD_TYPE_RGBA
;
469 pfd
->iLayerType
= PFD_MAIN_PLANE
;
471 p_eglGetConfigAttrib( display
, config
, EGL_BUFFER_SIZE
, &val
);
472 pfd
->cColorBits
= val
;
473 p_eglGetConfigAttrib( display
, config
, EGL_RED_SIZE
, &val
);
475 p_eglGetConfigAttrib( display
, config
, EGL_GREEN_SIZE
, &val
);
476 pfd
->cGreenBits
= val
;
477 p_eglGetConfigAttrib( display
, config
, EGL_BLUE_SIZE
, &val
);
478 pfd
->cBlueBits
= val
;
479 p_eglGetConfigAttrib( display
, config
, EGL_ALPHA_SIZE
, &val
);
480 pfd
->cAlphaBits
= val
;
481 p_eglGetConfigAttrib( display
, config
, EGL_DEPTH_SIZE
, &val
);
482 pfd
->cDepthBits
= val
;
483 p_eglGetConfigAttrib( display
, config
, EGL_STENCIL_SIZE
, &val
);
484 pfd
->cStencilBits
= val
;
486 pfd
->cAlphaShift
= 0;
487 pfd
->cBlueShift
= pfd
->cAlphaShift
+ pfd
->cAlphaBits
;
488 pfd
->cGreenShift
= pfd
->cBlueShift
+ pfd
->cBlueBits
;
489 pfd
->cRedShift
= pfd
->cGreenShift
+ pfd
->cGreenBits
;
491 TRACE( "fmt %u color %u %u/%u/%u/%u depth %u stencil %u\n",
492 fmt
, pfd
->cColorBits
, pfd
->cRedBits
, pfd
->cGreenBits
, pfd
->cBlueBits
,
493 pfd
->cAlphaBits
, pfd
->cDepthBits
, pfd
->cStencilBits
);
494 return nb_onscreen_formats
;
497 /***********************************************************************
498 * android_wglGetPixelFormat
500 static int android_wglGetPixelFormat( HDC hdc
)
502 struct gl_drawable
*gl
;
505 if ((gl
= get_gl_drawable( WindowFromDC( hdc
), hdc
)))
508 /* offscreen formats can't be used with traditional WGL calls */
509 if (!is_onscreen_pixel_format( ret
)) ret
= 1;
510 release_gl_drawable( gl
);
515 /***********************************************************************
516 * android_wglGetProcAddress
518 static PROC
android_wglGetProcAddress( LPCSTR name
)
521 if (!strncmp( name
, "wgl", 3 )) return NULL
;
522 ret
= (PROC
)p_eglGetProcAddress( name
);
523 TRACE( "%s -> %p\n", name
, ret
);
527 /***********************************************************************
528 * android_wglMakeCurrent
530 static BOOL
android_wglMakeCurrent( HDC hdc
, struct wgl_context
*ctx
)
533 struct gl_drawable
*gl
;
536 TRACE( "%p %p\n", hdc
, ctx
);
540 p_eglMakeCurrent( display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
541 NtCurrentTeb()->glContext
= NULL
;
545 hwnd
= WindowFromDC( hdc
);
546 if ((gl
= get_gl_drawable( hwnd
, hdc
)))
548 EGLSurface surface
= gl
->surface
? gl
->surface
: gl
->pbuffer
;
549 TRACE( "%p hwnd %p context %p surface %p\n", hdc
, gl
->hwnd
, ctx
->context
, surface
);
550 ret
= p_eglMakeCurrent( display
, surface
, surface
, ctx
->context
);
553 ctx
->surface
= gl
->surface
;
555 ctx
->refresh
= FALSE
;
556 NtCurrentTeb()->glContext
= ctx
;
560 SetLastError( ERROR_INVALID_HANDLE
);
563 release_gl_drawable( gl
);
567 /***********************************************************************
568 * android_wglSetPixelFormat
570 static BOOL
android_wglSetPixelFormat( HDC hdc
, int format
, const PIXELFORMATDESCRIPTOR
*pfd
)
572 return set_pixel_format( hdc
, format
, FALSE
);
575 /***********************************************************************
576 * android_wglShareLists
578 static BOOL
android_wglShareLists( struct wgl_context
*org
, struct wgl_context
*dest
)
580 FIXME( "%p %p\n", org
, dest
);
584 /***********************************************************************
585 * android_wglSwapBuffers
587 static BOOL
android_wglSwapBuffers( HDC hdc
)
589 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
591 if (!ctx
) return FALSE
;
593 TRACE( "%p hwnd %p context %p surface %p\n", hdc
, ctx
->hwnd
, ctx
->context
, ctx
->surface
);
595 if (refresh_context( ctx
)) return TRUE
;
596 if (ctx
->surface
) p_eglSwapBuffers( display
, ctx
->surface
);
600 static void wglFinish(void)
602 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
605 TRACE( "hwnd %p context %p\n", ctx
->hwnd
, ctx
->context
);
606 refresh_context( ctx
);
610 static void wglFlush(void)
612 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
615 TRACE( "hwnd %p context %p\n", ctx
->hwnd
, ctx
->context
);
616 refresh_context( ctx
);
620 static void register_extension( const char *ext
)
622 if (wgl_extensions
[0]) strcat( wgl_extensions
, " " );
623 strcat( wgl_extensions
, ext
);
624 TRACE( "%s\n", ext
);
627 static void init_extensions(void)
631 register_extension("WGL_ARB_create_context");
632 register_extension("WGL_ARB_create_context_profile");
633 egl_funcs
.ext
.p_wglCreateContextAttribsARB
= android_wglCreateContextAttribsARB
;
635 register_extension("WGL_ARB_extensions_string");
636 egl_funcs
.ext
.p_wglGetExtensionsStringARB
= android_wglGetExtensionsStringARB
;
638 register_extension("WGL_ARB_make_current_read");
639 egl_funcs
.ext
.p_wglGetCurrentReadDCARB
= (void *)1; /* never called */
640 egl_funcs
.ext
.p_wglMakeContextCurrentARB
= android_wglMakeContextCurrentARB
;
642 register_extension("WGL_EXT_extensions_string");
643 egl_funcs
.ext
.p_wglGetExtensionsStringEXT
= android_wglGetExtensionsStringEXT
;
645 register_extension("WGL_EXT_swap_control");
646 egl_funcs
.ext
.p_wglSwapIntervalEXT
= android_wglSwapIntervalEXT
;
647 egl_funcs
.ext
.p_wglGetSwapIntervalEXT
= android_wglGetSwapIntervalEXT
;
649 register_extension("WGL_EXT_framebuffer_sRGB");
651 /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
652 * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
654 register_extension("WGL_WINE_pixel_format_passthrough");
655 egl_funcs
.ext
.p_wglSetPixelFormatWINE
= android_wglSetPixelFormatWINE
;
657 /* load standard functions and extensions exported from the OpenGL library */
659 #define USE_GL_FUNC(func) if ((ptr = wine_dlsym( opengl_handle, #func, NULL, 0 ))) egl_funcs.gl.p_##func = ptr;
663 #define LOAD_FUNCPTR(func) egl_funcs.ext.p_##func = wine_dlsym( opengl_handle, #func, NULL, 0 )
664 LOAD_FUNCPTR( glActiveShaderProgram
);
665 LOAD_FUNCPTR( glActiveTexture
);
666 LOAD_FUNCPTR( glAttachShader
);
667 LOAD_FUNCPTR( glBeginQuery
);
668 LOAD_FUNCPTR( glBeginTransformFeedback
);
669 LOAD_FUNCPTR( glBindAttribLocation
);
670 LOAD_FUNCPTR( glBindBuffer
);
671 LOAD_FUNCPTR( glBindBufferBase
);
672 LOAD_FUNCPTR( glBindBufferRange
);
673 LOAD_FUNCPTR( glBindFramebuffer
);
674 LOAD_FUNCPTR( glBindImageTexture
);
675 LOAD_FUNCPTR( glBindProgramPipeline
);
676 LOAD_FUNCPTR( glBindRenderbuffer
);
677 LOAD_FUNCPTR( glBindSampler
);
678 LOAD_FUNCPTR( glBindTransformFeedback
);
679 LOAD_FUNCPTR( glBindVertexArray
);
680 LOAD_FUNCPTR( glBindVertexBuffer
);
681 LOAD_FUNCPTR( glBlendBarrierKHR
);
682 LOAD_FUNCPTR( glBlendColor
);
683 LOAD_FUNCPTR( glBlendEquation
);
684 LOAD_FUNCPTR( glBlendEquationSeparate
);
685 LOAD_FUNCPTR( glBlendFuncSeparate
);
686 LOAD_FUNCPTR( glBlitFramebuffer
);
687 LOAD_FUNCPTR( glBufferData
);
688 LOAD_FUNCPTR( glBufferSubData
);
689 LOAD_FUNCPTR( glCheckFramebufferStatus
);
690 LOAD_FUNCPTR( glClearBufferfi
);
691 LOAD_FUNCPTR( glClearBufferfv
);
692 LOAD_FUNCPTR( glClearBufferiv
);
693 LOAD_FUNCPTR( glClearBufferuiv
);
694 LOAD_FUNCPTR( glClearDepthf
);
695 LOAD_FUNCPTR( glClientWaitSync
);
696 LOAD_FUNCPTR( glCompileShader
);
697 LOAD_FUNCPTR( glCompressedTexImage2D
);
698 LOAD_FUNCPTR( glCompressedTexImage3D
);
699 LOAD_FUNCPTR( glCompressedTexSubImage2D
);
700 LOAD_FUNCPTR( glCompressedTexSubImage3D
);
701 LOAD_FUNCPTR( glCopyBufferSubData
);
702 LOAD_FUNCPTR( glCopyTexSubImage3D
);
703 LOAD_FUNCPTR( glCreateProgram
);
704 LOAD_FUNCPTR( glCreateShader
);
705 LOAD_FUNCPTR( glCreateShaderProgramv
);
706 LOAD_FUNCPTR( glDeleteBuffers
);
707 LOAD_FUNCPTR( glDeleteFramebuffers
);
708 LOAD_FUNCPTR( glDeleteProgram
);
709 LOAD_FUNCPTR( glDeleteProgramPipelines
);
710 LOAD_FUNCPTR( glDeleteQueries
);
711 LOAD_FUNCPTR( glDeleteRenderbuffers
);
712 LOAD_FUNCPTR( glDeleteSamplers
);
713 LOAD_FUNCPTR( glDeleteShader
);
714 LOAD_FUNCPTR( glDeleteSync
);
715 LOAD_FUNCPTR( glDeleteTransformFeedbacks
);
716 LOAD_FUNCPTR( glDeleteVertexArrays
);
717 LOAD_FUNCPTR( glDepthRangef
);
718 LOAD_FUNCPTR( glDetachShader
);
719 LOAD_FUNCPTR( glDisableVertexAttribArray
);
720 LOAD_FUNCPTR( glDispatchCompute
);
721 LOAD_FUNCPTR( glDispatchComputeIndirect
);
722 LOAD_FUNCPTR( glDrawArraysIndirect
);
723 LOAD_FUNCPTR( glDrawArraysInstanced
);
724 LOAD_FUNCPTR( glDrawBuffers
);
725 LOAD_FUNCPTR( glDrawElementsIndirect
);
726 LOAD_FUNCPTR( glDrawElementsInstanced
);
727 LOAD_FUNCPTR( glDrawRangeElements
);
728 LOAD_FUNCPTR( glEnableVertexAttribArray
);
729 LOAD_FUNCPTR( glEndQuery
);
730 LOAD_FUNCPTR( glEndTransformFeedback
);
731 LOAD_FUNCPTR( glFenceSync
);
732 LOAD_FUNCPTR( glFlushMappedBufferRange
);
733 LOAD_FUNCPTR( glFramebufferParameteri
);
734 LOAD_FUNCPTR( glFramebufferRenderbuffer
);
735 LOAD_FUNCPTR( glFramebufferTexture2D
);
736 LOAD_FUNCPTR( glFramebufferTextureEXT
);
737 LOAD_FUNCPTR( glFramebufferTextureLayer
);
738 LOAD_FUNCPTR( glGenBuffers
);
739 LOAD_FUNCPTR( glGenFramebuffers
);
740 LOAD_FUNCPTR( glGenProgramPipelines
);
741 LOAD_FUNCPTR( glGenQueries
);
742 LOAD_FUNCPTR( glGenRenderbuffers
);
743 LOAD_FUNCPTR( glGenSamplers
);
744 LOAD_FUNCPTR( glGenTransformFeedbacks
);
745 LOAD_FUNCPTR( glGenVertexArrays
);
746 LOAD_FUNCPTR( glGenerateMipmap
);
747 LOAD_FUNCPTR( glGetActiveAttrib
);
748 LOAD_FUNCPTR( glGetActiveUniform
);
749 LOAD_FUNCPTR( glGetActiveUniformBlockName
);
750 LOAD_FUNCPTR( glGetActiveUniformBlockiv
);
751 LOAD_FUNCPTR( glGetActiveUniformsiv
);
752 LOAD_FUNCPTR( glGetAttachedShaders
);
753 LOAD_FUNCPTR( glGetAttribLocation
);
754 LOAD_FUNCPTR( glGetBooleani_v
);
755 LOAD_FUNCPTR( glGetBufferParameteri64v
);
756 LOAD_FUNCPTR( glGetBufferParameteriv
);
757 LOAD_FUNCPTR( glGetBufferPointerv
);
758 LOAD_FUNCPTR( glGetFragDataLocation
);
759 LOAD_FUNCPTR( glGetFramebufferAttachmentParameteriv
);
760 LOAD_FUNCPTR( glGetFramebufferParameteriv
);
761 LOAD_FUNCPTR( glGetInteger64i_v
);
762 LOAD_FUNCPTR( glGetInteger64v
);
763 LOAD_FUNCPTR( glGetIntegeri_v
);
764 LOAD_FUNCPTR( glGetInternalformativ
);
765 LOAD_FUNCPTR( glGetMultisamplefv
);
766 LOAD_FUNCPTR( glGetProgramBinary
);
767 LOAD_FUNCPTR( glGetProgramInfoLog
);
768 LOAD_FUNCPTR( glGetProgramInterfaceiv
);
769 LOAD_FUNCPTR( glGetProgramPipelineInfoLog
);
770 LOAD_FUNCPTR( glGetProgramPipelineiv
);
771 LOAD_FUNCPTR( glGetProgramResourceIndex
);
772 LOAD_FUNCPTR( glGetProgramResourceLocation
);
773 LOAD_FUNCPTR( glGetProgramResourceName
);
774 LOAD_FUNCPTR( glGetProgramResourceiv
);
775 LOAD_FUNCPTR( glGetProgramiv
);
776 LOAD_FUNCPTR( glGetQueryObjectuiv
);
777 LOAD_FUNCPTR( glGetQueryiv
);
778 LOAD_FUNCPTR( glGetRenderbufferParameteriv
);
779 LOAD_FUNCPTR( glGetSamplerParameterfv
);
780 LOAD_FUNCPTR( glGetSamplerParameteriv
);
781 LOAD_FUNCPTR( glGetShaderInfoLog
);
782 LOAD_FUNCPTR( glGetShaderPrecisionFormat
);
783 LOAD_FUNCPTR( glGetShaderSource
);
784 LOAD_FUNCPTR( glGetShaderiv
);
785 LOAD_FUNCPTR( glGetStringi
);
786 LOAD_FUNCPTR( glGetSynciv
);
787 LOAD_FUNCPTR( glGetTexParameterIivEXT
);
788 LOAD_FUNCPTR( glGetTexParameterIuivEXT
);
789 LOAD_FUNCPTR( glGetTransformFeedbackVarying
);
790 LOAD_FUNCPTR( glGetUniformBlockIndex
);
791 LOAD_FUNCPTR( glGetUniformIndices
);
792 LOAD_FUNCPTR( glGetUniformLocation
);
793 LOAD_FUNCPTR( glGetUniformfv
);
794 LOAD_FUNCPTR( glGetUniformiv
);
795 LOAD_FUNCPTR( glGetUniformuiv
);
796 LOAD_FUNCPTR( glGetVertexAttribIiv
);
797 LOAD_FUNCPTR( glGetVertexAttribIuiv
);
798 LOAD_FUNCPTR( glGetVertexAttribPointerv
);
799 LOAD_FUNCPTR( glGetVertexAttribfv
);
800 LOAD_FUNCPTR( glGetVertexAttribiv
);
801 LOAD_FUNCPTR( glInvalidateFramebuffer
);
802 LOAD_FUNCPTR( glInvalidateSubFramebuffer
);
803 LOAD_FUNCPTR( glIsBuffer
);
804 LOAD_FUNCPTR( glIsFramebuffer
);
805 LOAD_FUNCPTR( glIsProgram
);
806 LOAD_FUNCPTR( glIsProgramPipeline
);
807 LOAD_FUNCPTR( glIsQuery
);
808 LOAD_FUNCPTR( glIsRenderbuffer
);
809 LOAD_FUNCPTR( glIsSampler
);
810 LOAD_FUNCPTR( glIsShader
);
811 LOAD_FUNCPTR( glIsSync
);
812 LOAD_FUNCPTR( glIsTransformFeedback
);
813 LOAD_FUNCPTR( glIsVertexArray
);
814 LOAD_FUNCPTR( glLinkProgram
);
815 LOAD_FUNCPTR( glMapBufferRange
);
816 LOAD_FUNCPTR( glMemoryBarrier
);
817 LOAD_FUNCPTR( glMemoryBarrierByRegion
);
818 LOAD_FUNCPTR( glPauseTransformFeedback
);
819 LOAD_FUNCPTR( glProgramBinary
);
820 LOAD_FUNCPTR( glProgramParameteri
);
821 LOAD_FUNCPTR( glProgramUniform1f
);
822 LOAD_FUNCPTR( glProgramUniform1fv
);
823 LOAD_FUNCPTR( glProgramUniform1i
);
824 LOAD_FUNCPTR( glProgramUniform1iv
);
825 LOAD_FUNCPTR( glProgramUniform1ui
);
826 LOAD_FUNCPTR( glProgramUniform1uiv
);
827 LOAD_FUNCPTR( glProgramUniform2f
);
828 LOAD_FUNCPTR( glProgramUniform2fv
);
829 LOAD_FUNCPTR( glProgramUniform2i
);
830 LOAD_FUNCPTR( glProgramUniform2iv
);
831 LOAD_FUNCPTR( glProgramUniform2ui
);
832 LOAD_FUNCPTR( glProgramUniform2uiv
);
833 LOAD_FUNCPTR( glProgramUniform3f
);
834 LOAD_FUNCPTR( glProgramUniform3fv
);
835 LOAD_FUNCPTR( glProgramUniform3i
);
836 LOAD_FUNCPTR( glProgramUniform3iv
);
837 LOAD_FUNCPTR( glProgramUniform3ui
);
838 LOAD_FUNCPTR( glProgramUniform3uiv
);
839 LOAD_FUNCPTR( glProgramUniform4f
);
840 LOAD_FUNCPTR( glProgramUniform4fv
);
841 LOAD_FUNCPTR( glProgramUniform4i
);
842 LOAD_FUNCPTR( glProgramUniform4iv
);
843 LOAD_FUNCPTR( glProgramUniform4ui
);
844 LOAD_FUNCPTR( glProgramUniform4uiv
);
845 LOAD_FUNCPTR( glProgramUniformMatrix2fv
);
846 LOAD_FUNCPTR( glProgramUniformMatrix2x3fv
);
847 LOAD_FUNCPTR( glProgramUniformMatrix2x4fv
);
848 LOAD_FUNCPTR( glProgramUniformMatrix3fv
);
849 LOAD_FUNCPTR( glProgramUniformMatrix3x2fv
);
850 LOAD_FUNCPTR( glProgramUniformMatrix3x4fv
);
851 LOAD_FUNCPTR( glProgramUniformMatrix4fv
);
852 LOAD_FUNCPTR( glProgramUniformMatrix4x2fv
);
853 LOAD_FUNCPTR( glProgramUniformMatrix4x3fv
);
854 LOAD_FUNCPTR( glReleaseShaderCompiler
);
855 LOAD_FUNCPTR( glRenderbufferStorage
);
856 LOAD_FUNCPTR( glRenderbufferStorageMultisample
);
857 LOAD_FUNCPTR( glResumeTransformFeedback
);
858 LOAD_FUNCPTR( glSampleCoverage
);
859 LOAD_FUNCPTR( glSampleMaski
);
860 LOAD_FUNCPTR( glSamplerParameterf
);
861 LOAD_FUNCPTR( glSamplerParameterfv
);
862 LOAD_FUNCPTR( glSamplerParameteri
);
863 LOAD_FUNCPTR( glSamplerParameteriv
);
864 LOAD_FUNCPTR( glShaderBinary
);
865 LOAD_FUNCPTR( glShaderSource
);
866 LOAD_FUNCPTR( glStencilFuncSeparate
);
867 LOAD_FUNCPTR( glStencilMaskSeparate
);
868 LOAD_FUNCPTR( glStencilOpSeparate
);
869 LOAD_FUNCPTR( glTexBufferEXT
);
870 LOAD_FUNCPTR( glTexImage3D
);
871 LOAD_FUNCPTR( glTexParameterIivEXT
);
872 LOAD_FUNCPTR( glTexParameterIuivEXT
);
873 LOAD_FUNCPTR( glTexStorage2D
);
874 LOAD_FUNCPTR( glTexStorage2DMultisample
);
875 LOAD_FUNCPTR( glTexStorage3D
);
876 LOAD_FUNCPTR( glTexSubImage3D
);
877 LOAD_FUNCPTR( glTransformFeedbackVaryings
);
878 LOAD_FUNCPTR( glUniform1f
);
879 LOAD_FUNCPTR( glUniform1fv
);
880 LOAD_FUNCPTR( glUniform1i
);
881 LOAD_FUNCPTR( glUniform1iv
);
882 LOAD_FUNCPTR( glUniform1ui
);
883 LOAD_FUNCPTR( glUniform1uiv
);
884 LOAD_FUNCPTR( glUniform2f
);
885 LOAD_FUNCPTR( glUniform2fv
);
886 LOAD_FUNCPTR( glUniform2i
);
887 LOAD_FUNCPTR( glUniform2iv
);
888 LOAD_FUNCPTR( glUniform2ui
);
889 LOAD_FUNCPTR( glUniform2uiv
);
890 LOAD_FUNCPTR( glUniform3f
);
891 LOAD_FUNCPTR( glUniform3fv
);
892 LOAD_FUNCPTR( glUniform3i
);
893 LOAD_FUNCPTR( glUniform3iv
);
894 LOAD_FUNCPTR( glUniform3ui
);
895 LOAD_FUNCPTR( glUniform3uiv
);
896 LOAD_FUNCPTR( glUniform4f
);
897 LOAD_FUNCPTR( glUniform4fv
);
898 LOAD_FUNCPTR( glUniform4i
);
899 LOAD_FUNCPTR( glUniform4iv
);
900 LOAD_FUNCPTR( glUniform4ui
);
901 LOAD_FUNCPTR( glUniform4uiv
);
902 LOAD_FUNCPTR( glUniformBlockBinding
);
903 LOAD_FUNCPTR( glUniformMatrix2fv
);
904 LOAD_FUNCPTR( glUniformMatrix2x3fv
);
905 LOAD_FUNCPTR( glUniformMatrix2x4fv
);
906 LOAD_FUNCPTR( glUniformMatrix3fv
);
907 LOAD_FUNCPTR( glUniformMatrix3x2fv
);
908 LOAD_FUNCPTR( glUniformMatrix3x4fv
);
909 LOAD_FUNCPTR( glUniformMatrix4fv
);
910 LOAD_FUNCPTR( glUniformMatrix4x2fv
);
911 LOAD_FUNCPTR( glUniformMatrix4x3fv
);
912 LOAD_FUNCPTR( glUnmapBuffer
);
913 LOAD_FUNCPTR( glUseProgram
);
914 LOAD_FUNCPTR( glUseProgramStages
);
915 LOAD_FUNCPTR( glValidateProgram
);
916 LOAD_FUNCPTR( glValidateProgramPipeline
);
917 LOAD_FUNCPTR( glVertexAttrib1f
);
918 LOAD_FUNCPTR( glVertexAttrib1fv
);
919 LOAD_FUNCPTR( glVertexAttrib2f
);
920 LOAD_FUNCPTR( glVertexAttrib2fv
);
921 LOAD_FUNCPTR( glVertexAttrib3f
);
922 LOAD_FUNCPTR( glVertexAttrib3fv
);
923 LOAD_FUNCPTR( glVertexAttrib4f
);
924 LOAD_FUNCPTR( glVertexAttrib4fv
);
925 LOAD_FUNCPTR( glVertexAttribBinding
);
926 LOAD_FUNCPTR( glVertexAttribDivisor
);
927 LOAD_FUNCPTR( glVertexAttribFormat
);
928 LOAD_FUNCPTR( glVertexAttribI4i
);
929 LOAD_FUNCPTR( glVertexAttribI4iv
);
930 LOAD_FUNCPTR( glVertexAttribI4ui
);
931 LOAD_FUNCPTR( glVertexAttribI4uiv
);
932 LOAD_FUNCPTR( glVertexAttribIFormat
);
933 LOAD_FUNCPTR( glVertexAttribIPointer
);
934 LOAD_FUNCPTR( glVertexAttribPointer
);
935 LOAD_FUNCPTR( glVertexBindingDivisor
);
936 LOAD_FUNCPTR( glWaitSync
);
939 /* redirect some standard OpenGL functions */
941 #define REDIRECT(func) \
942 do { p##func = egl_funcs.gl.p_##func; egl_funcs.gl.p_##func = w##func; } while(0)
948 static BOOL
egl_init(void)
950 static int retval
= -1;
952 EGLint major
, minor
, count
, i
, pass
;
955 if (retval
!= -1) return retval
;
958 if (!(egl_handle
= wine_dlopen( SONAME_LIBEGL
, RTLD_NOW
|RTLD_GLOBAL
, buffer
, sizeof(buffer
) )))
960 ERR( "failed to load %s: %s\n", SONAME_LIBEGL
, buffer
);
963 if (!(opengl_handle
= wine_dlopen( SONAME_LIBGLESV2
, RTLD_NOW
|RTLD_GLOBAL
, buffer
, sizeof(buffer
) )))
965 ERR( "failed to load %s: %s\n", SONAME_LIBGLESV2
, buffer
);
969 #define LOAD_FUNCPTR(func) do { \
970 if (!(p_##func = wine_dlsym( egl_handle, #func, NULL, 0 ))) \
971 { ERR( "can't find symbol %s\n", #func); return FALSE; } \
973 LOAD_FUNCPTR( eglCreateContext
);
974 LOAD_FUNCPTR( eglCreateWindowSurface
);
975 LOAD_FUNCPTR( eglCreatePbufferSurface
);
976 LOAD_FUNCPTR( eglDestroyContext
);
977 LOAD_FUNCPTR( eglDestroySurface
);
978 LOAD_FUNCPTR( eglGetConfigAttrib
);
979 LOAD_FUNCPTR( eglGetConfigs
);
980 LOAD_FUNCPTR( eglGetDisplay
);
981 LOAD_FUNCPTR( eglGetProcAddress
);
982 LOAD_FUNCPTR( eglInitialize
);
983 LOAD_FUNCPTR( eglMakeCurrent
);
984 LOAD_FUNCPTR( eglSwapBuffers
);
985 LOAD_FUNCPTR( eglSwapInterval
);
988 display
= p_eglGetDisplay( EGL_DEFAULT_DISPLAY
);
989 if (!p_eglInitialize( display
, &major
, &minor
)) return 0;
990 TRACE( "display %p version %u.%u\n", display
, major
, minor
);
992 p_eglGetConfigs( display
, NULL
, 0, &count
);
993 configs
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*configs
) );
994 pixel_formats
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*pixel_formats
) );
995 p_eglGetConfigs( display
, configs
, count
, &count
);
996 if (!count
|| !configs
|| !pixel_formats
)
998 HeapFree( GetProcessHeap(), 0, configs
);
999 HeapFree( GetProcessHeap(), 0, pixel_formats
);
1000 ERR( "eglGetConfigs returned no configs\n" );
1004 for (pass
= 0; pass
< 2; pass
++)
1006 for (i
= 0; i
< count
; i
++)
1008 EGLint id
, type
, visual_id
, native
, render
, color
, r
, g
, b
, d
, s
;
1010 p_eglGetConfigAttrib( display
, configs
[i
], EGL_SURFACE_TYPE
, &type
);
1011 if (!(type
& EGL_WINDOW_BIT
) == !pass
) continue;
1012 p_eglGetConfigAttrib( display
, configs
[i
], EGL_RENDERABLE_TYPE
, &render
);
1013 if (egl_client_version
== 2 && !(render
& EGL_OPENGL_ES2_BIT
)) continue;
1015 pixel_formats
[nb_pixel_formats
++].config
= configs
[i
];
1017 p_eglGetConfigAttrib( display
, configs
[i
], EGL_CONFIG_ID
, &id
);
1018 p_eglGetConfigAttrib( display
, configs
[i
], EGL_NATIVE_VISUAL_ID
, &visual_id
);
1019 p_eglGetConfigAttrib( display
, configs
[i
], EGL_NATIVE_RENDERABLE
, &native
);
1020 p_eglGetConfigAttrib( display
, configs
[i
], EGL_COLOR_BUFFER_TYPE
, &color
);
1021 p_eglGetConfigAttrib( display
, configs
[i
], EGL_RED_SIZE
, &r
);
1022 p_eglGetConfigAttrib( display
, configs
[i
], EGL_GREEN_SIZE
, &g
);
1023 p_eglGetConfigAttrib( display
, configs
[i
], EGL_BLUE_SIZE
, &b
);
1024 p_eglGetConfigAttrib( display
, configs
[i
], EGL_DEPTH_SIZE
, &d
);
1025 p_eglGetConfigAttrib( display
, configs
[i
], EGL_STENCIL_SIZE
, &s
);
1026 TRACE( "%u: config %u id %u type %x visual %u native %u render %x colortype %u rgb %u,%u,%u depth %u stencil %u\n",
1027 nb_pixel_formats
, i
, id
, type
, visual_id
, native
, render
, color
, r
, g
, b
, d
, s
);
1029 if (!pass
) nb_onscreen_formats
= nb_pixel_formats
;
1038 /* generate stubs for GL functions that are not exported on Android */
1040 #define USE_GL_FUNC(name) \
1041 static void glstub_##name(void) \
1043 ERR( #name " called\n" ); \
1051 static struct opengl_funcs egl_funcs
=
1054 android_wglCopyContext
,
1055 android_wglCreateContext
,
1056 android_wglDeleteContext
,
1057 android_wglDescribePixelFormat
,
1058 android_wglGetPixelFormat
,
1059 android_wglGetProcAddress
,
1060 android_wglMakeCurrent
,
1061 android_wglSetPixelFormat
,
1062 android_wglShareLists
,
1063 android_wglSwapBuffers
,
1065 #define USE_GL_FUNC(name) (void *)glstub_##name,
1070 struct opengl_funcs
*get_wgl_driver( UINT version
)
1072 if (version
!= WINE_WGL_DRIVER_VERSION
)
1074 ERR( "version mismatch, opengl32 wants %u but driver has %u\n", version
, WINE_WGL_DRIVER_VERSION
);
1077 if (!egl_init()) return NULL
;