From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 76 ++++++++++++++++++------------------ dlls/win32u/dce.c | 8 ---- dlls/win32u/opengl.c | 56 ++++++++++++++++---------- dlls/win32u/win32u_private.h | 5 --- include/wine/opengl_driver.h | 1 - 5 files changed, 74 insertions(+), 72 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 0131a68e3d8..55125722297 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -2552,27 +2552,27 @@ static DWORD CALLBACK test_window_dc_thread( void *arg )
ctx = wglCreateContext( hdc ); ok( ctx != NULL, "got %p\n", ctx ); - todo_wine ok_ret( TRUE, wglMakeCurrent( hdc, ctx ) ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, wglMakeCurrent( hdc, ctx ) ); + ok_ret( GL_NO_ERROR, glGetError() ); glReadBuffer( GL_BACK ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); todo_wine ok( pixel == 0xff0000ff, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
glClearColor( 0.0, 1.0, 0.0, 1.0 ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() ); glClear( GL_COLOR_BUFFER_BIT ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( pixel == 0xff00ff00, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok( pixel == 0xff00ff00, "got %#x\n", pixel ); + ok_ret( GL_NO_ERROR, glGetError() );
- todo_wine ok_ret( TRUE, wglMakeCurrent( NULL, NULL ) ); + ok_ret( TRUE, wglMakeCurrent( NULL, NULL ) ); ok_ret( TRUE, wglDeleteContext( ctx ) );
ReleaseDC( hwnd, hdc ); @@ -2652,45 +2652,45 @@ static void test_window_dc(void) dc = GetWindowDC( window ); ctx = wglCreateContext( dc ); ok( ctx != NULL, "got %p\n", ctx ); - todo_wine ok_ret( TRUE, wglMakeCurrent( dc, ctx ) ); + ok_ret( TRUE, wglMakeCurrent( dc, ctx ) ); glReadBuffer( GL_BACK ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
glClearColor( 1.0, 0.0, 0.0, 1.0 ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() ); glClear( GL_COLOR_BUFFER_BIT ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( pixel == 0xff0000ff, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok( pixel == 0xff0000ff, "got %#x\n", pixel ); + ok_ret( GL_NO_ERROR, glGetError() );
ReleaseDC( window, dc );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( pixel == 0xff0000ff, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok( pixel == 0xff0000ff, "got %#x\n", pixel ); + ok_ret( GL_NO_ERROR, glGetError() );
glFlush(); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( pixel == 0xff0000ff, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok( pixel == 0xff0000ff, "got %#x\n", pixel ); + ok_ret( GL_NO_ERROR, glGetError() );
dc = GetWindowDC( window ); ok( dc != NULL, "got %p\n", dc ); - todo_wine ok_ret( TRUE, wglMakeCurrent( dc, ctx ) ); + ok_ret( TRUE, wglMakeCurrent( dc, ctx ) );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( pixel == 0xff0000ff, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok( pixel == 0xff0000ff, "got %#x\n", pixel ); + ok_ret( GL_NO_ERROR, glGetError() );
thread = CreateThread( NULL, 0, test_window_dc_thread, window, 0, NULL ); ok( thread != NULL, "got %p\n", thread ); @@ -2700,32 +2700,32 @@ static void test_window_dc(void) pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); todo_wine ok( pixel == 0xff00ff00, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
dc1 = GetWindowDC( window ); ok( dc1 != NULL, "got %p\n", dc1 ); - todo_wine ok_ret( TRUE, wglMakeCurrent( dc1, ctx ) ); + ok_ret( TRUE, wglMakeCurrent( dc1, ctx ) );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); todo_wine ok( pixel == 0xff00ff00, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
ctx1 = wglCreateContext( dc1 ); ok( ctx1 != NULL, "got %p\n", ctx1 ); - todo_wine ok_ret( TRUE, wglMakeCurrent( dc1, ctx1 ) ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, wglMakeCurrent( dc1, ctx1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); glReadBuffer( GL_BACK ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( pixel == 0xff00ff00, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok( pixel == 0xff00ff00, "got %#x\n", pixel ); + ok_ret( GL_NO_ERROR, glGetError() );
- todo_wine ok_ret( TRUE, wglMakeCurrent( NULL, NULL ) ); + ok_ret( TRUE, wglMakeCurrent( NULL, NULL ) ); ok_ret( TRUE, wglDeleteContext( ctx1 ) ); ReleaseDC( window, dc1 );
@@ -2737,17 +2737,17 @@ static void test_window_dc(void) ok( dc != NULL, "got %p\n", dc ); ctx = wglCreateContext( dc ); ok( ctx != NULL, "got %p\n", ctx ); - todo_wine ok_ret( TRUE, wglMakeCurrent( dc, ctx ) ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, wglMakeCurrent( dc, ctx ) ); + ok_ret( GL_NO_ERROR, glGetError() ); glReadBuffer( GL_BACK ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( GL_NO_ERROR, glGetError() );
pixel = 0xdeadbeef; glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( pixel == 0xff00ff00, "got %#x\n", pixel ); - todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok( pixel == 0xff00ff00, "got %#x\n", pixel ); + ok_ret( GL_NO_ERROR, glGetError() );
- todo_wine ok_ret( TRUE, wglMakeCurrent( NULL, NULL ) ); + ok_ret( TRUE, wglMakeCurrent( NULL, NULL ) ); ok_ret( TRUE, wglDeleteContext( ctx ) ); ok_ret( TRUE, SwapBuffers( dc ) ); ReleaseDC( window, dc ); diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 142c3c1dc93..1eb966d3fca 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -886,7 +886,6 @@ static void release_dce( struct dce *dce )
set_visible_region( dce->hdc, 0, &dummy_surface.rect, &dummy_surface.rect, &dummy_surface ); user_driver->pReleaseDC( dce->hwnd, dce->hdc ); - set_dc_opengl_drawable( dce->hdc, NULL );
if (dce->clip_rgn) NtGdiDeleteObjectApp( dce->clip_rgn ); dce->clip_rgn = 0; @@ -1224,7 +1223,6 @@ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint ) if (end_paint || (dce->flags & DCX_CACHE)) delete_clip_rgn( dce ); if (dce->flags & DCX_CACHE) { - set_dc_opengl_drawable( dce->hdc, NULL ); dce->count = 0; set_dce_flags( dce->hdc, DCHF_DISABLEDC ); } @@ -1365,12 +1363,6 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags ) if (get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) NtGdiSetLayout( dce->hdc, -1, LAYOUT_RTL );
- if (dce->hwnd != hwnd) - { - struct opengl_drawable *drawable = get_window_current_drawable( hwnd ); - set_dc_opengl_drawable( dce->hdc, drawable ); - if (drawable) opengl_drawable_release( drawable ); - } dce->hwnd = hwnd; dce->flags = (dce->flags & ~user_flags) | (flags & user_flags);
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 003435250be..57e0aa0e27c 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1119,7 +1119,7 @@ void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *new_drawable if (old_drawable) opengl_drawable_release( old_drawable ); }
-struct opengl_drawable *get_window_current_drawable( HWND hwnd ) +static struct opengl_drawable *get_window_current_drawable( HWND hwnd ) { struct opengl_drawable *drawable = NULL; WND *win; @@ -1163,7 +1163,7 @@ static struct opengl_drawable *get_window_unused_drawable( HWND hwnd, int format return drawable; }
-void set_dc_opengl_drawable( HDC hdc, struct opengl_drawable *new_drawable ) +static void set_dc_opengl_drawable( HDC hdc, struct opengl_drawable *new_drawable ) { void *old_drawable = NULL; DC *dc; @@ -1290,7 +1290,6 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal )
if ((drawable = get_window_unused_drawable( hwnd, new_format ))) { - set_dc_opengl_drawable( hdc, drawable ); set_window_opengl_drawable( hwnd, drawable, TRUE ); set_window_opengl_drawable( hwnd, drawable, FALSE ); opengl_drawable_release( drawable ); @@ -1354,18 +1353,38 @@ static BOOL context_unset_current( struct wgl_context *context ) return FALSE; }
+/* 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 ); + if (!hdc && drawable && drawable->client) hwnd = drawable->client->hwnd; + 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 ))) + { + opengl_drawable_release( current ); + opengl_drawable_add_ref( drawable ); + return drawable; + } + + /* get an updated drawable with the desired format */ + return get_window_unused_drawable( hwnd, format ); +} + static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, HDC read_hdc ) { struct opengl_drawable *new_draw, *new_read, *old_draw = NULL, *old_read = NULL; struct wgl_context *previous = NtCurrentTeb()->glContext; BOOL ret = FALSE; - HWND hwnd; - - new_draw = get_dc_opengl_drawable( draw_hdc );
- /* get the last used window drawable when reading */ - if ((hwnd = NtUserWindowFromDC( read_hdc ))) new_read = get_window_current_drawable( hwnd ); - else new_read = get_dc_opengl_drawable( read_hdc ); + new_draw = get_updated_drawable( draw_hdc, context->format, context->draw ); + if (!draw_hdc && context->draw == context->read) opengl_drawable_add_ref( (new_read = new_draw) ); + else if (draw_hdc && draw_hdc == read_hdc) opengl_drawable_add_ref( (new_read = new_draw) ); + else new_read = get_updated_drawable( read_hdc, context->format, context->read );
TRACE( "context %p, new_draw %s, new_read %s\n", context, debugstr_opengl_drawable( new_draw ), debugstr_opengl_drawable( new_read ) );
@@ -1405,7 +1424,7 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H 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, TRUE ); + if (new_draw->client) set_window_opengl_drawable( new_draw->client->hwnd, new_draw, TRUE ); context_exchange_drawables( context, &new_draw, &new_read ); } else if (previous) @@ -1957,19 +1976,17 @@ static BOOL flush_memory_pbuffer( void (*flush)(void) )
static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)(void) ) { - HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; const struct opengl_funcs *funcs = &display_funcs; + struct opengl_drawable *draw = context->draw; UINT flags = 0; int interval; - HWND hwnd;
- if (!(hwnd = NtUserWindowFromDC( draw_hdc ))) return flush_memory_pbuffer( flush ); + if (!draw->client) return flush_memory_pbuffer( flush ); + interval = get_window_swap_interval( draw->client->hwnd );
- interval = get_window_swap_interval( hwnd ); - - TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d, flush %p\n", context, hwnd, draw_hdc, interval, flush ); + TRACE( "context %p, hwnd %p, interval %d, flush %p\n", context, draw->client->hwnd, interval, flush );
- context_sync_drawables( context, draw_hdc, read_hdc ); + context_sync_drawables( context, 0, 0 );
if (flush) flush(); if (flush == funcs->p_glFinish) flags |= GL_FLUSH_FINISHED; @@ -1980,7 +1997,6 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)
static BOOL win32u_wglSwapBuffers( HDC hdc ) { - HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; struct wgl_context *context = NtCurrentTeb()->glContext; const struct opengl_funcs *funcs = &display_funcs; struct opengl_drawable *draw; @@ -1992,9 +2008,9 @@ static BOOL win32u_wglSwapBuffers( HDC hdc )
interval = get_window_swap_interval( hwnd );
- TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d\n", context, hwnd, draw_hdc, interval ); + TRACE( "context %p, hwnd %p, hdc %p, interval %d\n", context, hwnd, hdc, interval );
- if (context) context_sync_drawables( context, draw_hdc, read_hdc ); + if (context) context_sync_drawables( context, 0, 0 );
if (context) opengl_drawable_add_ref( (draw = context->draw) ); else if (!(draw = get_window_current_drawable( hwnd ))) return FALSE; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 4c7ce21d5b4..5db351836de 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -189,11 +189,6 @@ extern void user_lock(void); extern void user_unlock(void); extern void user_check_not_lock(void);
-/* opengl.c */ - -struct opengl_drawable; -extern void set_dc_opengl_drawable( HDC hdc, struct opengl_drawable *new_drawable ); - /* d3dkmtc. */
struct vulkan_gpu diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index ed3e09d3cc5..38b14f57e3b 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -183,7 +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 struct opengl_drawable *get_window_current_drawable( HWND hwnd ); W32KAPI void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *drawable, BOOL current );
/* interface between win32u and the user drivers */