Discussion:
[cairo] Cairo+Direct3D interaction bug and fix (x86 FPU precision)
Pauli Ojala
2006-10-16 11:15:25 UTC
Permalink
Hello all,

I'm making a Windows GTK+ app that also uses Direct3D for some separate
rendering within the same process. Unfortunately simply creating a Direct3D
device breaks Cairo's rendering: most drawing operations will produce no output.

After a day of pulling my hair out, I finally discovered the fix. The root of
the problem is that Direct3D switches the FPU to single-precision mode, which
causes _cairo_color_compute_shorts() in cairo-color.c to produce incorrect
values. More specifically, the code assumes that 1.0 *
CAIRO_COLOR_ONE_MINUS_EPSILON will produce 65535.0... But when the FPU is in
single-precision mode, that computes to 65536.0 instead, so the uint16 value
overflows to 0.

Now that I'm aware of Direct3D's evil FPU manipulation, I found a special flag
that can be used to disable this behavior in D3D (it's rather nuts that they
silently mess with the FPU by default).

Although in this case it was all Microsoft's fault, it might still be useful if
Cairo took into account the possibility that the x87 FPU is in single-precision
mode. Even just doing a simple test and printing out a big warning in case the
expected epsilon rounds to zero might spare a lot of time for someone who's
trying to use Direct3D. And there may also be other platforms out there where
doubles are really floats, so Cairo would be better prepared for that.

Best regards,
Pauli Ojala
Behdad Esfahbod
2006-10-16 11:37:51 UTC
Permalink
Post by Pauli Ojala
Although in this case it was all Microsoft's fault, it might still be useful if
Cairo took into account the possibility that the x87 FPU is in single-precision
mode. Even just doing a simple test and printing out a big warning in case the
expected epsilon rounds to zero might spare a lot of time for someone who's
trying to use Direct3D. And there may also be other platforms out there where
doubles are really floats, so Cairo would be better prepared for that.
See:

https://bugs.freedesktop.org/show_bug.cgi?id=7497

behdad
Post by Pauli Ojala
Best regards,
Pauli Ojala
--
behdad
http://behdad.org/

"Commandment Three says Do Not Kill, Amendment Two says Blood Will Spill"
-- Dan Bern, "New American Language"
Carl Worth
2006-10-16 15:18:59 UTC
Permalink
Post by Behdad Esfahbod
Post by Pauli Ojala
Although in this case it was all Microsoft's fault, it might still be useful if
Cairo took into account the possibility that the x87 FPU is in single-precision
mode.
Yes, this was simply a bug in cairo. A kind user had previously
reported this, and I'm sorry that we hadn't yet gotten a fix pushed
out for it.
Post by Behdad Esfahbod
https://bugs.freedesktop.org/show_bug.cgi?id=7497
Behdad chased down pointers to all the interesting bits of history
there. We had a lot of enlightening conversation around the problem,
and the answers were all there, but a complete patch never did appear
on the mailing list.

However, I did find that I had a complete commit with a fix sitting in
a branch of my repository. That's pushed out now:

http://gitweb.freedesktop.org/?p=cairo;a=commit;h=b62710d4f8602203d848daf2d444865b611fff09

It's rather embarrassing to find fixes just sitting there that haven't
been pushed out. I'll have to sweep through my branches at some point
to see what other gems might be there. I'd like for other people to be
able to help in this process, so I've got some changes coming for my
personal repository. More on that in a following mail.

-Carl



-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20061016/17adfa6c/attachment.pgp
Loading...