[cairo] Cairo 1.14.2 problems with Solaris 10, libXrender
suzuki toshiya
mpsuzuki at hiroshima-u.ac.jp
Wed Aug 5 08:29:39 PDT 2015
> No. Symbol checking is done at compile time (by configure). The runtime
> check is performed using the function
>
> Status XRenderQueryVersion (Display *dpy,
> int *major_versionp,
> int *minor_versionp);
>
> which is declared in Xrender.h and which queries the version of the X
> server (i.e. display) we have connected to (represented by the Display
> pointer).
Oh, I see. The function availability could be checked by
the XRender version...
Regards,
mpsuzuki
Andreas F. Borchert wrote:
> On Wed, Aug 05, 2015 at 11:07:20PM +0900, suzuki toshiya wrote:
>> The issue was found by the inconsistent header/library in
>> Solaris 10 (so, it would be possible for Solaris 10 users
>> to bypass this problem by tweaking the configure script),
>> but your comment is that the hardwired configuration about
>> the availability of XrenderCreateSolidFill etc is not good
>> idea, they should be checked in runtime.
>>
>> Is this correct understanding?
>
> We have checks by configure (compile time) and during runtime (using
> XRenderQueryVersion, see below). Currently both is checked and we need
> also both. The point is that we should not invoke functions that were
> no-op'd as they are not included in the libXrender client library when
> they appear to be supported by an actual X server (i.e. display) we
> connect to.
>
>> If this is correct understanding, the runtime checking of
>> the availability would be a symbol checking in libXrender?
>
> No. Symbol checking is done at compile time (by configure). The runtime
> check is performed using the function
>
> Status XRenderQueryVersion (Display *dpy,
> int *major_versionp,
> int *minor_versionp);
>
> which is declared in Xrender.h and which queries the version of the X
> server (i.e. display) we have connected to (represented by the Display
> pointer).
>
> The actual code checks the runtime version only. Example:
>
> if (CAIRO_RENDER_HAS_GRADIENTS(dst->display)) {
> picture = XRenderCreateSolidFill (dpy, &xcolor);
> } else {
> // ...
> }
>
> The macro CAIRO_RENDER_HAS_GRADIENTS has been defined in
> cairo-xlib-private.h as
>
> #define CAIRO_RENDER_HAS_GRADIENTS(surface) \
> CAIRO_RENDER_AT_LEAST((surface), 0, 10)
>
> where CAIRO_RENDER_AT_LEAST accesses render_major and
> render_minor which are initialized by using XRenderQueryVersion
> (see cairo-xlib-display.c):
>
> #define CAIRO_RENDER_AT_LEAST(surface, major, minor) \
> (((surface)->render_major > major) || \
> (((surface)->render_major == major) && \
> ((surface)->render_minor >= minor)))
>
> The Cairo library should be prepared for the case that
> the XRender version of the actual X Server is more recent
> than that of the XRender client library Cairo was linked
> against. Hence I would suggest to use #ifdefs as follows:
>
> #if HAVE_XRENDERCREATELINEARGRADIENT
> if (CAIRO_RENDER_HAS_GRADIENTS(dst->display)) {
> picture = XRenderCreateSolidFill (dpy, &xcolor);
> } else {
> #endif
> // ...
> #if HAVE_XRENDERCREATELINEARGRADIENT
> }
> #endif
>
> And to defend against accidental invocations of a no-op
> I would suggest to replace in cairo-xlib-xrender-private.h
>
> __attribute__((__unused__)) static int
> _int_consume (void *p, ...) { return 0; }
>
> // ...
>
> #if !HAVE_XRENDERCREATESOLIDFILL
> #define XRenderCreateSolidFill _int_consume
> #endif
>
> by
>
> __attribute__((__unused__)) static int
> _int_consume_and_abort (void *p, ...) { assert(0); return 0; }
>
> // ...
>
> #if !HAVE_XRENDERCREATESOLIDFILL
> #define XRenderCreateSolidFill _int_consume_and_abort
> #endif
>
> or something similar, i.e. if against all odds a no-op is called,
> a crash, error or warning message would be most helpful to track
> this down. Rendering should not be silently skipped.
>
> Regards, Andreas.
>
More information about the cairo
mailing list