d2d1/tests: Fix stroke style object leak (Valgrind).
[wine.git] / dlls / wineandroid.drv / opengl.c
blobec26000cbb28f82fd5b4766bc74c58bf41e39f03
1 /*
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
27 #include "config.h"
28 #include "wine/port.h"
30 #include <assert.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #ifdef HAVE_EGL_EGL_H
35 #include <EGL/egl.h>
36 #endif
38 #include "android.h"
39 #include "winternl.h"
41 #define GLAPIENTRY /* nothing */
42 #include "wine/wgl.h"
43 #undef GLAPIENTRY
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 );
65 #undef DECL_FUNCPTR
67 static const int egl_client_version = 2;
69 struct wgl_pixel_format
71 EGLConfig config;
74 struct wgl_context
76 struct list entry;
77 EGLConfig config;
78 EGLContext context;
79 EGLSurface surface;
80 HWND hwnd;
81 BOOL refresh;
84 struct gl_drawable
86 struct list entry;
87 HWND hwnd;
88 HDC hdc;
89 int format;
90 ANativeWindow *window;
91 EGLSurface surface;
92 EGLSurface pbuffer;
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) );
129 gl->hwnd = hwnd;
130 gl->hdc = hdc;
131 gl->format = format;
132 gl->window = create_ioctl_window( hwnd, TRUE );
133 gl->surface = 0;
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 );
137 return gl;
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 );
151 return NULL;
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 );
172 break;
174 LeaveCriticalSection( &drawable_section );
177 static BOOL refresh_context( struct wgl_context *ctx )
179 BOOL ret = InterlockedExchange( &ctx->refresh, FALSE );
181 if (ret)
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 );
187 return ret;
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 )))
197 if (!gl->surface &&
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 );
207 else
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 );
220 int prev = 0;
222 if (!hwnd || hwnd == GetDesktopWindow())
224 WARN( "not a proper window DC %p/%p\n", hdc, hwnd );
225 return FALSE;
227 if (!is_onscreen_pixel_format( format ))
229 WARN( "Invalid format %d\n", format );
230 return FALSE;
232 TRACE( "%p/%p format %d\n", hdc, hwnd, format );
234 if ((gl = get_gl_drawable( hwnd, 0 )))
236 prev = gl->format;
237 if (allow_change)
239 EGLint pf;
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 );
242 gl->format = format;
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 );
252 return FALSE;
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;
265 ctx->surface = 0;
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 );
272 return ctx;
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,
297 const int *attribs )
299 int count = 0, egl_attribs[3];
300 BOOL opengl_es = FALSE;
302 while (attribs && *attribs && count < 2)
304 switch (*attribs)
306 case WGL_CONTEXT_PROFILE_MASK_ARB:
307 if (attribs[1] == WGL_CONTEXT_ES2_PROFILE_BIT_EXT)
308 opengl_es = TRUE;
309 break;
310 case WGL_CONTEXT_MAJOR_VERSION_ARB:
311 egl_attribs[count++] = EGL_CONTEXT_CLIENT_VERSION;
312 egl_attribs[count++] = attribs[1];
313 break;
314 default:
315 FIXME("Unhandled attributes: %#x %#x\n", attribs[0], attribs[1]);
317 attribs += 2;
319 if (!opengl_es)
321 WARN("Requested creation of an OpenGL (non ES) context, that's not supported.\n");
322 return NULL;
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 )
339 BOOL ret = FALSE;
340 struct gl_drawable *draw_gl, *read_gl = NULL;
341 EGLSurface draw_surface, read_surface;
342 HWND draw_hwnd;
344 TRACE( "%p %p %p\n", draw_hdc, read_hdc, ctx );
346 if (!ctx)
348 p_eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
349 NtCurrentTeb()->glContext = NULL;
350 return TRUE;
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 );
362 if (ret)
364 ctx->surface = draw_gl->surface;
365 ctx->hwnd = draw_hwnd;
366 ctx->refresh = FALSE;
367 NtCurrentTeb()->glContext = ctx;
368 goto done;
371 SetLastError( ERROR_INVALID_HANDLE );
373 done:
374 release_gl_drawable( read_gl );
375 release_gl_drawable( draw_gl );
376 return ret;
379 /***********************************************************************
380 * android_wglSwapIntervalEXT
382 static BOOL android_wglSwapIntervalEXT( int interval )
384 BOOL ret = TRUE;
386 TRACE("(%d)\n", interval);
388 if (interval < 0)
390 SetLastError(ERROR_INVALID_DATA);
391 return FALSE;
394 ret = p_eglSwapInterval( display, interval );
396 if (ret)
397 swap_interval = interval;
398 else
399 SetLastError( ERROR_DC_NOT_FOUND );
401 return ret;
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 );
426 return FALSE;
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 )
456 EGLint val;
457 EGLConfig config;
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);
466 pfd->nVersion = 1;
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 );
474 pfd->cRedBits = 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;
503 int ret = 0;
505 if ((gl = get_gl_drawable( WindowFromDC( hdc ), hdc )))
507 ret = gl->format;
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 );
512 return ret;
515 /***********************************************************************
516 * android_wglGetProcAddress
518 static PROC android_wglGetProcAddress( LPCSTR name )
520 PROC ret;
521 if (!strncmp( name, "wgl", 3 )) return NULL;
522 ret = (PROC)p_eglGetProcAddress( name );
523 TRACE( "%s -> %p\n", name, ret );
524 return ret;
527 /***********************************************************************
528 * android_wglMakeCurrent
530 static BOOL android_wglMakeCurrent( HDC hdc, struct wgl_context *ctx )
532 BOOL ret = FALSE;
533 struct gl_drawable *gl;
534 HWND hwnd;
536 TRACE( "%p %p\n", hdc, ctx );
538 if (!ctx)
540 p_eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
541 NtCurrentTeb()->glContext = NULL;
542 return TRUE;
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 );
551 if (ret)
553 ctx->surface = gl->surface;
554 ctx->hwnd = hwnd;
555 ctx->refresh = FALSE;
556 NtCurrentTeb()->glContext = ctx;
557 goto done;
560 SetLastError( ERROR_INVALID_HANDLE );
562 done:
563 release_gl_drawable( gl );
564 return ret;
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 );
581 return FALSE;
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 );
597 return TRUE;
600 static void wglFinish(void)
602 struct wgl_context *ctx = NtCurrentTeb()->glContext;
604 if (!ctx) return;
605 TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context );
606 refresh_context( ctx );
607 pglFinish();
610 static void wglFlush(void)
612 struct wgl_context *ctx = NtCurrentTeb()->glContext;
614 if (!ctx) return;
615 TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context );
616 refresh_context( ctx );
617 pglFlush();
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)
629 void *ptr;
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;
660 ALL_WGL_FUNCS
661 #undef USE_GL_FUNC
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 );
937 #undef LOAD_FUNCPTR
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)
943 REDIRECT(glFinish);
944 REDIRECT(glFlush);
945 #undef REDIRECT
948 static BOOL egl_init(void)
950 static int retval = -1;
951 EGLConfig *configs;
952 EGLint major, minor, count, i, pass;
953 char buffer[200];
955 if (retval != -1) return retval;
956 retval = 0;
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 );
961 return FALSE;
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 );
966 return FALSE;
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; } \
972 } while(0)
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 );
986 #undef LOAD_FUNCPTR
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" );
1001 return 0;
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;
1032 init_extensions();
1033 retval = 1;
1034 return TRUE;
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" ); \
1044 assert( 0 ); \
1045 ExitProcess( 1 ); \
1048 ALL_WGL_FUNCS
1049 #undef USE_GL_FUNC
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,
1066 { ALL_WGL_FUNCS }
1067 #undef USE_GL_FUNC
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 );
1075 return NULL;
1077 if (!egl_init()) return NULL;
1078 return &egl_funcs;