From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58491 --- dlls/win32u/opengl.c | 4 +--- dlls/win32u/win32u_private.h | 1 + dlls/win32u/window.c | 12 ++++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 57e0aa0e27c..e0c584f0dbf 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1356,7 +1356,6 @@ static BOOL context_unset_current( struct wgl_context *context ) /* return an updated drawable, recreating one if the window drawables have been invalidated (mostly wineandroid) */ static struct opengl_drawable *get_updated_drawable( HDC hdc, int format, struct opengl_drawable *drawable ) { - struct opengl_drawable *current; HWND hwnd = NULL;
if (hdc && !(hwnd = NtUserWindowFromDC( hdc ))) return get_dc_opengl_drawable( hdc ); @@ -1364,9 +1363,8 @@ static struct opengl_drawable *get_updated_drawable( HDC hdc, int format, struct if (!hwnd) return NULL;
/* if the window still has a drawable, keep using the one we have */ - if (drawable && (current = get_window_current_drawable( hwnd ))) + if (drawable && is_client_surface_window( drawable->client, hwnd )) { - opengl_drawable_release( current ); opengl_drawable_add_ref( drawable ); return drawable; } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 5db351836de..69d7b5b5257 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -286,6 +286,7 @@ extern HWND window_from_point( HWND hwnd, POINT pt, INT *hittest ); extern HWND get_shell_window(void); extern HWND get_progman_window(void); extern HWND get_taskman_window(void); +extern BOOL is_client_surface_window( struct client_surface *surface, HWND hwnd );
/* to release pointers retrieved by win_get_ptr */ static inline void release_win_ptr( struct tagWND *ptr ) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index f91ab2bfcef..ad9526c6ebd 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -339,6 +339,18 @@ void client_surface_present( struct client_surface *surface ) pthread_mutex_unlock( &surfaces_lock ); }
+BOOL is_client_surface_window( struct client_surface *surface, HWND hwnd ) +{ + BOOL ret; + + if (!surface) return FALSE; + pthread_mutex_lock( &surfaces_lock ); + ret = surface->hwnd == hwnd; + pthread_mutex_unlock( &surfaces_lock ); + + return ret; +} + /******************************************************************* * get_hwnd_message_parent *
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
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 4 +--- dlls/win32u/window.c | 2 +- dlls/wineandroid.drv/android.h | 1 - dlls/wineandroid.drv/window.c | 2 +- include/wine/gdi_driver.h | 1 + include/wine/opengl_driver.h | 2 -- 6 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index e0c584f0dbf..efd6ea63b1a 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1101,13 +1101,11 @@ static int win32u_wglGetPixelFormat( HDC hdc ) return format > 0 ? format : 0; }
-void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *new_drawable, BOOL current ) +static void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *new_drawable, BOOL current ) { struct opengl_drawable *old_drawable = NULL; WND *win;
- TRACE( "hwnd %p, new_drawable %s\n", hwnd, debugstr_opengl_drawable( new_drawable ) ); - if ((win = get_win_ptr( hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) { struct opengl_drawable **ptr = current ? &win->current_drawable : &win->unused_drawable; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index ad9526c6ebd..23ebf8a92f6 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -237,7 +237,7 @@ void *free_user_handle( HANDLE handle, unsigned short type ) static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER; static struct list client_surfaces = LIST_INIT( client_surfaces );
-static void detach_client_surfaces( HWND hwnd ) +void detach_client_surfaces( HWND hwnd ) { struct list detached = LIST_INIT( detached ); struct client_surface *surface, *next; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index b96d744e425..07c0f9ea7b7 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -54,7 +54,6 @@ DECL_FUNCPTR( ANativeWindow_release ); */
extern pthread_mutex_t drawable_mutex; -extern void update_gl_drawable( HWND hwnd ); extern UINT ANDROID_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, const struct opengl_driver_funcs **driver_funcs );
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 71bc04e9d73..9c0dc8d6115 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1192,7 +1192,7 @@ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) release_win_data( data ); }
- update_gl_drawable( hwnd ); + detach_client_surfaces( hwnd ); } else { diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index abf1b699cab..b3b392dc474 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -272,6 +272,7 @@ W32KAPI void *client_surface_create( UINT size, const struct client_surface_func W32KAPI void client_surface_add_ref( struct client_surface *surface ); W32KAPI void client_surface_release( struct client_surface *surface ); W32KAPI void client_surface_present( struct client_surface *surface ); +W32KAPI void detach_client_surfaces( HWND hwnd );
static inline const char *debugstr_client_surface( struct client_surface *surface ) { diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 38b14f57e3b..60fe402621c 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -183,8 +183,6 @@ W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_fu W32KAPI void opengl_drawable_add_ref( struct opengl_drawable *drawable ); W32KAPI void opengl_drawable_release( struct opengl_drawable *drawable );
-W32KAPI void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *drawable, BOOL current ); - /* interface between win32u and the user drivers */ struct opengl_driver_funcs {