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
45 #define GLAPIENTRY /* nothing */
48 #include "wine/wgl_driver.h"
49 #include "wine/debug.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(android
);
53 #define DECL_FUNCPTR(f) typeof(f) * p_##f = NULL
54 DECL_FUNCPTR( eglCreateContext
);
55 DECL_FUNCPTR( eglCreateWindowSurface
);
56 DECL_FUNCPTR( eglCreatePbufferSurface
);
57 DECL_FUNCPTR( eglDestroyContext
);
58 DECL_FUNCPTR( eglDestroySurface
);
59 DECL_FUNCPTR( eglGetConfigAttrib
);
60 DECL_FUNCPTR( eglGetConfigs
);
61 DECL_FUNCPTR( eglGetDisplay
);
62 DECL_FUNCPTR( eglGetProcAddress
);
63 DECL_FUNCPTR( eglInitialize
);
64 DECL_FUNCPTR( eglMakeCurrent
);
65 DECL_FUNCPTR( eglSwapBuffers
);
66 DECL_FUNCPTR( eglSwapInterval
);
69 static const int egl_client_version
= 2;
71 struct wgl_pixel_format
92 ANativeWindow
*window
;
97 static void *egl_handle
;
98 static void *opengl_handle
;
99 static struct wgl_pixel_format
*pixel_formats
;
100 static int nb_pixel_formats
, nb_onscreen_formats
;
101 static EGLDisplay display
;
102 static int swap_interval
;
103 static char wgl_extensions
[4096];
104 static struct opengl_funcs egl_funcs
;
106 static struct list gl_contexts
= LIST_INIT( gl_contexts
);
107 static struct list gl_drawables
= LIST_INIT( gl_drawables
);
109 static void (*pglFinish
)(void);
110 static void (*pglFlush
)(void);
112 pthread_mutex_t drawable_mutex
;
114 static inline BOOL
is_onscreen_pixel_format( int format
)
116 return format
> 0 && format
<= nb_onscreen_formats
;
119 static struct gl_drawable
*create_gl_drawable( HWND hwnd
, HDC hdc
, int format
)
121 static const int attribs
[] = { EGL_WIDTH
, 1, EGL_HEIGHT
, 1, EGL_NONE
};
122 struct gl_drawable
*gl
= malloc( sizeof(*gl
) );
127 gl
->window
= create_ioctl_window( hwnd
, TRUE
, 1.0f
);
129 gl
->pbuffer
= p_eglCreatePbufferSurface( display
, pixel_formats
[gl
->format
- 1].config
, attribs
);
130 pthread_mutex_lock( &drawable_mutex
);
131 list_add_head( &gl_drawables
, &gl
->entry
);
135 static struct gl_drawable
*get_gl_drawable( HWND hwnd
, HDC hdc
)
137 struct gl_drawable
*gl
;
139 pthread_mutex_lock( &drawable_mutex
);
140 LIST_FOR_EACH_ENTRY( gl
, &gl_drawables
, struct gl_drawable
, entry
)
142 if (hwnd
&& gl
->hwnd
== hwnd
) return gl
;
143 if (hdc
&& gl
->hdc
== hdc
) return gl
;
145 pthread_mutex_unlock( &drawable_mutex
);
149 static void release_gl_drawable( struct gl_drawable
*gl
)
151 if (gl
) pthread_mutex_unlock( &drawable_mutex
);
154 void destroy_gl_drawable( HWND hwnd
)
156 struct gl_drawable
*gl
;
158 pthread_mutex_lock( &drawable_mutex
);
159 LIST_FOR_EACH_ENTRY( gl
, &gl_drawables
, struct gl_drawable
, entry
)
161 if (gl
->hwnd
!= hwnd
) continue;
162 list_remove( &gl
->entry
);
163 if (gl
->surface
) p_eglDestroySurface( display
, gl
->surface
);
164 if (gl
->pbuffer
) p_eglDestroySurface( display
, gl
->pbuffer
);
165 release_ioctl_window( gl
->window
);
169 pthread_mutex_unlock( &drawable_mutex
);
172 static BOOL
refresh_context( struct wgl_context
*ctx
)
174 BOOL ret
= InterlockedExchange( &ctx
->refresh
, FALSE
);
178 TRACE( "refreshing hwnd %p context %p surface %p\n", ctx
->hwnd
, ctx
->context
, ctx
->surface
);
179 p_eglMakeCurrent( display
, ctx
->surface
, ctx
->surface
, ctx
->context
);
180 NtUserRedrawWindow( ctx
->hwnd
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
);
185 void update_gl_drawable( HWND hwnd
)
187 struct gl_drawable
*gl
;
188 struct wgl_context
*ctx
;
190 if ((gl
= get_gl_drawable( hwnd
, 0 )))
193 (gl
->surface
= p_eglCreateWindowSurface( display
, pixel_formats
[gl
->format
- 1].config
, gl
->window
, NULL
)))
195 LIST_FOR_EACH_ENTRY( ctx
, &gl_contexts
, struct wgl_context
, entry
)
197 if (ctx
->hwnd
!= hwnd
) continue;
198 TRACE( "hwnd %p refreshing %p %scurrent\n", hwnd
, ctx
, NtCurrentTeb()->glContext
== ctx
? "" : "not " );
199 ctx
->surface
= gl
->surface
;
200 if (NtCurrentTeb()->glContext
== ctx
)
201 p_eglMakeCurrent( display
, ctx
->surface
, ctx
->surface
, ctx
->context
);
203 InterlockedExchange( &ctx
->refresh
, TRUE
);
206 release_gl_drawable( gl
);
207 NtUserRedrawWindow( hwnd
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
);
211 static BOOL
set_pixel_format( HDC hdc
, int format
, BOOL allow_change
)
213 struct gl_drawable
*gl
;
214 HWND hwnd
= NtUserWindowFromDC( hdc
);
217 if (!hwnd
|| hwnd
== NtUserGetDesktopWindow())
219 WARN( "not a proper window DC %p/%p\n", hdc
, hwnd
);
222 if (!is_onscreen_pixel_format( format
))
224 WARN( "Invalid format %d\n", format
);
227 TRACE( "%p/%p format %d\n", hdc
, hwnd
, format
);
229 if ((gl
= get_gl_drawable( hwnd
, 0 )))
235 p_eglGetConfigAttrib( display
, pixel_formats
[format
- 1].config
, EGL_NATIVE_VISUAL_ID
, &pf
);
236 gl
->window
->perform( gl
->window
, NATIVE_WINDOW_SET_BUFFERS_FORMAT
, pf
);
240 else gl
= create_gl_drawable( hwnd
, 0, format
);
242 release_gl_drawable( gl
);
244 if (prev
&& prev
!= format
&& !allow_change
) return FALSE
;
245 if (NtUserSetWindowPixelFormat( hwnd
, format
)) return TRUE
;
246 destroy_gl_drawable( hwnd
);
250 static struct wgl_context
*create_context( HDC hdc
, struct wgl_context
*share
, const int *attribs
)
252 struct gl_drawable
*gl
;
253 struct wgl_context
*ctx
;
255 if (!(gl
= get_gl_drawable( NtUserWindowFromDC( hdc
), hdc
))) return NULL
;
257 ctx
= malloc( sizeof(*ctx
) );
259 ctx
->config
= pixel_formats
[gl
->format
- 1].config
;
261 ctx
->refresh
= FALSE
;
262 ctx
->context
= p_eglCreateContext( display
, ctx
->config
,
263 share
? share
->context
: EGL_NO_CONTEXT
, attribs
);
264 TRACE( "%p fmt %d ctx %p\n", hdc
, gl
->format
, ctx
->context
);
265 list_add_head( &gl_contexts
, &ctx
->entry
);
266 release_gl_drawable( gl
);
270 /***********************************************************************
271 * android_wglGetExtensionsStringARB
273 static const char *android_wglGetExtensionsStringARB( HDC hdc
)
275 TRACE( "() returning \"%s\"\n", wgl_extensions
);
276 return wgl_extensions
;
279 /***********************************************************************
280 * android_wglGetExtensionsStringEXT
282 static const char *android_wglGetExtensionsStringEXT(void)
284 TRACE( "() returning \"%s\"\n", wgl_extensions
);
285 return wgl_extensions
;
288 /***********************************************************************
289 * android_wglCreateContextAttribsARB
291 static struct wgl_context
*android_wglCreateContextAttribsARB( HDC hdc
, struct wgl_context
*share
,
294 int count
= 0, egl_attribs
[3];
295 BOOL opengl_es
= FALSE
;
297 while (attribs
&& *attribs
&& count
< 2)
301 case WGL_CONTEXT_PROFILE_MASK_ARB
:
302 if (attribs
[1] == WGL_CONTEXT_ES2_PROFILE_BIT_EXT
)
305 case WGL_CONTEXT_MAJOR_VERSION_ARB
:
306 egl_attribs
[count
++] = EGL_CONTEXT_CLIENT_VERSION
;
307 egl_attribs
[count
++] = attribs
[1];
310 FIXME("Unhandled attributes: %#x %#x\n", attribs
[0], attribs
[1]);
316 WARN("Requested creation of an OpenGL (non ES) context, that's not supported.\n");
319 if (!count
) /* FIXME: force version if not specified */
321 egl_attribs
[count
++] = EGL_CONTEXT_CLIENT_VERSION
;
322 egl_attribs
[count
++] = egl_client_version
;
324 egl_attribs
[count
] = EGL_NONE
;
326 return create_context( hdc
, share
, egl_attribs
);
329 /***********************************************************************
330 * android_wglMakeContextCurrentARB
332 static BOOL
android_wglMakeContextCurrentARB( HDC draw_hdc
, HDC read_hdc
, struct wgl_context
*ctx
)
335 struct gl_drawable
*draw_gl
, *read_gl
= NULL
;
336 EGLSurface draw_surface
, read_surface
;
339 TRACE( "%p %p %p\n", draw_hdc
, read_hdc
, ctx
);
343 p_eglMakeCurrent( display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
344 NtCurrentTeb()->glContext
= NULL
;
348 draw_hwnd
= NtUserWindowFromDC( draw_hdc
);
349 if ((draw_gl
= get_gl_drawable( draw_hwnd
, draw_hdc
)))
351 read_gl
= get_gl_drawable( NtUserWindowFromDC( read_hdc
), read_hdc
);
352 draw_surface
= draw_gl
->surface
? draw_gl
->surface
: draw_gl
->pbuffer
;
353 read_surface
= read_gl
->surface
? read_gl
->surface
: read_gl
->pbuffer
;
354 TRACE( "%p/%p context %p surface %p/%p\n",
355 draw_hdc
, read_hdc
, ctx
->context
, draw_surface
, read_surface
);
356 ret
= p_eglMakeCurrent( display
, draw_surface
, read_surface
, ctx
->context
);
359 ctx
->surface
= draw_gl
->surface
;
360 ctx
->hwnd
= draw_hwnd
;
361 ctx
->refresh
= FALSE
;
362 NtCurrentTeb()->glContext
= ctx
;
366 RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
369 release_gl_drawable( read_gl
);
370 release_gl_drawable( draw_gl
);
374 /***********************************************************************
375 * android_wglSwapIntervalEXT
377 static BOOL
android_wglSwapIntervalEXT( int interval
)
381 TRACE("(%d)\n", interval
);
385 RtlSetLastWin32Error( ERROR_INVALID_DATA
);
389 ret
= p_eglSwapInterval( display
, interval
);
392 swap_interval
= interval
;
394 RtlSetLastWin32Error( ERROR_DC_NOT_FOUND
);
399 /***********************************************************************
400 * android_wglGetSwapIntervalEXT
402 static int android_wglGetSwapIntervalEXT(void)
404 return swap_interval
;
407 /***********************************************************************
408 * android_wglSetPixelFormatWINE
410 static BOOL
android_wglSetPixelFormatWINE( HDC hdc
, int format
)
412 return set_pixel_format( hdc
, format
, TRUE
);
415 /***********************************************************************
416 * android_wglCopyContext
418 static BOOL WINAPI
android_wglCopyContext( struct wgl_context
*src
, struct wgl_context
*dst
, UINT mask
)
420 FIXME( "%p -> %p mask %#x unsupported\n", src
, dst
, mask
);
424 /***********************************************************************
425 * android_wglCreateContext
427 static struct wgl_context
* WINAPI
android_wglCreateContext( HDC hdc
)
429 int egl_attribs
[3] = { EGL_CONTEXT_CLIENT_VERSION
, egl_client_version
, EGL_NONE
};
431 return create_context( hdc
, NULL
, egl_attribs
);
434 /***********************************************************************
435 * android_wglDeleteContext
437 static BOOL WINAPI
android_wglDeleteContext( struct wgl_context
*ctx
)
439 pthread_mutex_lock( &drawable_mutex
);
440 list_remove( &ctx
->entry
);
441 pthread_mutex_unlock( &drawable_mutex
);
442 p_eglDestroyContext( display
, ctx
->context
);
447 /***********************************************************************
448 * android_wglDescribePixelFormat
450 static int WINAPI
android_wglDescribePixelFormat( HDC hdc
, int fmt
, UINT size
, PIXELFORMATDESCRIPTOR
*pfd
)
455 if (!pfd
) return nb_onscreen_formats
;
456 if (!is_onscreen_pixel_format( fmt
)) return 0;
457 if (size
< sizeof(*pfd
)) return 0;
458 config
= pixel_formats
[fmt
- 1].config
;
460 memset( pfd
, 0, sizeof(*pfd
) );
461 pfd
->nSize
= sizeof(*pfd
);
463 pfd
->dwFlags
= PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_WINDOW
| PFD_DOUBLEBUFFER
;
464 pfd
->iPixelType
= PFD_TYPE_RGBA
;
465 pfd
->iLayerType
= PFD_MAIN_PLANE
;
467 p_eglGetConfigAttrib( display
, config
, EGL_BUFFER_SIZE
, &val
);
468 pfd
->cColorBits
= val
;
469 p_eglGetConfigAttrib( display
, config
, EGL_RED_SIZE
, &val
);
471 p_eglGetConfigAttrib( display
, config
, EGL_GREEN_SIZE
, &val
);
472 pfd
->cGreenBits
= val
;
473 p_eglGetConfigAttrib( display
, config
, EGL_BLUE_SIZE
, &val
);
474 pfd
->cBlueBits
= val
;
475 p_eglGetConfigAttrib( display
, config
, EGL_ALPHA_SIZE
, &val
);
476 pfd
->cAlphaBits
= val
;
477 p_eglGetConfigAttrib( display
, config
, EGL_DEPTH_SIZE
, &val
);
478 pfd
->cDepthBits
= val
;
479 p_eglGetConfigAttrib( display
, config
, EGL_STENCIL_SIZE
, &val
);
480 pfd
->cStencilBits
= val
;
482 pfd
->cAlphaShift
= 0;
483 pfd
->cBlueShift
= pfd
->cAlphaShift
+ pfd
->cAlphaBits
;
484 pfd
->cGreenShift
= pfd
->cBlueShift
+ pfd
->cBlueBits
;
485 pfd
->cRedShift
= pfd
->cGreenShift
+ pfd
->cGreenBits
;
487 TRACE( "fmt %u color %u %u/%u/%u/%u depth %u stencil %u\n",
488 fmt
, pfd
->cColorBits
, pfd
->cRedBits
, pfd
->cGreenBits
, pfd
->cBlueBits
,
489 pfd
->cAlphaBits
, pfd
->cDepthBits
, pfd
->cStencilBits
);
490 return nb_onscreen_formats
;
493 /***********************************************************************
494 * android_wglGetPixelFormat
496 static int WINAPI
android_wglGetPixelFormat( HDC hdc
)
498 struct gl_drawable
*gl
;
501 if ((gl
= get_gl_drawable( NtUserWindowFromDC( hdc
), hdc
)))
504 /* offscreen formats can't be used with traditional WGL calls */
505 if (!is_onscreen_pixel_format( ret
)) ret
= 1;
506 release_gl_drawable( gl
);
511 /***********************************************************************
512 * android_wglGetProcAddress
514 static PROC WINAPI
android_wglGetProcAddress( LPCSTR name
)
517 if (!strncmp( name
, "wgl", 3 )) return NULL
;
518 ret
= (PROC
)p_eglGetProcAddress( name
);
519 TRACE( "%s -> %p\n", name
, ret
);
523 /***********************************************************************
524 * android_wglMakeCurrent
526 static BOOL WINAPI
android_wglMakeCurrent( HDC hdc
, struct wgl_context
*ctx
)
529 struct gl_drawable
*gl
;
532 TRACE( "%p %p\n", hdc
, ctx
);
536 p_eglMakeCurrent( display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
537 NtCurrentTeb()->glContext
= NULL
;
541 hwnd
= NtUserWindowFromDC( hdc
);
542 if ((gl
= get_gl_drawable( hwnd
, hdc
)))
544 EGLSurface surface
= gl
->surface
? gl
->surface
: gl
->pbuffer
;
545 TRACE( "%p hwnd %p context %p surface %p\n", hdc
, gl
->hwnd
, ctx
->context
, surface
);
546 ret
= p_eglMakeCurrent( display
, surface
, surface
, ctx
->context
);
549 ctx
->surface
= gl
->surface
;
551 ctx
->refresh
= FALSE
;
552 NtCurrentTeb()->glContext
= ctx
;
556 RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
559 release_gl_drawable( gl
);
563 /***********************************************************************
564 * android_wglSetPixelFormat
566 static BOOL WINAPI
android_wglSetPixelFormat( HDC hdc
, int format
, const PIXELFORMATDESCRIPTOR
*pfd
)
568 return set_pixel_format( hdc
, format
, FALSE
);
571 /***********************************************************************
572 * android_wglShareLists
574 static BOOL WINAPI
android_wglShareLists( struct wgl_context
*org
, struct wgl_context
*dest
)
576 FIXME( "%p %p\n", org
, dest
);
580 /***********************************************************************
581 * android_wglSwapBuffers
583 static BOOL WINAPI
android_wglSwapBuffers( HDC hdc
)
585 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
587 if (!ctx
) return FALSE
;
589 TRACE( "%p hwnd %p context %p surface %p\n", hdc
, ctx
->hwnd
, ctx
->context
, ctx
->surface
);
591 if (refresh_context( ctx
)) return TRUE
;
592 if (ctx
->surface
) p_eglSwapBuffers( display
, ctx
->surface
);
596 static void wglFinish(void)
598 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
601 TRACE( "hwnd %p context %p\n", ctx
->hwnd
, ctx
->context
);
602 refresh_context( ctx
);
606 static void wglFlush(void)
608 struct wgl_context
*ctx
= NtCurrentTeb()->glContext
;
611 TRACE( "hwnd %p context %p\n", ctx
->hwnd
, ctx
->context
);
612 refresh_context( ctx
);
616 static void register_extension( const char *ext
)
618 if (wgl_extensions
[0]) strcat( wgl_extensions
, " " );
619 strcat( wgl_extensions
, ext
);
620 TRACE( "%s\n", ext
);
623 static void init_extensions(void)
627 register_extension("WGL_ARB_create_context");
628 register_extension("WGL_ARB_create_context_profile");
629 egl_funcs
.ext
.p_wglCreateContextAttribsARB
= android_wglCreateContextAttribsARB
;
631 register_extension("WGL_ARB_extensions_string");
632 egl_funcs
.ext
.p_wglGetExtensionsStringARB
= android_wglGetExtensionsStringARB
;
634 register_extension("WGL_ARB_make_current_read");
635 egl_funcs
.ext
.p_wglGetCurrentReadDCARB
= (void *)1; /* never called */
636 egl_funcs
.ext
.p_wglMakeContextCurrentARB
= android_wglMakeContextCurrentARB
;
638 register_extension("WGL_EXT_extensions_string");
639 egl_funcs
.ext
.p_wglGetExtensionsStringEXT
= android_wglGetExtensionsStringEXT
;
641 register_extension("WGL_EXT_swap_control");
642 egl_funcs
.ext
.p_wglSwapIntervalEXT
= android_wglSwapIntervalEXT
;
643 egl_funcs
.ext
.p_wglGetSwapIntervalEXT
= android_wglGetSwapIntervalEXT
;
645 register_extension("WGL_EXT_framebuffer_sRGB");
647 /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
648 * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
650 register_extension("WGL_WINE_pixel_format_passthrough");
651 egl_funcs
.ext
.p_wglSetPixelFormatWINE
= android_wglSetPixelFormatWINE
;
653 /* load standard functions and extensions exported from the OpenGL library */
655 #define USE_GL_FUNC(func) if ((ptr = dlsym( opengl_handle, #func ))) egl_funcs.gl.p_##func = ptr;
659 #define LOAD_FUNCPTR(func) egl_funcs.ext.p_##func = dlsym( opengl_handle, #func )
660 LOAD_FUNCPTR( glActiveShaderProgram
);
661 LOAD_FUNCPTR( glActiveTexture
);
662 LOAD_FUNCPTR( glAttachShader
);
663 LOAD_FUNCPTR( glBeginQuery
);
664 LOAD_FUNCPTR( glBeginTransformFeedback
);
665 LOAD_FUNCPTR( glBindAttribLocation
);
666 LOAD_FUNCPTR( glBindBuffer
);
667 LOAD_FUNCPTR( glBindBufferBase
);
668 LOAD_FUNCPTR( glBindBufferRange
);
669 LOAD_FUNCPTR( glBindFramebuffer
);
670 LOAD_FUNCPTR( glBindImageTexture
);
671 LOAD_FUNCPTR( glBindProgramPipeline
);
672 LOAD_FUNCPTR( glBindRenderbuffer
);
673 LOAD_FUNCPTR( glBindSampler
);
674 LOAD_FUNCPTR( glBindTransformFeedback
);
675 LOAD_FUNCPTR( glBindVertexArray
);
676 LOAD_FUNCPTR( glBindVertexBuffer
);
677 LOAD_FUNCPTR( glBlendBarrierKHR
);
678 LOAD_FUNCPTR( glBlendColor
);
679 LOAD_FUNCPTR( glBlendEquation
);
680 LOAD_FUNCPTR( glBlendEquationSeparate
);
681 LOAD_FUNCPTR( glBlendFuncSeparate
);
682 LOAD_FUNCPTR( glBlitFramebuffer
);
683 LOAD_FUNCPTR( glBufferData
);
684 LOAD_FUNCPTR( glBufferSubData
);
685 LOAD_FUNCPTR( glCheckFramebufferStatus
);
686 LOAD_FUNCPTR( glClearBufferfi
);
687 LOAD_FUNCPTR( glClearBufferfv
);
688 LOAD_FUNCPTR( glClearBufferiv
);
689 LOAD_FUNCPTR( glClearBufferuiv
);
690 LOAD_FUNCPTR( glClearDepthf
);
691 LOAD_FUNCPTR( glClientWaitSync
);
692 LOAD_FUNCPTR( glCompileShader
);
693 LOAD_FUNCPTR( glCompressedTexImage2D
);
694 LOAD_FUNCPTR( glCompressedTexImage3D
);
695 LOAD_FUNCPTR( glCompressedTexSubImage2D
);
696 LOAD_FUNCPTR( glCompressedTexSubImage3D
);
697 LOAD_FUNCPTR( glCopyBufferSubData
);
698 LOAD_FUNCPTR( glCopyTexSubImage3D
);
699 LOAD_FUNCPTR( glCreateProgram
);
700 LOAD_FUNCPTR( glCreateShader
);
701 LOAD_FUNCPTR( glCreateShaderProgramv
);
702 LOAD_FUNCPTR( glDeleteBuffers
);
703 LOAD_FUNCPTR( glDeleteFramebuffers
);
704 LOAD_FUNCPTR( glDeleteProgram
);
705 LOAD_FUNCPTR( glDeleteProgramPipelines
);
706 LOAD_FUNCPTR( glDeleteQueries
);
707 LOAD_FUNCPTR( glDeleteRenderbuffers
);
708 LOAD_FUNCPTR( glDeleteSamplers
);
709 LOAD_FUNCPTR( glDeleteShader
);
710 LOAD_FUNCPTR( glDeleteSync
);
711 LOAD_FUNCPTR( glDeleteTransformFeedbacks
);
712 LOAD_FUNCPTR( glDeleteVertexArrays
);
713 LOAD_FUNCPTR( glDepthRangef
);
714 LOAD_FUNCPTR( glDetachShader
);
715 LOAD_FUNCPTR( glDisableVertexAttribArray
);
716 LOAD_FUNCPTR( glDispatchCompute
);
717 LOAD_FUNCPTR( glDispatchComputeIndirect
);
718 LOAD_FUNCPTR( glDrawArraysIndirect
);
719 LOAD_FUNCPTR( glDrawArraysInstanced
);
720 LOAD_FUNCPTR( glDrawBuffers
);
721 LOAD_FUNCPTR( glDrawElementsIndirect
);
722 LOAD_FUNCPTR( glDrawElementsInstanced
);
723 LOAD_FUNCPTR( glDrawRangeElements
);
724 LOAD_FUNCPTR( glEnableVertexAttribArray
);
725 LOAD_FUNCPTR( glEndQuery
);
726 LOAD_FUNCPTR( glEndTransformFeedback
);
727 LOAD_FUNCPTR( glFenceSync
);
728 LOAD_FUNCPTR( glFlushMappedBufferRange
);
729 LOAD_FUNCPTR( glFramebufferParameteri
);
730 LOAD_FUNCPTR( glFramebufferRenderbuffer
);
731 LOAD_FUNCPTR( glFramebufferTexture2D
);
732 LOAD_FUNCPTR( glFramebufferTextureEXT
);
733 LOAD_FUNCPTR( glFramebufferTextureLayer
);
734 LOAD_FUNCPTR( glGenBuffers
);
735 LOAD_FUNCPTR( glGenFramebuffers
);
736 LOAD_FUNCPTR( glGenProgramPipelines
);
737 LOAD_FUNCPTR( glGenQueries
);
738 LOAD_FUNCPTR( glGenRenderbuffers
);
739 LOAD_FUNCPTR( glGenSamplers
);
740 LOAD_FUNCPTR( glGenTransformFeedbacks
);
741 LOAD_FUNCPTR( glGenVertexArrays
);
742 LOAD_FUNCPTR( glGenerateMipmap
);
743 LOAD_FUNCPTR( glGetActiveAttrib
);
744 LOAD_FUNCPTR( glGetActiveUniform
);
745 LOAD_FUNCPTR( glGetActiveUniformBlockName
);
746 LOAD_FUNCPTR( glGetActiveUniformBlockiv
);
747 LOAD_FUNCPTR( glGetActiveUniformsiv
);
748 LOAD_FUNCPTR( glGetAttachedShaders
);
749 LOAD_FUNCPTR( glGetAttribLocation
);
750 LOAD_FUNCPTR( glGetBooleani_v
);
751 LOAD_FUNCPTR( glGetBufferParameteri64v
);
752 LOAD_FUNCPTR( glGetBufferParameteriv
);
753 LOAD_FUNCPTR( glGetBufferPointerv
);
754 LOAD_FUNCPTR( glGetFragDataLocation
);
755 LOAD_FUNCPTR( glGetFramebufferAttachmentParameteriv
);
756 LOAD_FUNCPTR( glGetFramebufferParameteriv
);
757 LOAD_FUNCPTR( glGetInteger64i_v
);
758 LOAD_FUNCPTR( glGetInteger64v
);
759 LOAD_FUNCPTR( glGetIntegeri_v
);
760 LOAD_FUNCPTR( glGetInternalformativ
);
761 LOAD_FUNCPTR( glGetMultisamplefv
);
762 LOAD_FUNCPTR( glGetProgramBinary
);
763 LOAD_FUNCPTR( glGetProgramInfoLog
);
764 LOAD_FUNCPTR( glGetProgramInterfaceiv
);
765 LOAD_FUNCPTR( glGetProgramPipelineInfoLog
);
766 LOAD_FUNCPTR( glGetProgramPipelineiv
);
767 LOAD_FUNCPTR( glGetProgramResourceIndex
);
768 LOAD_FUNCPTR( glGetProgramResourceLocation
);
769 LOAD_FUNCPTR( glGetProgramResourceName
);
770 LOAD_FUNCPTR( glGetProgramResourceiv
);
771 LOAD_FUNCPTR( glGetProgramiv
);
772 LOAD_FUNCPTR( glGetQueryObjectuiv
);
773 LOAD_FUNCPTR( glGetQueryiv
);
774 LOAD_FUNCPTR( glGetRenderbufferParameteriv
);
775 LOAD_FUNCPTR( glGetSamplerParameterfv
);
776 LOAD_FUNCPTR( glGetSamplerParameteriv
);
777 LOAD_FUNCPTR( glGetShaderInfoLog
);
778 LOAD_FUNCPTR( glGetShaderPrecisionFormat
);
779 LOAD_FUNCPTR( glGetShaderSource
);
780 LOAD_FUNCPTR( glGetShaderiv
);
781 LOAD_FUNCPTR( glGetStringi
);
782 LOAD_FUNCPTR( glGetSynciv
);
783 LOAD_FUNCPTR( glGetTexParameterIivEXT
);
784 LOAD_FUNCPTR( glGetTexParameterIuivEXT
);
785 LOAD_FUNCPTR( glGetTransformFeedbackVarying
);
786 LOAD_FUNCPTR( glGetUniformBlockIndex
);
787 LOAD_FUNCPTR( glGetUniformIndices
);
788 LOAD_FUNCPTR( glGetUniformLocation
);
789 LOAD_FUNCPTR( glGetUniformfv
);
790 LOAD_FUNCPTR( glGetUniformiv
);
791 LOAD_FUNCPTR( glGetUniformuiv
);
792 LOAD_FUNCPTR( glGetVertexAttribIiv
);
793 LOAD_FUNCPTR( glGetVertexAttribIuiv
);
794 LOAD_FUNCPTR( glGetVertexAttribPointerv
);
795 LOAD_FUNCPTR( glGetVertexAttribfv
);
796 LOAD_FUNCPTR( glGetVertexAttribiv
);
797 LOAD_FUNCPTR( glInvalidateFramebuffer
);
798 LOAD_FUNCPTR( glInvalidateSubFramebuffer
);
799 LOAD_FUNCPTR( glIsBuffer
);
800 LOAD_FUNCPTR( glIsFramebuffer
);
801 LOAD_FUNCPTR( glIsProgram
);
802 LOAD_FUNCPTR( glIsProgramPipeline
);
803 LOAD_FUNCPTR( glIsQuery
);
804 LOAD_FUNCPTR( glIsRenderbuffer
);
805 LOAD_FUNCPTR( glIsSampler
);
806 LOAD_FUNCPTR( glIsShader
);
807 LOAD_FUNCPTR( glIsSync
);
808 LOAD_FUNCPTR( glIsTransformFeedback
);
809 LOAD_FUNCPTR( glIsVertexArray
);
810 LOAD_FUNCPTR( glLinkProgram
);
811 LOAD_FUNCPTR( glMapBufferRange
);
812 LOAD_FUNCPTR( glMemoryBarrier
);
813 LOAD_FUNCPTR( glMemoryBarrierByRegion
);
814 LOAD_FUNCPTR( glPauseTransformFeedback
);
815 LOAD_FUNCPTR( glProgramBinary
);
816 LOAD_FUNCPTR( glProgramParameteri
);
817 LOAD_FUNCPTR( glProgramUniform1f
);
818 LOAD_FUNCPTR( glProgramUniform1fv
);
819 LOAD_FUNCPTR( glProgramUniform1i
);
820 LOAD_FUNCPTR( glProgramUniform1iv
);
821 LOAD_FUNCPTR( glProgramUniform1ui
);
822 LOAD_FUNCPTR( glProgramUniform1uiv
);
823 LOAD_FUNCPTR( glProgramUniform2f
);
824 LOAD_FUNCPTR( glProgramUniform2fv
);
825 LOAD_FUNCPTR( glProgramUniform2i
);
826 LOAD_FUNCPTR( glProgramUniform2iv
);
827 LOAD_FUNCPTR( glProgramUniform2ui
);
828 LOAD_FUNCPTR( glProgramUniform2uiv
);
829 LOAD_FUNCPTR( glProgramUniform3f
);
830 LOAD_FUNCPTR( glProgramUniform3fv
);
831 LOAD_FUNCPTR( glProgramUniform3i
);
832 LOAD_FUNCPTR( glProgramUniform3iv
);
833 LOAD_FUNCPTR( glProgramUniform3ui
);
834 LOAD_FUNCPTR( glProgramUniform3uiv
);
835 LOAD_FUNCPTR( glProgramUniform4f
);
836 LOAD_FUNCPTR( glProgramUniform4fv
);
837 LOAD_FUNCPTR( glProgramUniform4i
);
838 LOAD_FUNCPTR( glProgramUniform4iv
);
839 LOAD_FUNCPTR( glProgramUniform4ui
);
840 LOAD_FUNCPTR( glProgramUniform4uiv
);
841 LOAD_FUNCPTR( glProgramUniformMatrix2fv
);
842 LOAD_FUNCPTR( glProgramUniformMatrix2x3fv
);
843 LOAD_FUNCPTR( glProgramUniformMatrix2x4fv
);
844 LOAD_FUNCPTR( glProgramUniformMatrix3fv
);
845 LOAD_FUNCPTR( glProgramUniformMatrix3x2fv
);
846 LOAD_FUNCPTR( glProgramUniformMatrix3x4fv
);
847 LOAD_FUNCPTR( glProgramUniformMatrix4fv
);
848 LOAD_FUNCPTR( glProgramUniformMatrix4x2fv
);
849 LOAD_FUNCPTR( glProgramUniformMatrix4x3fv
);
850 LOAD_FUNCPTR( glReleaseShaderCompiler
);
851 LOAD_FUNCPTR( glRenderbufferStorage
);
852 LOAD_FUNCPTR( glRenderbufferStorageMultisample
);
853 LOAD_FUNCPTR( glResumeTransformFeedback
);
854 LOAD_FUNCPTR( glSampleCoverage
);
855 LOAD_FUNCPTR( glSampleMaski
);
856 LOAD_FUNCPTR( glSamplerParameterf
);
857 LOAD_FUNCPTR( glSamplerParameterfv
);
858 LOAD_FUNCPTR( glSamplerParameteri
);
859 LOAD_FUNCPTR( glSamplerParameteriv
);
860 LOAD_FUNCPTR( glShaderBinary
);
861 LOAD_FUNCPTR( glShaderSource
);
862 LOAD_FUNCPTR( glStencilFuncSeparate
);
863 LOAD_FUNCPTR( glStencilMaskSeparate
);
864 LOAD_FUNCPTR( glStencilOpSeparate
);
865 LOAD_FUNCPTR( glTexBufferEXT
);
866 LOAD_FUNCPTR( glTexImage3D
);
867 LOAD_FUNCPTR( glTexParameterIivEXT
);
868 LOAD_FUNCPTR( glTexParameterIuivEXT
);
869 LOAD_FUNCPTR( glTexStorage2D
);
870 LOAD_FUNCPTR( glTexStorage2DMultisample
);
871 LOAD_FUNCPTR( glTexStorage3D
);
872 LOAD_FUNCPTR( glTexSubImage3D
);
873 LOAD_FUNCPTR( glTransformFeedbackVaryings
);
874 LOAD_FUNCPTR( glUniform1f
);
875 LOAD_FUNCPTR( glUniform1fv
);
876 LOAD_FUNCPTR( glUniform1i
);
877 LOAD_FUNCPTR( glUniform1iv
);
878 LOAD_FUNCPTR( glUniform1ui
);
879 LOAD_FUNCPTR( glUniform1uiv
);
880 LOAD_FUNCPTR( glUniform2f
);
881 LOAD_FUNCPTR( glUniform2fv
);
882 LOAD_FUNCPTR( glUniform2i
);
883 LOAD_FUNCPTR( glUniform2iv
);
884 LOAD_FUNCPTR( glUniform2ui
);
885 LOAD_FUNCPTR( glUniform2uiv
);
886 LOAD_FUNCPTR( glUniform3f
);
887 LOAD_FUNCPTR( glUniform3fv
);
888 LOAD_FUNCPTR( glUniform3i
);
889 LOAD_FUNCPTR( glUniform3iv
);
890 LOAD_FUNCPTR( glUniform3ui
);
891 LOAD_FUNCPTR( glUniform3uiv
);
892 LOAD_FUNCPTR( glUniform4f
);
893 LOAD_FUNCPTR( glUniform4fv
);
894 LOAD_FUNCPTR( glUniform4i
);
895 LOAD_FUNCPTR( glUniform4iv
);
896 LOAD_FUNCPTR( glUniform4ui
);
897 LOAD_FUNCPTR( glUniform4uiv
);
898 LOAD_FUNCPTR( glUniformBlockBinding
);
899 LOAD_FUNCPTR( glUniformMatrix2fv
);
900 LOAD_FUNCPTR( glUniformMatrix2x3fv
);
901 LOAD_FUNCPTR( glUniformMatrix2x4fv
);
902 LOAD_FUNCPTR( glUniformMatrix3fv
);
903 LOAD_FUNCPTR( glUniformMatrix3x2fv
);
904 LOAD_FUNCPTR( glUniformMatrix3x4fv
);
905 LOAD_FUNCPTR( glUniformMatrix4fv
);
906 LOAD_FUNCPTR( glUniformMatrix4x2fv
);
907 LOAD_FUNCPTR( glUniformMatrix4x3fv
);
908 LOAD_FUNCPTR( glUnmapBuffer
);
909 LOAD_FUNCPTR( glUseProgram
);
910 LOAD_FUNCPTR( glUseProgramStages
);
911 LOAD_FUNCPTR( glValidateProgram
);
912 LOAD_FUNCPTR( glValidateProgramPipeline
);
913 LOAD_FUNCPTR( glVertexAttrib1f
);
914 LOAD_FUNCPTR( glVertexAttrib1fv
);
915 LOAD_FUNCPTR( glVertexAttrib2f
);
916 LOAD_FUNCPTR( glVertexAttrib2fv
);
917 LOAD_FUNCPTR( glVertexAttrib3f
);
918 LOAD_FUNCPTR( glVertexAttrib3fv
);
919 LOAD_FUNCPTR( glVertexAttrib4f
);
920 LOAD_FUNCPTR( glVertexAttrib4fv
);
921 LOAD_FUNCPTR( glVertexAttribBinding
);
922 LOAD_FUNCPTR( glVertexAttribDivisor
);
923 LOAD_FUNCPTR( glVertexAttribFormat
);
924 LOAD_FUNCPTR( glVertexAttribI4i
);
925 LOAD_FUNCPTR( glVertexAttribI4iv
);
926 LOAD_FUNCPTR( glVertexAttribI4ui
);
927 LOAD_FUNCPTR( glVertexAttribI4uiv
);
928 LOAD_FUNCPTR( glVertexAttribIFormat
);
929 LOAD_FUNCPTR( glVertexAttribIPointer
);
930 LOAD_FUNCPTR( glVertexAttribPointer
);
931 LOAD_FUNCPTR( glVertexBindingDivisor
);
932 LOAD_FUNCPTR( glWaitSync
);
935 /* redirect some standard OpenGL functions */
937 #define REDIRECT(func) \
938 do { p##func = egl_funcs.gl.p_##func; egl_funcs.gl.p_##func = w##func; } while(0)
944 static BOOL
egl_init(void)
946 static int retval
= -1;
948 EGLint major
, minor
, count
, i
, pass
;
950 if (retval
!= -1) return retval
;
953 if (!(egl_handle
= dlopen( SONAME_LIBEGL
, RTLD_NOW
|RTLD_GLOBAL
)))
955 ERR( "failed to load %s: %s\n", SONAME_LIBEGL
, dlerror() );
958 if (!(opengl_handle
= dlopen( SONAME_LIBGLESV2
, RTLD_NOW
|RTLD_GLOBAL
)))
960 ERR( "failed to load %s: %s\n", SONAME_LIBGLESV2
, dlerror() );
964 #define LOAD_FUNCPTR(func) do { \
965 if (!(p_##func = dlsym( egl_handle, #func ))) \
966 { ERR( "can't find symbol %s\n", #func); return FALSE; } \
968 LOAD_FUNCPTR( eglCreateContext
);
969 LOAD_FUNCPTR( eglCreateWindowSurface
);
970 LOAD_FUNCPTR( eglCreatePbufferSurface
);
971 LOAD_FUNCPTR( eglDestroyContext
);
972 LOAD_FUNCPTR( eglDestroySurface
);
973 LOAD_FUNCPTR( eglGetConfigAttrib
);
974 LOAD_FUNCPTR( eglGetConfigs
);
975 LOAD_FUNCPTR( eglGetDisplay
);
976 LOAD_FUNCPTR( eglGetProcAddress
);
977 LOAD_FUNCPTR( eglInitialize
);
978 LOAD_FUNCPTR( eglMakeCurrent
);
979 LOAD_FUNCPTR( eglSwapBuffers
);
980 LOAD_FUNCPTR( eglSwapInterval
);
983 display
= p_eglGetDisplay( EGL_DEFAULT_DISPLAY
);
984 if (!p_eglInitialize( display
, &major
, &minor
)) return 0;
985 TRACE( "display %p version %u.%u\n", display
, major
, minor
);
987 p_eglGetConfigs( display
, NULL
, 0, &count
);
988 configs
= malloc( count
* sizeof(*configs
) );
989 pixel_formats
= malloc( count
* sizeof(*pixel_formats
) );
990 p_eglGetConfigs( display
, configs
, count
, &count
);
991 if (!count
|| !configs
|| !pixel_formats
)
994 free( pixel_formats
);
995 ERR( "eglGetConfigs returned no configs\n" );
999 for (pass
= 0; pass
< 2; pass
++)
1001 for (i
= 0; i
< count
; i
++)
1003 EGLint id
, type
, visual_id
, native
, render
, color
, r
, g
, b
, d
, s
;
1005 p_eglGetConfigAttrib( display
, configs
[i
], EGL_SURFACE_TYPE
, &type
);
1006 if (!(type
& EGL_WINDOW_BIT
) == !pass
) continue;
1007 p_eglGetConfigAttrib( display
, configs
[i
], EGL_RENDERABLE_TYPE
, &render
);
1008 if (egl_client_version
== 2 && !(render
& EGL_OPENGL_ES2_BIT
)) continue;
1010 pixel_formats
[nb_pixel_formats
++].config
= configs
[i
];
1012 p_eglGetConfigAttrib( display
, configs
[i
], EGL_CONFIG_ID
, &id
);
1013 p_eglGetConfigAttrib( display
, configs
[i
], EGL_NATIVE_VISUAL_ID
, &visual_id
);
1014 p_eglGetConfigAttrib( display
, configs
[i
], EGL_NATIVE_RENDERABLE
, &native
);
1015 p_eglGetConfigAttrib( display
, configs
[i
], EGL_COLOR_BUFFER_TYPE
, &color
);
1016 p_eglGetConfigAttrib( display
, configs
[i
], EGL_RED_SIZE
, &r
);
1017 p_eglGetConfigAttrib( display
, configs
[i
], EGL_GREEN_SIZE
, &g
);
1018 p_eglGetConfigAttrib( display
, configs
[i
], EGL_BLUE_SIZE
, &b
);
1019 p_eglGetConfigAttrib( display
, configs
[i
], EGL_DEPTH_SIZE
, &d
);
1020 p_eglGetConfigAttrib( display
, configs
[i
], EGL_STENCIL_SIZE
, &s
);
1021 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",
1022 nb_pixel_formats
, i
, id
, type
, visual_id
, native
, render
, color
, r
, g
, b
, d
, s
);
1024 if (!pass
) nb_onscreen_formats
= nb_pixel_formats
;
1033 /* generate stubs for GL functions that are not exported on Android */
1035 #define USE_GL_FUNC(name) \
1036 static void glstub_##name(void) \
1038 ERR( #name " called\n" ); \
1046 static struct opengl_funcs egl_funcs
=
1049 android_wglCopyContext
,
1050 android_wglCreateContext
,
1051 android_wglDeleteContext
,
1052 android_wglDescribePixelFormat
,
1053 android_wglGetPixelFormat
,
1054 android_wglGetProcAddress
,
1055 android_wglMakeCurrent
,
1056 android_wglSetPixelFormat
,
1057 android_wglShareLists
,
1058 android_wglSwapBuffers
,
1060 #define USE_GL_FUNC(name) (void *)glstub_##name,
1065 struct opengl_funcs
*get_wgl_driver( UINT version
)
1067 if (version
!= WINE_WGL_DRIVER_VERSION
)
1069 ERR( "version mismatch, opengl32 wants %u but driver has %u\n", version
, WINE_WGL_DRIVER_VERSION
);
1072 if (!egl_init()) return NULL
;