From fff8dbd9b8ed22bd92eceb8dce16aa540ab4a41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Molinari?= Date: Thu, 25 May 2023 09:02:26 +0200 Subject: [PATCH] gl-renderer: Move clip_quad() to clipper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clip_quad() is a dedicated clipping function for quads that doesn't depend on any GL renderer internal structures. It can be moved out to the clipper to be called by both the renderer and the clipping test client without having to duplicate code. Signed-off-by: Loïc Molinari --- clients/cliptest.c | 53 ----------------------------- libweston/renderer-gl/gl-renderer.c | 53 ----------------------------- libweston/vertex-clipping.c | 46 +++++++++++++++++++++++++ libweston/vertex-clipping.h | 13 +++++++ 4 files changed, 59 insertions(+), 106 deletions(-) diff --git a/clients/cliptest.c b/clients/cliptest.c index f9dfc2e6..9923a911 100644 --- a/clients/cliptest.c +++ b/clients/cliptest.c @@ -151,59 +151,6 @@ rect_to_quad(pixman_box32_t *rect, struct weston_view *ev, } } -/* - * Compute the boundary vertices of the intersection of an arbitrary - * quadrilateral 'quad' and the axis-aligned rectangle 'surf_rect'. 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. - */ -static int -clip_quad(struct gl_quad *quad, pixman_box32_t *surf_rect, - struct clip_vertex *vertices) -{ - struct clip_context ctx = { - .clip.x1 = surf_rect->x1, - .clip.y1 = surf_rect->y1, - .clip.x2 = surf_rect->x2, - .clip.y2 = surf_rect->y2, - }; - int n; - - /* Simple case: quad edges are parallel to surface rect edges, there - * will be either four or zero edges. We just need to clip the quad to - * the surface rect bounds and test for non-zero area: - */ - if (quad->axis_aligned) { - clip_simple(&ctx, &quad->vertices, vertices); - if ((vertices[0].x != vertices[1].x) && - (vertices[0].y != vertices[2].y)) - return 4; - else - return 0; - } - - /* Transformed case: first, simple bounding box check to discard early a - * quad that does not intersect with the rect: - */ - if ((quad->bbox.x1 >= ctx.clip.x2) || (quad->bbox.x2 <= ctx.clip.x1) || - (quad->bbox.y1 >= ctx.clip.y2) || (quad->bbox.y2 <= ctx.clip.y1)) - return 0; - - /* Then, use a general polygon clipping algorithm to clip the quad with - * each side of the surface rect. The algorithm is Sutherland-Hodgman, - * as explained in - * https://www.codeguru.com/cplusplus/polygon-clipping/ - * but without looking at any of that code. - */ - n = clip_transformed(&ctx, &quad->vertices, vertices); - - if (n < 3) - return 0; - - return n; -} - /* ---------------------- copied ends -----------------------*/ static void diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 06b85d9b..24e85060 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -479,59 +479,6 @@ rect_to_quad(pixman_box32_t *rect, struct weston_view *ev, } } -/* - * Compute the boundary vertices of the intersection of an arbitrary - * quadrilateral 'quad' and the axis-aligned rectangle 'surf_rect'. 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. - */ -static int -clip_quad(struct gl_quad *quad, pixman_box32_t *surf_rect, - struct clip_vertex *vertices) -{ - struct clip_context ctx = { - .clip.x1 = surf_rect->x1, - .clip.y1 = surf_rect->y1, - .clip.x2 = surf_rect->x2, - .clip.y2 = surf_rect->y2, - }; - int n; - - /* Simple case: quad edges are parallel to surface rect edges, there - * will be either four or zero edges. We just need to clip the quad to - * the surface rect bounds and test for non-zero area: - */ - if (quad->axis_aligned) { - clip_simple(&ctx, &quad->vertices, vertices); - if ((vertices[0].x != vertices[1].x) && - (vertices[0].y != vertices[2].y)) - return 4; - else - return 0; - } - - /* Transformed case: first, simple bounding box check to discard early a - * quad that does not intersect with the rect: - */ - if ((quad->bbox.x1 >= ctx.clip.x2) || (quad->bbox.x2 <= ctx.clip.x1) || - (quad->bbox.y1 >= ctx.clip.y2) || (quad->bbox.y2 <= ctx.clip.y1)) - return 0; - - /* Then, use a general polygon clipping algorithm to clip the quad with - * each side of the surface rect. The algorithm is Sutherland-Hodgman, - * as explained in - * https://www.codeguru.com/cplusplus/polygon-clipping/ - * but without looking at any of that code. - */ - n = clip_transformed(&ctx, &quad->vertices, vertices); - - if (n < 3) - return 0; - - return n; -} - static bool merge_down(pixman_box32_t *a, pixman_box32_t *b, pixman_box32_t *merge) { diff --git a/libweston/vertex-clipping.c b/libweston/vertex-clipping.c index 98faa3cd..8896527a 100644 --- a/libweston/vertex-clipping.c +++ b/libweston/vertex-clipping.c @@ -321,3 +321,49 @@ clip_transformed(struct clip_context *ctx, return n; } + +int +clip_quad(struct gl_quad *quad, pixman_box32_t *surf_rect, + struct clip_vertex *vertices) +{ + struct clip_context ctx = { + .clip.x1 = surf_rect->x1, + .clip.y1 = surf_rect->y1, + .clip.x2 = surf_rect->x2, + .clip.y2 = surf_rect->y2, + }; + int n; + + /* Simple case: quad edges are parallel to surface rect edges, there + * will be either four or zero edges. We just need to clip the quad to + * the surface rect bounds and test for non-zero area: + */ + if (quad->axis_aligned) { + clip_simple(&ctx, &quad->vertices, vertices); + if ((vertices[0].x != vertices[1].x) && + (vertices[0].y != vertices[2].y)) + return 4; + else + return 0; + } + + /* Transformed case: first, simple bounding box check to discard early a + * quad that does not intersect with the rect: + */ + if ((quad->bbox.x1 >= ctx.clip.x2) || (quad->bbox.x2 <= ctx.clip.x1) || + (quad->bbox.y1 >= ctx.clip.y2) || (quad->bbox.y2 <= ctx.clip.y1)) + return 0; + + /* Then, use a general polygon clipping algorithm to clip the quad with + * each side of the surface rect. The algorithm is Sutherland-Hodgman, + * as explained in + * https://www.codeguru.com/cplusplus/polygon-clipping/ + * but without looking at any of that code. + */ + n = clip_transformed(&ctx, &quad->vertices, vertices); + + if (n < 3) + return 0; + + return n; +} diff --git a/libweston/vertex-clipping.h b/libweston/vertex-clipping.h index 9bd3d324..1b0fdc42 100644 --- a/libweston/vertex-clipping.h +++ b/libweston/vertex-clipping.h @@ -26,6 +26,7 @@ #define _WESTON_VERTEX_CLIPPING_H #include +#include struct clip_vertex { float x, y; @@ -66,4 +67,16 @@ clip_transformed(struct clip_context *ctx, struct polygon8 *surf, struct clip_vertex *restrict vertices); +/* + * Compute the boundary vertices of the intersection of an arbitrary + * quadrilateral 'quad' and the axis-aligned rectangle 'surf_rect'. 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. + */ +int +clip_quad(struct gl_quad *quad, + pixman_box32_t *surf_rect, + struct clip_vertex *vertices); + #endif