[Mesa-dev] [PATCH 12/16] gallium/auxiliary: add contained and rect checks

David Heidelberger david.heidelberger at ixit.cz
Mon Oct 20 15:12:22 PDT 2014


Dne 2014-10-20 17:38, Brian Paul napsal:
> A bunch of style nitpicks below...
> 
> On 10/18/2014 05:55 AM, David Heidelberger wrote:
>> From: Christoph Bumiller <christoph.bumiller at speed.at>
>> 
>> Signed-off-by: David Heidelberger <david.heidelberger at ixit.cz>
>> ---
>>   src/gallium/auxiliary/util/u_box.h  | 201 
>> ++++++++++++++++++++++++++++++++++++
>>   src/gallium/auxiliary/util/u_rect.h |  28 +++++
>>   2 files changed, 229 insertions(+)
>> 
>> diff --git a/src/gallium/auxiliary/util/u_box.h 
>> b/src/gallium/auxiliary/util/u_box.h
>> index 0b28d0f..b05d361 100644
>> --- a/src/gallium/auxiliary/util/u_box.h
>> +++ b/src/gallium/auxiliary/util/u_box.h
>> @@ -2,6 +2,7 @@
>>   #define UTIL_BOX_INLINES_H
>> 
>>   #include "pipe/p_state.h"
>> +#include "util/u_math.h"
>> 
>>   static INLINE
>>   void u_box_1d( unsigned x,
>> @@ -77,4 +78,204 @@ void u_box_3d( unsigned x,
>>      box->depth = d;
>>   }
>> 
>> +/* Returns whether @a is contained in or equal to @b. */
>> +static INLINE
>> +boolean u_box_contained(struct pipe_box *a, struct pipe_box *b)
> 
> static INLINE boolean
> u_box_contained(const struct pipe_box *a, const struct pipe_box *b)
> 
> 
>> +{
>> +   return
>> +      a->x >= b->x && (a->x + a->width  <= b->x + b->width) &&
>> +      a->y >= b->y && (a->y + a->height <= b->y + b->height) &&
>> +      a->z >= b->z && (a->z + a->depth  <= b->z + b->depth);
>> +}
>> +
>> +/* Clips @box to width @w and height @h.
>> + * Returns -1 if the resulting box would be empty (then @box is left 
>> unchanged).
>> + * Otherwise, returns 1/2/0/3 if width/height/neither/both have been 
>> reduced.
>> + * Aliasing permitted.
>> + */
>> +static INLINE
>> +int u_box_clip_2d(struct pipe_box *dst,
>> +                  struct pipe_box *box, int w, int h)
> 
> static INLINE int
> u_box_clip_2d(struct pipe_box *dst, const struct pipe_box *box, int w, 
> int h)
> 

Thanks, fixed coding style.

> That's a complicated return value.  Maybe a new enumerated type would
> be better than magic numbers.

At this moment we use -1 (not visible), 0 (no changes), >= 1 changes.
Implementing enum for this would be really ugly, if you want, I can't 
force it to return only 1 when success.

> 
> 
>> +{
>> +   int i, a[2], b[2], dim[2], res = 0;
>> +
>> +   if (!box->width || !box->height)
>> +      return -1;
>> +   dim[0] = w;
>> +   dim[1] = h;
>> +   a[0] = box->x;
>> +   a[1] = box->y;
>> +   b[0] = box->x + box->width;
>> +   b[1] = box->y + box->height;
>> +
>> +   for (i = 0; i < 2; ++i) {
>> +      if (b[i] < a[i]) {
>> +         if (a[i] < 0 || b[i] >= dim[i])
>> +            return -1;
>> +         if (a[i] > dim[i]) { a[i] = dim[i]; res |= (1 << i); }
> 
> if (condition) {
>    code;
> }
> 
> 
>> +         if (b[i] < 0) { b[i] = 0; res |= (1 << i); }
>> +      } else {
>> +         if (b[i] < 0 || a[i] >= dim[i])
>> +            return -1;
>> +         if (a[i] < 0) { a[i] = 0; res |= (1 << i); }
>> +         if (b[i] > dim[i]) { b[i] = dim[i]; res |= (1 << i); }
>> +      }
>> +   }
>> +
>> +   if (res) {
>> +      dst->x = a[0];
>> +      dst->y = a[1];
>> +      dst->width = b[0] - a[0];
>> +      dst->height = b[1] - a[1];
>> +   }
>> +   return res;
>> +}
>> +
>> +static INLINE
>> +int u_box_clip_3d(struct pipe_box *dst,
>> +                  struct pipe_box *box, int w, int h, int d)
> 
> Same comment as above.
> 
> 
>> +{
>> +   int i, a[3], b[3], dim[3], res = 0;
>> +
>> +   if (!box->width || !box->height)
>> +      return -1;
>> +   dim[0] = w;
>> +   dim[1] = h;
>> +   dim[2] = d;
>> +   a[0] = box->x;
>> +   a[1] = box->y;
>> +   a[2] = box->z;
>> +   b[0] = box->x + box->width;
>> +   b[1] = box->y + box->height;
>> +   b[2] = box->z + box->depth;
>> +

We noticed, that u_box_clip_3d do not correctly clip Z. As I looking at 
code, seems solution
with for (i = 0; i < 3; ++i) { isn't enough. We'll have to figure out 
something.

>> +   for (i = 0; i < 2; ++i) {
>> +      if (b[i] < a[i]) {
>> +         if (a[i] < 0 || b[i] >= dim[i])
>> +            return -1;
>> +         if (a[i] > dim[i]) { a[i] = dim[i]; res |= (1 << i); }
>> +         if (b[i] < 0) { b[i] = 0; res |= (1 << i); }
>> +      } else {
>> +         if (b[i] < 0 || a[i] >= dim[i])
>> +            return -1;
>> +         if (a[i] < 0) { a[i] = 0; res |= (1 << i); }
>> +         if (b[i] > dim[i]) { b[i] = dim[i]; res |= (1 << i); }
>> +      }
>> +   }
>> +
>> +   if (res) {
>> +      dst->x = a[0];
>> +      dst->y = a[1];
>> +      dst->z = a[2];
>> +      dst->width = b[0] - a[0];
>> +      dst->height = b[1] - a[1];
>> +      dst->depth = b[2] - a[2];
>> +   }
>> +   return res;
>> +}
>> +
>> +/* Return true if @a is contained in or equal to @b.
>> + */
>> +static INLINE
>> +boolean u_box_contained_2d(const struct pipe_box *a, const struct 
>> pipe_box *b)
> 
> static INLINE boolean
> u_box_contained_2d(...)
> 
> Same style should be used for all functions here.
> 
> 
>> +{
>> +   int a_x1 = a->x + a->width;
>> +   int b_x1 = b->x + b->width;
>> +   int a_y1 = a->y + a->height;
>> +   int b_y1 = b->y + b->height;
>> +   return
>> +      a->x >= b->x && a_x1 <= b_x1 &&
>> +      a->y >= b->y && a_y1 <= b_y1;
>> +}
>> +
>> +static INLINE
>> +int64_t u_box_volume(const struct pipe_box *box)
>> +{
>> +   return (int64_t)box->width * box->height * box->depth;
>> +}
>> +
>> +/* Aliasing of @dst and @a permitted. */
>> +static INLINE
>> +void u_box_cover_2d(struct pipe_box *dst,
>> +                    struct pipe_box *a, const struct pipe_box *b)
>> +{
>> +   int x1_a = a->x + a->width;
>> +   int y1_a = a->y + a->height;
>> +   int x1_b = b->x + b->width;
>> +   int y1_b = b->y + b->height;
>> +
>> +   dst->x = MIN2(a->x, b->x);
>> +   dst->y = MIN2(a->y, b->y);
>> +
>> +   dst->width = MAX2(x1_a, x1_b) - dst->x;
>> +   dst->height = MAX2(y1_a, y1_b) - dst->y;
>> +}
>> +
>> +/* Aliasing of @dst and @a permitted. */
>> +static INLINE
>> +void u_box_cover(struct pipe_box *dst,
>> +                 struct pipe_box *a, const struct pipe_box *b)
>> +{
>> +   int x1_a = a->x + a->width;
>> +   int y1_a = a->y + a->height;
>> +   int z1_a = a->z + a->depth;
>> +   int x1_b = b->x + b->width;
>> +   int y1_b = b->y + b->height;
>> +   int z1_b = b->z + b->depth;
>> +
>> +   dst->x = MIN2(a->x, b->x);
>> +   dst->y = MIN2(a->y, b->y);
>> +   dst->z = MIN2(a->z, b->z);
>> +
>> +   dst->width = MAX2(x1_a, x1_b) - dst->x;
>> +   dst->height = MAX2(y1_a, y1_b) - dst->y;
>> +   dst->depth = MAX2(z1_a, z1_b) - dst->z;
>> +}
>> +
>> +static INLINE
>> +boolean u_box_test_intersection_xy_only(const struct pipe_box *a,
>> +                                        const struct pipe_box *b)
>> +{
>> +   int i;
>> +   unsigned a_l[2], a_r[2], b_l[2], b_r[2];
>> +
>> +   a_l[0] = MIN2(a->x, a->x + a->width);
>> +   a_r[0] = MAX2(a->x, a->x + a->width);
>> +   a_l[1] = MIN2(a->y, a->y + a->height);
>> +   a_r[1] = MAX2(a->y, a->y + a->height);
>> +
>> +   b_l[0] = MIN2(b->x, b->x + b->width);
>> +   b_r[0] = MAX2(b->x, b->x + b->width);
>> +   b_l[1] = MIN2(b->y, b->y + b->height);
>> +   b_r[1] = MAX2(b->y, b->y + b->height);
>> +
>> +   for (i = 0; i < 2; ++i) {
>> +      if (a_l[i] > b_r[i] || a_r[i] < b_l[i])
>> +         return FALSE;
>> +   }
>> +   return TRUE;
>> +}
>> +
>> +static INLINE
>> +void u_box_minify(struct pipe_box *dst,
>> +                  const struct pipe_box *src, unsigned l)
>> +{
>> +   dst->x = src->x >> l;
>> +   dst->y = src->y >> l;
>> +   dst->z = src->z >> l;
>> +   dst->width = MAX2(src->width >> l, 1);
>> +   dst->height = MAX2(src->height >> l, 1);
>> +   dst->depth = MAX2(src->depth >> l, 1);
>> +}
>> +
>> +static INLINE
>> +void u_box_minify_2d(struct pipe_box *dst,
>> +                     const struct pipe_box *src, unsigned l)
>> +{
>> +   dst->x = src->x >> l;
>> +   dst->y = src->y >> l;
>> +   dst->width = MAX2(src->width >> l, 1);
>> +   dst->height = MAX2(src->height >> l, 1);
>> +}
>> +
>>   #endif
>> diff --git a/src/gallium/auxiliary/util/u_rect.h 
>> b/src/gallium/auxiliary/util/u_rect.h
>> index dd87f81..c8eda4a 100644
>> --- a/src/gallium/auxiliary/util/u_rect.h
>> +++ b/src/gallium/auxiliary/util/u_rect.h
>> @@ -30,6 +30,7 @@
>>   #define U_RECT_H
>> 
>>   #include "pipe/p_compiler.h"
>> +#include "util/u_math.h"
>> 
>>   #ifdef __cplusplus
>>   extern "C" {
>> @@ -67,6 +68,22 @@ u_rect_find_intersection(const struct u_rect *a,
>>   }
>> 
>> 
>> +/* Return true if @a is contained in or equal to @b.
>> + */
>> +static INLINE boolean
>> +u_rect_contained(const struct u_rect *a, const struct u_rect *b)
>> +{
>> +   return
>> +      a->x0 >= b->x0 && a->x1 <= b->x1 &&
>> +      a->y0 >= b->y0 && a->y1 <= b->y1;
>> +}
>> +
>> +static INLINE int
>> +u_rect_area(const struct u_rect *r)
>> +{
>> +   return (r->x1 - r->x0) * (r->y1 - r->y0);
>> +}
>> +
>>   static INLINE void
>>   u_rect_possible_intersection(const struct u_rect *a,
>>                                struct u_rect *b)
>> @@ -79,6 +96,17 @@ u_rect_possible_intersection(const struct u_rect 
>> *a,
>>      }
>>   }
>> 
>> +/* Set @d to a rectangle that covers both @a and @b.
>> + */
>> +static INLINE void
>> +u_rect_cover(struct u_rect *d, const struct u_rect *a, const struct 
>> u_rect *b)
>> +{
>> +   d->x0 = MIN2(a->x0, b->x0);
>> +   d->y0 = MIN2(a->y0, b->y0);
>> +   d->x1 = MAX2(a->x1, b->x1);
>> +   d->y1 = MAX2(a->y1, b->y1);
>> +}
>> +
>>   #ifdef __cplusplus
>>   }
>>   #endif
>> 


More information about the mesa-dev mailing list