gdiplus: Add GdipGetPenCompoundCount implementation.
[wine.git] / dlls / wineandroid.drv / opengl.c
blob337486ba6be1f3def044486f9526a54a2b21525b
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 #if 0
28 #pragma makedep unix
29 #endif
31 #include "config.h"
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <dlfcn.h>
38 #ifdef HAVE_EGL_EGL_H
39 #include <EGL/egl.h>
40 #endif
42 #include "android.h"
43 #include "winternl.h"
45 #define GLAPIENTRY /* nothing */
46 #include "wine/wgl.h"
47 #undef GLAPIENTRY
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 );
67 #undef DECL_FUNCPTR
69 static const int egl_client_version = 2;
71 struct wgl_pixel_format
73 EGLConfig config;
76 struct wgl_context
78 struct list entry;
79 EGLConfig config;
80 EGLContext context;
81 EGLSurface surface;
82 HWND hwnd;
83 BOOL refresh;
86 struct gl_drawable
88 struct list entry;
89 HWND hwnd;
90 HDC hdc;
91 int format;
92 ANativeWindow *window;
93 EGLSurface surface;
94 EGLSurface pbuffer;
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) );
124 gl->hwnd = hwnd;
125 gl->hdc = hdc;
126 gl->format = format;
127 gl->window = create_ioctl_window( hwnd, TRUE, 1.0f );
128 gl->surface = 0;
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 );
132 return gl;
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 );
146 return NULL;
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 );
166 free( gl );
167 break;
169 pthread_mutex_unlock( &drawable_mutex );
172 static BOOL refresh_context( struct wgl_context *ctx )
174 BOOL ret = InterlockedExchange( &ctx->refresh, FALSE );
176 if (ret)
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 );
182 return ret;
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 )))
192 if (!gl->surface &&
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 );
202 else
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 );
215 int prev = 0;
217 if (!hwnd || hwnd == NtUserGetDesktopWindow())
219 WARN( "not a proper window DC %p/%p\n", hdc, hwnd );
220 return FALSE;
222 if (!is_onscreen_pixel_format( format ))
224 WARN( "Invalid format %d\n", format );
225 return FALSE;
227 TRACE( "%p/%p format %d\n", hdc, hwnd, format );
229 if ((gl = get_gl_drawable( hwnd, 0 )))
231 prev = gl->format;
232 if (allow_change)
234 EGLint pf;
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 );
237 gl->format = format;
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 );
247 return FALSE;
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;
260 ctx->surface = 0;
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 );
267 return ctx;
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,
292 const int *attribs )
294 int count = 0, egl_attribs[3];
295 BOOL opengl_es = FALSE;
297 while (attribs && *attribs && count < 2)
299 switch (*attribs)
301 case WGL_CONTEXT_PROFILE_MASK_ARB:
302 if (attribs[1] == WGL_CONTEXT_ES2_PROFILE_BIT_EXT)
303 opengl_es = TRUE;
304 break;
305 case WGL_CONTEXT_MAJOR_VERSION_ARB:
306 egl_attribs[count++] = EGL_CONTEXT_CLIENT_VERSION;
307 egl_attribs[count++] = attribs[1];
308 break;
309 default:
310 FIXME("Unhandled attributes: %#x %#x\n", attribs[0], attribs[1]);
312 attribs += 2;
314 if (!opengl_es)
316 WARN("Requested creation of an OpenGL (non ES) context, that's not supported.\n");
317 return NULL;
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 )
334 BOOL ret = FALSE;
335 struct gl_drawable *draw_gl, *read_gl = NULL;
336 EGLSurface draw_surface, read_surface;
337 HWND draw_hwnd;
339 TRACE( "%p %p %p\n", draw_hdc, read_hdc, ctx );
341 if (!ctx)
343 p_eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
344 NtCurrentTeb()->glContext = NULL;
345 return TRUE;
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 );
357 if (ret)
359 ctx->surface = draw_gl->surface;
360 ctx->hwnd = draw_hwnd;
361 ctx->refresh = FALSE;
362 NtCurrentTeb()->glContext = ctx;
363 goto done;
366 RtlSetLastWin32Error( ERROR_INVALID_HANDLE );
368 done:
369 release_gl_drawable( read_gl );
370 release_gl_drawable( draw_gl );
371 return ret;
374 /***********************************************************************
375 * android_wglSwapIntervalEXT
377 static BOOL android_wglSwapIntervalEXT( int interval )
379 BOOL ret = TRUE;
381 TRACE("(%d)\n", interval);
383 if (interval < 0)
385 RtlSetLastWin32Error( ERROR_INVALID_DATA );
386 return FALSE;
389 ret = p_eglSwapInterval( display, interval );
391 if (ret)
392 swap_interval = interval;
393 else
394 RtlSetLastWin32Error( ERROR_DC_NOT_FOUND );
396 return ret;
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 );
421 return FALSE;
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 );
443 free( ctx );
444 return TRUE;
447 /***********************************************************************
448 * android_wglDescribePixelFormat
450 static int WINAPI android_wglDescribePixelFormat( HDC hdc, int fmt, UINT size, PIXELFORMATDESCRIPTOR *pfd )
452 EGLint val;
453 EGLConfig config;
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);
462 pfd->nVersion = 1;
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 );
470 pfd->cRedBits = 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;
499 int ret = 0;
501 if ((gl = get_gl_drawable( NtUserWindowFromDC( hdc ), hdc )))
503 ret = gl->format;
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 );
508 return ret;
511 /***********************************************************************
512 * android_wglGetProcAddress
514 static PROC WINAPI android_wglGetProcAddress( LPCSTR name )
516 PROC ret;
517 if (!strncmp( name, "wgl", 3 )) return NULL;
518 ret = (PROC)p_eglGetProcAddress( name );
519 TRACE( "%s -> %p\n", name, ret );
520 return ret;
523 /***********************************************************************
524 * android_wglMakeCurrent
526 static BOOL WINAPI android_wglMakeCurrent( HDC hdc, struct wgl_context *ctx )
528 BOOL ret = FALSE;
529 struct gl_drawable *gl;
530 HWND hwnd;
532 TRACE( "%p %p\n", hdc, ctx );
534 if (!ctx)
536 p_eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
537 NtCurrentTeb()->glContext = NULL;
538 return TRUE;
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 );
547 if (ret)
549 ctx->surface = gl->surface;
550 ctx->hwnd = hwnd;
551 ctx->refresh = FALSE;
552 NtCurrentTeb()->glContext = ctx;
553 goto done;
556 RtlSetLastWin32Error( ERROR_INVALID_HANDLE );
558 done:
559 release_gl_drawable( gl );
560 return ret;
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 );
577 return FALSE;
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 );
593 return TRUE;
596 static void wglFinish(void)
598 struct wgl_context *ctx = NtCurrentTeb()->glContext;
600 if (!ctx) return;
601 TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context );
602 refresh_context( ctx );
603 pglFinish();
606 static void wglFlush(void)
608 struct wgl_context *ctx = NtCurrentTeb()->glContext;
610 if (!ctx) return;
611 TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context );
612 refresh_context( ctx );
613 pglFlush();
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)
625 void *ptr;
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;
656 ALL_WGL_FUNCS
657 #undef USE_GL_FUNC
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 );
933 #undef LOAD_FUNCPTR
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)
939 REDIRECT(glFinish);
940 REDIRECT(glFlush);
941 #undef REDIRECT
944 static BOOL egl_init(void)
946 static int retval = -1;
947 EGLConfig *configs;
948 EGLint major, minor, count, i, pass;
950 if (retval != -1) return retval;
951 retval = 0;
953 if (!(egl_handle = dlopen( SONAME_LIBEGL, RTLD_NOW|RTLD_GLOBAL )))
955 ERR( "failed to load %s: %s\n", SONAME_LIBEGL, dlerror() );
956 return FALSE;
958 if (!(opengl_handle = dlopen( SONAME_LIBGLESV2, RTLD_NOW|RTLD_GLOBAL )))
960 ERR( "failed to load %s: %s\n", SONAME_LIBGLESV2, dlerror() );
961 return FALSE;
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; } \
967 } while(0)
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 );
981 #undef LOAD_FUNCPTR
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)
993 free( configs );
994 free( pixel_formats );
995 ERR( "eglGetConfigs returned no configs\n" );
996 return 0;
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;
1027 init_extensions();
1028 retval = 1;
1029 return TRUE;
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" ); \
1039 assert( 0 ); \
1040 ExitProcess( 1 ); \
1043 ALL_WGL_FUNCS
1044 #undef USE_GL_FUNC
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,
1061 { ALL_WGL_FUNCS }
1062 #undef USE_GL_FUNC
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 );
1070 return NULL;
1072 if (!egl_init()) return NULL;
1073 return &egl_funcs;