Commit 01439ef5 authored by Alexandre Julliard's avatar Alexandre Julliard

wineandroid: Create a proper EGL window surface once we receive a surface from Java.

parent 1f736b5f
...@@ -52,6 +52,7 @@ DECL_FUNCPTR( ANativeWindow_release ); ...@@ -52,6 +52,7 @@ DECL_FUNCPTR( ANativeWindow_release );
* OpenGL driver * OpenGL driver
*/ */
extern void update_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN; extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern struct opengl_funcs *get_wgl_driver( UINT version ) DECLSPEC_HIDDEN; extern struct opengl_funcs *get_wgl_driver( UINT version ) DECLSPEC_HIDDEN;
......
...@@ -461,7 +461,7 @@ static void CALLBACK register_native_window_callback( ULONG_PTR arg1, ULONG_PTR ...@@ -461,7 +461,7 @@ static void CALLBACK register_native_window_callback( ULONG_PTR arg1, ULONG_PTR
if (!data || data->parent == win) if (!data || data->parent == win)
{ {
if (win) pANativeWindow_release( win ); if (win) pANativeWindow_release( win );
if (data && win) PostMessageW( hwnd, WM_ANDROID_REFRESH, 0, 0 ); if (data && win) PostMessageW( hwnd, WM_ANDROID_REFRESH, opengl, 0 );
TRACE( "%p -> %p win %p (unchanged)\n", hwnd, data, win ); TRACE( "%p -> %p win %p (unchanged)\n", hwnd, data, win );
return; return;
} }
...@@ -475,7 +475,7 @@ static void CALLBACK register_native_window_callback( ULONG_PTR arg1, ULONG_PTR ...@@ -475,7 +475,7 @@ static void CALLBACK register_native_window_callback( ULONG_PTR arg1, ULONG_PTR
win->perform( win, NATIVE_WINDOW_SET_BUFFERS_FORMAT, data->buffer_format ); win->perform( win, NATIVE_WINDOW_SET_BUFFERS_FORMAT, data->buffer_format );
win->setSwapInterval( win, data->swap_interval ); win->setSwapInterval( win, data->swap_interval );
unwrap_java_call(); unwrap_java_call();
PostMessageW( hwnd, WM_ANDROID_REFRESH, 0, 0 ); PostMessageW( hwnd, WM_ANDROID_REFRESH, opengl, 0 );
} }
TRACE( "%p -> %p win %p\n", hwnd, data, win ); TRACE( "%p -> %p win %p\n", hwnd, data, win );
} }
......
...@@ -76,7 +76,9 @@ struct wgl_context ...@@ -76,7 +76,9 @@ struct wgl_context
struct list entry; struct list entry;
EGLConfig config; EGLConfig config;
EGLContext context; EGLContext context;
EGLSurface surface;
HWND hwnd; HWND hwnd;
BOOL refresh;
}; };
struct gl_drawable struct gl_drawable
...@@ -86,6 +88,7 @@ struct gl_drawable ...@@ -86,6 +88,7 @@ struct gl_drawable
HDC hdc; HDC hdc;
int format; int format;
ANativeWindow *window; ANativeWindow *window;
EGLSurface surface;
EGLSurface pbuffer; EGLSurface pbuffer;
}; };
...@@ -100,6 +103,9 @@ static struct opengl_funcs egl_funcs; ...@@ -100,6 +103,9 @@ static struct opengl_funcs egl_funcs;
static struct list gl_contexts = LIST_INIT( gl_contexts ); static struct list gl_contexts = LIST_INIT( gl_contexts );
static struct list gl_drawables = LIST_INIT( gl_drawables ); static struct list gl_drawables = LIST_INIT( gl_drawables );
static void (*pglFinish)(void);
static void (*pglFlush)(void);
static CRITICAL_SECTION drawable_section; static CRITICAL_SECTION drawable_section;
static CRITICAL_SECTION_DEBUG critsect_debug = static CRITICAL_SECTION_DEBUG critsect_debug =
{ {
...@@ -123,6 +129,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format ) ...@@ -123,6 +129,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format )
gl->hdc = hdc; gl->hdc = hdc;
gl->format = format; gl->format = format;
gl->window = create_ioctl_window( hwnd, TRUE ); gl->window = create_ioctl_window( hwnd, TRUE );
gl->surface = 0;
gl->pbuffer = p_eglCreatePbufferSurface( display, pixel_formats[gl->format - 1].config, attribs ); gl->pbuffer = p_eglCreatePbufferSurface( display, pixel_formats[gl->format - 1].config, attribs );
EnterCriticalSection( &drawable_section ); EnterCriticalSection( &drawable_section );
list_add_head( &gl_drawables, &gl->entry ); list_add_head( &gl_drawables, &gl->entry );
...@@ -157,6 +164,7 @@ void destroy_gl_drawable( HWND hwnd ) ...@@ -157,6 +164,7 @@ void destroy_gl_drawable( HWND hwnd )
{ {
if (gl->hwnd != hwnd) continue; if (gl->hwnd != hwnd) continue;
list_remove( &gl->entry ); list_remove( &gl->entry );
if (gl->surface) p_eglDestroySurface( display, gl->surface );
if (gl->pbuffer) p_eglDestroySurface( display, gl->pbuffer ); if (gl->pbuffer) p_eglDestroySurface( display, gl->pbuffer );
release_ioctl_window( gl->window ); release_ioctl_window( gl->window );
HeapFree( GetProcessHeap(), 0, gl ); HeapFree( GetProcessHeap(), 0, gl );
...@@ -165,6 +173,45 @@ void destroy_gl_drawable( HWND hwnd ) ...@@ -165,6 +173,45 @@ void destroy_gl_drawable( HWND hwnd )
LeaveCriticalSection( &drawable_section ); LeaveCriticalSection( &drawable_section );
} }
static BOOL refresh_context( struct wgl_context *ctx )
{
BOOL ret = InterlockedExchange( &ctx->refresh, FALSE );
if (ret)
{
TRACE( "refreshing hwnd %p context %p surface %p\n", ctx->hwnd, ctx->context, ctx->surface );
p_eglMakeCurrent( display, ctx->surface, ctx->surface, ctx->context );
RedrawWindow( ctx->hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE );
}
return ret;
}
void update_gl_drawable( HWND hwnd )
{
struct gl_drawable *gl;
struct wgl_context *ctx;
if ((gl = get_gl_drawable( hwnd, 0 )))
{
if (!gl->surface &&
(gl->surface = p_eglCreateWindowSurface( display, pixel_formats[gl->format - 1].config, gl->window, NULL )))
{
LIST_FOR_EACH_ENTRY( ctx, &gl_contexts, struct wgl_context, entry )
{
if (ctx->hwnd != hwnd) continue;
TRACE( "hwnd %p refreshing %p %scurrent\n", hwnd, ctx, NtCurrentTeb()->glContext == ctx ? "" : "not " );
ctx->surface = gl->surface;
if (NtCurrentTeb()->glContext == ctx)
p_eglMakeCurrent( display, ctx->surface, ctx->surface, ctx->context );
else
InterlockedExchange( &ctx->refresh, TRUE );
}
}
release_gl_drawable( gl );
RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE );
}
}
static BOOL set_pixel_format( HDC hdc, int format, BOOL allow_change ) static BOOL set_pixel_format( HDC hdc, int format, BOOL allow_change )
{ {
struct gl_drawable *gl; struct gl_drawable *gl;
...@@ -214,6 +261,8 @@ static struct wgl_context *create_context( HDC hdc, struct wgl_context *share, c ...@@ -214,6 +261,8 @@ static struct wgl_context *create_context( HDC hdc, struct wgl_context *share, c
ctx = HeapAlloc( GetProcessHeap(), 0, sizeof(*ctx) ); ctx = HeapAlloc( GetProcessHeap(), 0, sizeof(*ctx) );
ctx->config = pixel_formats[gl->format - 1].config; ctx->config = pixel_formats[gl->format - 1].config;
ctx->surface = 0;
ctx->refresh = FALSE;
ctx->context = p_eglCreateContext( display, ctx->config, ctx->context = p_eglCreateContext( display, ctx->config,
share ? share->context : EGL_NO_CONTEXT, attribs ); share ? share->context : EGL_NO_CONTEXT, attribs );
TRACE( "%p fmt %d ctx %p\n", hdc, gl->format, ctx->context ); TRACE( "%p fmt %d ctx %p\n", hdc, gl->format, ctx->context );
...@@ -376,12 +425,14 @@ static BOOL android_wglMakeCurrent( HDC hdc, struct wgl_context *ctx ) ...@@ -376,12 +425,14 @@ static BOOL android_wglMakeCurrent( HDC hdc, struct wgl_context *ctx )
hwnd = WindowFromDC( hdc ); hwnd = WindowFromDC( hdc );
if ((gl = get_gl_drawable( hwnd, hdc ))) if ((gl = get_gl_drawable( hwnd, hdc )))
{ {
EGLSurface surface = gl->pbuffer; EGLSurface surface = gl->surface ? gl->surface : gl->pbuffer;
TRACE( "%p hwnd %p context %p surface %p\n", hdc, gl->hwnd, ctx->context, surface ); TRACE( "%p hwnd %p context %p surface %p\n", hdc, gl->hwnd, ctx->context, surface );
ret = p_eglMakeCurrent( display, surface, surface, ctx->context ); ret = p_eglMakeCurrent( display, surface, surface, ctx->context );
if (ret) if (ret)
{ {
ctx->surface = gl->surface;
ctx->hwnd = hwnd; ctx->hwnd = hwnd;
ctx->refresh = FALSE;
NtCurrentTeb()->glContext = ctx; NtCurrentTeb()->glContext = ctx;
goto done; goto done;
} }
...@@ -419,10 +470,33 @@ static BOOL android_wglSwapBuffers( HDC hdc ) ...@@ -419,10 +470,33 @@ static BOOL android_wglSwapBuffers( HDC hdc )
if (!ctx) return FALSE; if (!ctx) return FALSE;
TRACE( "%p hwnd %p context %p\n", hdc, ctx->hwnd, ctx->context ); TRACE( "%p hwnd %p context %p surface %p\n", hdc, ctx->hwnd, ctx->context, ctx->surface );
if (refresh_context( ctx )) return TRUE;
if (ctx->surface) p_eglSwapBuffers( display, ctx->surface );
return TRUE; return TRUE;
} }
static void wglFinish(void)
{
struct wgl_context *ctx = NtCurrentTeb()->glContext;
if (!ctx) return;
TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context );
refresh_context( ctx );
pglFinish();
}
static void wglFlush(void)
{
struct wgl_context *ctx = NtCurrentTeb()->glContext;
if (!ctx) return;
TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context );
refresh_context( ctx );
pglFlush();
}
static void register_extension( const char *ext ) static void register_extension( const char *ext )
{ {
if (wgl_extensions[0]) strcat( wgl_extensions, " " ); if (wgl_extensions[0]) strcat( wgl_extensions, " " );
...@@ -729,6 +803,14 @@ static void init_extensions(void) ...@@ -729,6 +803,14 @@ static void init_extensions(void)
LOAD_FUNCPTR( glVertexBindingDivisor ); LOAD_FUNCPTR( glVertexBindingDivisor );
LOAD_FUNCPTR( glWaitSync ); LOAD_FUNCPTR( glWaitSync );
#undef LOAD_FUNCPTR #undef LOAD_FUNCPTR
/* redirect some standard OpenGL functions */
#define REDIRECT(func) \
do { p##func = egl_funcs.gl.p_##func; egl_funcs.gl.p_##func = w##func; } while(0)
REDIRECT(glFinish);
REDIRECT(glFlush);
#undef REDIRECT
} }
static BOOL egl_init(void) static BOOL egl_init(void)
......
...@@ -1330,7 +1330,11 @@ LRESULT CDECL ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) ...@@ -1330,7 +1330,11 @@ LRESULT CDECL ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
switch (msg) switch (msg)
{ {
case WM_ANDROID_REFRESH: case WM_ANDROID_REFRESH:
if ((data = get_win_data( hwnd ))) if (wp) /* opengl client window */
{
update_gl_drawable( hwnd );
}
else if ((data = get_win_data( hwnd )))
{ {
struct window_surface *surface = data->surface; struct window_surface *surface = data->surface;
if (surface) if (surface)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment