pixman: Branch 'master'
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jul 24 01:41:02 PDT 2009
pixman/pixman-radial-gradient.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
New commits:
commit 11d888a2837b3fe309348126b4f7c56df559df4e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 24 09:36:08 2009 +0100
Explain how we can simplify the radial gradient computation
Soeren rightfully complained that I had removed all the comments from
André's patch, most importantly that explain why the transformation is
valid. So add a few details to show that B varies linearly across the
scanline and how we can therefore reduce the per-pixel cost of evaluating
B.
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 04c170e..67a618d 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -155,9 +155,6 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
* for t:
*
* t = (-2·B ± â·(B² - 4·A·C)) / 2·A
- *
- * When computing t over a scanline, we notice that some expressions are
- * constant so we can compute them just once.
*/
gradient_t *gradient = (gradient_t *)image;
@@ -201,6 +198,33 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
if (affine)
{
+ /* When computing t over a scanline, we notice that some expressions
+ * are constant so we can compute them just once. Given:
+ *
+ * t = (-2·B ± â·(B² - 4·A·C)) / 2·A
+ *
+ * where
+ *
+ * A = cdx² + cdy² - dr² [precomputed as radial->A]
+ * B = -2·(pdx·cdx + pdy·cdy + râ·dr)
+ * C = pdx² + pdy² - râ²
+ *
+ * Since we have an affine transformation, we know that (pdx, pdy)
+ * increase linearly with each pixel,
+ *
+ * pdx = pdxâ + n·cx,
+ * pdy = pdyâ + n·cy,
+ *
+ * we can then express B in terms of an linear increment along
+ * the scanline:
+ *
+ * B = Bâ + n·cB, with
+ * Bâ = -2·(pdxâ·cdx + pdyâ·cdy + râ·dr) and
+ * cB = -2·(cx·cdx + cy·cdy)
+ *
+ * Thus we can replace the full evaluation of B per-pixel (4 multiplies,
+ * 2 additions) with a single addition.
+ */
double r1 = radial->c1.radius / 65536.;
double r1sq = r1 * r1;
double pdx = rx - radial->c1.x / 65536.;
More information about the xorg-commit
mailing list