winex11: Use a GLXPixmap for offscreen OpenGL rendering when XComposite isn't available.
This commit is contained in:
parent
3629ea4cfd
commit
37d835bf9a
|
@ -152,12 +152,14 @@ static void update_visible_region( struct dce *dce )
|
|||
escape.drawable = data->icon_window;
|
||||
escape.fbconfig_id = 0;
|
||||
escape.gl_drawable = 0;
|
||||
escape.pixmap = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
escape.drawable = X11DRV_get_whole_window( top );
|
||||
escape.fbconfig_id = X11DRV_get_fbconfig_id( dce->hwnd );
|
||||
escape.gl_drawable = X11DRV_get_gl_drawable( dce->hwnd );
|
||||
escape.pixmap = X11DRV_get_gl_pixmap( dce->hwnd );
|
||||
}
|
||||
|
||||
escape.code = X11DRV_SET_DRAWABLE;
|
||||
|
@ -195,6 +197,7 @@ static void release_dce( struct dce *dce )
|
|||
virtual_screen_rect.bottom - virtual_screen_rect.top );
|
||||
escape.fbconfig_id = 0;
|
||||
escape.gl_drawable = 0;
|
||||
escape.pixmap = 0;
|
||||
ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
|
||||
}
|
||||
|
||||
|
|
|
@ -342,6 +342,7 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID
|
|||
physDev->drawable_rect = data->drawable_rect;
|
||||
physDev->current_pf = pixelformat_from_fbconfig_id( data->fbconfig_id );
|
||||
physDev->gl_drawable = data->gl_drawable;
|
||||
physDev->pixmap = data->pixmap;
|
||||
wine_tsx11_lock();
|
||||
XSetSubwindowMode( gdi_display, physDev->gc, data->mode );
|
||||
wine_tsx11_unlock();
|
||||
|
|
|
@ -972,6 +972,12 @@ static inline void sync_context(Wine_GLContext *context)
|
|||
}
|
||||
|
||||
|
||||
Drawable create_glxpixmap(Display *display, XVisualInfo *vis, Pixmap parent)
|
||||
{
|
||||
return pglXCreateGLXPixmap(display, vis, parent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* X11DRV_ChoosePixelFormat
|
||||
*
|
||||
|
@ -1965,12 +1971,14 @@ static inline void update_drawable(X11DRV_PDEVICE *physDev)
|
|||
h = physDev->dc_rect.bottom - physDev->dc_rect.top;
|
||||
|
||||
if(w > 0 && h > 0) {
|
||||
Drawable src = physDev->pixmap;
|
||||
if(!src) src = physDev->gl_drawable;
|
||||
|
||||
/* The GL drawable may be lagged behind if we don't flush first, so
|
||||
* flush the display make sure we copy up-to-date data */
|
||||
XFlush(gdi_display);
|
||||
XCopyArea(gdi_display, physDev->gl_drawable, physDev->drawable,
|
||||
physDev->gc, 0, 0, w, h, physDev->dc_rect.left,
|
||||
physDev->dc_rect.top);
|
||||
XCopyArea(gdi_display, src, physDev->drawable, physDev->gc, 0, 0, w, h,
|
||||
physDev->dc_rect.left, physDev->dc_rect.top);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3189,7 +3197,7 @@ static void X11DRV_WineGL_LoadExtensions(void)
|
|||
}
|
||||
|
||||
|
||||
static XID create_glxpixmap(X11DRV_PDEVICE *physDev)
|
||||
static XID create_bitmap_glxpixmap(X11DRV_PDEVICE *physDev)
|
||||
{
|
||||
GLXPixmap ret;
|
||||
XVisualInfo *vis;
|
||||
|
@ -3220,7 +3228,7 @@ Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
|
|||
else
|
||||
{
|
||||
if(!physDev->bitmap->glxpixmap)
|
||||
physDev->bitmap->glxpixmap = create_glxpixmap(physDev);
|
||||
physDev->bitmap->glxpixmap = create_bitmap_glxpixmap(physDev);
|
||||
ret = physDev->bitmap->glxpixmap;
|
||||
}
|
||||
}
|
||||
|
@ -3344,6 +3352,11 @@ void mark_drawable_dirty(Drawable old, Drawable new)
|
|||
{
|
||||
}
|
||||
|
||||
Drawable create_glxpixmap(Display *display, XVisualInfo *vis, Pixmap parent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ChoosePixelFormat (X11DRV.@)
|
||||
*/
|
||||
|
|
|
@ -58,6 +58,7 @@ static const char whole_window_prop[] = "__wine_x11_whole_window";
|
|||
static const char icon_window_prop[] = "__wine_x11_icon_window";
|
||||
static const char fbconfig_id_prop[] = "__wine_x11_fbconfig_id";
|
||||
static const char gl_drawable_prop[] = "__wine_x11_gl_drawable";
|
||||
static const char pixmap_prop[] = "__wine_x11_pixmap";
|
||||
static const char managed_prop[] = "__wine_x11_managed";
|
||||
static const char visual_id_prop[] = "__wine_x11_visual_id";
|
||||
|
||||
|
@ -241,7 +242,27 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
|
|||
XMapWindow(display, data->gl_drawable);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
WARN("XComposite is not available, using GLXPixmap hack\n");
|
||||
|
||||
data->pixmap = XCreatePixmap(display, parent, w, h, vis->depth);
|
||||
if(!data->pixmap)
|
||||
{
|
||||
ERR("Failed to create pixmap for offscreen rendering\n");
|
||||
XFree(vis);
|
||||
wine_tsx11_unlock();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data->gl_drawable = create_glxpixmap(display, vis, data->pixmap);
|
||||
if(!data->gl_drawable)
|
||||
{
|
||||
XFreePixmap(display, data->pixmap);
|
||||
data->pixmap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(!data->gl_drawable)
|
||||
{
|
||||
|
@ -263,6 +284,7 @@ done:
|
|||
data->fbconfig_id = fbconfig_id;
|
||||
SetPropA(hwnd, fbconfig_id_prop, (HANDLE)data->fbconfig_id);
|
||||
SetPropA(hwnd, gl_drawable_prop, (HANDLE)data->gl_drawable);
|
||||
SetPropA(hwnd, pixmap_prop, (HANDLE)data->pixmap);
|
||||
invalidate_dce( hwnd, &data->window_rect );
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -271,6 +293,11 @@ static void update_gl_drawable(Display *display, struct x11drv_win_data *data, c
|
|||
{
|
||||
int w = data->client_rect.right - data->client_rect.left;
|
||||
int h = data->client_rect.bottom - data->client_rect.top;
|
||||
XVisualInfo *vis;
|
||||
Drawable parent;
|
||||
HWND next_hwnd;
|
||||
Drawable glxp;
|
||||
Pixmap pix;
|
||||
|
||||
if((w == old_client_rect->right - old_client_rect->left &&
|
||||
h == old_client_rect->bottom - old_client_rect->top) ||
|
||||
|
@ -290,6 +317,60 @@ static void update_gl_drawable(Display *display, struct x11drv_win_data *data, c
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
parent = data->whole_window;
|
||||
next_hwnd = data->hwnd;
|
||||
while(!parent)
|
||||
{
|
||||
next_hwnd = GetAncestor(next_hwnd, GA_PARENT);
|
||||
if(!next_hwnd)
|
||||
{
|
||||
ERR("Could not find parent HWND with a drawable!\n");
|
||||
return;
|
||||
}
|
||||
parent = X11DRV_get_whole_window(next_hwnd);
|
||||
}
|
||||
|
||||
wine_tsx11_lock();
|
||||
|
||||
vis = visual_from_fbconfig_id(data->fbconfig_id);
|
||||
if(!vis) return;
|
||||
|
||||
pix = XCreatePixmap(display, parent, w, h, vis->depth);
|
||||
if(!pix)
|
||||
{
|
||||
ERR("Failed to create pixmap for offscreen rendering\n");
|
||||
XFree(vis);
|
||||
wine_tsx11_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
glxp = create_glxpixmap(display, vis, pix);
|
||||
if(!glxp)
|
||||
{
|
||||
ERR("Failed to create drawable for offscreen rendering\n");
|
||||
XFreePixmap(display, pix);
|
||||
XFree(vis);
|
||||
wine_tsx11_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
XFree(vis);
|
||||
|
||||
mark_drawable_dirty(data->gl_drawable, glxp);
|
||||
|
||||
XFreePixmap(display, data->pixmap);
|
||||
destroy_glxpixmap(display, data->gl_drawable);
|
||||
|
||||
data->pixmap = pix;
|
||||
data->gl_drawable = glxp;
|
||||
|
||||
XFlush(display);
|
||||
wine_tsx11_unlock();
|
||||
|
||||
SetPropA(data->hwnd, gl_drawable_prop, (HANDLE)data->gl_drawable);
|
||||
SetPropA(data->hwnd, pixmap_prop, (HANDLE)data->pixmap);
|
||||
invalidate_dce( data->hwnd, &data->window_rect );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1046,7 +1127,14 @@ void X11DRV_DestroyWindow( HWND hwnd )
|
|||
|
||||
if (!(data = X11DRV_get_win_data( hwnd ))) return;
|
||||
|
||||
if (data->gl_drawable)
|
||||
if (data->pixmap)
|
||||
{
|
||||
destroy_glxpixmap(display, data->gl_drawable);
|
||||
wine_tsx11_lock();
|
||||
XFreePixmap(display, data->pixmap);
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
else if (data->gl_drawable)
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
XDestroyWindow(display, data->gl_drawable);
|
||||
|
@ -1079,6 +1167,7 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
|
|||
data->icon_window = 0;
|
||||
data->fbconfig_id = 0;
|
||||
data->gl_drawable = 0;
|
||||
data->pixmap = 0;
|
||||
data->xic = 0;
|
||||
data->managed = FALSE;
|
||||
data->dce = NULL;
|
||||
|
@ -1397,6 +1486,19 @@ Drawable X11DRV_get_gl_drawable( HWND hwnd )
|
|||
return data->gl_drawable;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_get_gl_pixmap
|
||||
*
|
||||
* Return the Pixmap associated with the GL drawable (if any) for this window.
|
||||
*/
|
||||
Pixmap X11DRV_get_gl_pixmap( HWND hwnd )
|
||||
{
|
||||
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
|
||||
|
||||
if (!data) return (Pixmap)GetPropA( hwnd, pixmap_prop );
|
||||
return data->pixmap;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_get_ic
|
||||
|
|
|
@ -140,6 +140,7 @@ typedef struct
|
|||
struct dce *dce; /* opaque pointer to DCE */
|
||||
int current_pf;
|
||||
Drawable gl_drawable;
|
||||
Pixmap pixmap; /* Pixmap for a GLXPixmap gl_drawable */
|
||||
XRENDERINFO xrender;
|
||||
} X11DRV_PDEVICE;
|
||||
|
||||
|
@ -488,6 +489,7 @@ struct x11drv_escape_set_drawable
|
|||
RECT drawable_rect;/* Drawable rectangle relative to screen */
|
||||
XID fbconfig_id; /* fbconfig id used by the GL drawable */
|
||||
Drawable gl_drawable; /* GL drawable */
|
||||
Pixmap pixmap; /* Pixmap for a GLXPixmap gl_drawable */
|
||||
};
|
||||
|
||||
struct x11drv_escape_set_dce
|
||||
|
@ -648,6 +650,7 @@ struct x11drv_win_data
|
|||
Window icon_window; /* X window for the icon */
|
||||
XID fbconfig_id; /* fbconfig id for the GL drawable this hwnd uses */
|
||||
Drawable gl_drawable; /* Optional GL drawable for rendering the client area */
|
||||
Pixmap pixmap; /* Base pixmap for if gl_drawable is a GLXPixmap */
|
||||
RECT window_rect; /* USER window rectangle relative to parent */
|
||||
RECT whole_rect; /* X window rectangle for the whole window relative to parent */
|
||||
RECT client_rect; /* client area relative to whole window */
|
||||
|
@ -664,6 +667,7 @@ extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
|
|||
extern Window X11DRV_get_whole_window( HWND hwnd );
|
||||
extern XID X11DRV_get_fbconfig_id( HWND hwnd );
|
||||
extern Drawable X11DRV_get_gl_drawable( HWND hwnd );
|
||||
extern Pixmap X11DRV_get_gl_pixmap( HWND hwnd );
|
||||
extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect );
|
||||
extern XIC X11DRV_get_ic( HWND hwnd );
|
||||
extern BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig );
|
||||
|
@ -671,6 +675,7 @@ extern BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig );
|
|||
extern int pixelformat_from_fbconfig_id( XID fbconfig_id );
|
||||
extern XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id );
|
||||
extern void mark_drawable_dirty( Drawable old, Drawable new );
|
||||
extern Drawable create_glxpixmap( Display *display, XVisualInfo *vis, Pixmap parent );
|
||||
|
||||
extern void alloc_window_dce( struct x11drv_win_data *data );
|
||||
extern void free_window_dce( struct x11drv_win_data *data );
|
||||
|
|
Loading…
Reference in New Issue