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/library.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(android
);
50 #define DECL_FUNCPTR(f) typeof(f) * p_##f = NULL
51 DECL_FUNCPTR( eglCreateContext
);
52 DECL_FUNCPTR( eglCreateWindowSurface
);
53 DECL_FUNCPTR( eglCreatePbufferSurface
);
54 DECL_FUNCPTR( eglDestroyContext
);
55 DECL_FUNCPTR( eglDestroySurface
);
56 DECL_FUNCPTR( eglGetConfigAttrib
);
57 DECL_FUNCPTR( eglGetConfigs
);
58 DECL_FUNCPTR( eglGetDisplay
);
59 DECL_FUNCPTR( eglGetProcAddress
);
60 DECL_FUNCPTR( eglInitialize
);
61 DECL_FUNCPTR( eglMakeCurrent
);
62 DECL_FUNCPTR( eglSwapBuffers
);
63 DECL_FUNCPTR( eglSwapInterval
);
66 static const int egl_client_version
= 2;
68 struct wgl_pixel_format
89 ANativeWindow
*window
;
94 static void *egl_handle
;
95 static void *opengl_handle
;
96 static struct wgl_pixel_format
*pixel_formats
;
97 static int nb_pixel_formats
, nb_onscreen_formats
;
98 static EGLDisplay display
;
99 static int swap_interval
;
100 static char wgl_extensions
[4096];
101 static struct opengl_funcs egl_funcs
;
103 static struct list gl_contexts
= LIST_INIT( gl_contexts
);
104 static struct list gl_drawables
= LIST_INIT( gl_drawables
);
106 static void (*pglFinish
)(void);
107 static void (*pglFlush
)(void);
109 static CRITICAL_SECTION drawable_section
;
110 static CRITICAL_SECTION_DEBUG critsect_debug
=
112 0, 0, &drawable_section
,
113 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
114 0, 0, { (DWORD_PTR
)(__FILE__
": drawable_section") }
116 static CRITICAL_SECTION drawable_section
= { &critsect_debug
, -1, 0, 0, 0, 0 };
118 static inline BOOL
is_onscreen_pixel_format( int format
)
120 return format
> 0 && format
<= nb_onscreen_formats
;
123 static struct gl_drawable
*create_gl_drawable( HWND hwnd
, HDC hdc
, int format
)
125 static const int attribs
[] = { EGL_WIDTH
, 1, EGL_HEIGHT
, 1, EGL_NONE
};
126 struct gl_drawable
*gl
= HeapAlloc( GetProcessHeap(), 0, sizeof(*gl
) );
131 gl
->window
= create_ioctl_window( hwnd
, TRUE
);
133 gl
->pbuffer
= p_eglCreatePbufferSurface( display
, pixel_formats
[gl
->format
- 1].config
, attribs
);
134 EnterCriticalSection( &drawable_section
);
135 list_add_head( &gl_drawables
, &gl
->entry
);
139 static struct gl_drawable
*get_gl_drawable( HWND hwnd
, HDC hdc
)
141 struct gl_drawable
*gl
;
143 EnterCriticalSection( &drawable_section
);
144 LIST_FOR_EACH_ENTRY( gl
, &gl_drawables
, struct gl_drawable
, entry
)
146 if (hwnd
&& gl
->hwnd
== hwnd
) return gl
;
147 if (hdc
&& gl
->hdc
== hdc
) return gl
;
149 LeaveCriticalSection( &drawable_section
);
153 static void release_gl_drawable( struct gl_drawable
*gl
)
155 if (gl
) LeaveCriticalSection( &drawable_section
);
158 void destroy_gl_drawable( HWND hwnd
)
160 struct gl_drawable
*gl
;
162 EnterCriticalSection( &drawable_section
);
163 LIST_FOR_EACH_ENTRY( gl
, &gl_drawables
, struct gl_drawable
, entry
)
165 if (gl
->hwnd
!= hwnd
) continue;
166 list_remove( &gl
->entry
);
167 if (gl
->surface
) p_eglDestroySurface( display
, gl
->surface
);
168 if (gl
->pbuffer
) p_eglDestroySurface( display
, gl
->pbuffer
);
169 release_ioctl_window( gl
->window
);
170 HeapFree( GetProcessHeap(), 0, gl
);
173 LeaveCriticalSection( &drawable_section
);
176 static BOOL
refresh_context( struct wgl_context
*ctx
)
178 BOOL ret
= InterlockedExchange( &ctx
->refresh
, FALSE
);
182 TRACE( "refreshing hwnd %p context %p surface %p\n", ctx
->hwnd
, ctx
->context
, ctx
->surface
);
183 p_eglMakeCurrent( display
, ctx
->surface
, ctx
->surface
, ctx
->context
);
184 RedrawWindow( ctx
->hwnd
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
);
189 void update_gl_drawable( HWND hwnd
)
191 struct gl_drawable
*gl
;
192 struct wgl_context
*ctx
;
194 if ((gl
= get_gl_drawable( hwnd
, 0 )))
197 (gl
->surface
= p_eglCreateWindowSurface( display
, pixel_formats
[gl
->format
- 1].config
, gl
->window
, NULL
)))
199 LIST_FOR_EACH_ENTRY( ctx
, &gl_contexts
, struct wgl_context
, entry
)
201 if (ctx
->hwnd
!= hwnd
) continue;
202 TRACE( "hwnd %p refreshing %p %scurrent\n", hwnd
, ctx
, NtCurrentTeb()->glContext
== ctx
? "" : "not " );
203 ctx
->surface
= gl
->surface
;
204 if (NtCurrentTeb()->glContext
== ctx
)
205 p_eglMakeCurrent( display
, ctx
->surface
, ctx
->surface
, ctx
->context
);
207 InterlockedExchange( &ctx
->refresh
, TRUE
);
210 release_gl_drawable( gl
);
211 RedrawWindow( hwnd
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
);
215 static BOOL
set_pixel_format( HDC hdc
, int format
, BOOL allow_change
)
217 struct gl_drawable
*gl
;
218 HWND hwnd
= WindowFromDC( hdc
);
221 if (!hwnd
|| hwnd
== GetDesktopWindow())
223 WARN( "not a proper window DC %p/%p\n", hdc
, hwnd
);
226 if (!is_onscreen_pixel_format( format
))
228 WARN( "Invalid format %d\n", format
);
231 TRACE( "%p/%p format %d\n", hdc
, hwnd
, format
);
233 if ((gl
= get_gl_drawable( hwnd
, 0 )))
239 p_eglGetConfigAttrib( display
, pixel_formats
[format
- 1].config
, EGL_NATIVE_VISUAL_ID
, &pf
);
240 gl
->window
->perform( gl
->window
, NATIVE_WINDOW_SET_BUFFERS_FORMAT
, pf
);
244 else gl
= create_gl_drawable( hwnd
, 0, format
);
246 release_gl_drawable( gl
);
248 if (prev
&& prev
!= format
&& !allow_change
) return FALSE
;
249 if (__wine_set_pixel_format( hwnd
, format
)) return TRUE
;
250 destroy_gl_drawable( hwnd
);
254 static struct wgl_context
*create_context( HDC hdc
, struct wgl_context
*share
, const int *attribs
)
256 struct gl_drawable
*gl
;
257 struct wgl_context
*ctx
;
259 if (!(gl
= get_gl_drawable( WindowFromDC( hdc
), hdc
))) return NULL
;
261 ctx
= HeapAlloc( GetProcessHeap(), 0, sizeof(*ctx
) );
263 ctx
->config
= pixel_formats
[gl
->format
- 1].config
;
265 ctx
->refresh
= FALSE
;
266 ctx
->context
= p_eglCreateContext( display
, ctx
->config
,
267 share
? share
->context
: EGL_NO_CONTEXT
, attribs
);
268 TRACE( "%p fmt %d ctx %p\n", hdc
, gl
->format
, ctx
->context
);
269 list_add_head( &gl_contexts
, &ctx
->entry
);
270 release_gl_drawable( gl
);
274 /***********************************************************************
275 * android_wglGetExtensionsStringARB
277 static const char *android_wglGetExtensionsStringARB( HDC hdc
)
279 TRACE( "() returning \"%s\"\n", wgl_extensions
);
280 return wgl_extensions
;
283 /***********************************************************************
284 * android_wglGetExtensionsStringEXT
286 static const char *android_wglGetExtensionsStringEXT(void)
288 TRACE( "() returning \"%s\"\n", wgl_extensions
);
289 return wgl_extensions
;
292 /***********************************************************************
293 * android_wglCreateContextAttribsARB
295 static struct wgl_context
*android_wglCreateContextAttribsARB( HDC hdc
, struct wgl_context
*share
,
298 int count
= 0, egl_attribs
[3];
299 BOOL opengl_es
= FALSE
;
301 while (attribs
&& *attribs
&& count
< 2)
305 case WGL_CONTEXT_PROFILE_MASK_ARB
:
306 if (attribs
[1] == WGL_CONTEXT_ES2_PROFILE_BIT_EXT
)
309 case WGL_CONTEXT_MAJOR_VERSION_ARB
:
310 egl_attribs
[count
++] = EGL_CONTEXT_CLIENT_VERSION
;
311 egl_attribs
[count
++] = attribs
[1];
314 FIXME("Unhandled attributes: %#x %#x\n", attribs
[0], attribs
[1]);
320 WARN("Requested creation of an OpenGL (non ES) context, that's not supported.\n");
323 if (!count
) /* FIXME: force version if not specified */
325 egl_attribs
[count
++] = EGL_CONTEXT_CLIENT_VERSION
;
326 egl_attribs
[count
++] = egl_client_version
;
328 egl_attribs
[count
] = EGL_NONE
;
330 return create_context( hdc
, share
, egl_attribs
);
333 /***********************************************************************
334 * android_wglMakeContextCurrentARB
336 static BOOL
android_wglMakeContextCurrentARB( HDC draw_hdc
, HDC read_hdc
, struct wgl_context
*ctx
)
339 struct gl_drawable
*draw_gl
, *read_gl
= NULL
;
340 EGLSurface draw_surface
, read_surface
;
343 TRACE( "%p %p %p\n", draw_hdc
, read_hdc
, ctx
);
347 p_eglMakeCurrent( display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
348 NtCurrentTeb()->glContext
= NULL
;
352 draw_hwnd
= WindowFromDC( draw_hdc
);
353 if ((draw_gl
= get_gl_drawable( draw_hwnd
, draw_hdc
)))
355 read_gl
= get_gl_drawable( WindowFromDC( read_hdc
), read_hdc
);
356 draw_surface
= draw_gl
->surface
? draw_gl
->surface
: draw_gl
->pbuffer
;
357 read_surface
= read_gl
->surface
? read_gl
->surface
: read_gl
->pbuffer
;
358 TRACE( "%p/%p context %p surface %p/%p\n",
359 draw_hdc
, read_hdc
, ctx
->context
, draw_surface
, read_surface
);
360 ret
= p_eglMakeCurrent( display
, draw_surface
, read_surface
, ctx
->context
);
363 ctx
->surface
= draw_gl
->surface
;
364 ctx
->hwnd
= draw_hwnd
;
365 ctx
->refresh
= FALSE
;
366 NtCurrentTeb()->glContext
= ctx
;
370 SetLastError( ERROR_INVALID_HANDLE
);
373 release_gl_drawable( read_gl
);
374 release_gl_drawable( draw_gl
);
378 /***********************************************************************
379 * android_wglSwapIntervalEXT
381 static BOOL
android_wglSwapIntervalEXT( int interval
)
385 TRACE("(%d)\n", interval
);
389 SetLastError(ERROR_INVALID_DATA
);
393 ret
= p_eglSwapInterval( display
, interval
);
396 swap_interval
= interval
;
398 SetLastError( ERROR_DC_NOT_FOUND
);
403 /***********************************************************************
404 * android_wglGetSwapIntervalEXT
406 static int android_wglGetSwapIntervalEXT(void)
408 return swap_interval
;
411 /***********************************************************************
412 * android_wglSetPixelFormatWINE
414 static BOOL
android_wglSetPixelFormatWINE( HDC hdc
, int format
)
416 return set_pixel_format( hdc
, format
, TRUE
);
419 /***********************************************************************
420 * android_wglCopyContext
422 static BOOL
android_wglCopyContext( struct wgl_context
*src
, struct wgl_context
*dst
, UINT mask
)
424 FIXME( "%p -> %p mask %#x unsupported\n", src
, dst
, mask
);
428 /***********************************************************************
429 * android_wglCreateContext
431 static struct wgl_context
*android_wglCreateContext( HDC hdc
)
433 int egl_attribs
[3] = { EGL_CONTEXT_CLIENT_VERSION
, egl_client_version
, EGL_NONE
};
435 return create_context( hdc
, NULL
, egl_attribs
);
438 /***********************************************************************
439 * android_wglDeleteContext
441 static BOOL
android_wglDeleteContext( struct wgl_context
*ctx
)
443 EnterCriticalSection( &drawable_section
);
444 list_remove( &ctx
->entry
);
445 LeaveCriticalSection( &drawable_section
);
446 p_eglDestroyContext( display
, ctx
->context
);
447 return HeapFree( GetProcessHeap(), 0, ctx
);
450 /***********************************************************************
451 * android_wglDescribePixelFormat
453 static int android_wglDescribePixelFormat( HDC hdc
, int fmt
, UINT size
, PIXELFORMATDESCRIPTOR
*pfd
)
458 if (!pfd
) return nb_onscreen_formats
;
459 if (!is_onscreen_pixel_format( fmt
)) return 0;
460 if (size
< sizeof(*pfd
)) return 0;
461 config
= pixel_formats
[fmt
- 1].config
;
463 memset( pfd
, 0, sizeof(*pfd
) );
464 pfd
->nSize
= sizeof(*pfd
);
466 pfd
->dwFlags
= PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_WINDOW
| PFD_DOUBLEBUFFER
;
467 pfd
->iPixelType
= PFD_TYPE_RGBA
;
468 pfd
->iLayerType
= PFD_MAIN_PLANE
;
470 p_eglGetConfigAttrib( display
, config
, EGL_BUFFER_SIZE
, &val
);
471 pfd
->cColorBits
= val
;
472 p_eglGetConfigAttrib( display
, config
, EGL_RED_SIZE
, &val
);
474 p_eglGetConfigAttrib( display
, config
, EGL_GREEN_SIZE
, &val
);
475 pfd
->cGreenBits
= val
;
476 p_eglGetConfigAttrib( display
, config
, EGL_BLUE_SIZE
, &val
);
477 pfd
->cBlueBits
= val
;
478 p_eglGetConfigAttrib( display
, config
, EGL_ALPHA_SIZE
, &val
);
479 pfd
->cAlphaBits
= val
;
480 p_eglGetConfigAttrib( display
, config
, EGL_DEPTH_SIZE
, &val
);
481 pfd
->cDepthBits
= val
;
482 p_eglGetConfigAttrib( display
, config
, EGL_STENCIL_SIZE
, &val
);
483 pfd
->cStencilBits
= val
;
485 pfd
->cAlphaShift
= 0;
486 pfd
->cBlueShift
= pfd
->cAlphaShift
+ pfd
->cAlphaBits
;
487 pfd
->cGreenShift
= pfd
->cBlueShift
+ pfd
->cBlueBits
;
488 pfd
->cRedShift
= pfd
->cGreenShift
+ pfd
->cGreenBits
;
490 TRACE( "fmt %u color %u %u/%u/%u/%u depth %u stencil %u\n",
491 fmt
, pfd
->cColorBits
, pfd
->cRedBits
, pfd
->cGreenBits
, pfd
->cBlueBits
,
492 pfd
->cAlphaBits
, pfd
->cDepthBits
, pfd
->cStencilBits
);
493 return nb_onscreen_formats
;
496 /***********************************************************************
497 * android_wglGetPixelFormat
499 static int android_wglGetPixelFormat( HDC hdc
)
501 struct gl_drawable
*gl
;
504 if ((gl
= get_gl_drawable( WindowFromDC( hdc
), hdc
)))
507 /* offscreen formats can't be used with traditional WGL calls */
508 if (!is_onscreen_pixel_format( ret
)) ret
= 1;
509 release_gl_drawable( gl
);
514 /***********************************************************************
515 * android_wglGetProcAddress
517 static PROC
android_wglGetProcAddress( LPCSTR name
)
520 if (!strncmp( name
, "wgl", 3 )) return NULL
;
521 ret
= (PROC
)p_eglGetProcAddress( name
);
522 TRACE( "%s -> %p\n", name
, ret
);
526 /***********************************************************************
527 * android_wglMakeCurrent
529 static BOOL
android_wglMakeCurrent( HDC hdc
, struct wgl_context
*ctx
)
532 struct gl_drawable
*gl
;
535 TRACE( "%p %p\n", hdc
, ctx
);
539 p_eglMakeCurrent( display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
540 NtCurrentTeb()->glContext
= NULL
;
544 hwnd
= WindowFromDC( hdc
);
545 if ((gl
= get_gl_drawable( hwnd
, hdc
)))
547 EGLSurface surface
= gl
->surface
? gl
->surface
: gl
->pbuffer
;
548 TRACE( "%p hwnd %p context %p surface %p\n", hdc
, gl
->hwnd
, ctx
->context
, surface
);
549 ret
= p_eglMakeCurrent( display
, surface
, surface
, ctx
->context
);
552 ctx
->surface
= gl
->surface
;
554 ctx
->refresh
= FALSE
;
555 NtCurrentTeb()->glContext
= ctx
;
559 SetLastError( ERROR_INVALID_HANDLE
);
562 release_gl_drawable( gl
);
566 /***********************************************************************
567 * android_wglSetPixelFormat
569 static BOOL
android_wglSetPixelFormat( HDC hdc
, int format
, const PIXELFORMATDESCRIPTOR
*pfd
)
571 return set_pixel_format( hdc
, format
, FALSE
);
574 /***********************************************************************
575 * android_wglShareLists
577 static BOOL
android_wglShareLists( struct wgl_context
*org
, struct wgl_context
*dest
)
579 FIXME( "%p %p\n", org
, dest
);
583 /***********************************************************************
584 * android_wglSwapBuffers
586 static BOOL
android_wglSwapBuffers( HDC hdc
)
588 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
590 if (!ctx
) return FALSE
;
592 TRACE( "%p hwnd %p context %p surface %p\n", hdc
, ctx
->hwnd
, ctx
->context
, ctx
->surface
);
594 if (refresh_context( ctx
)) return TRUE
;
595 if (ctx
->surface
) p_eglSwapBuffers( display
, ctx
->surface
);
599 static void wglFinish(void)
601 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
604 TRACE( "hwnd %p context %p\n", ctx
->hwnd
, ctx
->context
);
605 refresh_context( ctx
);
609 static void wglFlush(void)
611 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
614 TRACE( "hwnd %p context %p\n", ctx
->hwnd
, ctx
->context
);
615 refresh_context( ctx
);
619 static void register_extension( const char *ext
)
621 if (wgl_extensions
[0]) strcat( wgl_extensions
, " " );
622 strcat( wgl_extensions
, ext
);
623 TRACE( "%s\n", ext
);
626 static void init_extensions(void)
630 register_extension("WGL_ARB_create_context");
631 register_extension("WGL_ARB_create_context_profile");
632 egl_funcs
.ext
.p_wglCreateContextAttribsARB
= android_wglCreateContextAttribsARB
;
634 register_extension("WGL_ARB_extensions_string");
635 egl_funcs
.ext
.p_wglGetExtensionsStringARB
= android_wglGetExtensionsStringARB
;
637 register_extension("WGL_ARB_make_current_read");
638 egl_funcs
.ext
.p_wglGetCurrentReadDCARB
= (void *)1; /* never called */
639 egl_funcs
.ext
.p_wglMakeContextCurrentARB
= android_wglMakeContextCurrentARB
;
641 register_extension("WGL_EXT_extensions_string");
642 egl_funcs
.ext
.p_wglGetExtensionsStringEXT
= android_wglGetExtensionsStringEXT
;
644 register_extension("WGL_EXT_swap_control");
645 egl_funcs
.ext
.p_wglSwapIntervalEXT
= android_wglSwapIntervalEXT
;
646 egl_funcs
.ext
.p_wglGetSwapIntervalEXT
= android_wglGetSwapIntervalEXT
;
648 register_extension("WGL_EXT_framebuffer_sRGB");
650 /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
651 * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
653 register_extension("WGL_WINE_pixel_format_passthrough");
654 egl_funcs
.ext
.p_wglSetPixelFormatWINE
= android_wglSetPixelFormatWINE
;
656 /* load standard functions and extensions exported from the OpenGL library */
658 #define USE_GL_FUNC(func) if ((ptr = wine_dlsym( opengl_handle, #func, NULL, 0 ))) egl_funcs.gl.p_##func = ptr;
662 #define LOAD_FUNCPTR(func) egl_funcs.ext.p_##func = wine_dlsym( opengl_handle, #func, NULL, 0 )
663 LOAD_FUNCPTR( glActiveShaderProgram
);
664 LOAD_FUNCPTR( glActiveTexture
);
665 LOAD_FUNCPTR( glAttachShader
);
666 LOAD_FUNCPTR( glBeginQuery
);
667 LOAD_FUNCPTR( glBeginTransformFeedback
);
668 LOAD_FUNCPTR( glBindAttribLocation
);
669 LOAD_FUNCPTR( glBindBuffer
);
670 LOAD_FUNCPTR( glBindBufferBase
);
671 LOAD_FUNCPTR( glBindBufferRange
);
672 LOAD_FUNCPTR( glBindFramebuffer
);
673 LOAD_FUNCPTR( glBindImageTexture
);
674 LOAD_FUNCPTR( glBindProgramPipeline
);
675 LOAD_FUNCPTR( glBindRenderbuffer
);
676 LOAD_FUNCPTR( glBindSampler
);
677 LOAD_FUNCPTR( glBindTransformFeedback
);
678 LOAD_FUNCPTR( glBindVertexArray
);
679 LOAD_FUNCPTR( glBindVertexBuffer
);
680 LOAD_FUNCPTR( glBlendBarrierKHR
);
681 LOAD_FUNCPTR( glBlendColor
);
682 LOAD_FUNCPTR( glBlendEquation
);
683 LOAD_FUNCPTR( glBlendEquationSeparate
);
684 LOAD_FUNCPTR( glBlendFuncSeparate
);
685 LOAD_FUNCPTR( glBlitFramebuffer
);
686 LOAD_FUNCPTR( glBufferData
);
687 LOAD_FUNCPTR( glBufferSubData
);
688 LOAD_FUNCPTR( glCheckFramebufferStatus
);
689 LOAD_FUNCPTR( glClearBufferfi
);
690 LOAD_FUNCPTR( glClearBufferfv
);
691 LOAD_FUNCPTR( glClearBufferiv
);
692 LOAD_FUNCPTR( glClearBufferuiv
);
693 LOAD_FUNCPTR( glClearDepthf
);
694 LOAD_FUNCPTR( glClientWaitSync
);
695 LOAD_FUNCPTR( glCompileShader
);
696 LOAD_FUNCPTR( glCompressedTexImage2D
);
697 LOAD_FUNCPTR( glCompressedTexImage3D
);
698 LOAD_FUNCPTR( glCompressedTexSubImage2D
);
699 LOAD_FUNCPTR( glCompressedTexSubImage3D
);
700 LOAD_FUNCPTR( glCopyBufferSubData
);
701 LOAD_FUNCPTR( glCopyTexSubImage3D
);
702 LOAD_FUNCPTR( glCreateProgram
);
703 LOAD_FUNCPTR( glCreateShader
);
704 LOAD_FUNCPTR( glCreateShaderProgramv
);
705 LOAD_FUNCPTR( glDeleteBuffers
);
706 LOAD_FUNCPTR( glDeleteFramebuffers
);
707 LOAD_FUNCPTR( glDeleteProgram
);
708 LOAD_FUNCPTR( glDeleteProgramPipelines
);
709 LOAD_FUNCPTR( glDeleteQueries
);
710 LOAD_FUNCPTR( glDeleteRenderbuffers
);
711 LOAD_FUNCPTR( glDeleteSamplers
);
712 LOAD_FUNCPTR( glDeleteShader
);
713 LOAD_FUNCPTR( glDeleteSync
);
714 LOAD_FUNCPTR( glDeleteTransformFeedbacks
);
715 LOAD_FUNCPTR( glDeleteVertexArrays
);
716 LOAD_FUNCPTR( glDepthRangef
);
717 LOAD_FUNCPTR( glDetachShader
);
718 LOAD_FUNCPTR( glDisableVertexAttribArray
);
719 LOAD_FUNCPTR( glDispatchCompute
);
720 LOAD_FUNCPTR( glDispatchComputeIndirect
);
721 LOAD_FUNCPTR( glDrawArraysIndirect
);
722 LOAD_FUNCPTR( glDrawArraysInstanced
);
723 LOAD_FUNCPTR( glDrawBuffers
);
724 LOAD_FUNCPTR( glDrawElementsIndirect
);
725 LOAD_FUNCPTR( glDrawElementsInstanced
);
726 LOAD_FUNCPTR( glDrawRangeElements
);
727 LOAD_FUNCPTR( glEnableVertexAttribArray
);
728 LOAD_FUNCPTR( glEndQuery
);
729 LOAD_FUNCPTR( glEndTransformFeedback
);
730 LOAD_FUNCPTR( glFenceSync
);
731 LOAD_FUNCPTR( glFlushMappedBufferRange
);
732 LOAD_FUNCPTR( glFramebufferParameteri
);
733 LOAD_FUNCPTR( glFramebufferRenderbuffer
);
734 LOAD_FUNCPTR( glFramebufferTexture2D
);
735 LOAD_FUNCPTR( glFramebufferTextureEXT
);
736 LOAD_FUNCPTR( glFramebufferTextureLayer
);
737 LOAD_FUNCPTR( glGenBuffers
);
738 LOAD_FUNCPTR( glGenFramebuffers
);
739 LOAD_FUNCPTR( glGenProgramPipelines
);
740 LOAD_FUNCPTR( glGenQueries
);
741 LOAD_FUNCPTR( glGenRenderbuffers
);
742 LOAD_FUNCPTR( glGenSamplers
);
743 LOAD_FUNCPTR( glGenTransformFeedbacks
);
744 LOAD_FUNCPTR( glGenVertexArrays
);
745 LOAD_FUNCPTR( glGenerateMipmap
);
746 LOAD_FUNCPTR( glGetActiveAttrib
);
747 LOAD_FUNCPTR( glGetActiveUniform
);
748 LOAD_FUNCPTR( glGetActiveUniformBlockName
);
749 LOAD_FUNCPTR( glGetActiveUniformBlockiv
);
750 LOAD_FUNCPTR( glGetActiveUniformsiv
);
751 LOAD_FUNCPTR( glGetAttachedShaders
);
752 LOAD_FUNCPTR( glGetAttribLocation
);
753 LOAD_FUNCPTR( glGetBooleani_v
);
754 LOAD_FUNCPTR( glGetBufferParameteri64v
);
755 LOAD_FUNCPTR( glGetBufferParameteriv
);
756 LOAD_FUNCPTR( glGetBufferPointerv
);
757 LOAD_FUNCPTR( glGetFragDataLocation
);
758 LOAD_FUNCPTR( glGetFramebufferAttachmentParameteriv
);
759 LOAD_FUNCPTR( glGetFramebufferParameteriv
);
760 LOAD_FUNCPTR( glGetInteger64i_v
);
761 LOAD_FUNCPTR( glGetInteger64v
);
762 LOAD_FUNCPTR( glGetIntegeri_v
);
763 LOAD_FUNCPTR( glGetInternalformativ
);
764 LOAD_FUNCPTR( glGetMultisamplefv
);
765 LOAD_FUNCPTR( glGetProgramBinary
);
766 LOAD_FUNCPTR( glGetProgramInfoLog
);
767 LOAD_FUNCPTR( glGetProgramInterfaceiv
);
768 LOAD_FUNCPTR( glGetProgramPipelineInfoLog
);
769 LOAD_FUNCPTR( glGetProgramPipelineiv
);
770 LOAD_FUNCPTR( glGetProgramResourceIndex
);
771 LOAD_FUNCPTR( glGetProgramResourceLocation
);
772 LOAD_FUNCPTR( glGetProgramResourceName
);
773 LOAD_FUNCPTR( glGetProgramResourceiv
);
774 LOAD_FUNCPTR( glGetProgramiv
);
775 LOAD_FUNCPTR( glGetQueryObjectuiv
);
776 LOAD_FUNCPTR( glGetQueryiv
);
777 LOAD_FUNCPTR( glGetRenderbufferParameteriv
);
778 LOAD_FUNCPTR( glGetSamplerParameterfv
);
779 LOAD_FUNCPTR( glGetSamplerParameteriv
);
780 LOAD_FUNCPTR( glGetShaderInfoLog
);
781 LOAD_FUNCPTR( glGetShaderPrecisionFormat
);
782 LOAD_FUNCPTR( glGetShaderSource
);
783 LOAD_FUNCPTR( glGetShaderiv
);
784 LOAD_FUNCPTR( glGetStringi
);
785 LOAD_FUNCPTR( glGetSynciv
);
786 LOAD_FUNCPTR( glGetTexParameterIivEXT
);
787 LOAD_FUNCPTR( glGetTexParameterIuivEXT
);
788 LOAD_FUNCPTR( glGetTransformFeedbackVarying
);
789 LOAD_FUNCPTR( glGetUniformBlockIndex
);
790 LOAD_FUNCPTR( glGetUniformIndices
);
791 LOAD_FUNCPTR( glGetUniformLocation
);
792 LOAD_FUNCPTR( glGetUniformfv
);
793 LOAD_FUNCPTR( glGetUniformiv
);
794 LOAD_FUNCPTR( glGetUniformuiv
);
795 LOAD_FUNCPTR( glGetVertexAttribIiv
);
796 LOAD_FUNCPTR( glGetVertexAttribIuiv
);
797 LOAD_FUNCPTR( glGetVertexAttribPointerv
);
798 LOAD_FUNCPTR( glGetVertexAttribfv
);
799 LOAD_FUNCPTR( glGetVertexAttribiv
);
800 LOAD_FUNCPTR( glInvalidateFramebuffer
);
801 LOAD_FUNCPTR( glInvalidateSubFramebuffer
);
802 LOAD_FUNCPTR( glIsBuffer
);
803 LOAD_FUNCPTR( glIsFramebuffer
);
804 LOAD_FUNCPTR( glIsProgram
);
805 LOAD_FUNCPTR( glIsProgramPipeline
);
806 LOAD_FUNCPTR( glIsQuery
);
807 LOAD_FUNCPTR( glIsRenderbuffer
);
808 LOAD_FUNCPTR( glIsSampler
);
809 LOAD_FUNCPTR( glIsShader
);
810 LOAD_FUNCPTR( glIsSync
);
811 LOAD_FUNCPTR( glIsTransformFeedback
);
812 LOAD_FUNCPTR( glIsVertexArray
);
813 LOAD_FUNCPTR( glLinkProgram
);
814 LOAD_FUNCPTR( glMapBufferRange
);
815 LOAD_FUNCPTR( glMemoryBarrier
);
816 LOAD_FUNCPTR( glMemoryBarrierByRegion
);
817 LOAD_FUNCPTR( glPauseTransformFeedback
);
818 LOAD_FUNCPTR( glProgramBinary
);
819 LOAD_FUNCPTR( glProgramParameteri
);
820 LOAD_FUNCPTR( glProgramUniform1f
);
821 LOAD_FUNCPTR( glProgramUniform1fv
);
822 LOAD_FUNCPTR( glProgramUniform1i
);
823 LOAD_FUNCPTR( glProgramUniform1iv
);
824 LOAD_FUNCPTR( glProgramUniform1ui
);
825 LOAD_FUNCPTR( glProgramUniform1uiv
);
826 LOAD_FUNCPTR( glProgramUniform2f
);
827 LOAD_FUNCPTR( glProgramUniform2fv
);
828 LOAD_FUNCPTR( glProgramUniform2i
);
829 LOAD_FUNCPTR( glProgramUniform2iv
);
830 LOAD_FUNCPTR( glProgramUniform2ui
);
831 LOAD_FUNCPTR( glProgramUniform2uiv
);
832 LOAD_FUNCPTR( glProgramUniform3f
);
833 LOAD_FUNCPTR( glProgramUniform3fv
);
834 LOAD_FUNCPTR( glProgramUniform3i
);
835 LOAD_FUNCPTR( glProgramUniform3iv
);
836 LOAD_FUNCPTR( glProgramUniform3ui
);
837 LOAD_FUNCPTR( glProgramUniform3uiv
);
838 LOAD_FUNCPTR( glProgramUniform4f
);
839 LOAD_FUNCPTR( glProgramUniform4fv
);
840 LOAD_FUNCPTR( glProgramUniform4i
);
841 LOAD_FUNCPTR( glProgramUniform4iv
);
842 LOAD_FUNCPTR( glProgramUniform4ui
);
843 LOAD_FUNCPTR( glProgramUniform4uiv
);
844 LOAD_FUNCPTR( glProgramUniformMatrix2fv
);
845 LOAD_FUNCPTR( glProgramUniformMatrix2x3fv
);
846 LOAD_FUNCPTR( glProgramUniformMatrix2x4fv
);
847 LOAD_FUNCPTR( glProgramUniformMatrix3fv
);
848 LOAD_FUNCPTR( glProgramUniformMatrix3x2fv
);
849 LOAD_FUNCPTR( glProgramUniformMatrix3x4fv
);
850 LOAD_FUNCPTR( glProgramUniformMatrix4fv
);
851 LOAD_FUNCPTR( glProgramUniformMatrix4x2fv
);
852 LOAD_FUNCPTR( glProgramUniformMatrix4x3fv
);
853 LOAD_FUNCPTR( glReleaseShaderCompiler
);
854 LOAD_FUNCPTR( glRenderbufferStorage
);
855 LOAD_FUNCPTR( glRenderbufferStorageMultisample
);
856 LOAD_FUNCPTR( glResumeTransformFeedback
);
857 LOAD_FUNCPTR( glSampleCoverage
);
858 LOAD_FUNCPTR( glSampleMaski
);
859 LOAD_FUNCPTR( glSamplerParameterf
);
860 LOAD_FUNCPTR( glSamplerParameterfv
);
861 LOAD_FUNCPTR( glSamplerParameteri
);
862 LOAD_FUNCPTR( glSamplerParameteriv
);
863 LOAD_FUNCPTR( glShaderBinary
);
864 LOAD_FUNCPTR( glShaderSource
);
865 LOAD_FUNCPTR( glStencilFuncSeparate
);
866 LOAD_FUNCPTR( glStencilMaskSeparate
);
867 LOAD_FUNCPTR( glStencilOpSeparate
);
868 LOAD_FUNCPTR( glTexBufferEXT
);
869 LOAD_FUNCPTR( glTexImage3D
);
870 LOAD_FUNCPTR( glTexParameterIivEXT
);
871 LOAD_FUNCPTR( glTexParameterIuivEXT
);
872 LOAD_FUNCPTR( glTexStorage2D
);
873 LOAD_FUNCPTR( glTexStorage2DMultisample
);
874 LOAD_FUNCPTR( glTexStorage3D
);
875 LOAD_FUNCPTR( glTexSubImage3D
);
876 LOAD_FUNCPTR( glTransformFeedbackVaryings
);
877 LOAD_FUNCPTR( glUniform1f
);
878 LOAD_FUNCPTR( glUniform1fv
);
879 LOAD_FUNCPTR( glUniform1i
);
880 LOAD_FUNCPTR( glUniform1iv
);
881 LOAD_FUNCPTR( glUniform1ui
);
882 LOAD_FUNCPTR( glUniform1uiv
);
883 LOAD_FUNCPTR( glUniform2f
);
884 LOAD_FUNCPTR( glUniform2fv
);
885 LOAD_FUNCPTR( glUniform2i
);
886 LOAD_FUNCPTR( glUniform2iv
);
887 LOAD_FUNCPTR( glUniform2ui
);
888 LOAD_FUNCPTR( glUniform2uiv
);
889 LOAD_FUNCPTR( glUniform3f
);
890 LOAD_FUNCPTR( glUniform3fv
);
891 LOAD_FUNCPTR( glUniform3i
);
892 LOAD_FUNCPTR( glUniform3iv
);
893 LOAD_FUNCPTR( glUniform3ui
);
894 LOAD_FUNCPTR( glUniform3uiv
);
895 LOAD_FUNCPTR( glUniform4f
);
896 LOAD_FUNCPTR( glUniform4fv
);
897 LOAD_FUNCPTR( glUniform4i
);
898 LOAD_FUNCPTR( glUniform4iv
);
899 LOAD_FUNCPTR( glUniform4ui
);
900 LOAD_FUNCPTR( glUniform4uiv
);
901 LOAD_FUNCPTR( glUniformBlockBinding
);
902 LOAD_FUNCPTR( glUniformMatrix2fv
);
903 LOAD_FUNCPTR( glUniformMatrix2x3fv
);
904 LOAD_FUNCPTR( glUniformMatrix2x4fv
);
905 LOAD_FUNCPTR( glUniformMatrix3fv
);
906 LOAD_FUNCPTR( glUniformMatrix3x2fv
);
907 LOAD_FUNCPTR( glUniformMatrix3x4fv
);
908 LOAD_FUNCPTR( glUniformMatrix4fv
);
909 LOAD_FUNCPTR( glUniformMatrix4x2fv
);
910 LOAD_FUNCPTR( glUniformMatrix4x3fv
);
911 LOAD_FUNCPTR( glUnmapBuffer
);
912 LOAD_FUNCPTR( glUseProgram
);
913 LOAD_FUNCPTR( glUseProgramStages
);
914 LOAD_FUNCPTR( glValidateProgram
);
915 LOAD_FUNCPTR( glValidateProgramPipeline
);
916 LOAD_FUNCPTR( glVertexAttrib1f
);
917 LOAD_FUNCPTR( glVertexAttrib1fv
);
918 LOAD_FUNCPTR( glVertexAttrib2f
);
919 LOAD_FUNCPTR( glVertexAttrib2fv
);
920 LOAD_FUNCPTR( glVertexAttrib3f
);
921 LOAD_FUNCPTR( glVertexAttrib3fv
);
922 LOAD_FUNCPTR( glVertexAttrib4f
);
923 LOAD_FUNCPTR( glVertexAttrib4fv
);
924 LOAD_FUNCPTR( glVertexAttribBinding
);
925 LOAD_FUNCPTR( glVertexAttribDivisor
);
926 LOAD_FUNCPTR( glVertexAttribFormat
);
927 LOAD_FUNCPTR( glVertexAttribI4i
);
928 LOAD_FUNCPTR( glVertexAttribI4iv
);
929 LOAD_FUNCPTR( glVertexAttribI4ui
);
930 LOAD_FUNCPTR( glVertexAttribI4uiv
);
931 LOAD_FUNCPTR( glVertexAttribIFormat
);
932 LOAD_FUNCPTR( glVertexAttribIPointer
);
933 LOAD_FUNCPTR( glVertexAttribPointer
);
934 LOAD_FUNCPTR( glVertexBindingDivisor
);
935 LOAD_FUNCPTR( glWaitSync
);
938 /* redirect some standard OpenGL functions */
940 #define REDIRECT(func) \
941 do { p##func = egl_funcs.gl.p_##func; egl_funcs.gl.p_##func = w##func; } while(0)
947 static BOOL
egl_init(void)
949 static int retval
= -1;
951 EGLint major
, minor
, count
, i
, pass
;
954 if (retval
!= -1) return retval
;
957 if (!(egl_handle
= wine_dlopen( SONAME_LIBEGL
, RTLD_NOW
|RTLD_GLOBAL
, buffer
, sizeof(buffer
) )))
959 ERR( "failed to load %s: %s\n", SONAME_LIBEGL
, buffer
);
962 if (!(opengl_handle
= wine_dlopen( SONAME_LIBGLESV2
, RTLD_NOW
|RTLD_GLOBAL
, buffer
, sizeof(buffer
) )))
964 ERR( "failed to load %s: %s\n", SONAME_LIBGLESV2
, buffer
);
968 #define LOAD_FUNCPTR(func) do { \
969 if (!(p_##func = wine_dlsym( egl_handle, #func, NULL, 0 ))) \
970 { ERR( "can't find symbol %s\n", #func); return FALSE; } \
972 LOAD_FUNCPTR( eglCreateContext
);
973 LOAD_FUNCPTR( eglCreateWindowSurface
);
974 LOAD_FUNCPTR( eglCreatePbufferSurface
);
975 LOAD_FUNCPTR( eglDestroyContext
);
976 LOAD_FUNCPTR( eglDestroySurface
);
977 LOAD_FUNCPTR( eglGetConfigAttrib
);
978 LOAD_FUNCPTR( eglGetConfigs
);
979 LOAD_FUNCPTR( eglGetDisplay
);
980 LOAD_FUNCPTR( eglGetProcAddress
);
981 LOAD_FUNCPTR( eglInitialize
);
982 LOAD_FUNCPTR( eglMakeCurrent
);
983 LOAD_FUNCPTR( eglSwapBuffers
);
984 LOAD_FUNCPTR( eglSwapInterval
);
987 display
= p_eglGetDisplay( EGL_DEFAULT_DISPLAY
);
988 if (!p_eglInitialize( display
, &major
, &minor
)) return 0;
989 TRACE( "display %p version %u.%u\n", display
, major
, minor
);
991 p_eglGetConfigs( display
, NULL
, 0, &count
);
992 configs
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*configs
) );
993 pixel_formats
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*pixel_formats
) );
994 p_eglGetConfigs( display
, configs
, count
, &count
);
995 if (!count
|| !configs
|| !pixel_formats
)
997 HeapFree( GetProcessHeap(), 0, configs
);
998 HeapFree( GetProcessHeap(), 0, pixel_formats
);
999 ERR( "eglGetConfigs returned no configs\n" );
1003 for (pass
= 0; pass
< 2; pass
++)
1005 for (i
= 0; i
< count
; i
++)
1007 EGLint id
, type
, visual_id
, native
, render
, color
, r
, g
, b
, d
, s
;
1009 p_eglGetConfigAttrib( display
, configs
[i
], EGL_SURFACE_TYPE
, &type
);
1010 if (!(type
& EGL_WINDOW_BIT
) == !pass
) continue;
1011 p_eglGetConfigAttrib( display
, configs
[i
], EGL_RENDERABLE_TYPE
, &render
);
1012 if (egl_client_version
== 2 && !(render
& EGL_OPENGL_ES2_BIT
)) continue;
1014 pixel_formats
[nb_pixel_formats
++].config
= configs
[i
];
1016 p_eglGetConfigAttrib( display
, configs
[i
], EGL_CONFIG_ID
, &id
);
1017 p_eglGetConfigAttrib( display
, configs
[i
], EGL_NATIVE_VISUAL_ID
, &visual_id
);
1018 p_eglGetConfigAttrib( display
, configs
[i
], EGL_NATIVE_RENDERABLE
, &native
);
1019 p_eglGetConfigAttrib( display
, configs
[i
], EGL_COLOR_BUFFER_TYPE
, &color
);
1020 p_eglGetConfigAttrib( display
, configs
[i
], EGL_RED_SIZE
, &r
);
1021 p_eglGetConfigAttrib( display
, configs
[i
], EGL_GREEN_SIZE
, &g
);
1022 p_eglGetConfigAttrib( display
, configs
[i
], EGL_BLUE_SIZE
, &b
);
1023 p_eglGetConfigAttrib( display
, configs
[i
], EGL_DEPTH_SIZE
, &d
);
1024 p_eglGetConfigAttrib( display
, configs
[i
], EGL_STENCIL_SIZE
, &s
);
1025 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",
1026 nb_pixel_formats
, i
, id
, type
, visual_id
, native
, render
, color
, r
, g
, b
, d
, s
);
1028 if (!pass
) nb_onscreen_formats
= nb_pixel_formats
;
1037 /* generate stubs for GL functions that are not exported on Android */
1039 #define USE_GL_FUNC(name) \
1040 static void glstub_##name(void) \
1042 ERR( #name " called\n" ); \
1050 static struct opengl_funcs egl_funcs
=
1053 android_wglCopyContext
,
1054 android_wglCreateContext
,
1055 android_wglDeleteContext
,
1056 android_wglDescribePixelFormat
,
1057 android_wglGetPixelFormat
,
1058 android_wglGetProcAddress
,
1059 android_wglMakeCurrent
,
1060 android_wglSetPixelFormat
,
1061 android_wglShareLists
,
1062 android_wglSwapBuffers
,
1064 #define USE_GL_FUNC(name) (void *)glstub_##name,
1069 struct opengl_funcs
*get_wgl_driver( UINT version
)
1071 if (version
!= WINE_WGL_DRIVER_VERSION
)
1073 ERR( "version mismatch, opengl32 wants %u but driver has %u\n", version
, WINE_WGL_DRIVER_VERSION
);
1076 if (!egl_init()) return NULL
;