pixman: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Sep 1 20:45:21 UTC 2021


 pixman/pixman-bits-image.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

New commits:
commit 5f5e752f15acff7f39c861f2defed8ca10fa041c
Author: Manuel Stoeckl <code at mstoeckl.com>
Date:   Mon Aug 2 21:48:38 2021 -0400

    Fix masked pixel fetching with wide format
    
    In __bits_image_fetch_affine_no_alpha and __bits_image_fetch_general,
    when `wide` is true, the mask is actually an array of argb_t instead
    of the array of uint32_t it was cast to, and the access to `mask[i]`
    does not correctly detect when the pixel is nontrivial. The code now
    uses a check appropriate for argb_t when `wide` is true.
    
    One caveat: this new check only skips entries when the mask pixel data
    is binary all zero; this misses cases like `-0.f` which would be caught
    by the FLOAT_IS_ZERO macro. As the mask check only appears to be a
    performance optimization to avoid loading inconsequential pixels, it
    erring on the side of loading more pixels is safe.
    
    Signed-off-by: Manuel Stoeckl <code at mstoeckl.com>

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 8f3d9f2..a0d9441 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -482,6 +482,7 @@ __bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
     int             width  = iter->width;
     uint32_t *      buffer = iter->buffer;
 
+    const uint32_t wide_zero[4] = {0};
     pixman_fixed_t x, y;
     pixman_fixed_t ux, uy;
     pixman_vector_t v;
@@ -513,7 +514,8 @@ __bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
 
     for (i = 0; i < width; ++i)
     {
-	if (!mask || mask[i])
+	if (!mask || (!wide && mask[i]) ||
+	    (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0))
 	{
 	    bits_image_fetch_pixel_filtered (
 		&image->bits, wide, x, y, get_pixel, buffer);
@@ -636,6 +638,7 @@ __bits_image_fetch_general (pixman_iter_t  *iter,
     get_pixel_t     get_pixel =
 	wide ? fetch_pixel_general_float : fetch_pixel_general_32;
 
+    const uint32_t wide_zero[4] = {0};
     pixman_fixed_t x, y, w;
     pixman_fixed_t ux, uy, uw;
     pixman_vector_t v;
@@ -670,7 +673,8 @@ __bits_image_fetch_general (pixman_iter_t  *iter,
     {
 	pixman_fixed_t x0, y0;
 
-	if (!mask || mask[i])
+	if (!mask || (!wide && mask[i]) ||
+	    (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0))
 	{
 	    if (w != 0)
 	    {


More information about the xorg-commit mailing list