[cairo] [Pixman] help building cairo on windows

Andrea Canciani ranma42 at gmail.com
Mon Sep 10 23:38:03 PDT 2012


On Mon, Sep 10, 2012 at 11:38 PM, Dimiter 'malkia' Stanev
<malkia at gmail.com> wrote:
> Hi Andrea,
>
> I'm still supporting XP with MSVCRT.DLL, and since I'm compiling pixman as
> dll (crazy, but even if it was part of cairo, it would've been dll) then
> __declspec(thread) does not work properly. Raymond Chen (newoldthing), Ken
> Johnson (skywing), and other people explained the problem which Raymond
> summarized here:

I don't think a pixman dll is so crazy... in fact if you look through
my simpleops-for-master branch, it changes the Makefile.win32 files
(and some of the source files) so that pixman also builds as dll.

>
> http://blogs.msdn.com/b/oldnewthing/archive/2010/11/22/10094489.aspx
>
> Since MINGW does not support __declspec(thread), and has to go through the
> tls API (tlsGetValue, tlsSetValue), I've made this mini patch.
>
> It's tested using Windows DDK 7.1 (7600) - a VS2008 compiler.
>
> Now this would turn off __declspec(thread) completely for all _MSC_VER
> compilers, but if XP is still desired platform it should be in.
>
> I'm not sure how much of an impact this is (API vs. some compiler generated
> code), but probably it's not much (on Linux it has to go through pthread
> anyway).

Actually ./configure will try to detect if the compiler supports
__thread or __declspec(thread), even on linux, so in some cases it
might not go through pthread.

Anyway, in the simpleops-for-master branch you never use static
thread-local variables, you always go through the appropriate TLS API
(pthread, win32).
(additionally, the simpleops-for branch adds a couple of tests to
check that loading/unloading the library does not leak and that the
TLS data is not leaked)
I do not expect this to be a performance issue in pixman, because
these functions are not used in tight loops (currently it is only used
once per composite operation) and the cost of a function call (and
maybe a couple more memory accesses) should be negligible with all of
the other computations going on.
Moreover the simpleops interface is compatible with (the latest draft
for) C1x, so it will eventually start using that (and compilers might
do some additional optimizations and get rid of the overhead).

Andrea

>
>
> Thanks,
> Dimiter 'malkia' Stanev
>
> here is the patch:
>
> diff --git a/pixman/pixman-compiler.h b/pixman/pixman-compiler.h
> index a978acc..b6a769c 100644
>
> --- a/pixman/pixman-compiler.h
> +++ b/pixman/pixman-compiler.h
> @@ -108,10 +108,13 @@
>  #   define PIXMAN_GET_THREAD_LOCAL(name)                               \
>      (&name)
>
> -#elif defined(__MINGW32__)
> +#elif defined(__MINGW32__) || defined(_MSC_VER) /* XP Support */
>
>  #   define _NO_W32_PSEUDO_MODIFIERS
>  #   include <windows.h>
> +#   ifdef IN
> +#   undef IN /* Window.h defines IN, OUT, IN_OUT */
>
> +#   endif
>
>  #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                      \
>      static volatile int tls_ ## name ## _initialized = 0;              \
>
>
>
> On 9/10/2012 1:48 PM, Andrea Canciani wrote:
>>
>> This reminds me that I have some patches to improve building pixman on
>> win32:
>>
>> http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master
>>
>> Soren, is it ok if I push the attached patches?
>>
>> I will work a little more on simpleops before proposing it again (in
>> particular, I'd like to make it behave like the gstreamer git
>> submodules and I need to investigate how it is integrated with
>> packaging and releasing), but the first two commits in the branch
>> should be ok for merge regardless of simpleops.
>>
>> Andrea
>>
>> On Mon, Sep 10, 2012 at 8:17 PM, Dimiter 'malkia' Stanev
>> <malkia-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org> wrote:
>>>
>>> On 9/10/2012 7:04 AM, Cosmin Apreutesei wrote:
>>>>
>>>>
>>>> Hi,
>>>>
>>>> I have to build cairo on windows because I want to use the recording
>>>> surface and I can't find binaries above 1.10 anywhere on the net (till
>>>> now I have used the binaries from GTK but these are old and the
>>>> recording surface doesn't work with those).
>>>>
>>>> Trying to build pixman with:
>>>>
>>>>> make CFG=debug -f Makefile.win32
>>>>
>>>>
>>>>
>>>> gives me:
>>>>
>>>> pixman-mmx.c(545) : error C2143: syntax error : missing ';' before
>>>> 'type'
>>>>
>>>> and then 100 syntax errors like that (other c files compile ok until
>>>> the mmx one).
>>>>
>>>> The sources were pulled today from git. The environment is VSE2008.
>>>> make is 3.81 from mingw (I also had to throw in pkg-config binaries +
>>>> dependencies from GTK).
>>>>
>>>> I also tried to build the latest pixman (0.26.2) with the same command
>>>> but it failed with:
>>>>
>>>> Entering directory `/x/work/pixman-0.26.2/test'
>>>> Makefile.win32: No such file or directory
>>>>
>>>> I also tried building with mozilla-build from the mingw bash prompt,
>>>> with the same results.
>>>>
>>>>
>>>> So what's the best (preferably from cmdline) way to build pixman and
>>>> cairo under windows? And which is the best version? The release or the
>>>> git one?
>>>>
>>>> Btw, if anyone has an up-to-date cairo.dll that would work for me too.
>>>>
>>>
>>> Hi Cosmin,
>>>
>>> With this patch you should be able to compile.
>>>
>>> Thanks,
>>> Dimiter 'malkia' Stanev
>>>
>>> pixman-mmx.diff
>>>
>>> diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
>>> index 74a5e87..9e597db 100644
>>> --- a/pixman/pixman-mmx.c
>>> +++ b/pixman/pixman-mmx.c
>>> @@ -541,7 +541,7 @@ expand565 (__m64 pixel, int pos)
>>>   static force_inline void
>>>   expand_4xpacked565 (__m64 vin, __m64 *vout0, __m64 *vout1, int
>>> full_alpha)
>>>   {
>>> -    __m64 t0, t1, alpha = _mm_setzero_si64 ();;
>>> +    __m64 t0, t1, alpha = _mm_setzero_si64 ();
>>>       __m64 r = _mm_and_si64 (vin, MC (expand_565_r));
>>>       __m64 g = _mm_and_si64 (vin, MC (expand_565_g));
>>>       __m64 b = _mm_and_si64 (vin, MC (expand_565_b));
>>> @@ -1902,22 +1902,22 @@ mmx_composite_over_8888_0565
>>> (pixman_implementation_t *imp,
>>>          while (w >= 4)
>>>          {
>>>              __m64 vdest = *(__m64 *)dst;
>>> -           __m64 v0, v1, v2, v3;
>>> +           __m64 v0, v1, v2, v3, vsrc0, vsrc1, vsrc2, vsrc3;
>>>
>>>              expand_4x565 (vdest, &v0, &v1, &v2, &v3, 0);
>>>
>>> -           __m64 vsrc0 = load8888 ((src + 0));
>>> -           __m64 vsrc1 = load8888 ((src + 1));
>>> -           __m64 vsrc2 = load8888 ((src + 2));
>>> -           __m64 vsrc3 = load8888 ((src + 3));
>>> -
>>> +           vsrc0 = load8888 ((src + 0));
>>> +           vsrc1 = load8888 ((src + 1));
>>> +           vsrc2 = load8888 ((src + 2));
>>> +           vsrc3 = load8888 ((src + 3));
>>> +
>>>              v0 = over (vsrc0, expand_alpha (vsrc0), v0);
>>>              v1 = over (vsrc1, expand_alpha (vsrc1), v1);
>>>              v2 = over (vsrc2, expand_alpha (vsrc2), v2);
>>>              v3 = over (vsrc3, expand_alpha (vsrc3), v3);
>>> -
>>> +
>>>              *(__m64 *)dst = pack_4x565 (v0, v1, v2, v3);
>>> -
>>> +
>>>              w -= 4;
>>>              dst += 4;
>>>              src += 4;
>>> @@ -2454,22 +2454,22 @@ mmx_composite_over_n_8_0565
>>> (pixman_implementation_t
>>> *imp,
>>>              else if (m0 | m1 | m2 | m3)
>>>              {
>>>                  __m64 vdest = *(__m64 *)dst;
>>> -               __m64 v0, v1, v2, v3;
>>> +               __m64 v0, v1, v2, v3, vm0, vm1, vm2, vm3;
>>>
>>>                  expand_4x565 (vdest, &v0, &v1, &v2, &v3, 0);
>>>
>>> -               __m64 vm0 = to_m64 (m0);
>>> +               vm0 = to_m64 (m0);
>>>                  v0 = in_over (vsrc, vsrca, expand_alpha_rev (vm0), v0);
>>> -
>>> -               __m64 vm1 = to_m64 (m1);
>>> +
>>> +               vm1 = to_m64 (m1);
>>>                  v1 = in_over (vsrc, vsrca, expand_alpha_rev (vm1), v1);
>>> -
>>> -               __m64 vm2 = to_m64 (m2);
>>> +
>>> +               vm2 = to_m64 (m2);
>>>                  v2 = in_over (vsrc, vsrca, expand_alpha_rev (vm2), v2);
>>> -
>>> -               __m64 vm3 = to_m64 (m3);
>>> +
>>> +               vm3 = to_m64 (m3);
>>>                  v3 = in_over (vsrc, vsrca, expand_alpha_rev (vm3), v3);
>>> -
>>> +
>>>                  *(__m64 *)dst = pack_4x565 (v0, v1, v2, v3);;
>>>              }
>>>
>>> @@ -3545,32 +3545,35 @@ mmx_composite_over_reverse_n_8888
>>> (pixman_implementation_t *imp,
>>>
>>>   #define BILINEAR_INTERPOLATE_ONE_PIXEL(pix)
>>> \
>>>   do {
>>> \
>>> +    __m64 t_hi, t_lo, b_hi, b_lo, hi, lo;          \
>>>       /* fetch 2x2 pixel block into 2 mmx registers */
>>> \
>>>       __m64 t = ldq_u ((__m64 *)&src_top [pixman_fixed_to_int (vx)]);
>>> \
>>>       __m64 b = ldq_u ((__m64 *)&src_bottom [pixman_fixed_to_int (vx)]);
>>> \
>>>       vx += unit_x;
>>> \
>>>       /* vertical interpolation */
>>> \
>>> -    __m64 t_hi = _mm_mullo_pi16 (_mm_unpackhi_pi8 (t, mm_zero), mm_wt);
>>> \
>>> -    __m64 t_lo = _mm_mullo_pi16 (_mm_unpacklo_pi8 (t, mm_zero), mm_wt);
>>> \
>>> -    __m64 b_hi = _mm_mullo_pi16 (_mm_unpackhi_pi8 (b, mm_zero), mm_wb);
>>> \
>>> -    __m64 b_lo = _mm_mullo_pi16 (_mm_unpacklo_pi8 (b, mm_zero), mm_wb);
>>> \
>>> -    __m64 hi = _mm_add_pi16 (t_hi, b_hi);
>>> \
>>> -    __m64 lo = _mm_add_pi16 (t_lo, b_lo);
>>> \
>>> +    t_hi = _mm_mullo_pi16 (_mm_unpackhi_pi8 (t, mm_zero), mm_wt);
>>> \
>>> +    t_lo = _mm_mullo_pi16 (_mm_unpacklo_pi8 (t, mm_zero), mm_wt);
>>> \
>>> +    b_hi = _mm_mullo_pi16 (_mm_unpackhi_pi8 (b, mm_zero), mm_wb);
>>> \
>>> +    b_lo = _mm_mullo_pi16 (_mm_unpacklo_pi8 (b, mm_zero), mm_wb);
>>> \
>>> +    hi = _mm_add_pi16 (t_hi, b_hi);
>>> \
>>> +    lo = _mm_add_pi16 (t_lo, b_lo);
>>> \
>>>       if (BILINEAR_INTERPOLATION_BITS < 8)
>>> \
>>>       {
>>> \
>>> +        __m64 p, q;          \
>>>          /* calculate horizontal weights */
>>> \
>>>          __m64 mm_wh = _mm_add_pi16 (mm_addc7, _mm_xor_si64 (mm_xorc7,
>>> \
>>>                            _mm_srli_pi16 (mm_x,
>>> \
>>>                                           16 -
>>> BILINEAR_INTERPOLATION_BITS)));   \
>>>          mm_x = _mm_add_pi16 (mm_x, mm_ux);
>>> \
>>>          /* horizontal interpolation */
>>> \
>>> -       __m64 p = _mm_unpacklo_pi16 (lo, hi);
>>> \
>>> -       __m64 q = _mm_unpackhi_pi16 (lo, hi);
>>> \
>>> +        p = _mm_unpacklo_pi16 (lo, hi);
>>> \
>>> +       q = _mm_unpackhi_pi16 (lo, hi);
>>> \
>>>          lo = _mm_madd_pi16 (p, mm_wh);
>>> \
>>>          hi = _mm_madd_pi16 (q, mm_wh);
>>> \
>>>       }
>>> \
>>>       else
>>> \
>>>       {
>>> \
>>> +        __m64 mm_lo_lo, mm_lo_hi, mm_hi_lo, mm_hi_hi;
>>> \
>>>          /* calculate horizontal weights */
>>> \
>>>          __m64 mm_wh_lo = _mm_sub_pi16 (mm_BSHIFT, _mm_srli_pi16 (mm_x,
>>> \
>>>                                          16 -
>>> BILINEAR_INTERPOLATION_BITS));
>>> \
>>> @@ -3578,10 +3581,10 @@ do {
>>> \
>>>                                          16 -
>>> BILINEAR_INTERPOLATION_BITS);
>>> \
>>>          mm_x = _mm_add_pi16 (mm_x, mm_ux);
>>> \
>>>          /* horizontal interpolation */
>>> \
>>> -       __m64 mm_lo_lo = _mm_mullo_pi16 (lo, mm_wh_lo);
>>> \
>>> -       __m64 mm_lo_hi = _mm_mullo_pi16 (hi, mm_wh_hi);
>>> \
>>> -       __m64 mm_hi_lo = _mm_mulhi_pu16 (lo, mm_wh_lo);
>>> \
>>> -       __m64 mm_hi_hi = _mm_mulhi_pu16 (hi, mm_wh_hi);
>>> \
>>> +       mm_lo_lo = _mm_mullo_pi16 (lo, mm_wh_lo);
>>> \
>>> +       mm_lo_hi = _mm_mullo_pi16 (hi, mm_wh_hi);
>>> \
>>> +       mm_hi_lo = _mm_mulhi_pu16 (lo, mm_wh_lo);
>>> \
>>> +       mm_hi_hi = _mm_mulhi_pu16 (hi, mm_wh_hi);
>>> \
>>>          lo = _mm_add_pi32 (_mm_unpacklo_pi16 (mm_lo_lo, mm_hi_lo),
>>> \
>>>                             _mm_unpacklo_pi16 (mm_lo_hi, mm_hi_hi));
>>> \
>>>          hi = _mm_add_pi32 (_mm_unpackhi_pi16 (mm_lo_lo, mm_hi_lo),
>>> \
>>>
>>> --
>>> cairo mailing list
>>> cairo-+tBg5+tf/GYFvLozru7NVdi2O/JbrIOy at public.gmane.org
>>> http://lists.cairographics.org/mailman/listinfo/cairo
>>>
>>>
>>> _______________________________________________
>>> Pixman mailing list
>>> Pixman-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW at public.gmane.org
>>> http://lists.freedesktop.org/mailman/listinfo/pixman
>
>
> _______________________________________________
> Pixman mailing list
> Pixman at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pixman
>


More information about the cairo mailing list