-- v2: winex11: Remove unnecessary members from struct gl_drawable. win32u: Remove unnecessary HDC parameter from p_surface_create. win32u: Remove unnecessary HDC parameter from client_surface_present. opengl32: Resolve multisample draw buffer when using FBO surfaces. win32u: Create a separate draw FBO for multisampled formats. opengl32: Initialize viewport when using FBO surface.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index c28d5e2466e..d43647c8c8a 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -143,6 +143,7 @@ struct context struct hint_state hint; /* GL_HINT_BIT */ GLuint draw_fbo; /* currently bound draw FBO name */ GLuint read_fbo; /* currently bound read FBO name */ + GLboolean has_viewport; /* whether viewport has been initialized */ };
struct wgl_handle @@ -1088,7 +1089,6 @@ BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct context *ctx, *prev = get_current_context( teb, NULL, NULL ); const struct opengl_funcs *funcs = teb->glTable; - struct opengl_drawable *draw, *read;
if (hglrc) { @@ -1106,11 +1106,7 @@ BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) teb->glReserved1[1] = hdc; teb->glCurrentRC = hglrc; teb->glTable = (void *)funcs; - - if ((draw = ctx->base.draw) && !ctx->draw_fbo && draw->fbo) - funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, draw->fbo ); - if ((read = ctx->base.read) && !ctx->read_fbo && read->fbo) - funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, read->fbo ); + pop_default_fbo( teb ); } else if (prev) { @@ -1310,7 +1306,6 @@ BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct context *ctx, *prev = get_current_context( teb, NULL, NULL ); const struct opengl_funcs *funcs = teb->glTable; - struct opengl_drawable *draw, *read;
if (hglrc) { @@ -1329,11 +1324,7 @@ BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC teb->glReserved1[1] = read_hdc; teb->glCurrentRC = hglrc; teb->glTable = (void *)funcs; - - if ((draw = ctx->base.draw) && !ctx->draw_fbo && draw->fbo) - funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, draw->fbo ); - if ((read = ctx->base.read) && !ctx->read_fbo && read->fbo) - funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, read->fbo ); + pop_default_fbo( teb ); } else if (prev) { @@ -1488,10 +1479,17 @@ void pop_default_fbo( TEB *teb ) const struct opengl_funcs *funcs = teb->glTable; struct opengl_drawable *draw, *read; struct context *ctx; + RECT rect;
if (!(ctx = get_current_context( teb, &draw, &read ))) return; if (!ctx->draw_fbo && draw->fbo) funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, draw->fbo ); if (!ctx->read_fbo && read->fbo) funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, read->fbo ); + if (!ctx->has_viewport && draw->fbo && draw->client) + { + NtUserGetClientRect( draw->client->hwnd, &rect, NtUserGetDpiForWindow( draw->client->hwnd ) ); + funcs->p_glViewport( 0, 0, rect.right, rect.bottom ); + ctx->has_viewport = GL_TRUE; + } }
static GLenum *set_default_fbo_draw_buffers( struct context *ctx, struct opengl_drawable *draw,
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 50 ++++++++++++++++++------------------ dlls/win32u/opengl.c | 33 ++++++++++++++++++------ include/wine/opengl_driver.h | 3 ++- 3 files changed, 52 insertions(+), 34 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index d43647c8c8a..aeddb7e7cb5 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -789,29 +789,29 @@ static BOOL check_extension_support( TEB *teb, const char *extension, const char static BOOL get_default_fbo_integer( struct context *ctx, struct opengl_drawable *draw, struct opengl_drawable *read, GLenum pname, GLint *data ) { - if (pname == GL_READ_BUFFER && !ctx->read_fbo && read->fbo) + if (pname == GL_READ_BUFFER && !ctx->read_fbo && read->read_fbo) { if (ctx->pixel_mode.read_buffer) *data = ctx->pixel_mode.read_buffer; else *data = read->doublebuffer ? GL_BACK : GL_FRONT; return TRUE; } - if ((pname == GL_DRAW_BUFFER || pname == GL_DRAW_BUFFER0) && !ctx->draw_fbo && draw->fbo) + if ((pname == GL_DRAW_BUFFER || pname == GL_DRAW_BUFFER0) && !ctx->draw_fbo && draw->draw_fbo) { if (ctx->color_buffer.draw_buffers[0]) *data = ctx->color_buffer.draw_buffers[0]; else *data = draw->doublebuffer ? GL_BACK : GL_FRONT; return TRUE; } - if (pname >= GL_DRAW_BUFFER1 && pname <= GL_DRAW_BUFFER15 && !ctx->draw_fbo && draw->fbo) + if (pname >= GL_DRAW_BUFFER1 && pname <= GL_DRAW_BUFFER15 && !ctx->draw_fbo && draw->draw_fbo) { *data = ctx->color_buffer.draw_buffers[pname - GL_DRAW_BUFFER0]; return TRUE; } - if (pname == GL_DOUBLEBUFFER && draw->fbo) + if (pname == GL_DOUBLEBUFFER && draw->draw_fbo) { *data = draw->doublebuffer; return TRUE; } - if (pname == GL_STEREO && draw->fbo) + if (pname == GL_STEREO && draw->draw_fbo) { *data = draw->stereo; return TRUE; @@ -857,12 +857,12 @@ static BOOL get_integer( TEB *teb, GLenum pname, GLint *data )
if ((ctx = get_current_context( teb, &draw, &read ))) { - if (pname == GL_DRAW_FRAMEBUFFER_BINDING && draw->fbo) + if (pname == GL_DRAW_FRAMEBUFFER_BINDING && draw->draw_fbo) { *data = ctx->draw_fbo; return TRUE; } - if (pname == GL_READ_FRAMEBUFFER_BINDING && read->fbo) + if (pname == GL_READ_FRAMEBUFFER_BINDING && read->read_fbo) { *data = ctx->read_fbo; return TRUE; @@ -1457,9 +1457,9 @@ GLuint get_default_fbo( TEB *teb, GLenum target ) struct context *ctx;
if (!(ctx = get_current_context( teb, &draw, &read ))) return 0; - if (target == GL_FRAMEBUFFER) return draw->fbo; - if (target == GL_DRAW_FRAMEBUFFER) return draw->fbo; - if (target == GL_READ_FRAMEBUFFER) return read->fbo; + if (target == GL_FRAMEBUFFER) return draw->draw_fbo; + if (target == GL_DRAW_FRAMEBUFFER) return draw->draw_fbo; + if (target == GL_READ_FRAMEBUFFER) return read->read_fbo; return 0; }
@@ -1470,8 +1470,8 @@ void push_default_fbo( TEB *teb ) struct context *ctx;
if (!(ctx = get_current_context( teb, &draw, &read ))) return; - if (!ctx->draw_fbo && draw->fbo) funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); - if (!ctx->read_fbo && read->fbo) funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ); + if (!ctx->draw_fbo && draw->draw_fbo) funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); + if (!ctx->read_fbo && read->read_fbo) funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ); }
void pop_default_fbo( TEB *teb ) @@ -1482,9 +1482,9 @@ void pop_default_fbo( TEB *teb ) RECT rect;
if (!(ctx = get_current_context( teb, &draw, &read ))) return; - if (!ctx->draw_fbo && draw->fbo) funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, draw->fbo ); - if (!ctx->read_fbo && read->fbo) funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, read->fbo ); - if (!ctx->has_viewport && draw->fbo && draw->client) + if (!ctx->draw_fbo && draw->draw_fbo) funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, draw->draw_fbo ); + if (!ctx->read_fbo && read->read_fbo) funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, read->read_fbo ); + if (!ctx->has_viewport && draw->draw_fbo && draw->client) { NtUserGetClientRect( draw->client->hwnd, &rect, NtUserGetDpiForWindow( draw->client->hwnd ) ); funcs->p_glViewport( 0, 0, rect.right, rect.bottom ); @@ -1529,7 +1529,7 @@ void wrap_glDrawBuffers( TEB *teb, GLsizei n, const GLenum *bufs ) struct opengl_drawable *draw; struct context *ctx;
- if ((ctx = get_current_context( teb, &draw, NULL )) && !ctx->draw_fbo && draw->fbo) + if ((ctx = get_current_context( teb, &draw, NULL )) && !ctx->draw_fbo && draw->draw_fbo) bufs = set_default_fbo_draw_buffers( ctx, draw, n, bufs, buffer );
funcs->p_glDrawBuffers( n, bufs ); @@ -1542,7 +1542,7 @@ void wrap_glFramebufferDrawBuffersEXT( TEB *teb, GLuint fbo, GLsizei n, const GL struct opengl_drawable *draw; struct context *ctx;
- if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->fbo)) + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->draw_fbo)) bufs = set_default_fbo_draw_buffers( ctx, draw, n, bufs, buffer );
funcs->p_glFramebufferDrawBuffersEXT( fbo, n, bufs ); @@ -1555,7 +1555,7 @@ void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint fbo, GLsizei n, const struct opengl_drawable *draw; struct context *ctx;
- if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->fbo)) + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->draw_fbo)) bufs = set_default_fbo_draw_buffers( ctx, draw, n, bufs, buffer );
funcs->p_glNamedFramebufferDrawBuffers( fbo, n, bufs ); @@ -1632,7 +1632,7 @@ void wrap_glDrawBuffer( TEB *teb, GLenum buf ) struct opengl_drawable *draw; struct context *ctx;
- if ((ctx = get_current_context( teb, &draw, NULL )) && !ctx->draw_fbo && draw->fbo) + if ((ctx = get_current_context( teb, &draw, NULL )) && !ctx->draw_fbo && draw->draw_fbo) buf = set_default_fbo_draw_buffer( ctx, draw, buf );
funcs->p_glDrawBuffer( buf ); @@ -1644,7 +1644,7 @@ void wrap_glFramebufferDrawBufferEXT( TEB *teb, GLuint fbo, GLenum mode ) struct opengl_drawable *draw; struct context *ctx;
- if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->fbo)) + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->draw_fbo)) mode = set_default_fbo_draw_buffer( ctx, draw, mode );
funcs->p_glFramebufferDrawBufferEXT( fbo, mode ); @@ -1656,7 +1656,7 @@ void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint fbo, GLenum buf ) struct opengl_drawable *draw; struct context *ctx;
- if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->fbo)) + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && (fbo = draw->draw_fbo)) buf = set_default_fbo_draw_buffer( ctx, draw, buf );
funcs->p_glNamedFramebufferDrawBuffer( fbo, buf ); @@ -1701,7 +1701,7 @@ void wrap_glReadBuffer( TEB *teb, GLenum src ) struct opengl_drawable *read; struct context *ctx;
- if ((ctx = get_current_context( teb, NULL, &read )) && !ctx->read_fbo && read->fbo) + if ((ctx = get_current_context( teb, NULL, &read )) && !ctx->read_fbo && read->read_fbo) src = set_default_fbo_read_buffer( ctx, read, src );
funcs->p_glReadBuffer( src ); @@ -1713,7 +1713,7 @@ void wrap_glFramebufferReadBufferEXT( TEB *teb, GLuint fbo, GLenum mode ) struct opengl_drawable *read; struct context *ctx;
- if ((ctx = get_current_context( teb, NULL, &read )) && !fbo && (fbo = read->fbo)) + if ((ctx = get_current_context( teb, NULL, &read )) && !fbo && (fbo = read->read_fbo)) mode = set_default_fbo_read_buffer( ctx, read, mode );
funcs->p_glFramebufferReadBufferEXT( fbo, mode ); @@ -1725,7 +1725,7 @@ void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint fbo, GLenum src ) struct opengl_drawable *read; struct context *ctx;
- if ((ctx = get_current_context( teb, NULL, &read )) && !fbo && (fbo = read->fbo)) + if ((ctx = get_current_context( teb, NULL, &read )) && !fbo && (fbo = read->read_fbo)) src = set_default_fbo_read_buffer( ctx, read, src );
funcs->p_glNamedFramebufferReadBuffer( fbo, src ); @@ -1776,7 +1776,7 @@ void wrap_glGetFramebufferParameterivEXT( TEB *teb, GLuint fbo, GLenum pname, GL struct opengl_drawable *draw, *read; struct context *ctx;
- if ((ctx = get_current_context( teb, &draw, &read )) && !fbo && (fbo = draw->fbo)) + if ((ctx = get_current_context( teb, &draw, &read )) && !fbo && (fbo = draw->draw_fbo)) if (get_default_fbo_integer( ctx, draw, read, pname, params )) return;
funcs->p_glGetFramebufferParameterivEXT( fbo, pname, params ); diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index f6aa5a4c190..0cf20475bc7 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -322,7 +322,7 @@ static void framebuffer_surface_destroy( struct opengl_drawable *drawable )
static void framebuffer_surface_flush( struct opengl_drawable *drawable, UINT flags ) { - struct wgl_pixel_format desc = pixel_formats[drawable->format - 1]; + 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 ); @@ -331,22 +331,39 @@ static void framebuffer_surface_flush( struct opengl_drawable *drawable, UINT fl 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) { - destroy_framebuffer( drawable, &desc, drawable->fbo ); - drawable->fbo = 0; + if (drawable->draw_fbo != drawable->read_fbo) + { + destroy_framebuffer( drawable, &draw_desc, drawable->draw_fbo ); + drawable->draw_fbo = 0; + } + destroy_framebuffer( drawable, &read_desc, drawable->read_fbo ); + drawable->read_fbo = 0; }
if (flags & GL_FLUSH_SET_CURRENT) { - drawable->fbo = create_framebuffer( drawable, &desc ); - if (!drawable->fbo) ERR( "Failed to create framebuffer object\n" ); + drawable->read_fbo = create_framebuffer( drawable, &read_desc ); + if (!drawable->read_fbo) ERR( "Failed to create read framebuffer object\n" ); + + 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->fbo) + if ((flags & (GL_FLUSH_UPDATED | GL_FLUSH_SET_CURRENT)) && drawable->read_fbo) { - TRACE( "Resizing drawable %p/%u to %ux%u\n", drawable, drawable->fbo, rect.right, rect.bottom ); - resize_framebuffer( drawable, &desc, drawable->fbo, rect.right, rect.bottom ); + 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 ); + } } }
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 2a0cdb6859b..56f9c1c6793 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -169,7 +169,8 @@ struct opengl_drawable BOOL doublebuffer; /* pixel format is double buffered */ BOOL stereo; /* pixel format is stereo buffered */ EGLSurface surface; /* surface for EGL based drivers */ - GLuint fbo; /* default FBO name when emulating framebuffer */ + GLuint read_fbo; /* default read FBO name when emulating framebuffer */ + GLuint draw_fbo; /* default draw FBO name when emulating framebuffer */ };
static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 15 ++++++ dlls/opengl32/unix_private.h | 1 + dlls/opengl32/unix_thunks.c | 22 ++++++++ dlls/opengl32/unix_wgl.c | 98 ++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index ef6b32dca89..60ba6e2d5b1 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -248,6 +248,20 @@ my %hide_default_fbo_thunks = "glGetFramebufferAttachmentParameteriv" => 1, "glGetFramebufferAttachmentParameterivEXT" => 1, ); +my %resolve_default_fbo_thunks = + ( + "glCopyColorTable" => 1, + "glCopyPixels" => 1, + "glCopyTexImage1D" => 1, + "glCopyTexImage2D" => 1, + "glCopyTexSubImage1D" => 1, + "glCopyTexSubImage2D" => 1, + "glCopyTexSubImage3D" => 1, + "glCopyTextureSubImage1D" => 1, + "glCopyTextureSubImage2D" => 1, + "glCopyTextureSubImage3D" => 1, + "glReadPixels" => 1, + ); my %map_default_fbo_thunks = ( "glBindFramebuffer" => [ "framebuffer" ], @@ -555,6 +569,7 @@ sub generate_unix_thunk($$$$) $target = "params->target" if $call_args =~ "params->target"; $ret .= " if (!params->$arg) params->$arg = get_default_fbo( $teb, $target );\n"; } + $ret .= " resolve_default_fbo( $teb, TRUE );\n" if defined $resolve_default_fbo_thunks{$name}; $ret .= " push_default_fbo( $teb );\n" if defined $hide_default_fbo_thunks{$name}; $ret .= " pthread_mutex_lock( &wgl_lock );\n" if $need_lock; $ret .= " $ret_expr"; diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index 9caad96ebda..4b05a98cccf 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -86,5 +86,6 @@ extern void set_current_fbo( TEB *teb, GLenum target, GLuint framebuffer ); extern GLuint get_default_fbo( TEB *teb, GLenum target ); extern void push_default_fbo( TEB *teb ); extern void pop_default_fbo( TEB *teb ); +extern void resolve_default_fbo( TEB *teb, BOOL read );
#endif /* __WINE_OPENGL32_UNIX_PRIVATE_H */ diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 98d2a018e78..820bd47929f 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -574,6 +574,7 @@ static NTSTATUS gl_glCopyPixels( void *args ) { struct glCopyPixels_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyPixels( params->x, params->y, params->width, params->height, params->type ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -583,6 +584,7 @@ static NTSTATUS gl_glCopyTexImage1D( void *args ) { struct glCopyTexImage1D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTexImage1D( params->target, params->level, params->internalformat, params->x, params->y, params->width, params->border ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -592,6 +594,7 @@ static NTSTATUS gl_glCopyTexImage2D( void *args ) { struct glCopyTexImage2D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTexImage2D( params->target, params->level, params->internalformat, params->x, params->y, params->width, params->height, params->border ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -601,6 +604,7 @@ static NTSTATUS gl_glCopyTexSubImage1D( void *args ) { struct glCopyTexSubImage1D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTexSubImage1D( params->target, params->level, params->xoffset, params->x, params->y, params->width ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -610,6 +614,7 @@ static NTSTATUS gl_glCopyTexSubImage2D( void *args ) { struct glCopyTexSubImage2D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTexSubImage2D( params->target, params->level, params->xoffset, params->yoffset, params->x, params->y, params->width, params->height ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -2196,6 +2201,7 @@ static NTSTATUS gl_glReadBuffer( void *args ) static NTSTATUS gl_glReadPixels( void *args ) { struct glReadPixels_params *params = args; + resolve_default_fbo( params->teb, TRUE ); wrap_glReadPixels( params->teb, params->x, params->y, params->width, params->height, params->format, params->type, params->pixels ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -5580,6 +5586,7 @@ static NTSTATUS ext_glCopyColorTable( void *args ) { struct glCopyColorTable_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyColorTable( params->target, params->internalformat, params->x, params->y, params->width ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -5751,6 +5758,7 @@ static NTSTATUS ext_glCopyTexSubImage3D( void *args ) { struct glCopyTexSubImage3D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTexSubImage3D( params->target, params->level, params->xoffset, params->yoffset, params->zoffset, params->x, params->y, params->width, params->height ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -5787,6 +5795,7 @@ static NTSTATUS ext_glCopyTextureSubImage1D( void *args ) { struct glCopyTextureSubImage1D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTextureSubImage1D( params->texture, params->level, params->xoffset, params->x, params->y, params->width ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -5805,6 +5814,7 @@ static NTSTATUS ext_glCopyTextureSubImage2D( void *args ) { struct glCopyTextureSubImage2D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTextureSubImage2D( params->texture, params->level, params->xoffset, params->yoffset, params->x, params->y, params->width, params->height ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -5823,6 +5833,7 @@ static NTSTATUS ext_glCopyTextureSubImage3D( void *args ) { struct glCopyTextureSubImage3D_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; + resolve_default_fbo( params->teb, TRUE ); funcs->p_glCopyTextureSubImage3D( params->texture, params->level, params->xoffset, params->yoffset, params->zoffset, params->x, params->y, params->width, params->height ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -30894,6 +30905,7 @@ static NTSTATUS wow64_gl_glCopyPixels( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyPixels( params->x, params->y, params->width, params->height, params->type ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -30914,6 +30926,7 @@ static NTSTATUS wow64_gl_glCopyTexImage1D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTexImage1D( params->target, params->level, params->internalformat, params->x, params->y, params->width, params->border ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -30935,6 +30948,7 @@ static NTSTATUS wow64_gl_glCopyTexImage2D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTexImage2D( params->target, params->level, params->internalformat, params->x, params->y, params->width, params->height, params->border ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -30954,6 +30968,7 @@ static NTSTATUS wow64_gl_glCopyTexSubImage1D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTexSubImage1D( params->target, params->level, params->xoffset, params->x, params->y, params->width ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -30975,6 +30990,7 @@ static NTSTATUS wow64_gl_glCopyTexSubImage2D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTexSubImage2D( params->target, params->level, params->xoffset, params->yoffset, params->x, params->y, params->width, params->height ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -33675,6 +33691,7 @@ static NTSTATUS wow64_gl_glReadPixels( void *args ) PTR32 pixels; } *params = args; TEB *teb = get_teb64( params->teb ); + resolve_default_fbo( teb, TRUE ); wrap_glReadPixels( teb, params->x, params->y, params->width, params->height, params->format, params->type, ULongToPtr(params->pixels) ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -39916,6 +39933,7 @@ static NTSTATUS wow64_ext_glCopyColorTable( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyColorTable( params->target, params->internalformat, params->x, params->y, params->width ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -40308,6 +40326,7 @@ static NTSTATUS wow64_ext_glCopyTexSubImage3D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTexSubImage3D( params->target, params->level, params->xoffset, params->yoffset, params->zoffset, params->x, params->y, params->width, params->height ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -40392,6 +40411,7 @@ static NTSTATUS wow64_ext_glCopyTextureSubImage1D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTextureSubImage1D( params->texture, params->level, params->xoffset, params->x, params->y, params->width ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -40433,6 +40453,7 @@ static NTSTATUS wow64_ext_glCopyTextureSubImage2D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTextureSubImage2D( params->texture, params->level, params->xoffset, params->yoffset, params->x, params->y, params->width, params->height ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; @@ -40477,6 +40498,7 @@ static NTSTATUS wow64_ext_glCopyTextureSubImage3D( void *args ) } *params = args; TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; + resolve_default_fbo( teb, TRUE ); funcs->p_glCopyTextureSubImage3D( params->texture, params->level, params->xoffset, params->yoffset, params->zoffset, params->x, params->y, params->width, params->height ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index aeddb7e7cb5..46184fcd7a4 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1164,12 +1164,14 @@ void wrap_glFinish( TEB *teb ) { const struct opengl_funcs *funcs = teb->glTable; flush_context( teb, funcs->p_glFinish ); + resolve_default_fbo( teb, FALSE ); }
void wrap_glFlush( TEB *teb ) { const struct opengl_funcs *funcs = teb->glTable; flush_context( teb, funcs->p_glFlush ); + resolve_default_fbo( teb, FALSE ); }
void wrap_glClear( TEB *teb, GLbitfield mask ) @@ -1177,6 +1179,7 @@ void wrap_glClear( TEB *teb, GLbitfield mask ) const struct opengl_funcs *funcs = teb->glTable; flush_context( teb, NULL ); funcs->p_glClear( mask ); + resolve_default_fbo( teb, FALSE ); }
void wrap_glDrawPixels( TEB *teb, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels ) @@ -1184,6 +1187,7 @@ void wrap_glDrawPixels( TEB *teb, GLsizei width, GLsizei height, GLenum format, const struct opengl_funcs *funcs = teb->glTable; flush_context( teb, NULL ); funcs->p_glDrawPixels( width, height, format, type, pixels ); + resolve_default_fbo( teb, FALSE ); }
void wrap_glReadPixels( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels ) @@ -1198,6 +1202,7 @@ void wrap_glViewport( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height const struct opengl_funcs *funcs = teb->glTable; flush_context( teb, NULL ); funcs->p_glViewport( x, y, width, height ); + resolve_default_fbo( teb, FALSE ); }
BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ) @@ -1205,6 +1210,8 @@ BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ) const struct opengl_funcs *funcs = get_dc_funcs( hdc ); BOOL ret;
+ resolve_default_fbo( teb, FALSE ); + if (!(ret = funcs->p_wglSwapBuffers( hdc ))) { /* default implementation: implicitly flush the context */ @@ -1492,6 +1499,97 @@ void pop_default_fbo( TEB *teb ) } }
+static BOOL context_draws_back( struct context *ctx ) +{ + for (int i = 0; i < ARRAY_SIZE(ctx->color_buffer.draw_buffers); i++) + { + switch (ctx->color_buffer.draw_buffers[i]) + { + case GL_LEFT: + case GL_RIGHT: + case GL_BACK: + case GL_FRONT_AND_BACK: + case GL_BACK_LEFT: + case GL_BACK_RIGHT: + return TRUE; + } + } + + return FALSE; +} + +static BOOL context_draws_front( struct context *ctx ) +{ + for (int i = 0; i < ARRAY_SIZE(ctx->color_buffer.draw_buffers); i++) + { + switch (ctx->color_buffer.draw_buffers[i]) + { + case GL_LEFT: + case GL_RIGHT: + case GL_FRONT: + case GL_FRONT_AND_BACK: + case GL_FRONT_LEFT: + case GL_FRONT_RIGHT: + return TRUE; + } + } + + return FALSE; +} + +void resolve_default_fbo( TEB *teb, BOOL read ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *drawable; + struct context *ctx; + + if (!(ctx = get_current_context( teb, read ? NULL : &drawable, read ? &drawable : NULL )) || !drawable) return; + + if (drawable->draw_fbo && drawable->read_fbo && drawable->draw_fbo != drawable->read_fbo) + { + GLenum mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + RECT rect; + + NtUserGetClientRect( drawable->client->hwnd, &rect, NtUserGetDpiForWindow( drawable->client->hwnd ) ); + + if (context_draws_front( ctx )) + { + funcs->p_glNamedFramebufferReadBuffer( drawable->draw_fbo, GL_COLOR_ATTACHMENT0 ); + funcs->p_glNamedFramebufferDrawBuffer( drawable->read_fbo, GL_COLOR_ATTACHMENT0 ); + funcs->p_glBlitNamedFramebuffer( drawable->draw_fbo, drawable->read_fbo, 0, 0, 0, 0, rect.right, rect.bottom, + rect.right, rect.bottom, mask, GL_NEAREST ); + mask &= ~(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + + if ((drawable->doublebuffer && context_draws_back( ctx )) || (!drawable->doublebuffer && drawable->stereo && context_draws_front( ctx ))) + { + funcs->p_glNamedFramebufferReadBuffer( drawable->draw_fbo, GL_COLOR_ATTACHMENT1 ); + funcs->p_glNamedFramebufferDrawBuffer( drawable->read_fbo, GL_COLOR_ATTACHMENT1 ); + funcs->p_glBlitNamedFramebuffer( drawable->draw_fbo, drawable->read_fbo, 0, 0, 0, 0, rect.right, rect.bottom, + rect.right, rect.bottom, mask, GL_NEAREST ); + mask &= ~(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + + if (drawable->doublebuffer && drawable->stereo && context_draws_front( ctx )) + { + funcs->p_glNamedFramebufferReadBuffer( drawable->draw_fbo, GL_COLOR_ATTACHMENT2 ); + funcs->p_glNamedFramebufferDrawBuffer( drawable->read_fbo, GL_COLOR_ATTACHMENT2 ); + funcs->p_glBlitNamedFramebuffer( drawable->draw_fbo, drawable->read_fbo, 0, 0, 0, 0, rect.right, rect.bottom, + rect.right, rect.bottom, mask, GL_NEAREST ); + mask &= ~(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + + if (drawable->doublebuffer && drawable->stereo && context_draws_back( ctx )) + { + funcs->p_glNamedFramebufferReadBuffer( drawable->draw_fbo, GL_COLOR_ATTACHMENT3 ); + funcs->p_glNamedFramebufferDrawBuffer( drawable->read_fbo, GL_COLOR_ATTACHMENT3 ); + funcs->p_glBlitNamedFramebuffer( drawable->draw_fbo, drawable->read_fbo, 0, 0, 0, 0, rect.right, rect.bottom, + rect.right, rect.bottom, mask, GL_NEAREST ); + mask &= ~(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + } +} + static GLenum *set_default_fbo_draw_buffers( struct context *ctx, struct opengl_drawable *draw, GLsizei count, const GLenum *src, GLenum *dst ) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 2 +- dlls/win32u/window.c | 11 +++++------ dlls/winewayland.drv/opengl.c | 2 +- dlls/winex11.drv/opengl.c | 10 ++++------ include/wine/gdi_driver.h | 2 +- 5 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 5b78e0a0f61..6d6e5f81f54 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -430,7 +430,7 @@ static VkResult win32u_vkQueuePresentKHR( VkQueue client_queue, const VkPresentI struct surface *surface = swapchain->surface; RECT client_rect;
- client_surface_present( surface->client, NULL ); + client_surface_present( surface->client );
if (swapchain_res < VK_SUCCESS) continue; if (!NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) )) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 58bb27d75e4..4345c7b7ff4 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -324,18 +324,17 @@ void client_surface_release( struct client_surface *surface ) } }
-void client_surface_present( struct client_surface *surface, HDC hdc ) +void client_surface_present( struct client_surface *surface ) { + HDC hdc = 0; HWND hwnd; - HDC tmp;
pthread_mutex_lock( &surfaces_lock ); if ((hwnd = surface->hwnd)) { - if (hdc || !surface->offscreen) tmp = hdc; - else tmp = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE ); - surface->funcs->present( surface, surface->offscreen ? tmp : NULL ); - if (tmp && tmp != hdc) NtUserReleaseDC( hwnd, tmp ); + if (surface->offscreen) hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE ); + surface->funcs->present( surface, hdc ); + if (hdc) NtUserReleaseDC( hwnd, hdc ); } pthread_mutex_unlock( &surfaces_lock ); } diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index c3ccfc93202..41cb8463fb1 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -154,7 +154,7 @@ static BOOL wayland_drawable_swap(struct opengl_drawable *base) { struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
- client_surface_present(base->client, NULL); + client_surface_present(base->client); funcs->p_eglSwapBuffers(egl->display, gl->base.surface);
return TRUE; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 6c4a1b1ae6a..188b04ea449 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1199,7 +1199,7 @@ static void x11drv_surface_flush( struct opengl_drawable *base, UINT flags ) { if (!(flags & GL_FLUSH_FINISHED)) funcs->p_glFinish(); XFlush( gdi_display ); - client_surface_present( base->client, gl->hdc ); + client_surface_present( base->client ); } }
@@ -1465,7 +1465,7 @@ static BOOL x11drv_surface_swap( struct opengl_drawable *base ) if (InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) { if (!pglXWaitForSbcOML) XFlush( gdi_display ); - client_surface_present( base->client, gl->hdc ); + client_surface_present( base->client ); }
return TRUE; @@ -1478,8 +1478,6 @@ static void x11drv_egl_surface_destroy( struct opengl_drawable *base )
static void x11drv_egl_surface_flush( struct opengl_drawable *base, UINT flags ) { - struct gl_drawable *gl = impl_from_opengl_drawable( base ); - TRACE( "%s\n", debugstr_opengl_drawable( base ) );
if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval( egl->display, abs( base->interval ) ); @@ -1488,7 +1486,7 @@ static void x11drv_egl_surface_flush( struct opengl_drawable *base, UINT flags ) { if (!(flags & GL_FLUSH_FINISHED)) funcs->p_glFinish(); XFlush( gdi_display ); - client_surface_present( base->client, gl->hdc ); + client_surface_present( base->client ); } }
@@ -1503,7 +1501,7 @@ static BOOL x11drv_egl_surface_swap( struct opengl_drawable *base ) if (InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) { XFlush( gdi_display ); - client_surface_present( base->client, gl->hdc ); + client_surface_present( base->client ); }
return TRUE; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 78c93168132..9ecfa197f0f 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -272,7 +272,7 @@ struct client_surface W32KAPI void *client_surface_create( UINT size, const struct client_surface_funcs *funcs, HWND hwnd ); 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, HDC hdc ); +W32KAPI void client_surface_present( struct client_surface *surface );
static inline const char *debugstr_client_surface( struct client_surface *surface ) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 6 +++--- dlls/wineandroid.drv/opengl.c | 10 +++++----- dlls/winemac.drv/opengl.c | 4 ++-- dlls/winewayland.drv/opengl.c | 2 +- dlls/winex11.drv/opengl.c | 7 ++----- include/wine/opengl_driver.h | 2 +- 6 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 0cf20475bc7..1a5067c62e1 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -606,7 +606,7 @@ static const char *egldrv_init_wgl_extensions( struct opengl_funcs *funcs ) return ""; }
-static BOOL egldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) +static BOOL egldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { struct client_surface *client;
@@ -1000,7 +1000,7 @@ static const char *nulldrv_init_wgl_extensions( struct opengl_funcs *funcs ) return ""; }
-static BOOL nulldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) +static BOOL nulldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { return TRUE; } @@ -1258,7 +1258,7 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) if ((old_format = get_window_pixel_format( hwnd, FALSE )) && !internal) return old_format == new_format;
drawable = get_dc_opengl_drawable( hdc ); - if ((ret = driver_funcs->p_surface_create( hwnd, hdc, new_format, &drawable ))) + if ((ret = driver_funcs->p_surface_create( hwnd, new_format, &drawable ))) { /* update the current window drawable to the last used draw surface */ if ((hwnd = NtUserWindowFromDC( hdc ))) set_window_opengl_drawable( hwnd, drawable ); diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 54e22cc19af..4893e288289 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -71,7 +71,7 @@ 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, HDC hdc, int format, ANativeWindow *window ) +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; @@ -103,7 +103,7 @@ void update_gl_drawable( HWND hwnd ) struct gl_drawable *old, *new;
if (!(old = impl_from_opengl_drawable( get_window_opengl_drawable( hwnd ) ))) return; - if ((new = create_gl_drawable( hwnd, 0, old->base.format, old->window ))) + if ((new = create_gl_drawable( hwnd, old->base.format, old->window ))) { set_window_opengl_drawable( hwnd, &new->base ); opengl_drawable_release( &new->base ); @@ -113,11 +113,11 @@ void update_gl_drawable( HWND hwnd ) NtUserRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE ); }
-static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) +static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { struct gl_drawable *gl;
- TRACE( "hwnd %p, hdc %p, format %d, drawable %p\n", hwnd, hdc, format, drawable ); + TRACE( "hwnd %p, format %d, drawable %p\n", hwnd, format, drawable );
if (*drawable) { @@ -134,7 +134,7 @@ static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct openg return TRUE; }
- if (!(gl = create_gl_drawable( hwnd, hdc, format, NULL ))) return FALSE; + if (!(gl = create_gl_drawable( hwnd, format, NULL ))) return FALSE; *drawable = &gl->base; return TRUE; } diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index d9bc7067dfa..7f145b73711 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1458,13 +1458,13 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share, return TRUE; }
-static BOOL macdrv_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) +static BOOL macdrv_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) { struct macdrv_client_surface *client; struct macdrv_win_data *data; struct gl_drawable *gl;
- TRACE("hwnd %p, hdc %p, format %d, drawable %p\n", hwnd, hdc, format, drawable); + TRACE("hwnd %p, format %d, drawable %p\n", hwnd, format, drawable);
if (!(data = get_win_data(hwnd))) { diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 41cb8463fb1..158ad106fe3 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -83,7 +83,7 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) wl_egl_window_resize(gl->wl_egl_window, client_width, client_height, 0, 0); }
-static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) +static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) { EGLConfig config = egl_config_for_format(format); struct wayland_client_surface *client; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 188b04ea449..8dcc1b1b24a 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -202,7 +202,6 @@ struct gl_drawable Colormap colormap; /* colormap for the client window */ Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ BOOL offscreen; - HDC hdc; HDC hdc_src; HDC hdc_dst; }; @@ -484,7 +483,7 @@ static inline EGLConfig egl_config_for_format(int format) return egl->configs[format - egl->config_count - 1]; }
-static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) +static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { struct opengl_drawable *previous; struct client_surface *client; @@ -500,7 +499,6 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct op client_surface_release( client ); if (!gl) return FALSE; gl->rect = rect; - gl->hdc = hdc;
if (!(gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format( format ), (void *)window, NULL ))) @@ -926,7 +924,7 @@ static GLXContext create_glxcontext( int format, GLXContext share, const int *at return ctx; }
-static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) +static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); struct opengl_drawable *previous; @@ -949,7 +947,6 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl client_surface_release( client ); if (!gl) goto failed; gl->rect = rect; - gl->hdc = hdc; gl->colormap = colormap;
if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, window, NULL ))) diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 56f9c1c6793..984861f106d 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -194,7 +194,7 @@ struct opengl_driver_funcs UINT (*p_init_pixel_formats)(UINT*); BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); const char *(*p_init_wgl_extensions)(struct opengl_funcs *funcs); - BOOL (*p_surface_create)( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ); + BOOL (*p_surface_create)( HWND hwnd, int format, struct opengl_drawable **drawable ); BOOL (*p_context_create)( int format, void *share, const int *attribs, void **context ); BOOL (*p_context_destroy)(void*); BOOL (*p_make_current)( struct opengl_drawable *draw, struct opengl_drawable *read, void *private );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 8dcc1b1b24a..a5fd7bcb26c 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -197,13 +197,8 @@ struct glx_pixel_format struct gl_drawable { struct opengl_drawable base; - RECT rect; /* current size of the GL drawable */ GLXDrawable drawable; /* drawable for rendering with GL */ Colormap colormap; /* colormap for the client window */ - Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ - BOOL offscreen; - HDC hdc_src; - HDC hdc_dst; };
static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *base ) @@ -498,7 +493,6 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_draw gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); client_surface_release( client ); if (!gl) return FALSE; - gl->rect = rect;
if (!(gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format( format ), (void *)window, NULL ))) @@ -869,8 +863,6 @@ static void x11drv_surface_destroy( struct opengl_drawable *base )
if (gl->drawable) pglXDestroyWindow( gdi_display, gl->drawable ); if (gl->colormap) XFreeColormap( gdi_display, gl->colormap ); - if (gl->hdc_src) NtGdiDeleteObjectApp( gl->hdc_src ); - if (gl->hdc_dst) NtGdiDeleteObjectApp( gl->hdc_dst ); }
static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) @@ -946,7 +938,6 @@ static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ); client_surface_release( client ); if (!gl) goto failed; - gl->rect = rect; gl->colormap = colormap;
if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, window, NULL ))) @@ -1448,10 +1439,12 @@ static BOOL x11drv_surface_swap( struct opengl_drawable *base ) GLXContext ctx = NtCurrentTeb()->glReserved2; struct gl_drawable *gl = impl_from_opengl_drawable( base ); INT64 ust, msc, sbc, target_sbc = 0; + BOOL offscreen;
TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) );
- if (!ctx || gl->offscreen || !pglXSwapBuffersMscOML) pglXSwapBuffers( gdi_display, gl->drawable ); + if ((offscreen = InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) || + !ctx || !pglXSwapBuffersMscOML) pglXSwapBuffers( gdi_display, gl->drawable ); else { funcs->p_glFlush(); @@ -1459,7 +1452,7 @@ static BOOL x11drv_surface_swap( struct opengl_drawable *base ) if (pglXWaitForSbcOML) pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc ); }
- if (InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) + if (offscreen) { if (!pglXWaitForSbcOML) XFlush( gdi_display ); client_surface_present( base->client );
v2: Add a couple of cleanup changes.