2 * Copyright (C) 2020 Collabora, Ltd.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #include "util/ralloc.h"
26 #include "pan_partial_update.h"
28 static struct pan_rect
29 pan_make_rect(unsigned minx
, unsigned miny
, unsigned maxx
, unsigned maxy
)
41 static struct pan_rect
42 pan_from_pipe(const struct pipe_box
*p
)
44 return pan_make_rect(p
->x
, p
->y
, p
->x
+ p
->width
, p
->y
+ p
->height
);
47 /* Helper to clip a rect inside another box */
49 static struct pan_rect
51 const struct pan_rect
*r
,
52 const struct pan_rect
*clip
)
54 unsigned minx
= MAX2(r
->minx
, clip
->minx
);
55 unsigned miny
= MAX2(r
->miny
, clip
->miny
);
56 unsigned maxx
= MAX2(MIN2(r
->maxx
, clip
->maxx
), minx
);
57 unsigned maxy
= MAX2(MIN2(r
->maxy
, clip
->maxy
), miny
);
59 return pan_make_rect(minx
, miny
, maxx
, maxy
);
62 /* Subtract d from r, yielding four (possibly degenerate) rectangles for each
66 pan_subtract_from_rect(
68 const struct pan_rect
*r
,
69 const struct pan_rect
*d
)
71 struct pan_rect dc
= pan_clip_rect(r
, d
);
73 out
[0] = pan_make_rect(r
->minx
, r
->miny
, dc
.minx
, r
->maxy
);
74 out
[1] = pan_make_rect(dc
.minx
, r
->miny
, dc
.maxx
, dc
.miny
);
75 out
[2] = pan_make_rect(dc
.maxx
, r
->miny
, r
->maxx
, r
->maxy
);
76 out
[3] = pan_make_rect(dc
.minx
, dc
.maxy
, dc
.maxx
, r
->maxy
);
79 /* Subtract d from the set of rects R, returning the number of
80 * (non-degenerate) rectangles returned.
82 * out must be at least sizeof(struct pan_rect) * R_len * 4 bytes
84 * Trivially satisfies: return value < (R_len * 4) */
87 pan_subtract_from_rects(
89 const struct pan_rect
*R
,
91 const struct pan_rect
*d
)
94 struct pan_rect temp
[4];
96 for (unsigned r
= 0; r
< R_len
; ++r
) {
97 pan_subtract_from_rect(temp
, &R
[r
], d
);
99 /* Copy the rectangles with nonzero area */
100 for (unsigned i
= 0; i
< 4; ++i
) {
101 if (temp
[i
].maxx
<= temp
[i
].minx
) continue;
102 if (temp
[i
].maxy
<= temp
[i
].miny
) continue;
104 out
[count
++] = temp
[i
];
114 unsigned initial_w
, unsigned initial_h
,
116 const struct pipe_box
*rects
,
119 struct pan_rect
*R
= ralloc(memctx
, struct pan_rect
);
120 *R
= pan_make_rect(0, 0, initial_w
, initial_h
);
123 for (unsigned d
= 0; d
< nrects
; ++d
) {
124 const struct pan_rect D
= pan_from_pipe(&rects
[d
]);
125 struct pan_rect
*out
= rzalloc_array(memctx
, struct pan_rect
,
128 R_len
= pan_subtract_from_rects(out
, R
, R_len
, &D
);