From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wineandroid.drv/opengl.c | 28 +++++++++++++++------------- dlls/winewayland.drv/opengl.c | 19 +++++++++---------- dlls/winex11.drv/opengl.c | 29 ++++++++++++++++++----------- include/wine/opengl_driver.h | 15 +++++++++++++++ 4 files changed, 57 insertions(+), 34 deletions(-)
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 9075e7d4ac2..ae1cf6fa3f8 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -67,10 +67,8 @@ struct android_context
struct gl_drawable { + struct opengl_drawable base; struct list entry; - HWND hwnd; - HDC hdc; - int format; ANativeWindow *window; EGLSurface surface; EGLSurface pbuffer; @@ -93,16 +91,20 @@ static inline EGLConfig egl_config_for_format(int format) static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format ) { static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; - struct gl_drawable *gl = malloc( sizeof(*gl) ); + struct gl_drawable *gl; + + if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL; + gl->base.hwnd = hwnd; + gl->base.hdc = hdc; + gl->base.format = format;
- gl->hwnd = hwnd; - gl->hdc = hdc; - gl->format = format; gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); gl->surface = 0; - gl->pbuffer = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->format), attribs ); + gl->pbuffer = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->base.format), attribs ); pthread_mutex_lock( &drawable_mutex ); list_add_head( &gl_drawables, &gl->entry ); + + TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); return gl; }
@@ -113,8 +115,8 @@ static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) pthread_mutex_lock( &drawable_mutex ); LIST_FOR_EACH_ENTRY( gl, &gl_drawables, struct gl_drawable, entry ) { - if (hwnd && gl->hwnd == hwnd) return gl; - if (hdc && gl->hdc == hdc) return gl; + if (hwnd && gl->base.hwnd == hwnd) return gl; + if (hdc && gl->base.hdc == hdc) return gl; } pthread_mutex_unlock( &drawable_mutex ); return NULL; @@ -132,7 +134,7 @@ void destroy_gl_drawable( HWND hwnd ) pthread_mutex_lock( &drawable_mutex ); LIST_FOR_EACH_ENTRY( gl, &gl_drawables, struct gl_drawable, entry ) { - if (gl->hwnd != hwnd) continue; + if (gl->base.hwnd != hwnd) continue; list_remove( &gl->entry ); if (gl->surface) funcs->p_eglDestroySurface( egl->display, gl->surface ); if (gl->pbuffer) funcs->p_eglDestroySurface( egl->display, gl->pbuffer ); @@ -164,7 +166,7 @@ void update_gl_drawable( HWND hwnd ) if ((gl = get_gl_drawable( hwnd, 0 ))) { if (!gl->surface && - (gl->surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->format), + (gl->surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->base.format), gl->window, NULL ))) { LIST_FOR_EACH_ENTRY( ctx, &gl_contexts, struct android_context, entry ) @@ -196,7 +198,7 @@ static BOOL android_set_pixel_format( HWND hwnd, int old_format, int new_format, EGLint pf; funcs->p_eglGetConfigAttrib( egl->display, egl_config_for_format(new_format), EGL_NATIVE_VISUAL_ID, &pf ); gl->window->perform( gl->window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, pf ); - gl->format = new_format; + gl->base.format = new_format; } } else gl = create_gl_drawable( hwnd, 0, new_format ); diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index ce93fd1f432..ea4c542d770 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -55,10 +55,9 @@ static struct list gl_contexts = LIST_INIT(gl_contexts);
struct wayland_gl_drawable { + struct opengl_drawable base; struct list entry; LONG ref; - HWND hwnd; - HDC hdc; struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; EGLSurface surface; @@ -97,8 +96,8 @@ static struct wayland_gl_drawable *find_drawable(HWND hwnd, HDC hdc) struct wayland_gl_drawable *gl; LIST_FOR_EACH_ENTRY(gl, &gl_drawables, struct wayland_gl_drawable, entry) { - if (hwnd && gl->hwnd == hwnd) return gl; - if (hdc && gl->hdc == hdc) return gl; + if (hwnd && gl->base.hwnd == hwnd) return gl; + if (hdc && gl->base.hdc == hdc) return gl; } return NULL; } @@ -168,12 +167,12 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc } *attrib++ = EGL_NONE;
- gl = calloc(1, sizeof(*gl)); - if (!gl) return NULL; + if (!(gl = calloc(1, sizeof(*gl)))) return NULL; + gl->base.hwnd = hwnd; + gl->base.hdc = hdc; + gl->base.format = format;
gl->ref = 1; - gl->hwnd = hwnd; - gl->hdc = hdc; gl->swap_interval = 1;
/* Get the client surface for the HWND. If don't have a wayland surface @@ -198,7 +197,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc
gl->double_buffered = is_onscreen_format(format);
- TRACE("hwnd=%p egl_surface=%p\n", gl->hwnd, gl->surface); + TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->surface);
return gl;
@@ -241,7 +240,7 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl)
if (InterlockedCompareExchange(&gl->resized, FALSE, TRUE)) { - NtUserGetClientRect(gl->hwnd, &client_rect, NtUserGetDpiForWindow(gl->hwnd)); + NtUserGetClientRect(gl->base.hwnd, &client_rect, NtUserGetDpiForWindow(gl->base.hwnd)); client_width = client_rect.right - client_rect.left; client_height = client_rect.bottom - client_rect.top; if (client_width == 0 || client_height == 0) client_width = client_height = 1; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 5f7cc9a9276..35c750c91f7 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -211,9 +211,9 @@ enum dc_gl_type
struct gl_drawable { + struct opengl_drawable base; LONG ref; /* reference count */ enum dc_gl_type type; /* type of GL surface */ - HWND hwnd; RECT rect; /* current size of the GL drawable */ GLXDrawable drawable; /* drawable for rendering with GL */ Window window; /* window if drawable is a GLXWindow */ @@ -838,7 +838,7 @@ static void release_gl_drawable( struct gl_drawable *gl ) case DC_GL_WINDOW: TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable ); pglXDestroyWindow( gdi_display, gl->drawable ); - destroy_client_window( gl->hwnd, gl->window ); + destroy_client_window( gl->base.hwnd, gl->window ); XFreeColormap( gdi_display, gl->colormap ); break; case DC_GL_PBUFFER: @@ -932,11 +932,13 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL; + gl->base.hwnd = hwnd; + gl->base.hdc = 0; + gl->base.format = format;
/* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI there is no way to query it. */ gl->swap_interval = INT_MIN; gl->ref = 1; - gl->hwnd = hwnd; gl->rect = rect;
gl->type = DC_GL_WINDOW; @@ -945,7 +947,6 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) fmt->visual->class == DirectColor) ? AllocAll : AllocNone ); gl->window = create_client_window( hwnd, fmt->visual, gl->colormap ); if (gl->window) gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, gl->window, NULL ); - TRACE( "%p created client %lx drawable %lx, format %d\n", hwnd, gl->window, gl->drawable, format );
if (!gl->drawable) { @@ -953,6 +954,8 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) return NULL; }
+ TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), gl->window ); + pthread_mutex_lock( &context_mutex ); if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev )) release_gl_drawable( prev ); @@ -984,7 +987,7 @@ static void update_gl_drawable_size( struct gl_drawable *gl ) XWindowChanges changes; RECT rect;
- NtUserGetClientRect( gl->hwnd, &rect, NtUserGetDpiForWindow( gl->hwnd ) ); + NtUserGetClientRect( gl->base.hwnd, &rect, NtUserGetDpiForWindow( gl->base.hwnd ) ); if (EqualRect( &gl->rect, &rect )) return;
changes.width = min( max( 1, rect.right ), 65535 ); @@ -995,12 +998,12 @@ static void update_gl_drawable_size( struct gl_drawable *gl )
static void update_gl_drawable_offscreen( struct gl_drawable *gl ) { - BOOL offscreen = needs_offscreen_rendering( gl->hwnd ); + BOOL offscreen = needs_offscreen_rendering( gl->base.hwnd ); struct x11drv_win_data *data;
if (offscreen == gl->offscreen) { - if (!offscreen && (data = get_win_data( gl->hwnd ))) + if (!offscreen && (data = get_win_data( gl->base.hwnd ))) { attach_client_window( data, gl->window ); release_win_data( data ); @@ -1009,7 +1012,7 @@ static void update_gl_drawable_offscreen( struct gl_drawable *gl ) } gl->offscreen = offscreen;
- TRACE( "Moving hwnd %p client %lx drawable %lx %sscreen\n", gl->hwnd, gl->window, gl->drawable, offscreen ? "off" : "on" ); + TRACE( "Moving hwnd %p client %lx drawable %lx %sscreen\n", gl->base.hwnd, gl->window, gl->drawable, offscreen ? "off" : "on" );
if (!gl->offscreen) { @@ -1039,7 +1042,7 @@ static void update_gl_drawable_offscreen( struct gl_drawable *gl ) #endif }
- if ((data = get_win_data( gl->hwnd ))) + if ((data = get_win_data( gl->base.hwnd ))) { if (gl->offscreen) detach_client_window( data, gl->window ); else attach_client_window( data, gl->window ); @@ -1058,12 +1061,12 @@ void sync_gl_drawable( HWND hwnd ) pthread_mutex_lock( &context_mutex ); LIST_FOR_EACH_ENTRY( context, &context_list, struct x11drv_context, entry ) { - if ((gl = context->draw) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) + if ((gl = context->draw) && gl->type == DC_GL_WINDOW && gl->base.hwnd == hwnd) { update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); } - if ((gl = context->read) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) + if ((gl = context->read) && gl->type == DC_GL_WINDOW && gl->base.hwnd == hwnd) { update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); @@ -1524,6 +1527,10 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex glx_attribs[count++] = 0;
if (!(surface = calloc( 1, sizeof(*surface) ))) return FALSE; + surface->base.hwnd = 0; + surface->base.hdc = hdc; + surface->base.format = format; + surface->type = DC_GL_PBUFFER; surface->ref = 1;
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index ff8f3e6e339..cab2b8cc422 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -27,6 +27,7 @@ #include <wingdi.h>
#include "wine/wgl.h" +#include "wine/debug.h"
struct wgl_pixel_format { @@ -123,6 +124,20 @@ struct egl_platform BOOL has_EGL_EXT_pixel_format_float; };
+/* a driver opengl drawable, either a client surface of a pbuffer */ +struct opengl_drawable +{ + int format; /* pixel format of the drawable */ + HWND hwnd; /* window the drawable was created for */ + HDC hdc; /* DC the drawable was created for */ +}; + +static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable ) +{ + if (!drawable) return "(null)"; + return wine_dbg_sprintf( "%p (format %u, hwnd %p, hdc %p)", drawable, drawable->format, drawable->hwnd, drawable->hdc ); +} + /* interface between win32u and the user drivers */ struct opengl_driver_funcs {