Otherwise there might not be any current context.
And notify surfaces before unmaking them current / after making them current, in preparation for FBO surfaces.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 63 ++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 26 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 40742c692ec..9ffed79ed88 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1145,9 +1145,22 @@ static struct wgl_context *win32u_wglCreateContext( HDC hdc ) return context_create( hdc, NULL, NULL ); }
-static BOOL context_set_drawables( struct wgl_context *context, void *private, HDC draw_hdc, HDC read_hdc, BOOL force ) +static void context_set_drawables( struct wgl_context *context, struct opengl_drawable *new_draw, struct opengl_drawable *new_read ) { - struct opengl_drawable *new_draw, *new_read, *old_draw = context->draw, *old_read = context->read; + struct opengl_drawable *old_draw = context->draw, *old_read = context->read; + + TRACE( "context %p new_draw %s new_read %s\n", context, debugstr_opengl_drawable(new_draw), debugstr_opengl_drawable(new_read) ); + + if ((context->draw = new_draw)) opengl_drawable_add_ref( new_draw ); + if ((context->read = new_read)) opengl_drawable_add_ref( new_read ); + if (old_draw) opengl_drawable_release( old_draw ); + if (old_read) opengl_drawable_release( old_read ); +} + +static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, HDC read_hdc ) +{ + struct wgl_context *previous = NtCurrentTeb()->glContext; + struct opengl_drawable *new_draw, *new_read; BOOL ret = FALSE, flush; HWND hwnd;
@@ -1160,31 +1173,28 @@ static BOOL context_set_drawables( struct wgl_context *context, void *private, H
TRACE( "context %p, new_draw %s, new_read %s\n", context, debugstr_opengl_drawable( new_draw ), debugstr_opengl_drawable( new_read ) );
- if (private && (!new_draw || !new_read)) - WARN( "One of the drawable has been lost, ignoring\n" ); - else if (!private && (new_draw || new_read)) - WARN( "Unexpected drawables with NULL context\n" ); - else + if (!new_draw || !new_read) { - if (new_read) opengl_drawable_flush( new_read, new_read->interval, 0 ); - if (new_draw) opengl_drawable_flush( new_draw, new_draw->interval, 0 ); + WARN( "One of the drawable has been lost, ignoring\n" ); + return FALSE; + }
- if (!force && new_draw == context->draw && new_read == context->read) - TRACE( "Drawables didn't change, nothing to do\n" ); - else if ((ret = driver_funcs->p_make_current( new_draw, new_read, private ))) - { - if ((context->draw = new_draw)) opengl_drawable_add_ref( new_draw ); - if ((context->read = new_read)) opengl_drawable_add_ref( new_read ); - if (old_draw) opengl_drawable_release( old_draw ); - if (old_read) opengl_drawable_release( old_read ); + opengl_drawable_flush( new_read, new_read->interval, 0 ); + opengl_drawable_flush( new_draw, new_draw->interval, 0 );
- /* update the current window drawable to the last used draw surface */ - if (new_draw && (hwnd = NtUserWindowFromDC( draw_hdc ))) set_window_opengl_drawable( hwnd, new_draw ); - } + if (previous == context && new_draw == context->draw && new_read == context->read) + TRACE( "Drawables didn't change, nothing to do\n" ); + else if ((ret = driver_funcs->p_make_current( new_draw, new_read, context->driver_private ))) + { + NtCurrentTeb()->glContext = context; + context_set_drawables( context, new_draw, new_read ); + if (previous && previous != context) context_set_drawables( previous, NULL, NULL ); + /* update the current window drawable to the last used draw surface */ + if ((hwnd = NtUserWindowFromDC( draw_hdc ))) set_window_opengl_drawable( hwnd, new_draw ); }
- if (new_draw) opengl_drawable_release( new_draw ); - if (new_read) opengl_drawable_release( new_read ); + opengl_drawable_release( new_draw ); + opengl_drawable_release( new_read );
if (ret && flush) flush_memory_dc( context, draw_hdc, TRUE, NULL ); return ret; @@ -1232,8 +1242,9 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct if (!context) { if (!(context = prev_context)) return TRUE; - if (!context_set_drawables( context, NULL, NULL, NULL, TRUE )) return FALSE; + if (!driver_funcs->p_make_current( NULL, NULL, NULL )) return FALSE; NtCurrentTeb()->glContext = NULL; + context_set_drawables( context, NULL, NULL ); return TRUE; }
@@ -1250,7 +1261,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct return FALSE; }
- if (!context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, TRUE )) return FALSE; + if (!context_sync_drawables( context, draw_hdc, read_hdc )) return FALSE; NtCurrentTeb()->glContext = context; return TRUE; } @@ -1688,7 +1699,7 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)
TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d, flush %p\n", context, hwnd, draw_hdc, interval, flush );
- context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); + context_sync_drawables( context, draw_hdc, read_hdc ); if (flush_memory_dc( context, draw_hdc, FALSE, flush )) return TRUE;
if (flush) flush(); @@ -1714,7 +1725,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
- context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); + context_sync_drawables( context, draw_hdc, read_hdc ); if (flush_memory_dc( context, hdc, FALSE, funcs->p_glFlush )) return TRUE;
if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE;
From: Rémi Bernon rbernon@codeweavers.com
Otherwise there might not be any current context. --- dlls/win32u/opengl.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 9ffed79ed88..77df48d090c 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1179,24 +1179,25 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H return FALSE; }
- opengl_drawable_flush( new_read, new_read->interval, 0 ); - opengl_drawable_flush( new_draw, new_draw->interval, 0 ); - - if (previous == context && new_draw == context->draw && new_read == context->read) - TRACE( "Drawables didn't change, nothing to do\n" ); + if (previous == context && new_draw == context->draw && new_read == context->read) ret = TRUE; else if ((ret = driver_funcs->p_make_current( new_draw, new_read, context->driver_private ))) { NtCurrentTeb()->glContext = context; context_set_drawables( context, new_draw, new_read ); if (previous && previous != context) context_set_drawables( previous, NULL, NULL ); + } + + if (ret) + { + opengl_drawable_flush( new_read, new_read->interval, 0 ); + opengl_drawable_flush( new_draw, new_draw->interval, 0 ); /* update the current window drawable to the last used draw surface */ if ((hwnd = NtUserWindowFromDC( draw_hdc ))) set_window_opengl_drawable( hwnd, new_draw ); + if (flush) flush_memory_dc( context, draw_hdc, TRUE, NULL ); }
opengl_drawable_release( new_draw ); opengl_drawable_release( new_read ); - - if (ret && flush) flush_memory_dc( context, draw_hdc, TRUE, NULL ); return ret; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 35 +++++++++++++++++++++++++++++++++-- include/wine/opengl_driver.h | 2 ++ 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 77df48d090c..eea6c3f3ec5 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1157,6 +1157,21 @@ static void context_set_drawables( struct wgl_context *context, struct opengl_dr if (old_read) opengl_drawable_release( old_read ); }
+static BOOL context_unset_current( struct wgl_context *context ) +{ + struct opengl_drawable *old_draw = context->draw, *old_read = context->read; + + 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 ); + 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 ); + + return FALSE; +} + static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, HDC read_hdc ) { struct wgl_context *previous = NtCurrentTeb()->glContext; @@ -1180,11 +1195,21 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H }
if (previous == context && new_draw == context->draw && new_read == context->read) ret = TRUE; - else if ((ret = driver_funcs->p_make_current( new_draw, new_read, context->driver_private ))) + else if (previous) + { + struct opengl_drawable *old_draw = previous->draw, *old_read = previous->read; + 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 ); + } + + if (!ret && (ret = driver_funcs->p_make_current( new_draw, new_read, context->driver_private ))) { NtCurrentTeb()->glContext = context; context_set_drawables( context, new_draw, new_read ); if (previous && previous != context) context_set_drawables( previous, NULL, NULL ); + + 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 ); }
if (ret) @@ -1195,6 +1220,12 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H if ((hwnd = NtUserWindowFromDC( draw_hdc ))) set_window_opengl_drawable( hwnd, new_draw ); if (flush) flush_memory_dc( context, draw_hdc, TRUE, NULL ); } + else if (previous) + { + struct opengl_drawable *old_draw = previous->draw, *old_read = previous->read; + 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_release( new_draw ); opengl_drawable_release( new_read ); @@ -1243,7 +1274,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct if (!context) { if (!(context = prev_context)) return TRUE; - if (!driver_funcs->p_make_current( NULL, NULL, NULL )) return FALSE; + if (!context_unset_current( context )) return FALSE; NtCurrentTeb()->glContext = NULL; context_set_drawables( context, NULL, NULL ); return TRUE; diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index dec9abb0f91..2b5395c96f9 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -146,6 +146,8 @@ struct opengl_drawable_funcs #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
struct opengl_drawable {