winex11: Introduce get_xrender_picture for retrieving a Picture from a physDev and allocating a Picture when needed.

This commit is contained in:
Roderick Colenbrander 2009-10-08 17:24:46 +02:00 committed by Alexandre Julliard
parent 1622fd0e7a
commit 34116289a5
1 changed files with 57 additions and 46 deletions

View File

@ -146,7 +146,6 @@ struct xrender_info
Picture pict; Picture pict;
}; };
static gsCacheEntry *glyphsetCache = NULL; static gsCacheEntry *glyphsetCache = NULL;
static DWORD glyphsetCacheSize = 0; static DWORD glyphsetCacheSize = 0;
static INT lastfree = -1; static INT lastfree = -1;
@ -482,6 +481,49 @@ static WineXRenderFormat *get_xrender_format_from_color_shifts(int depth, ColorS
return NULL; return NULL;
} }
/* Set the x/y scaling and x/y offsets in the transformation matrix of the source picture */
static void set_xrender_transformation(Picture src_pict, float xscale, float yscale, int xoffset, int yoffset)
{
#ifdef HAVE_XRENDERSETPICTURETRANSFORM
XTransform xform = {{
{ XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(xoffset) },
{ XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(yoffset) },
{ XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }
}};
pXRenderSetPictureTransform(gdi_display, src_pict, &xform);
#endif
}
static Picture create_xrender_picture(Drawable drawable, int depth, ColorShifts *shifts)
{
Picture pict;
XRenderPictureAttributes pa;
WineXRenderFormat *fmt = get_xrender_format_from_color_shifts(depth, shifts);
if (!fmt) return 0;
wine_tsx11_lock();
pa.subwindow_mode = IncludeInferiors;
pict = pXRenderCreatePicture(gdi_display, drawable, fmt->pict_format, CPSubwindowMode, &pa);
wine_tsx11_unlock();
return pict;
}
static Picture get_xrender_picture(X11DRV_PDEVICE *physDev)
{
struct xrender_info *info = get_xrender_info(physDev);
if (!info) return 0;
if(!info->pict)
{
info->pict = create_xrender_picture(physDev->drawable, physDev->depth, physDev->color_shifts);
TRACE("Allocing pict=%lx dc=%p drawable=%08lx\n", info->pict, physDev->hdc, physDev->drawable);
}
return info->pict;
}
static BOOL fontcmp(LFANDSIZE *p1, LFANDSIZE *p2) static BOOL fontcmp(LFANDSIZE *p1, LFANDSIZE *p2)
{ {
if(p1->hash != p2->hash) return TRUE; if(p1->hash != p2->hash) return TRUE;
@ -1434,7 +1476,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
gsCacheEntry *entry; gsCacheEntry *entry;
gsCacheEntryFormat *formatEntry; gsCacheEntryFormat *formatEntry;
BOOL retv = FALSE; BOOL retv = FALSE;
HDC hdc = physDev->hdc;
int textPixel, backgroundPixel; int textPixel, backgroundPixel;
HRGN saved_region = 0; HRGN saved_region = 0;
BOOL disable_antialias = FALSE; BOOL disable_antialias = FALSE;
@ -1515,35 +1556,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
DeleteObject( clip_region ); DeleteObject( clip_region );
} }
if(X11DRV_XRender_Installed) {
if(!physDev->xrender->pict) {
XRenderPictureAttributes pa;
pa.subwindow_mode = IncludeInferiors;
wine_tsx11_lock();
physDev->xrender->pict = pXRenderCreatePicture(gdi_display,
physDev->drawable, dst_format->pict_format,
CPSubwindowMode, &pa);
wine_tsx11_unlock();
TRACE("allocing pict = %lx dc = %p drawable = %08lx\n",
physDev->xrender->pict, hdc, physDev->drawable);
} else {
TRACE("using existing pict = %lx dc = %p drawable = %08lx\n",
physDev->xrender->pict, hdc, physDev->drawable);
}
if ((data = X11DRV_GetRegionData( physDev->region, 0 )))
{
wine_tsx11_lock();
pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
physDev->dc_rect.left, physDev->dc_rect.top,
(XRectangle *)data->Buffer, data->rdh.nCount );
wine_tsx11_unlock();
HeapFree( GetProcessHeap(), 0, data );
}
}
EnterCriticalSection(&xrender_cs); EnterCriticalSection(&xrender_cs);
entry = glyphsetCache + physDev->xrender->cache_index; entry = glyphsetCache + physDev->xrender->cache_index;
@ -1578,6 +1590,17 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
INT offset = 0; INT offset = 0;
POINT desired, current; POINT desired, current;
int render_op = PictOpOver; int render_op = PictOpOver;
Picture pict = get_xrender_picture(physDev);
if ((data = X11DRV_GetRegionData( physDev->region, 0 )))
{
wine_tsx11_lock();
pXRenderSetPictureClipRectangles( gdi_display, pict,
physDev->dc_rect.left, physDev->dc_rect.top,
(XRectangle *)data->Buffer, data->rdh.nCount );
wine_tsx11_unlock();
HeapFree( GetProcessHeap(), 0, data );
}
/* There's a bug in XRenderCompositeText that ignores the xDst and yDst parameters. /* There's a bug in XRenderCompositeText that ignores the xDst and yDst parameters.
So we pass zeros to the function and move to our starting position using the first So we pass zeros to the function and move to our starting position using the first
@ -1618,9 +1641,11 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
} }
} }
wine_tsx11_lock(); wine_tsx11_lock();
/* Make sure we don't have any transforms set from a previous call */
set_xrender_transformation(pict, 1, 1, 0, 0);
pXRenderCompositeText16(gdi_display, render_op, pXRenderCompositeText16(gdi_display, render_op,
tile_pict, tile_pict,
physDev->xrender->pict, pict,
formatEntry->font_format->pict_format, formatEntry->font_format->pict_format,
0, 0, 0, 0, elts, count); 0, 0, 0, 0, elts, count);
wine_tsx11_unlock(); wine_tsx11_unlock();
@ -1781,20 +1806,6 @@ done_unlock:
return retv; return retv;
} }
/* Set the x/y scaling and x/y offsets in the transformation matrix of the source picture */
static void set_xrender_transformation(Picture src_pict, float xscale, float yscale, int xoffset, int yoffset)
{
#ifdef HAVE_XRENDERSETPICTURETRANSFORM
XTransform xform = {{
{ XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(xoffset) },
{ XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(yoffset) },
{ XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }
}};
pXRenderSetPictureTransform(gdi_display, src_pict, &xform);
#endif
}
/* Helper function for (stretched) blitting using xrender */ /* Helper function for (stretched) blitting using xrender */
static void xrender_blit(Picture src_pict, Picture mask_pict, Picture dst_pict, int x_src, int y_src, float xscale, float yscale, int width, int height) static void xrender_blit(Picture src_pict, Picture mask_pict, Picture dst_pict, int x_src, int y_src, float xscale, float yscale, int width, int height)
{ {