gl-renderer: Add init_quad() to clipper
Extract quad bounding box initialization from the GL renderer and move it to a dedicated initialization function in the clipper. It's used by both the renderer and the clipping test client, which further reduces code duplication. Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
parent
f74c5a4102
commit
2d0d0175d2
|
@ -23,9 +23,9 @@
|
|||
*/
|
||||
|
||||
/* cliptest:
|
||||
* For debugging the rect_to_quad() and clip_quad() functions. An arbitrary
|
||||
* quad (red) is transformed from global coordinate space to surface
|
||||
* coordinate space and clipped to an axis-aligned rect (blue).
|
||||
* For debugging the quad clipper. An arbitrary quad (red) is transformed
|
||||
* from global coordinate space to surface coordinate space and clipped to
|
||||
* an axis-aligned rect (blue).
|
||||
*
|
||||
* controls:
|
||||
* surface rect position: mouse left drag, keys: w a s d
|
||||
|
@ -111,8 +111,8 @@ weston_coord_global_to_surface(struct weston_view *view, struct weston_coord_glo
|
|||
/* Keep this in sync with what is in gl-renderer.c! */
|
||||
|
||||
static void
|
||||
rect_to_quad(pixman_box32_t *rect, struct weston_view *ev,
|
||||
struct gl_quad *quad)
|
||||
global_to_surface(pixman_box32_t *rect, struct weston_view *ev,
|
||||
struct clip_vertex polygon[4], bool *axis_aligned)
|
||||
{
|
||||
struct weston_coord_global rect_g[4] = {
|
||||
{ .c = weston_coord(rect->x1, rect->y1) },
|
||||
|
@ -123,31 +123,14 @@ rect_to_quad(pixman_box32_t *rect, struct weston_view *ev,
|
|||
struct weston_coord rect_s;
|
||||
int i;
|
||||
|
||||
/* Transform rect to surface space. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rect_s = weston_coord_global_to_surface(ev, rect_g[i]).c;
|
||||
quad->polygon[i].x = (float)rect_s.x;
|
||||
quad->polygon[i].y = (float)rect_s.y;
|
||||
polygon[i].x = (float)rect_s.x;
|
||||
polygon[i].y = (float)rect_s.y;
|
||||
}
|
||||
|
||||
quad->axis_aligned = !ev->transform.enabled ||
|
||||
*axis_aligned = !ev->transform.enabled ||
|
||||
(ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
|
||||
|
||||
/* Find axis-aligned bounding box. */
|
||||
if (!quad->axis_aligned) {
|
||||
quad->bbox[0].x = quad->bbox[1].x = quad->polygon[0].x;
|
||||
quad->bbox[0].y = quad->bbox[1].y = quad->polygon[0].y;
|
||||
for (i = 1; i < 4; i++) {
|
||||
quad->bbox[0].x = MIN(quad->bbox[0].x,
|
||||
quad->polygon[i].x);
|
||||
quad->bbox[1].x = MAX(quad->bbox[1].x,
|
||||
quad->polygon[i].x);
|
||||
quad->bbox[0].y = MIN(quad->bbox[0].y,
|
||||
quad->polygon[i].y);
|
||||
quad->bbox[1].y = MAX(quad->bbox[1].y,
|
||||
quad->polygon[i].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------- copied ends -----------------------*/
|
||||
|
@ -295,10 +278,13 @@ redraw_handler(struct widget *widget, void *data)
|
|||
cairo_t *cr;
|
||||
cairo_surface_t *surface;
|
||||
struct gl_quad quad;
|
||||
struct clip_vertex v[8];
|
||||
struct clip_vertex transformed_v[4], v[8];
|
||||
bool axis_aligned;
|
||||
int n;
|
||||
|
||||
rect_to_quad(&g->quad, &cliptest->view, &quad);
|
||||
global_to_surface(&g->quad, &cliptest->view, transformed_v,
|
||||
&axis_aligned);
|
||||
init_quad(&quad, transformed_v, axis_aligned);
|
||||
n = clip_quad_box32(&quad, &g->surf, v);
|
||||
|
||||
widget_get_allocation(cliptest->widget, &allocation);
|
||||
|
@ -567,7 +553,8 @@ benchmark(void)
|
|||
struct weston_view view;
|
||||
struct geometry geom;
|
||||
struct gl_quad quad;
|
||||
struct clip_vertex v[8];
|
||||
struct clip_vertex transformed_v[4], v[8];
|
||||
bool axis_aligned;
|
||||
int i;
|
||||
double t;
|
||||
const int N = 1000000;
|
||||
|
@ -592,7 +579,9 @@ benchmark(void)
|
|||
reset_timer();
|
||||
for (i = 0; i < N; i++) {
|
||||
geometry_set_phi(&geom, (float)i / 360.0f);
|
||||
rect_to_quad(&geom.quad, &view, &quad);
|
||||
global_to_surface(&geom.quad, &view, transformed_v,
|
||||
&axis_aligned);
|
||||
init_quad(&quad, transformed_v, axis_aligned);
|
||||
clip_quad_box32(&quad, &geom.surf, v);
|
||||
}
|
||||
t = read_timer();
|
||||
|
|
|
@ -472,8 +472,8 @@ timeline_submit_render_sync(struct gl_renderer *gr,
|
|||
}
|
||||
|
||||
static void
|
||||
rect_to_quad(pixman_box32_t *rect, struct weston_view *ev,
|
||||
struct gl_quad *quad)
|
||||
global_to_surface(pixman_box32_t *rect, struct weston_view *ev,
|
||||
struct clip_vertex polygon[4], bool *axis_aligned)
|
||||
{
|
||||
struct weston_coord_global rect_g[4] = {
|
||||
{ .c = weston_coord(rect->x1, rect->y1) },
|
||||
|
@ -484,31 +484,14 @@ rect_to_quad(pixman_box32_t *rect, struct weston_view *ev,
|
|||
struct weston_coord rect_s;
|
||||
int i;
|
||||
|
||||
/* Transform rect to surface space. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rect_s = weston_coord_global_to_surface(ev, rect_g[i]).c;
|
||||
quad->polygon[i].x = (float)rect_s.x;
|
||||
quad->polygon[i].y = (float)rect_s.y;
|
||||
polygon[i].x = (float)rect_s.x;
|
||||
polygon[i].y = (float)rect_s.y;
|
||||
}
|
||||
|
||||
quad->axis_aligned = !ev->transform.enabled ||
|
||||
*axis_aligned = !ev->transform.enabled ||
|
||||
(ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
|
||||
|
||||
/* Find axis-aligned bounding box. */
|
||||
if (!quad->axis_aligned) {
|
||||
quad->bbox[0].x = quad->bbox[1].x = quad->polygon[0].x;
|
||||
quad->bbox[0].y = quad->bbox[1].y = quad->polygon[0].y;
|
||||
for (i = 1; i < 4; i++) {
|
||||
quad->bbox[0].x = MIN(quad->bbox[0].x,
|
||||
quad->polygon[i].x);
|
||||
quad->bbox[1].x = MAX(quad->bbox[1].x,
|
||||
quad->polygon[i].x);
|
||||
quad->bbox[0].y = MIN(quad->bbox[0].y,
|
||||
quad->polygon[i].y);
|
||||
quad->bbox[1].y = MAX(quad->bbox[1].y,
|
||||
quad->polygon[i].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -572,7 +555,8 @@ texture_region(struct weston_paint_node *pnode,
|
|||
pixman_box32_t *rects, *surf_rects;
|
||||
pixman_box32_t *raw_rects;
|
||||
int i, j, nrects, nsurf, raw_nrects;
|
||||
bool used_band_compression;
|
||||
bool used_band_compression, axis_aligned;
|
||||
struct clip_vertex polygon[4];
|
||||
struct gl_quad quad;
|
||||
|
||||
raw_rects = pixman_region32_rectangles(region, &raw_nrects);
|
||||
|
@ -593,7 +577,8 @@ texture_region(struct weston_paint_node *pnode,
|
|||
vtxcnt = wl_array_add(&gr->vtxcnt, nrects * nsurf * sizeof *vtxcnt);
|
||||
|
||||
for (i = 0; i < nrects; i++) {
|
||||
rect_to_quad(&rects[i], ev, &quad);
|
||||
global_to_surface(&rects[i], ev, polygon, &axis_aligned);
|
||||
init_quad(&quad, polygon, axis_aligned);
|
||||
for (j = 0; j < nsurf; j++) {
|
||||
int n;
|
||||
|
||||
|
|
|
@ -329,6 +329,30 @@ clip_transformed(const struct clip_vertex *polygon,
|
|||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
init_quad(struct gl_quad *quad,
|
||||
const struct clip_vertex polygon[4],
|
||||
bool axis_aligned)
|
||||
{
|
||||
int i;
|
||||
|
||||
memcpy(quad->polygon, polygon, 4 * sizeof *polygon);
|
||||
quad->axis_aligned = axis_aligned;
|
||||
|
||||
if (axis_aligned)
|
||||
return;
|
||||
|
||||
/* Find axis-aligned bounding box. */
|
||||
quad->bbox[0].x = quad->bbox[1].x = polygon[0].x;
|
||||
quad->bbox[0].y = quad->bbox[1].y = polygon[0].y;
|
||||
for (i = 1; i < 4; i++) {
|
||||
quad->bbox[0].x = MIN(quad->bbox[0].x, polygon[i].x);
|
||||
quad->bbox[1].x = MAX(quad->bbox[1].x, polygon[i].x);
|
||||
quad->bbox[0].y = MIN(quad->bbox[0].y, polygon[i].y);
|
||||
quad->bbox[1].y = MAX(quad->bbox[1].y, polygon[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
clip_quad(struct gl_quad *quad,
|
||||
const struct clip_vertex box[2],
|
||||
|
|
|
@ -49,13 +49,25 @@ clip_transformed(const struct clip_vertex *polygon,
|
|||
struct clip_vertex *restrict vertices);
|
||||
|
||||
/*
|
||||
* Compute the boundary vertices of the intersection of an arbitrary
|
||||
* quadrilateral stored into a 'quad' clipping context and a clipping
|
||||
* 'box'. 'box' points to an array of 2 vertices where the values of the 1st
|
||||
* vertex are less than or equal to the values of the 2nd vertex. The vertices
|
||||
* are written to 'vertices', and the return value is the number of vertices.
|
||||
* Vertices are produced in clockwise winding order. Guarantees to produce
|
||||
* either zero vertices, or 3-8 vertices with non-zero polygon area.
|
||||
* Initialize a 'quad' clipping context. 'polygon' points to an array of 4
|
||||
* vertices defining a convex quadrilateral of any winding order. Call
|
||||
* 'clip_quad()' to clip an initialized 'quad' to a clipping box. Clipping is
|
||||
* faster if 'polygon' is an axis-aligned rectangle with edges parallel to the
|
||||
* axes of the coordinate space. 'axis_aligned' indicates whether 'polygon'
|
||||
* respects the conditions above.
|
||||
*/
|
||||
void
|
||||
init_quad(struct gl_quad *quad,
|
||||
const struct clip_vertex polygon[4],
|
||||
bool axis_aligned);
|
||||
|
||||
/*
|
||||
* Compute the boundary vertices of the intersection of a convex quadrilateral
|
||||
* stored into a 'quad' clipping context and a clipping 'box'. 'box' points to
|
||||
* an array of 2 vertices where the values of the 1st vertex are less than or
|
||||
* equal to the values of the 2nd vertex. Either 0 or [3, 8] resulting vertices,
|
||||
* with the same winding order than the 'polygon' passed to 'init_quad()', are
|
||||
* written to 'vertices'. The return value is the number of vertices created.
|
||||
*/
|
||||
int
|
||||
clip_quad(struct gl_quad *quad,
|
||||
|
|
Loading…
Reference in New Issue