mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:54:13 +00:00
winex11: Set XRender clipping lazily when retrieving the destination picture.
This commit is contained in:
parent
aa4655e899
commit
3be01b185d
3 changed files with 48 additions and 97 deletions
|
@ -188,7 +188,7 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
|
|||
/***********************************************************************
|
||||
* update_x11_clipping
|
||||
*/
|
||||
void update_x11_clipping( X11DRV_PDEVICE *physDev, const RGNDATA *data )
|
||||
static void update_x11_clipping( X11DRV_PDEVICE *physDev, const RGNDATA *data )
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
XSetClipRectangles( gdi_display, physDev->gc, physDev->dc_rect.left, physDev->dc_rect.top,
|
||||
|
|
|
@ -282,7 +282,6 @@ extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
|
|||
struct bitblt_coords *coords, const int *mapping, unsigned int zeropad_mask ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;
|
||||
extern void update_x11_clipping( X11DRV_PDEVICE *physDev, const RGNDATA *data ) DECLSPEC_HIDDEN;
|
||||
extern RGNDATA *add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;
|
||||
extern void restore_clipping_region( X11DRV_PDEVICE *dev, RGNDATA *data ) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ struct xrender_physdev
|
|||
X11DRV_PDEVICE *x11dev;
|
||||
enum wxr_format format;
|
||||
int cache_index;
|
||||
BOOL update_clip;
|
||||
Picture pict;
|
||||
Picture pict_src;
|
||||
XRenderPictFormat *pict_format;
|
||||
|
@ -550,27 +551,51 @@ static BOOL use_source_repeat( struct xrender_physdev *dev )
|
|||
dev->x11dev->drawable_rect.bottom - dev->x11dev->drawable_rect.top == 1);
|
||||
}
|
||||
|
||||
static Picture get_xrender_picture( struct xrender_physdev *dev )
|
||||
static Picture get_xrender_picture( struct xrender_physdev *dev, HRGN clip_rgn, const RECT *clip_rect )
|
||||
{
|
||||
if (!dev->pict && dev->pict_format)
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
RGNDATA *clip = X11DRV_GetRegionData( dev->x11dev->region, 0 );
|
||||
|
||||
wine_tsx11_lock();
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
dev->pict = pXRenderCreatePicture( gdi_display, dev->x11dev->drawable,
|
||||
dev->pict_format, CPSubwindowMode, &pa );
|
||||
if (dev->pict && clip)
|
||||
pXRenderSetPictureClipRectangles( gdi_display, dev->pict,
|
||||
dev->x11dev->dc_rect.left, dev->x11dev->dc_rect.top,
|
||||
(XRectangle *)clip->Buffer, clip->rdh.nCount );
|
||||
wine_tsx11_unlock();
|
||||
TRACE( "Allocing pict=%lx dc=%p drawable=%08lx\n",
|
||||
dev->pict, dev->dev.hdc, dev->x11dev->drawable );
|
||||
HeapFree( GetProcessHeap(), 0, clip );
|
||||
dev->update_clip = TRUE;
|
||||
}
|
||||
|
||||
if (dev->update_clip)
|
||||
{
|
||||
RGNDATA *clip_data;
|
||||
HRGN rgn = 0;
|
||||
|
||||
if (clip_rect)
|
||||
{
|
||||
rgn = CreateRectRgnIndirect( clip_rect );
|
||||
if (clip_rgn) CombineRgn( rgn, rgn, clip_rgn, RGN_AND );
|
||||
CombineRgn( rgn, rgn, dev->x11dev->region, RGN_AND );
|
||||
}
|
||||
else if (clip_rgn)
|
||||
{
|
||||
rgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( rgn, clip_rgn, dev->x11dev->region, RGN_AND );
|
||||
}
|
||||
|
||||
if ((clip_data = X11DRV_GetRegionData( rgn ? rgn : dev->x11dev->region, 0 )))
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
pXRenderSetPictureClipRectangles( gdi_display, dev->pict,
|
||||
dev->x11dev->dc_rect.left, dev->x11dev->dc_rect.top,
|
||||
(XRectangle *)clip_data->Buffer, clip_data->rdh.nCount );
|
||||
wine_tsx11_unlock();
|
||||
HeapFree( GetProcessHeap(), 0, clip_data );
|
||||
}
|
||||
dev->update_clip = (rgn != 0); /* have to update again if we are using a custom region */
|
||||
if (rgn) DeleteObject( rgn );
|
||||
}
|
||||
return dev->pict;
|
||||
}
|
||||
|
||||
|
@ -1102,46 +1127,6 @@ static HFONT xrenderdrv_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void update_xrender_clipping( struct xrender_physdev *dev, const RGNDATA *data )
|
||||
{
|
||||
if (dev->pict)
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
pXRenderSetPictureClipRectangles( gdi_display, dev->pict,
|
||||
dev->x11dev->dc_rect.left, dev->x11dev->dc_rect.top,
|
||||
(XRectangle *)data->Buffer, data->rdh.nCount );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static RGNDATA *add_xrender_clipping_region( struct xrender_physdev *dev, HRGN rgn )
|
||||
{
|
||||
RGNDATA *ret, *data;
|
||||
HRGN clip;
|
||||
|
||||
if (!(ret = X11DRV_GetRegionData( dev->x11dev->region, 0 ))) return NULL;
|
||||
if (!(clip = CreateRectRgn( 0, 0, 0, 0 )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, ret );
|
||||
return NULL;
|
||||
}
|
||||
CombineRgn( clip, dev->x11dev->region, rgn, RGN_AND );
|
||||
if ((data = X11DRV_GetRegionData( clip, 0 )))
|
||||
{
|
||||
update_xrender_clipping( dev, data );
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
DeleteObject( clip );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void restore_xrender_clipping_region( struct xrender_physdev *dev, RGNDATA *data )
|
||||
{
|
||||
if (!data) return;
|
||||
update_xrender_clipping( dev, data );
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
|
||||
static BOOL create_xrender_dc( PHYSDEV *pdev )
|
||||
{
|
||||
X11DRV_PDEVICE *x11dev = get_x11drv_dev( *pdev );
|
||||
|
@ -1321,14 +1306,11 @@ static DWORD xrenderdrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info
|
|||
static void xrenderdrv_SetDeviceClipping( PHYSDEV dev, HRGN vis_rgn, HRGN clip_rgn )
|
||||
{
|
||||
struct xrender_physdev *physdev = get_xrender_dev( dev );
|
||||
RGNDATA *data;
|
||||
|
||||
CombineRgn( physdev->x11dev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
|
||||
physdev->update_clip = TRUE;
|
||||
|
||||
if (!(data = X11DRV_GetRegionData( physdev->x11dev->region, 0 ))) return;
|
||||
update_x11_clipping( physdev->x11dev, data );
|
||||
update_xrender_clipping( physdev, data );
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
dev = GET_NEXT_PHYSDEV( dev, pSetDeviceClipping );
|
||||
dev->funcs->pSetDeviceClipping( dev, vis_rgn, clip_rgn );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2057,7 +2039,7 @@ BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
|||
POINT offset = {0, 0};
|
||||
POINT desired, current;
|
||||
int render_op = PictOpOver;
|
||||
Picture pict = get_xrender_picture( physdev );
|
||||
Picture pict = get_xrender_picture( physdev, 0, (flags & ETO_CLIPPED) ? lprect : NULL );
|
||||
XRenderColor col;
|
||||
|
||||
/* There's a bug in XRenderCompositeText that ignores the xDst and yDst parameters.
|
||||
|
@ -2106,13 +2088,6 @@ BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
|||
}
|
||||
}
|
||||
|
||||
if (flags & ETO_CLIPPED)
|
||||
{
|
||||
HRGN clip_region = CreateRectRgnIndirect( lprect );
|
||||
saved_region = add_xrender_clipping_region( physdev, clip_region );
|
||||
DeleteObject( clip_region );
|
||||
}
|
||||
|
||||
wine_tsx11_lock();
|
||||
/* Make sure we don't have any transforms set from a previous call */
|
||||
set_xrender_transformation(pict, 1, 1, 0, 0);
|
||||
|
@ -2123,7 +2098,6 @@ BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
|||
0, 0, 0, 0, elts, count);
|
||||
wine_tsx11_unlock();
|
||||
HeapFree(GetProcessHeap(), 0, elts);
|
||||
restore_xrender_clipping_region( physdev, saved_region );
|
||||
} else {
|
||||
POINT offset = {0, 0};
|
||||
|
||||
|
@ -2439,7 +2413,7 @@ static DWORD create_image_pixmap( BITMAPINFO *info, const struct gdi_image_bits
|
|||
}
|
||||
|
||||
static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xrender_physdev *physdev_dst,
|
||||
Drawable drawable, HRGN clip, const struct bitblt_coords *src,
|
||||
Drawable drawable, const struct bitblt_coords *src,
|
||||
const struct bitblt_coords *dst )
|
||||
{
|
||||
int width = abs( dst->width );
|
||||
|
@ -2450,7 +2424,6 @@ static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xr
|
|||
Picture src_pict = 0, dst_pict, mask_pict = 0;
|
||||
BOOL use_repeat;
|
||||
double xscale, yscale;
|
||||
RGNDATA *clip_data = NULL;
|
||||
|
||||
use_repeat = use_source_repeat( physdev_src );
|
||||
if (!use_repeat)
|
||||
|
@ -2464,23 +2437,18 @@ static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xr
|
|||
{
|
||||
XRenderPictureAttributes pa;
|
||||
|
||||
if (clip) clip_data = X11DRV_GetRegionData( clip, 0 );
|
||||
x_dst = dst->x;
|
||||
y_dst = dst->y;
|
||||
pa.repeat = RepeatNone;
|
||||
wine_tsx11_lock();
|
||||
dst_pict = pXRenderCreatePicture( gdi_display, drawable, physdev_dst->pict_format, CPRepeat, &pa );
|
||||
if (clip_data)
|
||||
pXRenderSetPictureClipRectangles( gdi_display, dst_pict, 0, 0,
|
||||
(XRectangle *)clip_data->Buffer, clip_data->rdh.nCount );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
x_dst = physdev_dst->x11dev->dc_rect.left + dst->x;
|
||||
y_dst = physdev_dst->x11dev->dc_rect.top + dst->y;
|
||||
dst_pict = get_xrender_picture( physdev_dst );
|
||||
if (clip) clip_data = add_xrender_clipping_region( physdev_dst, clip );
|
||||
dst_pict = get_xrender_picture( physdev_dst, 0, &dst->visrect );
|
||||
}
|
||||
|
||||
if (src->width < 0) x_src += src->width + 1;
|
||||
|
@ -2533,9 +2501,6 @@ static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xr
|
|||
pXRenderFreePicture( gdi_display, dst_pict );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
else update_xrender_clipping( physdev_dst, clip_data );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, clip_data );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2548,10 +2513,11 @@ static void xrender_put_image( Pixmap src_pixmap, Picture src_pict, HRGN clip,
|
|||
Picture dst_pict;
|
||||
XRenderPictureAttributes pa;
|
||||
double xscale, yscale;
|
||||
RGNDATA *clip_data = NULL;
|
||||
|
||||
if (drawable) /* using an intermediate pixmap */
|
||||
{
|
||||
RGNDATA *clip_data = NULL;
|
||||
|
||||
if (clip) clip_data = X11DRV_GetRegionData( clip, 0 );
|
||||
x_dst = dst->x;
|
||||
y_dst = dst->y;
|
||||
|
@ -2562,13 +2528,13 @@ static void xrender_put_image( Pixmap src_pixmap, Picture src_pict, HRGN clip,
|
|||
pXRenderSetPictureClipRectangles( gdi_display, dst_pict, 0, 0,
|
||||
(XRectangle *)clip_data->Buffer, clip_data->rdh.nCount );
|
||||
wine_tsx11_unlock();
|
||||
HeapFree( GetProcessHeap(), 0, clip_data );
|
||||
}
|
||||
else
|
||||
{
|
||||
x_dst = physdev->x11dev->dc_rect.left + dst->x;
|
||||
y_dst = physdev->x11dev->dc_rect.top + dst->y;
|
||||
dst_pict = get_xrender_picture( physdev );
|
||||
if (clip) clip_data = add_xrender_clipping_region( physdev, clip );
|
||||
dst_pict = get_xrender_picture( physdev, clip, &dst->visrect );
|
||||
}
|
||||
|
||||
if (!use_repeat)
|
||||
|
@ -2591,9 +2557,6 @@ static void xrender_put_image( Pixmap src_pixmap, Picture src_pict, HRGN clip,
|
|||
|
||||
if (drawable) pXRenderFreePicture( gdi_display, dst_pict );
|
||||
wine_tsx11_unlock();
|
||||
|
||||
if (!drawable) update_xrender_clipping( physdev, clip_data );
|
||||
HeapFree( GetProcessHeap(), 0, clip_data );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2658,7 +2621,7 @@ static BOOL xrenderdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
|||
tmp.visrect.bottom - tmp.visrect.top, physdev_dst->x11dev->depth );
|
||||
wine_tsx11_unlock();
|
||||
|
||||
xrender_stretch_blit( physdev_src, physdev_dst, tmp_pixmap, 0, src, &tmp );
|
||||
xrender_stretch_blit( physdev_src, physdev_dst, tmp_pixmap, src, &tmp );
|
||||
execute_rop( physdev_dst->x11dev, tmp_pixmap, tmpGC, &dst->visrect, rop );
|
||||
|
||||
wine_tsx11_lock();
|
||||
|
@ -2666,12 +2629,7 @@ static BOOL xrenderdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
|||
XFreeGC( gdi_display, tmpGC );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
HRGN rgn = CreateRectRgnIndirect( &dst->visrect );
|
||||
xrender_stretch_blit( physdev_src, physdev_dst, 0, rgn, src, dst );
|
||||
DeleteObject( rgn );
|
||||
}
|
||||
else xrender_stretch_blit( physdev_src, physdev_dst, 0, src, dst );
|
||||
|
||||
if (physdev_dst != physdev_src) X11DRV_UnlockDIBSection( physdev_src->x11dev, FALSE );
|
||||
X11DRV_UnlockDIBSection( physdev_dst->x11dev, TRUE );
|
||||
|
@ -2782,14 +2740,8 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
|
|||
|
||||
restore_clipping_region( physdev->x11dev, clip_data );
|
||||
}
|
||||
else
|
||||
{
|
||||
HRGN rgn = CreateRectRgnIndirect( &dst->visrect );
|
||||
if (clip) CombineRgn( rgn, rgn, clip, RGN_AND );
|
||||
xrender_put_image( src_pixmap, src_pict, rgn,
|
||||
physdev->pict_format, physdev, 0, src, dst, use_repeat );
|
||||
DeleteObject( rgn );
|
||||
}
|
||||
else xrender_put_image( src_pixmap, src_pict, clip,
|
||||
physdev->pict_format, physdev, 0, src, dst, use_repeat );
|
||||
|
||||
X11DRV_UnlockDIBSection( physdev->x11dev, TRUE );
|
||||
}
|
||||
|
@ -2834,7 +2786,7 @@ static BOOL xrenderdrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
|||
if (physdev_src != physdev_dst) X11DRV_LockDIBSection( physdev_src->x11dev, DIB_Status_GdiMod );
|
||||
X11DRV_LockDIBSection( physdev_dst->x11dev, DIB_Status_GdiMod );
|
||||
|
||||
dst_pict = get_xrender_picture( physdev_dst );
|
||||
dst_pict = get_xrender_picture( physdev_dst, 0, &dst->visrect );
|
||||
|
||||
use_repeat = use_source_repeat( physdev_src );
|
||||
if (!use_repeat)
|
||||
|
|
Loading…
Reference in a new issue