From 71181a516b5f234172f596aa82ee89e0783ac7cb Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 18 Jun 2020 12:11:20 +0100 Subject: [PATCH] box: Use isinf() and signbit() when isinff() is not available Instead of using bytewise comparison, use isinf() and hope it works correctly with single precision floats on the target platform; additionally, since the negative return value for negative infinities is a GNU extension, use signbit() to check if the number is a positive or negative infinity. --- src/graphene-box.c | 56 ++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/graphene-box.c b/src/graphene-box.c index 2099c60f..0a402386 100644 --- a/src/graphene-box.c +++ b/src/graphene-box.c @@ -436,18 +436,22 @@ graphene_box_is_empty (const graphene_box_t *box) return (isinff (vmin[0]) == 1 && isinff (vmin[1]) == 1 && isinff (vmin[2]) == 1) && (isinff (vmax[0]) == -1 && isinff (vmax[1]) == -1 && isinff (vmax[2]) == -1); #else - graphene_simd4f_t neg_inf = graphene_simd4f_init (-INFINITY, -INFINITY, -INFINITY, 0.f); - graphene_simd4f_t pos_inf = graphene_simd4f_init (INFINITY, INFINITY, INFINITY, 0.f); - - /* This is only every going to be valid for boxes that we have - * initialized ourselves, because we use the same values; the - * bitwise comparison will not hold for infinities generated by - * other operations - */ - int min_cmp = memcmp (&box->min.value, &pos_inf, sizeof (graphene_simd4f_t)); - int max_cmp = memcmp (&box->max.value, &neg_inf, sizeof (graphene_simd4f_t)); - - return min_cmp == 0 && max_cmp == 0; + float vmin[3], vmax[3]; + + graphene_simd4f_dup_3f (box->min.value, vmin); + graphene_simd4f_dup_3f (box->max.value, vmax); + + bool vmin_pos_inf = + (isinf (vmin[0]) && signbit (vmin[0]) == 0) && + (isinf (vmin[1]) && signbit (vmin[1]) == 0) && + (isinf (vmin[2]) && signbit (vmin[2]) == 0); + + bool vmax_neg_inf = + (isinf (vmax[0]) && signbit (vmax[0]) < 0) && + (isinf (vmax[1]) && signbit (vmax[1]) < 0) && + (isinf (vmax[2]) && signbit (vmax[2]) < 0); + + return vmin_pos_inf && vmax_neg_inf; #endif } @@ -463,18 +467,22 @@ graphene_box_is_infinity (const graphene_box_t *box) return (isinff (vmin[0]) == -1 && isinff (vmin[1]) == -1 && isinff (vmin[2]) == -1) && (isinff (vmax[0]) == 1 && isinff (vmax[1]) == 1 && isinff (vmax[2]) == 1); #else - graphene_simd4f_t neg_inf = graphene_simd4f_init (-INFINITY, -INFINITY, -INFINITY, 0.f); - graphene_simd4f_t pos_inf = graphene_simd4f_init (INFINITY, INFINITY, INFINITY, 0.f); - - /* This is only every going to be valid for boxes that we have - * initialized ourselves, because we use the same values; the - * bitwise comparison will not hold for infinities generated by - * other operations - */ - int min_cmp = memcmp (&box->min.value, &neg_inf, sizeof (graphene_simd4f_t)); - int max_cmp = memcmp (&box->max.value, &pos_inf, sizeof (graphene_simd4f_t)); - - return min_cmp == 0 && max_cmp == 0; + float vmin[3], vmax[3]; + + graphene_simd4f_dup_3f (box->min.value, vmin); + graphene_simd4f_dup_3f (box->max.value, vmax); + + bool vmin_neg_inf = + (isinf (vmin[0]) && signbit (vmin[0]) < 0) && + (isinf (vmin[1]) && signbit (vmin[1]) < 0) && + (isinf (vmin[2]) && signbit (vmin[2]) < 0); + + bool vmax_pos_inf = + (isinf (vmax[0]) && signbit (vmax[0]) == 0) && + (isinf (vmax[1]) && signbit (vmax[1]) == 0) && + (isinf (vmax[2]) && signbit (vmax[2]) == 0); + + return vmin_neg_inf && vmax_pos_inf; #endif }