From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 71 ++++++++++++++++++++++-------------- include/wine/opengl_driver.h | 6 +-- 2 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index efd6ea63b1a..43ecc9273f3 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -144,6 +144,12 @@ void opengl_drawable_release( struct opengl_drawable *drawable ) } }
+static void opengl_drawable_set_context( struct opengl_drawable *drawable, struct wgl_context *context ) +{ + if (!drawable->funcs->set_context) return; + drawable->funcs->set_context( drawable, context->driver_private ); +} + static void opengl_drawable_flush( struct opengl_drawable *drawable, int interval, UINT flags ) { if (!drawable->client) return; @@ -320,20 +326,35 @@ static void framebuffer_surface_destroy( struct opengl_drawable *drawable ) TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); }
-static void framebuffer_surface_flush( struct opengl_drawable *drawable, UINT flags ) +static void framebuffer_surface_resize( struct opengl_drawable *drawable ) { struct wgl_pixel_format draw_desc = pixel_formats[drawable->format - 1], read_desc = draw_desc; RECT rect;
- TRACE( "%s, flags %#x\n", debugstr_opengl_drawable( drawable ), flags ); - NtUserGetClientRect( drawable->client->hwnd, &rect, NtUserGetDpiForWindow( drawable->client->hwnd ) ); if (!rect.right) rect.right = 1; if (!rect.bottom) rect.bottom = 1;
read_desc.samples = read_desc.sample_buffers = 0;
- if (flags & GL_FLUSH_WAS_CURRENT) + TRACE( "Resizing drawable %p/%u to %ux%u\n", drawable, drawable->read_fbo, rect.right, rect.bottom ); + resize_framebuffer( drawable, &read_desc, drawable->read_fbo, rect.right, rect.bottom ); + + if (drawable->draw_fbo != drawable->read_fbo) + { + TRACE( "Resizing drawable %p/%u to %ux%u\n", drawable, drawable->draw_fbo, rect.right, rect.bottom ); + resize_framebuffer( drawable, &draw_desc, drawable->draw_fbo, rect.right, rect.bottom ); + } +} + +static void framebuffer_surface_set_context( struct opengl_drawable *drawable, void *private ) +{ + struct wgl_pixel_format draw_desc = pixel_formats[drawable->format - 1], read_desc = draw_desc; + read_desc.samples = read_desc.sample_buffers = 0; + + TRACE( "%s, private %p\n", debugstr_opengl_drawable( drawable ), private ); + + if (!private) { if (drawable->draw_fbo != drawable->read_fbo) { @@ -343,8 +364,7 @@ static void framebuffer_surface_flush( struct opengl_drawable *drawable, UINT fl destroy_framebuffer( drawable, &read_desc, drawable->read_fbo ); drawable->read_fbo = 0; } - - if (flags & GL_FLUSH_SET_CURRENT) + else { drawable->read_fbo = create_framebuffer( drawable, &read_desc ); if (!drawable->read_fbo) ERR( "Failed to create read framebuffer object\n" ); @@ -352,21 +372,17 @@ static void framebuffer_surface_flush( struct opengl_drawable *drawable, UINT fl if (!draw_desc.sample_buffers) drawable->draw_fbo = drawable->read_fbo; else drawable->draw_fbo = create_framebuffer( drawable, &draw_desc ); if (!drawable->draw_fbo) ERR( "Failed to create draw framebuffer object\n" ); - }
- if ((flags & (GL_FLUSH_UPDATED | GL_FLUSH_SET_CURRENT)) && drawable->read_fbo) - { - TRACE( "Resizing drawable %p/%u to %ux%u\n", drawable, drawable->read_fbo, rect.right, rect.bottom ); - resize_framebuffer( drawable, &read_desc, drawable->read_fbo, rect.right, rect.bottom ); - - if (drawable->draw_fbo != drawable->read_fbo) - { - TRACE( "Resizing drawable %p/%u to %ux%u\n", drawable, drawable->draw_fbo, rect.right, rect.bottom ); - resize_framebuffer( drawable, &draw_desc, drawable->draw_fbo, rect.right, rect.bottom ); - } + framebuffer_surface_resize( drawable ); } }
+static void framebuffer_surface_flush( struct opengl_drawable *drawable, UINT flags ) +{ + TRACE( "%s, flags %#x\n", debugstr_opengl_drawable( drawable ), flags ); + if (flags & GL_FLUSH_UPDATED && drawable->read_fbo) framebuffer_surface_resize( drawable ); +} + static BOOL framebuffer_surface_swap( struct opengl_drawable *drawable ) { TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); @@ -378,6 +394,7 @@ static const struct opengl_drawable_funcs framebuffer_surface_funcs = .destroy = framebuffer_surface_destroy, .flush = framebuffer_surface_flush, .swap = framebuffer_surface_swap, + .set_context = framebuffer_surface_set_context, };
static struct opengl_drawable *framebuffer_surface_create( int format, struct client_surface *client ) @@ -1342,11 +1359,11 @@ static BOOL context_unset_current( struct wgl_context *context )
TRACE( "context %p\n", context );
- opengl_drawable_flush( old_read, old_read->interval, GL_FLUSH_WAS_CURRENT ); - if (old_read != old_draw) opengl_drawable_flush( old_draw, old_draw->interval, GL_FLUSH_WAS_CURRENT ); + opengl_drawable_set_context( old_read, NULL ); + if (old_read != old_draw) opengl_drawable_set_context( old_draw, NULL ); if (driver_funcs->p_make_current( NULL, NULL, NULL )) return TRUE; - opengl_drawable_flush( old_read, old_read->interval, GL_FLUSH_SET_CURRENT ); - if (old_read != old_draw) opengl_drawable_flush( old_draw, old_draw->interval, GL_FLUSH_SET_CURRENT ); + opengl_drawable_set_context( old_read, context ); + if (old_read != old_draw) opengl_drawable_set_context( old_draw, context );
return FALSE; } @@ -1394,8 +1411,8 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H else if (previous) { context_exchange_drawables( previous, &old_draw, &old_read ); /* take ownership of the previous context drawables */ - opengl_drawable_flush( old_read, old_read->interval, GL_FLUSH_WAS_CURRENT ); - if (old_read != old_draw) opengl_drawable_flush( old_draw, old_draw->interval, GL_FLUSH_WAS_CURRENT ); + opengl_drawable_set_context( old_read, NULL ); + if (old_read != old_draw) opengl_drawable_set_context( old_draw, NULL ); }
if (!ret && (ret = driver_funcs->p_make_current( new_draw, new_read, context->driver_private ))) @@ -1411,8 +1428,8 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H if (old_draw) opengl_drawable_release( old_draw ); if (old_read) opengl_drawable_release( old_read );
- opengl_drawable_flush( new_read, new_read->interval, GL_FLUSH_SET_CURRENT ); - if (new_read != new_draw) opengl_drawable_flush( new_draw, new_draw->interval, GL_FLUSH_SET_CURRENT ); + opengl_drawable_set_context( new_read, context ); + if (new_read != new_draw) opengl_drawable_set_context( new_draw, context ); }
if (ret) @@ -1425,8 +1442,8 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H } else if (previous) { - opengl_drawable_flush( old_read, old_read->interval, GL_FLUSH_SET_CURRENT ); - if (old_read != old_draw) opengl_drawable_flush( old_draw, old_draw->interval, GL_FLUSH_SET_CURRENT ); + opengl_drawable_set_context( old_read, context ); + if (old_read != old_draw) opengl_drawable_set_context( old_draw, context ); context_exchange_drawables( previous, &old_draw, &old_read ); /* give back ownership of the previous drawables */ assert( !old_draw && !old_read ); } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 60fe402621c..296b030021d 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -64,7 +64,7 @@ struct wgl_pixel_format #include "wine/gdi_driver.h"
/* Wine internal opengl driver version, needs to be bumped upon opengl_funcs changes. */ -#define WINE_OPENGL_DRIVER_VERSION 36 +#define WINE_OPENGL_DRIVER_VERSION 37
struct opengl_drawable; struct wgl_context; @@ -149,14 +149,14 @@ struct opengl_drawable_funcs void (*flush)( struct opengl_drawable *iface, UINT flags ); /* swap and present the drawable buffers, called from render thread */ BOOL (*swap)( struct opengl_drawable *iface ); + /* drawable is being unset or made current, called from render thread */ + void (*set_context)( struct opengl_drawable *iface, void *private ); };
/* flags for opengl_drawable flush */ #define GL_FLUSH_FINISHED 0x01 #define GL_FLUSH_INTERVAL 0x02 #define GL_FLUSH_UPDATED 0x04 -#define GL_FLUSH_WAS_CURRENT 0x08 -#define GL_FLUSH_SET_CURRENT 0x10
/* a driver opengl drawable, either a client surface of a pbuffer */ struct opengl_drawable
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 10 ++++++++-- dlls/win32u/window.c | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 43ecc9273f3..fae9a71c988 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -152,7 +152,7 @@ static void opengl_drawable_set_context( struct opengl_drawable *drawable, struc
static void opengl_drawable_flush( struct opengl_drawable *drawable, int interval, UINT flags ) { - if (!drawable->client) return; + if (!is_client_surface_window( drawable->client, 0 )) return;
if (InterlockedCompareExchange( &drawable->client->updated, 0, 1 )) flags |= GL_FLUSH_UPDATED; if (interval != drawable->interval) @@ -165,6 +165,12 @@ static void opengl_drawable_flush( struct opengl_drawable *drawable, int interva drawable->funcs->flush( drawable, flags ); }
+static BOOL opengl_drawable_swap( struct opengl_drawable *drawable ) +{ + if (!is_client_surface_window( drawable->client, 0 )) return FALSE; + return drawable->funcs->swap( drawable ); +} + #ifdef SONAME_LIBEGL
struct framebuffer_surface @@ -2029,7 +2035,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) else if (!(draw = get_window_current_drawable( hwnd ))) return FALSE;
opengl_drawable_flush( draw, interval, 0 ); - ret = draw->funcs->swap( draw ); + ret = opengl_drawable_swap( draw ); opengl_drawable_release( draw );
return ret; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index bb6de9e065a..0363a00541f 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -359,7 +359,8 @@ BOOL is_client_surface_window( struct client_surface *surface, HWND hwnd )
if (!surface) return FALSE; pthread_mutex_lock( &surfaces_lock ); - ret = surface->hwnd == hwnd; + if (hwnd) ret = surface->hwnd == hwnd; + else ret = surface->hwnd != NULL; pthread_mutex_unlock( &surfaces_lock );
return ret;