mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-30 02:40:13 +01:00
XCB: Use xcb-renderutil where cairo-xlib used libXrender.
This commit is contained in:
parent
6b0d3433b7
commit
2eeb338590
2 changed files with 41 additions and 160 deletions
|
|
@ -241,7 +241,7 @@ CAIRO_BACKEND_ENABLE(quartz, Quartz, quartz, QUARTZ_SURFACE, no, [
|
|||
dnl ===========================================================================
|
||||
|
||||
CAIRO_BACKEND_ENABLE(xcb, XCB, xcb, XCB_SURFACE, no, [
|
||||
xcb_REQUIRES="xcb xcb-render"
|
||||
xcb_REQUIRES="xcb xcb-render xcb-renderutil"
|
||||
PKG_CHECK_MODULES(xcb, $xcb_REQUIRES, , [
|
||||
use_xcb="no (requires XCB http://xcb.freedesktop.org)"])
|
||||
])
|
||||
|
|
|
|||
|
|
@ -37,35 +37,10 @@
|
|||
#include "cairoint.h"
|
||||
#include "cairo-xcb.h"
|
||||
#include "cairo-xcb-xrender.h"
|
||||
#include <X11/XCB/xcb_renderutil.h>
|
||||
|
||||
#define AllPlanes ((unsigned long)~0L)
|
||||
|
||||
static XCBRenderPICTFORMAT
|
||||
format_from_visual(XCBConnection *c, XCBVISUALID visual)
|
||||
{
|
||||
static const XCBRenderPICTFORMAT nil = { 0 };
|
||||
XCBRenderQueryPictFormatsRep *r;
|
||||
XCBRenderPICTSCREENIter si;
|
||||
XCBRenderPICTDEPTHIter di;
|
||||
XCBRenderPICTVISUALIter vi;
|
||||
|
||||
r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
|
||||
if(!r)
|
||||
return nil;
|
||||
|
||||
for(si = XCBRenderQueryPictFormatsScreensIter(r); si.rem; XCBRenderPICTSCREENNext(&si))
|
||||
for(di = XCBRenderPICTSCREENDepthsIter(si.data); di.rem; XCBRenderPICTDEPTHNext(&di))
|
||||
for(vi = XCBRenderPICTDEPTHVisualsIter(di.data); vi.rem; XCBRenderPICTVISUALNext(&vi))
|
||||
if(vi.data->visual.id == visual.id)
|
||||
{
|
||||
XCBRenderPICTFORMAT ret = vi.data->format;
|
||||
free(r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static cairo_content_t
|
||||
_xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
|
||||
{
|
||||
|
|
@ -92,95 +67,6 @@ _xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
|
|||
|
||||
}
|
||||
|
||||
/* XXX: Why is this ridiculously complex compared to the equivalent
|
||||
* function in cairo-xlib-surface.c */
|
||||
static XCBRenderPICTFORMINFO
|
||||
_format_from_cairo(XCBConnection *c, cairo_format_t fmt)
|
||||
{
|
||||
XCBRenderPICTFORMINFO ret = {{ 0 }};
|
||||
struct tmpl_t {
|
||||
XCBRenderDIRECTFORMAT direct;
|
||||
CARD8 depth;
|
||||
};
|
||||
static const struct tmpl_t templates[] = {
|
||||
/* CAIRO_FORMAT_ARGB32 */
|
||||
{
|
||||
{
|
||||
16, 0xff,
|
||||
8, 0xff,
|
||||
0, 0xff,
|
||||
24, 0xff
|
||||
},
|
||||
32
|
||||
},
|
||||
/* CAIRO_FORMAT_RGB24 */
|
||||
{
|
||||
{
|
||||
16, 0xff,
|
||||
8, 0xff,
|
||||
0, 0xff,
|
||||
0, 0x00
|
||||
},
|
||||
24
|
||||
},
|
||||
/* CAIRO_FORMAT_A8 */
|
||||
{
|
||||
{
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0xff
|
||||
},
|
||||
8
|
||||
},
|
||||
/* CAIRO_FORMAT_A1 */
|
||||
{
|
||||
{
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0x01
|
||||
},
|
||||
1
|
||||
},
|
||||
};
|
||||
const struct tmpl_t *tmpl;
|
||||
XCBRenderQueryPictFormatsRep *r;
|
||||
XCBRenderPICTFORMINFOIter fi;
|
||||
|
||||
if(fmt < 0 || fmt >= (sizeof(templates) / sizeof(*templates)))
|
||||
return ret;
|
||||
tmpl = templates + fmt;
|
||||
|
||||
r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
|
||||
if(!r)
|
||||
return ret;
|
||||
|
||||
for(fi = XCBRenderQueryPictFormatsFormatsIter(r); fi.rem; XCBRenderPICTFORMINFONext(&fi))
|
||||
{
|
||||
const XCBRenderDIRECTFORMAT *t, *f;
|
||||
if(fi.data->type != XCBRenderPictTypeDirect)
|
||||
continue;
|
||||
if(fi.data->depth != tmpl->depth)
|
||||
continue;
|
||||
t = &tmpl->direct;
|
||||
f = &fi.data->direct;
|
||||
if(t->red_mask && (t->red_mask != f->red_mask || t->red_shift != f->red_shift))
|
||||
continue;
|
||||
if(t->green_mask && (t->green_mask != f->green_mask || t->green_shift != f->green_shift))
|
||||
continue;
|
||||
if(t->blue_mask && (t->blue_mask != f->blue_mask || t->blue_shift != f->blue_shift))
|
||||
continue;
|
||||
if(t->alpha_mask && (t->alpha_mask != f->alpha_mask || t->alpha_shift != f->alpha_shift))
|
||||
continue;
|
||||
|
||||
ret = *fi.data;
|
||||
}
|
||||
|
||||
free(r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Instead of taking two round trips for each blending request,
|
||||
* assume that if a particular drawable fails GetImage that it will
|
||||
|
|
@ -265,7 +151,7 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
|
|||
XCBDRAWABLE d;
|
||||
cairo_xcb_surface_t *surface;
|
||||
cairo_format_t format = _cairo_format_from_content (content);
|
||||
XCBRenderPICTFORMINFO xrender_format = _format_from_cairo (dpy, format);
|
||||
XCBRenderPICTFORMINFO *xrender_format;
|
||||
|
||||
/* As a good first approximation, if the display doesn't have COMPOSITE,
|
||||
* we're better off using image surfaces for all temporary operations
|
||||
|
|
@ -280,9 +166,11 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
|
|||
width <= 0 ? 1 : width,
|
||||
height <= 0 ? 1 : height);
|
||||
|
||||
xrender_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), format);
|
||||
/* XXX: what to do if xrender_format is null? */
|
||||
surface = (cairo_xcb_surface_t *)
|
||||
cairo_xcb_surface_create_with_xrender_format (dpy, d, src->screen,
|
||||
&xrender_format,
|
||||
xrender_format,
|
||||
width, height);
|
||||
if (surface->base.status) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
|
@ -1000,7 +888,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
cairo_int_status_t status;
|
||||
int render_reference_x, render_reference_y;
|
||||
int render_src_x, render_src_y;
|
||||
XCBRenderPICTFORMINFO render_format;
|
||||
int cairo_format;
|
||||
XCBRenderPICTFORMINFO *render_format;
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
|
@ -1025,21 +914,22 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
|
||||
switch (antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1);
|
||||
cairo_format = CAIRO_FORMAT_A1;
|
||||
break;
|
||||
default:
|
||||
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8);
|
||||
cairo_format = CAIRO_FORMAT_A8;
|
||||
break;
|
||||
}
|
||||
render_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dst->dpy), cairo_format);
|
||||
/* XXX: what to do if render_format is null? */
|
||||
|
||||
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
|
||||
/* XXX: _format_from_cairo is slow. should cache something. */
|
||||
status = _cairo_xcb_surface_set_attributes (src, &attributes);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
XCBRenderTrapezoids (dst->dpy,
|
||||
_render_operator (op),
|
||||
src->picture, dst->picture,
|
||||
render_format.id,
|
||||
render_format->id,
|
||||
render_src_x + attributes.x_offset,
|
||||
render_src_y + attributes.y_offset,
|
||||
num_traps, (XCBRenderTRAPEZOID *) traps);
|
||||
|
|
@ -1103,26 +993,6 @@ _cairo_surface_is_xcb (cairo_surface_t *surface)
|
|||
return surface->backend == &cairo_xcb_surface_backend;
|
||||
}
|
||||
|
||||
static void
|
||||
query_render_version (XCBConnection *c, cairo_xcb_surface_t *surface)
|
||||
{
|
||||
XCBRenderQueryVersionRep *r;
|
||||
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
|
||||
if (!XCBRenderInit(c))
|
||||
return;
|
||||
|
||||
r = XCBRenderQueryVersionReply(c, XCBRenderQueryVersion(c, 0, 6), 0);
|
||||
if (!r)
|
||||
return;
|
||||
|
||||
surface->render_major = r->major_version;
|
||||
surface->render_minor = r->minor_version;
|
||||
free(r);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
||||
XCBDRAWABLE drawable,
|
||||
|
|
@ -1134,6 +1004,7 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
|||
int depth)
|
||||
{
|
||||
cairo_xcb_surface_t *surface;
|
||||
const XCBRenderQueryVersionRep *r;
|
||||
|
||||
surface = malloc (sizeof (cairo_xcb_surface_t));
|
||||
if (surface == NULL) {
|
||||
|
|
@ -1189,30 +1060,40 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
|||
;
|
||||
}
|
||||
|
||||
query_render_version(dpy, surface);
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
|
||||
r = XCBRenderUtilQueryVersion(dpy);
|
||||
if (r) {
|
||||
surface->render_major = r->major_version;
|
||||
surface->render_minor = r->minor_version;
|
||||
}
|
||||
|
||||
surface->picture.xid = 0;
|
||||
|
||||
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface))
|
||||
{
|
||||
XCBRenderPICTFORMAT pict_format = {0};
|
||||
XCBRenderPICTFORMINFO format_info;
|
||||
static const XCBRenderPICTFORMAT nil = { 0 };
|
||||
const XCBRenderPICTFORMAT *pict_format = &nil;
|
||||
|
||||
surface->picture = XCBRenderPICTURENew(dpy);
|
||||
|
||||
if (!format) {
|
||||
if (visual) {
|
||||
pict_format = format_from_visual (dpy, visual->visual_id);
|
||||
} else if (depth == 1) {
|
||||
format_info = _format_from_cairo (dpy, CAIRO_FORMAT_A1);
|
||||
pict_format = format_info.id;
|
||||
}
|
||||
XCBRenderCreatePicture (dpy, surface->picture, drawable,
|
||||
pict_format, 0, NULL);
|
||||
} else {
|
||||
XCBRenderCreatePicture (dpy, surface->picture, drawable,
|
||||
format->id, 0, NULL);
|
||||
if (format) {
|
||||
pict_format = &format->id;
|
||||
} else if (visual) {
|
||||
XCBRenderPICTVISUAL *pict_visual;
|
||||
pict_visual = XCBRenderUtilFindVisualFormat (XCBRenderUtilQueryFormats (dpy), visual->visual_id);
|
||||
if (pict_visual)
|
||||
pict_format = &pict_visual->format;
|
||||
} else if (depth == 1) {
|
||||
XCBRenderPICTFORMINFO *format_info;
|
||||
format_info = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), CAIRO_FORMAT_A1);
|
||||
if (format_info)
|
||||
pict_format = &format_info->id;
|
||||
}
|
||||
|
||||
/* XXX: if pict_format is nil, should we still call CreatePicture? */
|
||||
surface->picture = XCBRenderPICTURENew(dpy);
|
||||
XCBRenderCreatePicture (dpy, surface->picture, drawable,
|
||||
*pict_format, 0, NULL);
|
||||
}
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue