From 10e70bf23c0a9845aa8865216763e7e29ef390f3 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 9 Feb 2022 11:17:42 -0600 Subject: [PATCH] clipping: Use struct weston_coord in vertex clipping code Remove the independent x, y floats from the clipping code and replace them with struct weston_cord. This includes the polygon8 structure as well. Signed-off-by: Derek Foreman --- clients/cliptest.c | 122 +++++++++++--------- clients/meson.build | 2 +- libweston/renderer-gl/gl-renderer.c | 71 ++++++------ libweston/vertex-clipping.c | 85 +++++++------- libweston/vertex-clipping.h | 16 +-- tests/vertex-clip-test.c | 168 ++++++++++++++++++---------- 6 files changed, 265 insertions(+), 199 deletions(-) diff --git a/clients/cliptest.c b/clients/cliptest.c index 6811e4e5..ada1ee77 100644 --- a/clients/cliptest.c +++ b/clients/cliptest.c @@ -51,6 +51,7 @@ #include #include "libweston/vertex-clipping.h" +#include "shared/helpers.h" #include "shared/xalloc.h" #include "window.h" @@ -65,7 +66,11 @@ struct geometry { float phi; }; +struct weston_surface { +}; + struct weston_view { + struct weston_surface *surface; struct { int enabled; } transform; @@ -74,8 +79,8 @@ struct weston_view { }; static void -weston_view_to_global_float(struct weston_view *view, - float sx, float sy, float *x, float *y) +weston_view_to_global_double(struct weston_view *view, + double sx, double sy, double *x, double *y) { struct geometry *g = view->geometry; @@ -84,12 +89,21 @@ weston_view_to_global_float(struct weston_view *view, *y = -g->s * sx + g->c * sy; } +static struct weston_coord_global +weston_coord_surface_to_global(struct weston_view *view, struct weston_coord_surface pos) +{ + double gx, gy; + struct weston_coord_global g_pos; + + weston_view_to_global_double(view, pos.c.x, pos.c.y, &gx, &gy); + g_pos.c = weston_coord(gx, gy); + + return g_pos; +} + /* ---------------------- copied begins -----------------------*/ /* Keep this in sync with what is in gl-renderer.c! */ -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define min(a, b) (((a) > (b)) ? (b) : (a)) - /* * Compute the boundary vertices of the intersection of the global coordinate * aligned rectangle 'rect', and an arbitrary quadrilateral produced from @@ -101,17 +115,22 @@ weston_view_to_global_float(struct weston_view *view, */ static int calculate_edges(struct weston_view *ev, pixman_box32_t *rect, - pixman_box32_t *surf_rect, GLfloat *ex, GLfloat *ey) + pixman_box32_t *surf_rect, struct weston_coord *e) { struct clip_context ctx; int i, n; GLfloat min_x, max_x, min_y, max_y; - struct polygon8 surf = { - { surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 }, - { surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 }, - 4 + struct weston_surface *es = ev->surface; + struct weston_coord_surface tmp[4] = { + weston_coord_surface(surf_rect->x1, surf_rect->y1, es), + weston_coord_surface(surf_rect->x2, surf_rect->y1, es), + weston_coord_surface(surf_rect->x2, surf_rect->y2, es), + weston_coord_surface(surf_rect->x1, surf_rect->y2, es), }; + struct polygon8 surf; + + surf.n = 4; ctx.clip.x1 = rect->x1; ctx.clip.y1 = rect->y1; @@ -120,18 +139,17 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, /* transform surface to screen space: */ for (i = 0; i < surf.n; i++) - weston_view_to_global_float(ev, surf.x[i], surf.y[i], - &surf.x[i], &surf.y[i]); + surf.pos[i] = weston_coord_surface_to_global(ev, tmp[i]).c; /* find bounding box: */ - min_x = max_x = surf.x[0]; - min_y = max_y = surf.y[0]; + min_x = max_x = surf.pos[0].x; + min_y = max_y = surf.pos[0].y; for (i = 1; i < surf.n; i++) { - min_x = min(min_x, surf.x[i]); - max_x = max(max_x, surf.x[i]); - min_y = min(min_y, surf.y[i]); - max_y = max(max_y, surf.y[i]); + min_x = MIN(min_x, surf.pos[i].x); + max_x = MAX(max_x, surf.pos[i].x); + min_y = MIN(min_y, surf.pos[i].y); + max_y = MAX(max_y, surf.pos[i].y); } /* First, simple bounding box check to discard early transformed @@ -146,7 +164,7 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, * vertices to the clip rect bounds: */ if (!ev->transform.enabled) - return clip_simple(&ctx, &surf, ex, ey); + return clip_simple(&ctx, &surf, e); /* Transformed case: use a general polygon clipping algorithm to * clip the surface rectangle with each side of 'rect'. @@ -154,7 +172,7 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, * http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm * but without looking at any of that code. */ - n = clip_transformed(&ctx, &surf, ex, ey); + n = clip_transformed(&ctx, &surf, e); if (n < 3) return 0; @@ -162,7 +180,6 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, return n; } - /* ---------------------- copied ends -----------------------*/ static void @@ -206,35 +223,36 @@ struct cliptest { struct ui_state ui; struct geometry geometry; + struct weston_surface surface; struct weston_view view; }; static void -draw_polygon_closed(cairo_t *cr, GLfloat *x, GLfloat *y, int n) +draw_polygon_closed(cairo_t *cr, struct weston_coord *pos, int n) { int i; - cairo_move_to(cr, x[0], y[0]); + cairo_move_to(cr, pos[0].x, pos[0].y); for (i = 1; i < n; i++) - cairo_line_to(cr, x[i], y[i]); - cairo_line_to(cr, x[0], y[0]); + cairo_line_to(cr, pos[i].x, pos[i].y); + cairo_line_to(cr, pos[0].x, pos[0].y); } static void -draw_polygon_labels(cairo_t *cr, GLfloat *x, GLfloat *y, int n) +draw_polygon_labels(cairo_t *cr, struct weston_coord *pos, int n) { char str[16]; int i; for (i = 0; i < n; i++) { snprintf(str, 16, "%d", i); - cairo_move_to(cr, x[i], y[i]); + cairo_move_to(cr, pos[i].x, pos[i].y); cairo_show_text(cr, str); } } static void -draw_coordinates(cairo_t *cr, double ox, double oy, GLfloat *x, GLfloat *y, int n) +draw_coordinates(cairo_t *cr, double ox, double oy, struct weston_coord *pos, int n) { char str[64]; int i; @@ -242,7 +260,7 @@ draw_coordinates(cairo_t *cr, double ox, double oy, GLfloat *x, GLfloat *y, int cairo_font_extents(cr, &ext); for (i = 0; i < n; i++) { - snprintf(str, 64, "%d: %14.9f, %14.9f", i, x[i], y[i]); + snprintf(str, 64, "%d: %14.9f, %14.9f", i, pos[i].x, pos[i].y); cairo_move_to(cr, ox, oy + ext.height * (i + 1)); cairo_show_text(cr, str); } @@ -251,34 +269,34 @@ draw_coordinates(cairo_t *cr, double ox, double oy, GLfloat *x, GLfloat *y, int static void draw_box(cairo_t *cr, pixman_box32_t *box, struct weston_view *view) { - GLfloat x[4], y[4]; + struct weston_coord pos[4]; if (view) { - weston_view_to_global_float(view, box->x1, box->y1, &x[0], &y[0]); - weston_view_to_global_float(view, box->x2, box->y1, &x[1], &y[1]); - weston_view_to_global_float(view, box->x2, box->y2, &x[2], &y[2]); - weston_view_to_global_float(view, box->x1, box->y2, &x[3], &y[3]); + weston_view_to_global_double(view, box->x1, box->y1, &pos[0].x, &pos[0].y); + weston_view_to_global_double(view, box->x2, box->y1, &pos[1].x, &pos[1].y); + weston_view_to_global_double(view, box->x2, box->y2, &pos[2].x, &pos[2].y); + weston_view_to_global_double(view, box->x1, box->y2, &pos[3].x, &pos[3].y); } else { - x[0] = box->x1; y[0] = box->y1; - x[1] = box->x2; y[1] = box->y1; - x[2] = box->x2; y[2] = box->y2; - x[3] = box->x1; y[3] = box->y2; + pos[0] = weston_coord(box->x1, box->y1); + pos[1] = weston_coord(box->x2, box->y1); + pos[2] = weston_coord(box->x2, box->y2); + pos[3] = weston_coord(box->x1, box->y2); } - draw_polygon_closed(cr, x, y, 4); + draw_polygon_closed(cr, pos, 4); } static void draw_geometry(cairo_t *cr, struct weston_view *view, - GLfloat *ex, GLfloat *ey, int n) + struct weston_coord *e, int n) { struct geometry *g = view->geometry; - float cx, cy; + double cx, cy; draw_box(cr, &g->surf, view); cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4); cairo_fill(cr); - weston_view_to_global_float(view, g->surf.x1 - 4, g->surf.y1 - 4, &cx, &cy); + weston_view_to_global_double(view, g->surf.x1 - 4, g->surf.y1 - 4, &cx, &cy); cairo_arc(cr, cx, cy, 1.5, 0.0, 2.0 * M_PI); if (view->transform.enabled == 0) cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.8); @@ -289,12 +307,12 @@ draw_geometry(cairo_t *cr, struct weston_view *view, cairo_fill(cr); if (n) { - draw_polygon_closed(cr, ex, ey, n); + draw_polygon_closed(cr, e, n); cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); cairo_stroke(cr); cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.5); - draw_polygon_labels(cr, ex, ey, n); + draw_polygon_labels(cr, e, n); } } @@ -306,11 +324,10 @@ redraw_handler(struct widget *widget, void *data) struct rectangle allocation; cairo_t *cr; cairo_surface_t *surface; - GLfloat ex[8]; - GLfloat ey[8]; + struct weston_coord e[8]; int n; - n = calculate_edges(&cliptest->view, &g->clip, &g->surf, ex, ey); + n = calculate_edges(&cliptest->view, &g->clip, &g->surf, e); widget_get_allocation(cliptest->widget, &allocation); @@ -344,7 +361,7 @@ redraw_handler(struct widget *widget, void *data) cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 5.0); - draw_geometry(cr, &cliptest->view, ex, ey, n); + draw_geometry(cr, &cliptest->view, e, n); cairo_pop_group_to_source(cr); cairo_paint(cr); @@ -352,7 +369,7 @@ redraw_handler(struct widget *widget, void *data) cairo_select_font_face(cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 12.0); - draw_coordinates(cr, 10.0, 10.0, ex, ey, n); + draw_coordinates(cr, 10.0, 10.0, e, n); cairo_destroy(cr); @@ -514,6 +531,7 @@ cliptest_create(struct display *display) struct cliptest *cliptest; cliptest = xzalloc(sizeof *cliptest); + cliptest->view.surface = &cliptest->surface; cliptest->view.geometry = &cliptest->geometry; cliptest->view.transform.enabled = 0; geometry_init(&cliptest->geometry); @@ -566,9 +584,10 @@ read_timer(void) static int benchmark(void) { + struct weston_surface surface; struct weston_view view; struct geometry geom; - GLfloat ex[8], ey[8]; + struct weston_coord e[8]; int i; double t; const int N = 1000000; @@ -585,13 +604,14 @@ benchmark(void) geometry_set_phi(&geom, 0.0); + view.surface = &surface; view.transform.enabled = 1; view.geometry = &geom; reset_timer(); for (i = 0; i < N; i++) { geometry_set_phi(&geom, (float)i / 360.0f); - calculate_edges(&view, &geom.clip, &geom.surf, ex, ey); + calculate_edges(&view, &geom.clip, &geom.surf, e); } t = read_timer(); diff --git a/clients/meson.build b/clients/meson.build index 359a314c..02d972e1 100644 --- a/clients/meson.build +++ b/clients/meson.build @@ -264,7 +264,7 @@ demo_clients = [ { 'basename': 'clickdot' }, { 'basename': 'cliptest', - 'dep_objs': dep_vertex_clipping + 'dep_objs': [ dep_vertex_clipping, dep_matrix_c ] }, { 'basename': 'confine' }, { diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index f0ed3266..f8743973 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -411,17 +411,22 @@ timeline_submit_render_sync(struct gl_renderer *gr, */ static int calculate_edges(struct weston_view *ev, pixman_box32_t *rect, - pixman_box32_t *surf_rect, GLfloat *ex, GLfloat *ey) + pixman_box32_t *surf_rect, struct weston_coord *e) { struct clip_context ctx; int i, n; GLfloat min_x, max_x, min_y, max_y; - struct polygon8 surf = { - { surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 }, - { surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 }, - 4 + struct weston_surface *es = ev->surface; + struct weston_coord_surface tmp[4] = { + weston_coord_surface(surf_rect->x1, surf_rect->y1, es), + weston_coord_surface(surf_rect->x2, surf_rect->y1, es), + weston_coord_surface(surf_rect->x2, surf_rect->y2, es), + weston_coord_surface(surf_rect->x1, surf_rect->y2, es), }; + struct polygon8 surf; + + surf.n = 4; ctx.clip.x1 = rect->x1; ctx.clip.y1 = rect->y1; @@ -429,25 +434,18 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, ctx.clip.y2 = rect->y2; /* transform surface to screen space: */ - for (i = 0; i < surf.n; i++) { - struct weston_coord_global cg; - struct weston_coord_surface cs; - - cs = weston_coord_surface(surf.x[i], surf.y[i], ev->surface); - cg = weston_coord_surface_to_global(ev, cs); - surf.x[i] = cg.c.x; - surf.y[i] = cg.c.y; - } + for (i = 0; i < surf.n; i++) + surf.pos[i] = weston_coord_surface_to_global(ev, tmp[i]).c; /* find bounding box: */ - min_x = max_x = surf.x[0]; - min_y = max_y = surf.y[0]; + min_x = max_x = surf.pos[0].x; + min_y = max_y = surf.pos[0].y; for (i = 1; i < surf.n; i++) { - min_x = MIN(min_x, surf.x[i]); - max_x = MAX(max_x, surf.x[i]); - min_y = MIN(min_y, surf.y[i]); - max_y = MAX(max_y, surf.y[i]); + min_x = MIN(min_x, surf.pos[i].x); + max_x = MAX(max_x, surf.pos[i].x); + min_y = MIN(min_y, surf.pos[i].y); + max_y = MAX(max_y, surf.pos[i].y); } /* First, simple bounding box check to discard early transformed @@ -462,7 +460,7 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, * vertices to the clip rect bounds: */ if (!ev->transform.enabled) - return clip_simple(&ctx, &surf, ex, ey); + return clip_simple(&ctx, &surf, e); /* Transformed case: use a general polygon clipping algorithm to * clip the surface rectangle with each side of 'rect'. @@ -470,7 +468,7 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, * http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm * but without looking at any of that code. */ - n = clip_transformed(&ctx, &surf, ex, ey); + n = clip_transformed(&ctx, &surf, e); if (n < 3) return 0; @@ -566,7 +564,7 @@ texture_region(struct weston_paint_node *pnode, pixman_box32_t *rect = &rects[i]; for (j = 0; j < nsurf; j++) { pixman_box32_t *surf_rect = &surf_rects[j]; - GLfloat ex[8], ey[8]; /* edge points in screen space */ + struct weston_coord e[8]; /* edge points in screen space */ int n; /* The transformed surface, after clipping to the clip region, @@ -583,28 +581,31 @@ texture_region(struct weston_paint_node *pnode, * form the intersection of the clip rect and the transformed * surface. */ - n = calculate_edges(ev, rect, surf_rect, ex, ey); + n = calculate_edges(ev, rect, surf_rect, e); if (n < 3) continue; /* emit edge points: */ for (k = 0; k < n; k++) { - struct weston_coord_global cg; - struct weston_coord_surface cs; - struct weston_coord_buffer cb; + struct weston_coord_global pos_g; + struct weston_coord_surface pos_s; + struct weston_coord_buffer pos_b; + + pos_g.c = e[k]; - cg.c = weston_coord(ex[k], ey[k]); - cs = weston_coord_global_to_surface(ev, cg); /* position: */ - *(v++) = ex[k]; - *(v++) = ey[k]; + *(v++) = pos_g.c.x; + *(v++) = pos_g.c.y; + /* texcoord: */ - cb = weston_coord_surface_to_buffer(ev->surface, cs); - *(v++) = cb.c.x * inv_width; + pos_s = weston_coord_global_to_surface(ev, pos_g); + pos_b = weston_coord_surface_to_buffer(ev->surface, pos_s); + + *(v++) = pos_b.c.x * inv_width; if (buffer->buffer_origin == ORIGIN_TOP_LEFT) { - *(v++) = cb.c.y * inv_height; + *(v++) = pos_b.c.y * inv_height; } else { - *(v++) = (buffer->height - cb.c.y) * inv_height; + *(v++) = (buffer->height - pos_b.c.y) * inv_height; } } diff --git a/libweston/vertex-clipping.c b/libweston/vertex-clipping.c index 7b471053..c0c2f51e 100644 --- a/libweston/vertex-clipping.c +++ b/libweston/vertex-clipping.c @@ -103,8 +103,8 @@ enum path_transition { static void clip_append_vertex(struct clip_context *ctx, float x, float y) { - *ctx->vertices.x++ = x; - *ctx->vertices.y++ = y; + *ctx->vertices = weston_coord(x, y); + ctx->vertices++; } static enum path_transition @@ -195,17 +195,16 @@ clip_polygon_topbottom(struct clip_context *ctx, static void clip_context_prepare(struct clip_context *ctx, const struct polygon8 *src, - float *dst_x, float *dst_y) + struct weston_coord *dst) { - ctx->prev.x = src->x[src->n - 1]; - ctx->prev.y = src->y[src->n - 1]; - ctx->vertices.x = dst_x; - ctx->vertices.y = dst_y; + ctx->prev.x = src->pos[src->n - 1].x; + ctx->prev.y = src->pos[src->n - 1].y; + ctx->vertices = dst; } static int clip_polygon_left(struct clip_context *ctx, const struct polygon8 *src, - float *dst_x, float *dst_y) + struct weston_coord *dst) { enum path_transition trans; int i; @@ -213,18 +212,18 @@ clip_polygon_left(struct clip_context *ctx, const struct polygon8 *src, if (src->n < 2) return 0; - clip_context_prepare(ctx, src, dst_x, dst_y); + clip_context_prepare(ctx, src, dst); for (i = 0; i < src->n; i++) { - trans = path_transition_left_edge(ctx, src->x[i], src->y[i]); - clip_polygon_leftright(ctx, trans, src->x[i], src->y[i], + trans = path_transition_left_edge(ctx, src->pos[i].x, src->pos[i].y); + clip_polygon_leftright(ctx, trans, src->pos[i].x, src->pos[i].y, ctx->clip.x1); } - return ctx->vertices.x - dst_x; + return ctx->vertices - dst; } static int clip_polygon_right(struct clip_context *ctx, const struct polygon8 *src, - float *dst_x, float *dst_y) + struct weston_coord *dst) { enum path_transition trans; int i; @@ -232,18 +231,18 @@ clip_polygon_right(struct clip_context *ctx, const struct polygon8 *src, if (src->n < 2) return 0; - clip_context_prepare(ctx, src, dst_x, dst_y); + clip_context_prepare(ctx, src, dst); for (i = 0; i < src->n; i++) { - trans = path_transition_right_edge(ctx, src->x[i], src->y[i]); - clip_polygon_leftright(ctx, trans, src->x[i], src->y[i], + trans = path_transition_right_edge(ctx, src->pos[i].x, src->pos[i].y); + clip_polygon_leftright(ctx, trans, src->pos[i].x, src->pos[i].y, ctx->clip.x2); } - return ctx->vertices.x - dst_x; + return ctx->vertices - dst; } static int clip_polygon_top(struct clip_context *ctx, const struct polygon8 *src, - float *dst_x, float *dst_y) + struct weston_coord *dst) { enum path_transition trans; int i; @@ -251,18 +250,18 @@ clip_polygon_top(struct clip_context *ctx, const struct polygon8 *src, if (src->n < 2) return 0; - clip_context_prepare(ctx, src, dst_x, dst_y); + clip_context_prepare(ctx, src, dst); for (i = 0; i < src->n; i++) { - trans = path_transition_top_edge(ctx, src->x[i], src->y[i]); - clip_polygon_topbottom(ctx, trans, src->x[i], src->y[i], + trans = path_transition_top_edge(ctx, src->pos[i].x, src->pos[i].y); + clip_polygon_topbottom(ctx, trans, src->pos[i].x, src->pos[i].y, ctx->clip.y1); } - return ctx->vertices.x - dst_x; + return ctx->vertices - dst; } static int clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src, - float *dst_x, float *dst_y) + struct weston_coord *dst) { enum path_transition trans; int i; @@ -270,25 +269,24 @@ clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src, if (src->n < 2) return 0; - clip_context_prepare(ctx, src, dst_x, dst_y); + clip_context_prepare(ctx, src, dst); for (i = 0; i < src->n; i++) { - trans = path_transition_bottom_edge(ctx, src->x[i], src->y[i]); - clip_polygon_topbottom(ctx, trans, src->x[i], src->y[i], + trans = path_transition_bottom_edge(ctx, src->pos[i].x, src->pos[i].y); + clip_polygon_topbottom(ctx, trans, src->pos[i].x, src->pos[i].y, ctx->clip.y2); } - return ctx->vertices.x - dst_x; + return ctx->vertices - dst; } WESTON_EXPORT_FOR_TESTS int clip_simple(struct clip_context *ctx, struct polygon8 *surf, - float *ex, - float *ey) + struct weston_coord *e) { int i; for (i = 0; i < surf->n; i++) { - ex[i] = CLIP(surf->x[i], ctx->clip.x1, ctx->clip.x2); - ey[i] = CLIP(surf->y[i], ctx->clip.y1, ctx->clip.y2); + e[i].x = CLIP(surf->pos[i].x, ctx->clip.x1, ctx->clip.x2); + e[i].y = CLIP(surf->pos[i].y, ctx->clip.y1, ctx->clip.y2); } return surf->n; } @@ -296,31 +294,28 @@ clip_simple(struct clip_context *ctx, WESTON_EXPORT_FOR_TESTS int clip_transformed(struct clip_context *ctx, struct polygon8 *surf, - float *ex, - float *ey) + struct weston_coord *e) { struct polygon8 polygon; int i, n; - polygon.n = clip_polygon_left(ctx, surf, polygon.x, polygon.y); - surf->n = clip_polygon_right(ctx, &polygon, surf->x, surf->y); - polygon.n = clip_polygon_top(ctx, surf, polygon.x, polygon.y); - surf->n = clip_polygon_bottom(ctx, &polygon, surf->x, surf->y); + polygon.n = clip_polygon_left(ctx, surf, polygon.pos); + surf->n = clip_polygon_right(ctx, &polygon, surf->pos); + polygon.n = clip_polygon_top(ctx, surf, polygon.pos); + surf->n = clip_polygon_bottom(ctx, &polygon, surf->pos); /* Get rid of duplicate vertices */ - ex[0] = surf->x[0]; - ey[0] = surf->y[0]; + e[0] = surf->pos[0]; n = 1; for (i = 1; i < surf->n; i++) { - if (float_difference(ex[n - 1], surf->x[i]) == 0.0f && - float_difference(ey[n - 1], surf->y[i]) == 0.0f) + if (float_difference(e[n - 1].x, surf->pos[i].x) == 0.0f && + float_difference(e[n - 1].y, surf->pos[i].y) == 0.0f) continue; - ex[n] = surf->x[i]; - ey[n] = surf->y[i]; + e[n] = surf->pos[i]; n++; } - if (float_difference(ex[n - 1], surf->x[0]) == 0.0f && - float_difference(ey[n - 1], surf->y[0]) == 0.0f) + if (float_difference(e[n - 1].x, surf->pos[0].x) == 0.0f && + float_difference(e[n - 1].y, surf->pos[0].y) == 0.0f) n--; return n; diff --git a/libweston/vertex-clipping.h b/libweston/vertex-clipping.h index 0c699021..0bf764be 100644 --- a/libweston/vertex-clipping.h +++ b/libweston/vertex-clipping.h @@ -25,9 +25,10 @@ #ifndef _WESTON_VERTEX_CLIPPING_H #define _WESTON_VERTEX_CLIPPING_H +#include + struct polygon8 { - float x[8]; - float y[8]; + struct weston_coord pos[8]; int n; }; @@ -42,10 +43,7 @@ struct clip_context { float x2, y2; } clip; - struct { - float *x; - float *y; - } vertices; + struct weston_coord *vertices; }; float @@ -54,13 +52,11 @@ float_difference(float a, float b); int clip_simple(struct clip_context *ctx, struct polygon8 *surf, - float *ex, - float *ey); + struct weston_coord *e); int clip_transformed(struct clip_context *ctx, struct polygon8 *surf, - float *ex, - float *ey);\ + struct weston_coord *e); #endif diff --git a/tests/vertex-clip-test.c b/tests/vertex-clip-test.c index 3e62412c..8cde2702 100644 --- a/tests/vertex-clip-test.c +++ b/tests/vertex-clip-test.c @@ -60,11 +60,10 @@ populate_clip_context (struct clip_context *ctx) static int clip_polygon (struct clip_context *ctx, struct polygon8 *polygon, - float *vertices_x, - float *vertices_y) + struct weston_coord *pos) { populate_clip_context(ctx); - return clip_transformed(ctx, polygon, vertices_x, vertices_y); + return clip_transformed(ctx, polygon, pos); } struct vertex_clip_test_data @@ -78,94 +77,152 @@ const struct vertex_clip_test_data test_data[] = /* All inside */ { { - { INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 }, - { INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = INSIDE_X1, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y2 }, + { .x = INSIDE_X1, .y = INSIDE_Y2 }, + }, + .n = 4 }, { - { INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 }, - { INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = INSIDE_X1, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y2 }, + { .x = INSIDE_X1, .y = INSIDE_Y2 }, + }, + .n = 4 } }, /* Top outside */ { { - { INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 }, - { INSIDE_Y1, INSIDE_Y1, OUTSIDE_Y2, OUTSIDE_Y2 }, - 4 + .pos = { + { .x = INSIDE_X1, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = OUTSIDE_Y2 }, + { .x = INSIDE_X1, .y = OUTSIDE_Y2 }, + }, + .n = 4 }, { - { INSIDE_X1, INSIDE_X1, INSIDE_X2, INSIDE_X2 }, - { BOUNDING_BOX_TOP_Y, INSIDE_Y1, INSIDE_Y1, BOUNDING_BOX_TOP_Y }, - 4 + .pos = { + { .x = INSIDE_X1, .y = BOUNDING_BOX_TOP_Y }, + { .x = INSIDE_X1, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = BOUNDING_BOX_TOP_Y }, + }, + .n = 4 } }, /* Bottom outside */ { { - { INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 }, - { OUTSIDE_Y1, OUTSIDE_Y1, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = INSIDE_X1, .y = OUTSIDE_Y1 }, + { .x = INSIDE_X2, .y = OUTSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y2 }, + { .x = INSIDE_X1, .y = INSIDE_Y2 }, + }, + .n = 4 }, { - { INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 }, - { BOUNDING_BOX_BOTTOM_Y, BOUNDING_BOX_BOTTOM_Y, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = INSIDE_X1, .y = BOUNDING_BOX_BOTTOM_Y }, + { .x = INSIDE_X2, .y = BOUNDING_BOX_BOTTOM_Y }, + { .x = INSIDE_X2, .y = INSIDE_Y2 }, + { .x = INSIDE_X1, .y = INSIDE_Y2 }, + }, + .n = 4 } }, /* Left outside */ { { - { OUTSIDE_X1, INSIDE_X2, INSIDE_X2, OUTSIDE_X1 }, - { INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = OUTSIDE_X1, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y2 }, + { .x = OUTSIDE_X1, .y = INSIDE_Y2 }, + }, + .n = 4 }, { - { BOUNDING_BOX_LEFT_X, INSIDE_X2, INSIDE_X2, BOUNDING_BOX_LEFT_X }, - { INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = BOUNDING_BOX_LEFT_X, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y1 }, + { .x = INSIDE_X2, .y = INSIDE_Y2 }, + { .x = BOUNDING_BOX_LEFT_X, .y = INSIDE_Y2 }, + }, + .n = 4 } }, /* Right outside */ { { - { INSIDE_X1, OUTSIDE_X2, OUTSIDE_X2, INSIDE_X1 }, - { INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = INSIDE_X1, .y = INSIDE_Y1 }, + { .x = OUTSIDE_X2, .y = INSIDE_Y1 }, + { .x = OUTSIDE_X2, .y = INSIDE_Y2 }, + { .x = INSIDE_X1, .y = INSIDE_Y2 }, + }, + .n = 4 }, { - { INSIDE_X1, BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_RIGHT_X, INSIDE_X1 }, - { INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 }, - 4 + .pos = { + { .x = INSIDE_X1, .y = INSIDE_Y1 }, + { .x = BOUNDING_BOX_RIGHT_X, .y = INSIDE_Y1 }, + { .x = BOUNDING_BOX_RIGHT_X, .y = INSIDE_Y2 }, + { .x = INSIDE_X1, .y = INSIDE_Y2 }, + }, + .n = 4 } }, /* Diamond extending from bounding box edges, clip to bounding box */ { { - { BOUNDING_BOX_LEFT_X - 25, BOUNDING_BOX_LEFT_X + 25, BOUNDING_BOX_RIGHT_X + 25, BOUNDING_BOX_RIGHT_X - 25 }, - { BOUNDING_BOX_BOTTOM_Y + 25, BOUNDING_BOX_TOP_Y + 25, BOUNDING_BOX_TOP_Y - 25, BOUNDING_BOX_BOTTOM_Y - 25 }, - 4 + .pos = { + { .x = BOUNDING_BOX_LEFT_X - 25, .y = BOUNDING_BOX_BOTTOM_Y + 25 }, + { .x = BOUNDING_BOX_LEFT_X + 25, .y = BOUNDING_BOX_TOP_Y + 25 }, + { .x = BOUNDING_BOX_RIGHT_X + 25, .y = BOUNDING_BOX_TOP_Y - 25 }, + { .x = BOUNDING_BOX_RIGHT_X - 25, .y = BOUNDING_BOX_BOTTOM_Y - 25 }, + }, + .n = 4 }, { - { BOUNDING_BOX_LEFT_X, BOUNDING_BOX_LEFT_X, BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_RIGHT_X }, - { BOUNDING_BOX_BOTTOM_Y, BOUNDING_BOX_TOP_Y, BOUNDING_BOX_TOP_Y, BOUNDING_BOX_BOTTOM_Y }, - 4 + .pos = { + { .x = BOUNDING_BOX_LEFT_X, .y = BOUNDING_BOX_BOTTOM_Y }, + { .x = BOUNDING_BOX_LEFT_X, .y = BOUNDING_BOX_TOP_Y }, + { .x = BOUNDING_BOX_RIGHT_X, .y = BOUNDING_BOX_TOP_Y }, + { .x = BOUNDING_BOX_RIGHT_X, .y = BOUNDING_BOX_BOTTOM_Y }, + }, + .n = 4 } }, /* Diamond inside of bounding box edges, clip t bounding box, 8 resulting vertices */ { { - { BOUNDING_BOX_LEFT_X - 12.5, BOUNDING_BOX_LEFT_X + 25, BOUNDING_BOX_RIGHT_X + 12.5, BOUNDING_BOX_RIGHT_X - 25 }, - { BOUNDING_BOX_BOTTOM_Y + 25, BOUNDING_BOX_TOP_Y + 12.5, BOUNDING_BOX_TOP_Y - 25, BOUNDING_BOX_BOTTOM_Y - 12.5 }, - 4 + .pos = { + { .x = BOUNDING_BOX_LEFT_X - 12.5, .y = BOUNDING_BOX_BOTTOM_Y + 25 }, + { .x = BOUNDING_BOX_LEFT_X + 25, .y = BOUNDING_BOX_TOP_Y + 12.5 }, + { .x = BOUNDING_BOX_RIGHT_X + 12.5, .y = BOUNDING_BOX_TOP_Y - 25 }, + { .x = BOUNDING_BOX_RIGHT_X - 25, .y = BOUNDING_BOX_BOTTOM_Y - 12.5 }, + }, + .n = 4 }, { - { BOUNDING_BOX_LEFT_X + 12.5, BOUNDING_BOX_LEFT_X, BOUNDING_BOX_LEFT_X, BOUNDING_BOX_LEFT_X + 12.5, - BOUNDING_BOX_RIGHT_X - 12.5, BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_RIGHT_X - 12.5 }, - { BOUNDING_BOX_BOTTOM_Y, BOUNDING_BOX_BOTTOM_Y + 12.5, BOUNDING_BOX_TOP_Y - 12.5, BOUNDING_BOX_TOP_Y, - BOUNDING_BOX_TOP_Y, BOUNDING_BOX_TOP_Y - 12.5, BOUNDING_BOX_BOTTOM_Y + 12.5, BOUNDING_BOX_BOTTOM_Y }, - 8 + .pos = { + { .x = BOUNDING_BOX_LEFT_X + 12.5, .y = BOUNDING_BOX_BOTTOM_Y }, + { .x = BOUNDING_BOX_LEFT_X, .y = BOUNDING_BOX_BOTTOM_Y + 12.5 }, + { .x = BOUNDING_BOX_LEFT_X, .y = BOUNDING_BOX_TOP_Y - 12.5 }, + { .x = BOUNDING_BOX_LEFT_X + 12.5, .y = BOUNDING_BOX_TOP_Y }, + { .x = BOUNDING_BOX_RIGHT_X - 12.5, .y = BOUNDING_BOX_TOP_Y }, + { .x = BOUNDING_BOX_RIGHT_X, .y = BOUNDING_BOX_TOP_Y - 12.5 }, + { .x = BOUNDING_BOX_RIGHT_X, .y = BOUNDING_BOX_BOTTOM_Y + 12.5}, + { .x = BOUNDING_BOX_RIGHT_X - 12.5, .y = BOUNDING_BOX_BOTTOM_Y }, + }, + .n = 8 } } }; @@ -176,8 +233,7 @@ static void deep_copy_polygon8(const struct polygon8 *src, struct polygon8 *dst) { dst->n = src->n; - ARRAY_COPY(dst->x, src->x); - ARRAY_COPY(dst->y, src->y); + ARRAY_COPY(dst->pos, src->pos); } TEST_P(clip_polygon_n_vertices_emitted, test_data) @@ -185,10 +241,9 @@ TEST_P(clip_polygon_n_vertices_emitted, test_data) struct vertex_clip_test_data *tdata = data; struct clip_context ctx; struct polygon8 polygon; - float vertices_x[8]; - float vertices_y[8]; + struct weston_coord vertices[8]; deep_copy_polygon8(&tdata->surface, &polygon); - int emitted = clip_polygon(&ctx, &polygon, vertices_x, vertices_y); + int emitted = clip_polygon(&ctx, &polygon, vertices); assert(emitted == tdata->expected.n); } @@ -198,16 +253,15 @@ TEST_P(clip_polygon_expected_vertices, test_data) struct vertex_clip_test_data *tdata = data; struct clip_context ctx; struct polygon8 polygon; - float vertices_x[8]; - float vertices_y[8]; + struct weston_coord vertices[8]; deep_copy_polygon8(&tdata->surface, &polygon); - int emitted = clip_polygon(&ctx, &polygon, vertices_x, vertices_y); + int emitted = clip_polygon(&ctx, &polygon, vertices); int i = 0; for (; i < emitted; ++i) { - assert(vertices_x[i] == tdata->expected.x[i]); - assert(vertices_y[i] == tdata->expected.y[i]); + assert(vertices[i].x == tdata->expected.pos[i].x); + assert(vertices[i].y == tdata->expected.pos[i].y); } }