Commit 8262e0a8 authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Alexandre Julliard

winex11: Get rid of the static Xrender picture format table.

parent 26caf2fd
...@@ -54,8 +54,57 @@ static BOOL X11DRV_XRender_Installed = FALSE; ...@@ -54,8 +54,57 @@ static BOOL X11DRV_XRender_Installed = FALSE;
#define RepeatReflect 3 #define RepeatReflect 3
#endif #endif
enum drawable_depth_type {mono_drawable, color_drawable}; #define MAX_FORMATS 9
static XRenderPictFormat *pict_formats[2]; typedef enum wine_xrformat
{
WXR_FORMAT_MONO,
WXR_FORMAT_X1R5G5B5,
WXR_FORMAT_X1B5G5R5,
WXR_FORMAT_R5G6B5,
WXR_FORMAT_B5G6R5,
WXR_FORMAT_R8G8B8,
WXR_FORMAT_B8G8R8,
WXR_FORMAT_A8R8G8B8,
WXR_FORMAT_X8R8G8B8,
} WXRFormat;
typedef struct wine_xrender_format_template
{
WXRFormat wxr_format;
unsigned int depth;
unsigned int alpha;
unsigned int alphaMask;
unsigned int red;
unsigned int redMask;
unsigned int green;
unsigned int greenMask;
unsigned int blue;
unsigned int blueMask;
} WineXRenderFormatTemplate;
static const WineXRenderFormatTemplate wxr_formats_template[] =
{
/* Format depth alpha mask red mask green mask blue mask*/
{WXR_FORMAT_MONO, 1, 0, 0x01, 0, 0, 0, 0, 0, 0 },
{WXR_FORMAT_X1R5G5B5, 16, 0, 0, 10, 0x1f, 5, 0x1f, 0, 0x1f },
{WXR_FORMAT_X1B5G5R5, 16, 0, 0, 0, 0x1f, 5, 0x1f, 10, 0x1f },
{WXR_FORMAT_R5G6B5, 16, 0, 0, 11, 0x1f, 5, 0x3f, 0, 0x1f },
{WXR_FORMAT_B5G6R5, 16, 0, 0, 0, 0x1f, 5, 0x3f, 11, 0x1f },
{WXR_FORMAT_R8G8B8, 24, 0, 0, 16, 0xff, 8, 0xff, 0, 0xff },
{WXR_FORMAT_B8G8R8, 24, 0, 0, 0, 0xff, 8, 0xff, 16, 0xff },
{WXR_FORMAT_A8R8G8B8, 32, 24, 0xff, 16, 0xff, 8, 0xff, 0, 0xff },
{WXR_FORMAT_X8R8G8B8, 32, 0, 0, 16, 0xff, 8, 0xff, 0, 0xff }
};
typedef struct wine_xrender_format
{
WXRFormat format;
XRenderPictFormat *pict_format;
} WineXRenderFormat;
static WineXRenderFormat wxr_formats[MAX_FORMATS];
static int WineXRenderFormatsListSize = 0;
static WineXRenderFormat *default_format = NULL;
typedef struct typedef struct
{ {
...@@ -155,6 +204,101 @@ static CRITICAL_SECTION xrender_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; ...@@ -155,6 +204,101 @@ static CRITICAL_SECTION xrender_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
#define NATIVE_BYTE_ORDER LSBFirst #define NATIVE_BYTE_ORDER LSBFirst
#endif #endif
static BOOL get_xrender_template(const WineXRenderFormatTemplate *fmt, XRenderPictFormat *templ, unsigned long *mask)
{
templ->id = 0;
templ->type = PictTypeDirect;
templ->depth = fmt->depth;
templ->direct.alpha = fmt->alpha;
templ->direct.alphaMask = fmt->alphaMask;
templ->direct.red = fmt->red;
templ->direct.redMask = fmt->redMask;
templ->direct.green = fmt->green;
templ->direct.greenMask = fmt->greenMask;
templ->direct.blue = fmt->blue;
templ->direct.blueMask = fmt->blueMask;
templ->colormap = 0;
*mask = PictFormatType | PictFormatDepth | PictFormatAlpha | PictFormatAlphaMask | PictFormatRed | PictFormatRedMask | PictFormatGreen | PictFormatGreenMask | PictFormatBlue | PictFormatBlueMask;
return TRUE;
}
static BOOL is_wxrformat_compatible_with_default_visual(const WineXRenderFormatTemplate *fmt)
{
if(fmt->depth != screen_depth)
return FALSE;
if( (fmt->redMask << fmt->red) != visual->red_mask)
return FALSE;
if( (fmt->greenMask << fmt->green) != visual->green_mask)
return FALSE;
if( (fmt->blueMask << fmt->blue) != visual->blue_mask)
return FALSE;
/* We never select a default ARGB visual */
if(fmt->alphaMask)
return FALSE;
return TRUE;
}
static int load_xrender_formats(void)
{
unsigned int i;
for(i = 0; i < (sizeof(wxr_formats_template) / sizeof(wxr_formats_template[0])); i++)
{
XRenderPictFormat templ, *pict_format;
if(is_wxrformat_compatible_with_default_visual(&wxr_formats_template[i]))
{
wine_tsx11_lock();
pict_format = pXRenderFindVisualFormat(gdi_display, visual);
if(!pict_format)
{
/* Xrender doesn't like DirectColor visuals, try to find a TrueColor one instead */
if (visual->class == DirectColor)
{
XVisualInfo info;
if (XMatchVisualInfo( gdi_display, DefaultScreen(gdi_display),
screen_depth, TrueColor, &info ))
{
pict_format = pXRenderFindVisualFormat(gdi_display, info.visual);
if (pict_format) visual = info.visual;
}
}
}
wine_tsx11_unlock();
if(pict_format)
{
wxr_formats[WineXRenderFormatsListSize].format = wxr_formats_template[i].wxr_format;
wxr_formats[WineXRenderFormatsListSize].pict_format = pict_format;
default_format = &wxr_formats[WineXRenderFormatsListSize];
WineXRenderFormatsListSize++;
TRACE("Loaded pict_format with id=%#lx for wxr_format=%#x\n", pict_format->id, wxr_formats_template[i].wxr_format);
}
}
else
{
unsigned long mask = 0;
get_xrender_template(&wxr_formats_template[i], &templ, &mask);
wine_tsx11_lock();
pict_format = pXRenderFindFormat(gdi_display, mask, &templ, 0);
wine_tsx11_unlock();
if(pict_format)
{
wxr_formats[WineXRenderFormatsListSize].format = wxr_formats_template[i].wxr_format;
wxr_formats[WineXRenderFormatsListSize].pict_format = pict_format;
WineXRenderFormatsListSize++;
TRACE("Loaded pict_format with id=%#lx for wxr_format=%#x\n", pict_format->id, wxr_formats_template[i].wxr_format);
}
}
}
return WineXRenderFormatsListSize;
}
/*********************************************************************** /***********************************************************************
* X11DRV_XRender_Init * X11DRV_XRender_Init
* *
...@@ -164,7 +308,6 @@ static CRITICAL_SECTION xrender_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; ...@@ -164,7 +308,6 @@ static CRITICAL_SECTION xrender_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
void X11DRV_XRender_Init(void) void X11DRV_XRender_Init(void)
{ {
int event_base, i; int event_base, i;
XRenderPictFormat pf;
if (client_side_with_render && if (client_side_with_render &&
wine_dlopen(SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && wine_dlopen(SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, NULL, 0) &&
...@@ -195,27 +338,12 @@ LOAD_OPTIONAL_FUNCPTR(XRenderSetPictureTransform) ...@@ -195,27 +338,12 @@ LOAD_OPTIONAL_FUNCPTR(XRenderSetPictureTransform)
#undef LOAD_OPTIONAL_FUNCPTR #undef LOAD_OPTIONAL_FUNCPTR
#endif #endif
wine_tsx11_lock(); wine_tsx11_lock();
if(pXRenderQueryExtension(gdi_display, &event_base, &xrender_error_base)) { X11DRV_XRender_Installed = pXRenderQueryExtension(gdi_display, &event_base, &xrender_error_base);
X11DRV_XRender_Installed = TRUE; wine_tsx11_unlock();
if(X11DRV_XRender_Installed) {
TRACE("Xrender is up and running error_base = %d\n", xrender_error_base); TRACE("Xrender is up and running error_base = %d\n", xrender_error_base);
pict_formats[color_drawable] = pXRenderFindVisualFormat(gdi_display, visual); if(!load_xrender_formats()) /* This fails in buggy versions of libXrender.so */
if(!pict_formats[color_drawable])
{
/* Xrender doesn't like DirectColor visuals, try to find a TrueColor one instead */
if (visual->class == DirectColor)
{
XVisualInfo info;
if (XMatchVisualInfo( gdi_display, DefaultScreen(gdi_display),
screen_depth, TrueColor, &info ))
{
pict_formats[color_drawable] = pXRenderFindVisualFormat(gdi_display, info.visual);
if (pict_formats[color_drawable]) visual = info.visual;
}
}
}
if(!pict_formats[color_drawable]) /* This fails in buggy versions of libXrender.so */
{ {
wine_tsx11_unlock(); wine_tsx11_unlock();
WINE_MESSAGE( WINE_MESSAGE(
...@@ -225,23 +353,12 @@ LOAD_OPTIONAL_FUNCPTR(XRenderSetPictureTransform) ...@@ -225,23 +353,12 @@ LOAD_OPTIONAL_FUNCPTR(XRenderSetPictureTransform)
X11DRV_XRender_Installed = FALSE; X11DRV_XRender_Installed = FALSE;
return; return;
} }
pf.type = PictTypeDirect;
pf.depth = 1;
pf.direct.alpha = 0;
pf.direct.alphaMask = 1;
pict_formats[mono_drawable] = pXRenderFindFormat(gdi_display, PictFormatType |
PictFormatDepth | PictFormatAlpha |
PictFormatAlphaMask, &pf, 0);
if(!pict_formats[mono_drawable]) {
ERR("mono_format == NULL?\n");
X11DRV_XRender_Installed = FALSE;
}
if (!visual->red_mask || !visual->green_mask || !visual->blue_mask) { if (!visual->red_mask || !visual->green_mask || !visual->blue_mask) {
WARN("one or more of the colour masks are 0, disabling XRENDER. Try running in 16-bit mode or higher.\n"); WARN("one or more of the colour masks are 0, disabling XRENDER. Try running in 16-bit mode or higher.\n");
X11DRV_XRender_Installed = FALSE; X11DRV_XRender_Installed = FALSE;
} }
} }
wine_tsx11_unlock();
} }
sym_not_found: sym_not_found:
...@@ -271,6 +388,39 @@ sym_not_found: ...@@ -271,6 +388,39 @@ sym_not_found:
else TRACE("Using X11 core fonts\n"); else TRACE("Using X11 core fonts\n");
} }
static WineXRenderFormat *get_xrender_format(WXRFormat format)
{
int i;
for(i=0; i<WineXRenderFormatsListSize; i++)
{
if(wxr_formats[i].format == format)
{
TRACE("Returning wxr_format=%#x\n", format);
return &wxr_formats[i];
}
}
return NULL;
}
static WineXRenderFormat *get_xrender_format_from_pdevice(X11DRV_PDEVICE *physDev)
{
WXRFormat format;
switch(physDev->depth)
{
case 1:
format = WXR_FORMAT_MONO;
break;
default:
/* For now fall back to the format of the default visual.
In the future we should check if we are using a DDB/DIB and what exact format we need.
*/
return default_format;
}
return get_xrender_format(format);
}
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;
...@@ -1153,33 +1303,33 @@ static void SmoothGlyphGray(XImage *image, int x, int y, void *bitmap, XGlyphInf ...@@ -1153,33 +1303,33 @@ static void SmoothGlyphGray(XImage *image, int x, int y, void *bitmap, XGlyphInf
* Returns an appropriate Picture for tiling the text colour. * Returns an appropriate Picture for tiling the text colour.
* Call and use result within the xrender_cs * Call and use result within the xrender_cs
*/ */
static Picture get_tile_pict(enum drawable_depth_type type, int text_pixel) static Picture get_tile_pict(WineXRenderFormat *wxr_format, int text_pixel)
{ {
static struct static struct
{ {
Pixmap xpm; Pixmap xpm;
Picture pict; Picture pict;
int current_color; int current_color;
} tiles[2], *tile; } tiles[MAX_FORMATS], *tile;
XRenderColor col; XRenderColor col;
tile = &tiles[type]; tile = &tiles[wxr_format->format];
if(!tile->xpm) if(!tile->xpm)
{ {
XRenderPictureAttributes pa; XRenderPictureAttributes pa;
wine_tsx11_lock(); wine_tsx11_lock();
tile->xpm = XCreatePixmap(gdi_display, root_window, 1, 1, pict_formats[type]->depth); tile->xpm = XCreatePixmap(gdi_display, root_window, 1, 1, wxr_format->pict_format->depth);
pa.repeat = RepeatNormal; pa.repeat = RepeatNormal;
tile->pict = pXRenderCreatePicture(gdi_display, tile->xpm, pict_formats[type], CPRepeat, &pa); tile->pict = pXRenderCreatePicture(gdi_display, tile->xpm, wxr_format->pict_format, CPRepeat, &pa);
wine_tsx11_unlock(); wine_tsx11_unlock();
/* init current_color to something different from text_pixel */ /* init current_color to something different from text_pixel */
tile->current_color = ~text_pixel; tile->current_color = ~text_pixel;
if(type == mono_drawable) if(wxr_format->format == WXR_FORMAT_MONO)
{ {
/* for a 1bpp bitmap we always need a 1 in the tile */ /* for a 1bpp bitmap we always need a 1 in the tile */
col.red = col.green = col.blue = 0; col.red = col.green = col.blue = 0;
...@@ -1190,7 +1340,7 @@ static Picture get_tile_pict(enum drawable_depth_type type, int text_pixel) ...@@ -1190,7 +1340,7 @@ static Picture get_tile_pict(enum drawable_depth_type type, int text_pixel)
} }
} }
if(text_pixel != tile->current_color && type == color_drawable) if(text_pixel != tile->current_color && wxr_format->format != WXR_FORMAT_MONO)
{ {
/* Map 0 -- 0xff onto 0 -- 0xffff */ /* Map 0 -- 0xff onto 0 -- 0xffff */
int r_shift, r_len; int r_shift, r_len;
...@@ -1243,7 +1393,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag ...@@ -1243,7 +1393,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
unsigned int idx; unsigned int idx;
double cosEsc, sinEsc; double cosEsc, sinEsc;
LOGFONTW lf; LOGFONTW lf;
enum drawable_depth_type depth_type = (physDev->depth == 1) ? mono_drawable : color_drawable; WineXRenderFormat *dst_format = get_xrender_format_from_pdevice(physDev);
Picture tile_pict = 0; Picture tile_pict = 0;
/* Do we need to disable antialiasing because of palette mode? */ /* Do we need to disable antialiasing because of palette mode? */
...@@ -1322,8 +1472,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag ...@@ -1322,8 +1472,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
wine_tsx11_lock(); wine_tsx11_lock();
physDev->xrender->pict = pXRenderCreatePicture(gdi_display, physDev->xrender->pict = pXRenderCreatePicture(gdi_display,
physDev->drawable, physDev->drawable, dst_format->pict_format,
pict_formats[depth_type],
CPSubwindowMode, &pa); CPSubwindowMode, &pa);
wine_tsx11_unlock(); wine_tsx11_unlock();
...@@ -1388,11 +1537,11 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag ...@@ -1388,11 +1537,11 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
desired.y = physDev->dc_rect.top + y; desired.y = physDev->dc_rect.top + y;
current.x = current.y = 0; current.x = current.y = 0;
tile_pict = get_tile_pict(depth_type, physDev->textPixel); tile_pict = get_tile_pict(dst_format, physDev->textPixel);
/* FIXME the mapping of Text/BkColor onto 1 or 0 needs investigation. /* FIXME the mapping of Text/BkColor onto 1 or 0 needs investigation.
*/ */
if((depth_type == mono_drawable) && (textPixel == 0)) if((dst_format->format == WXR_FORMAT_MONO) && (textPixel == 0))
render_op = PictOpOutReverse; /* This gives us 'black' text */ render_op = PictOpOutReverse; /* This gives us 'black' text */
for(idx = 0; idx < count; idx++) for(idx = 0; idx < count; idx++)
...@@ -1630,7 +1779,7 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid ...@@ -1630,7 +1779,7 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid
POINT pts[2]; POINT pts[2];
BOOL top_down = FALSE; BOOL top_down = FALSE;
RGNDATA *rgndata; RGNDATA *rgndata;
enum drawable_depth_type dst_depth_type = (devDst->depth == 1) ? mono_drawable : color_drawable; WineXRenderFormat *dst_format = get_xrender_format_from_pdevice(devDst);
int repeat_src; int repeat_src;
if(!X11DRV_XRender_Installed) { if(!X11DRV_XRender_Installed) {
...@@ -1761,7 +1910,7 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid ...@@ -1761,7 +1910,7 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid
/* FIXME use devDst->xrender->pict ? */ /* FIXME use devDst->xrender->pict ? */
dst_pict = pXRenderCreatePicture(gdi_display, dst_pict = pXRenderCreatePicture(gdi_display,
devDst->drawable, devDst->drawable,
pict_formats[dst_depth_type], dst_format->pict_format,
CPSubwindowMode, &pa); CPSubwindowMode, &pa);
TRACE("dst_pict %08lx\n", dst_pict); TRACE("dst_pict %08lx\n", dst_pict);
TRACE("src_drawable = %08lx\n", devSrc->drawable); TRACE("src_drawable = %08lx\n", devSrc->drawable);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment