From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wineandroid.drv/android.h | 2 ++ dlls/wineandroid.drv/opengl.c | 42 +++++++++++++++------------------- dlls/wineandroid.drv/window.c | 35 ++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 24 deletions(-)
diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 3316ee015ac..b96d744e425 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -98,6 +98,8 @@ extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, c extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, BOOL fullscreen, const struct window_rects *new_rects, struct window_surface *surface ); +extern ANativeWindow *get_client_window( HWND hwnd ); +extern BOOL has_client_surface( HWND hwnd );
/* unixlib interface */
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 2345d98e5ba..377d5b2d5ea 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -71,27 +71,6 @@ static inline EGLConfig egl_config_for_format(int format) return egl->configs[format - egl->config_count - 1]; }
-static struct gl_drawable *create_gl_drawable( HWND hwnd, int format, ANativeWindow *window ) -{ - static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; - struct client_surface *client; - struct gl_drawable *gl; - - if (!(client = client_surface_create( sizeof(*client), &android_client_surface_funcs, hwnd ))) return NULL; - gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ); - client_surface_release( client ); - if (!gl) return NULL; - - if (!window) gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); - else gl->window = grab_ioctl_window( window ); - - if (!window) gl->base.surface = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->base.format), attribs ); - else gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->base.format), gl->window, NULL ); - - TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); - return gl; -} - static void android_drawable_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); @@ -126,10 +105,25 @@ static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawabl TRACE( "Updated drawable %s\n", debugstr_opengl_drawable( *drawable ) ); return TRUE; } + else + { + static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; + EGLConfig config = egl_config_for_format( format ); + struct client_surface *client;
- if (!(gl = create_gl_drawable( hwnd, format, NULL ))) return FALSE; - *drawable = &gl->base; - return TRUE; + if (!(client = client_surface_create( sizeof(*client), &android_client_surface_funcs, hwnd ))) return FALSE; + gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ); + client_surface_release( client ); + if (!gl) return FALSE; + + gl->window = get_client_window( client->hwnd ); + if (!has_client_surface( client->hwnd )) gl->base.surface = funcs->p_eglCreatePbufferSurface( egl->display, config, attribs ); + else gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, config, gl->window, NULL ); + + TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); + *drawable = &gl->base; + return TRUE; + } }
static void android_init_egl_platform( struct egl_platform *platform ) diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index d1017fd8764..71bc04e9d73 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -54,6 +54,8 @@ struct android_win_data HWND parent; /* parent hwnd for child windows */ struct window_rects rects; /* window rects in monitor DPI, relative to parent client area */ ANativeWindow *window; /* native window wrapper that forwards calls to the desktop process */ + ANativeWindow *client; /* native client surface wrapper that forwards calls to the desktop process */ + BOOL has_surface; /* whether the client surface has been created on the Java side */ };
#define SWP_AGG_NOPOSCHANGE (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER) @@ -113,6 +115,7 @@ static void free_win_data( struct android_win_data *data ) { win_data_context[context_idx( data->hwnd )] = NULL; pthread_mutex_unlock( &win_data_mutex ); + if (data->client) release_ioctl_window( data->client ); if (data->window) release_ioctl_window( data->window ); free( data ); } @@ -1181,6 +1184,14 @@ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) case WM_ANDROID_REFRESH: if (wp) /* opengl client window */ { + struct android_win_data *data; + + if ((data = get_win_data( hwnd ))) + { + data->has_surface = TRUE; + release_win_data( data ); + } + update_gl_drawable( hwnd ); } else @@ -1194,6 +1205,30 @@ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) } }
+ANativeWindow *get_client_window( HWND hwnd ) +{ + struct android_win_data *data; + ANativeWindow *client; + + if (!(data = get_win_data( hwnd ))) return NULL; + if (!data->client) data->client = create_ioctl_window( hwnd, TRUE, 1.0f ); + client = grab_ioctl_window( data->client ); + release_win_data( data ); + + return client; +} + +BOOL has_client_surface( HWND hwnd ) +{ + struct android_win_data *data; + BOOL ret; + + if (!(data = get_win_data( hwnd ))) return FALSE; + ret = data->has_surface; + release_win_data( data ); + + return ret; +}
/*********************************************************************** * ANDROID_CreateDesktop