mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-07-21 10:44:25 +00:00
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 <derek.foreman@collabora.com>
This commit is contained in:
parent
f7609553a9
commit
10e70bf23c
|
@ -51,6 +51,7 @@
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
|
||||||
#include "libweston/vertex-clipping.h"
|
#include "libweston/vertex-clipping.h"
|
||||||
|
#include "shared/helpers.h"
|
||||||
#include "shared/xalloc.h"
|
#include "shared/xalloc.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
@ -65,7 +66,11 @@ struct geometry {
|
||||||
float phi;
|
float phi;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct weston_surface {
|
||||||
|
};
|
||||||
|
|
||||||
struct weston_view {
|
struct weston_view {
|
||||||
|
struct weston_surface *surface;
|
||||||
struct {
|
struct {
|
||||||
int enabled;
|
int enabled;
|
||||||
} transform;
|
} transform;
|
||||||
|
@ -74,8 +79,8 @@ struct weston_view {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
weston_view_to_global_float(struct weston_view *view,
|
weston_view_to_global_double(struct weston_view *view,
|
||||||
float sx, float sy, float *x, float *y)
|
double sx, double sy, double *x, double *y)
|
||||||
{
|
{
|
||||||
struct geometry *g = view->geometry;
|
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;
|
*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 -----------------------*/
|
/* ---------------------- copied begins -----------------------*/
|
||||||
/* Keep this in sync with what is in gl-renderer.c! */
|
/* 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
|
* Compute the boundary vertices of the intersection of the global coordinate
|
||||||
* aligned rectangle 'rect', and an arbitrary quadrilateral produced from
|
* aligned rectangle 'rect', and an arbitrary quadrilateral produced from
|
||||||
|
@ -101,17 +115,22 @@ weston_view_to_global_float(struct weston_view *view,
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
|
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;
|
struct clip_context ctx;
|
||||||
int i, n;
|
int i, n;
|
||||||
GLfloat min_x, max_x, min_y, max_y;
|
GLfloat min_x, max_x, min_y, max_y;
|
||||||
struct polygon8 surf = {
|
struct weston_surface *es = ev->surface;
|
||||||
{ surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 },
|
struct weston_coord_surface tmp[4] = {
|
||||||
{ surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 },
|
weston_coord_surface(surf_rect->x1, surf_rect->y1, es),
|
||||||
4
|
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.x1 = rect->x1;
|
||||||
ctx.clip.y1 = rect->y1;
|
ctx.clip.y1 = rect->y1;
|
||||||
|
@ -120,18 +139,17 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
|
||||||
|
|
||||||
/* transform surface to screen space: */
|
/* transform surface to screen space: */
|
||||||
for (i = 0; i < surf.n; i++)
|
for (i = 0; i < surf.n; i++)
|
||||||
weston_view_to_global_float(ev, surf.x[i], surf.y[i],
|
surf.pos[i] = weston_coord_surface_to_global(ev, tmp[i]).c;
|
||||||
&surf.x[i], &surf.y[i]);
|
|
||||||
|
|
||||||
/* find bounding box: */
|
/* find bounding box: */
|
||||||
min_x = max_x = surf.x[0];
|
min_x = max_x = surf.pos[0].x;
|
||||||
min_y = max_y = surf.y[0];
|
min_y = max_y = surf.pos[0].y;
|
||||||
|
|
||||||
for (i = 1; i < surf.n; i++) {
|
for (i = 1; i < surf.n; i++) {
|
||||||
min_x = min(min_x, surf.x[i]);
|
min_x = MIN(min_x, surf.pos[i].x);
|
||||||
max_x = max(max_x, surf.x[i]);
|
max_x = MAX(max_x, surf.pos[i].x);
|
||||||
min_y = min(min_y, surf.y[i]);
|
min_y = MIN(min_y, surf.pos[i].y);
|
||||||
max_y = max(max_y, surf.y[i]);
|
max_y = MAX(max_y, surf.pos[i].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First, simple bounding box check to discard early transformed
|
/* 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:
|
* vertices to the clip rect bounds:
|
||||||
*/
|
*/
|
||||||
if (!ev->transform.enabled)
|
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
|
/* Transformed case: use a general polygon clipping algorithm to
|
||||||
* clip the surface rectangle with each side of 'rect'.
|
* 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
|
* http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm
|
||||||
* but without looking at any of that code.
|
* but without looking at any of that code.
|
||||||
*/
|
*/
|
||||||
n = clip_transformed(&ctx, &surf, ex, ey);
|
n = clip_transformed(&ctx, &surf, e);
|
||||||
|
|
||||||
if (n < 3)
|
if (n < 3)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -162,7 +180,6 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------- copied ends -----------------------*/
|
/* ---------------------- copied ends -----------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -206,35 +223,36 @@ struct cliptest {
|
||||||
struct ui_state ui;
|
struct ui_state ui;
|
||||||
|
|
||||||
struct geometry geometry;
|
struct geometry geometry;
|
||||||
|
struct weston_surface surface;
|
||||||
struct weston_view view;
|
struct weston_view view;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
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;
|
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++)
|
for (i = 1; i < n; i++)
|
||||||
cairo_line_to(cr, x[i], y[i]);
|
cairo_line_to(cr, pos[i].x, pos[i].y);
|
||||||
cairo_line_to(cr, x[0], y[0]);
|
cairo_line_to(cr, pos[0].x, pos[0].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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];
|
char str[16];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
snprintf(str, 16, "%d", 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);
|
cairo_show_text(cr, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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];
|
char str[64];
|
||||||
int i;
|
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);
|
cairo_font_extents(cr, &ext);
|
||||||
for (i = 0; i < n; i++) {
|
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_move_to(cr, ox, oy + ext.height * (i + 1));
|
||||||
cairo_show_text(cr, str);
|
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
|
static void
|
||||||
draw_box(cairo_t *cr, pixman_box32_t *box, struct weston_view *view)
|
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) {
|
if (view) {
|
||||||
weston_view_to_global_float(view, box->x1, box->y1, &x[0], &y[0]);
|
weston_view_to_global_double(view, box->x1, box->y1, &pos[0].x, &pos[0].y);
|
||||||
weston_view_to_global_float(view, box->x2, box->y1, &x[1], &y[1]);
|
weston_view_to_global_double(view, box->x2, box->y1, &pos[1].x, &pos[1].y);
|
||||||
weston_view_to_global_float(view, box->x2, box->y2, &x[2], &y[2]);
|
weston_view_to_global_double(view, box->x2, box->y2, &pos[2].x, &pos[2].y);
|
||||||
weston_view_to_global_float(view, box->x1, box->y2, &x[3], &y[3]);
|
weston_view_to_global_double(view, box->x1, box->y2, &pos[3].x, &pos[3].y);
|
||||||
} else {
|
} else {
|
||||||
x[0] = box->x1; y[0] = box->y1;
|
pos[0] = weston_coord(box->x1, box->y1);
|
||||||
x[1] = box->x2; y[1] = box->y1;
|
pos[1] = weston_coord(box->x2, box->y1);
|
||||||
x[2] = box->x2; y[2] = box->y2;
|
pos[2] = weston_coord(box->x2, box->y2);
|
||||||
x[3] = box->x1; y[3] = 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
|
static void
|
||||||
draw_geometry(cairo_t *cr, struct weston_view *view,
|
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;
|
struct geometry *g = view->geometry;
|
||||||
float cx, cy;
|
double cx, cy;
|
||||||
|
|
||||||
draw_box(cr, &g->surf, view);
|
draw_box(cr, &g->surf, view);
|
||||||
cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4);
|
cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4);
|
||||||
cairo_fill(cr);
|
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);
|
cairo_arc(cr, cx, cy, 1.5, 0.0, 2.0 * M_PI);
|
||||||
if (view->transform.enabled == 0)
|
if (view->transform.enabled == 0)
|
||||||
cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.8);
|
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);
|
cairo_fill(cr);
|
||||||
|
|
||||||
if (n) {
|
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_set_source_rgb(cr, 0.0, 1.0, 0.0);
|
||||||
cairo_stroke(cr);
|
cairo_stroke(cr);
|
||||||
|
|
||||||
cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.5);
|
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;
|
struct rectangle allocation;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
GLfloat ex[8];
|
struct weston_coord e[8];
|
||||||
GLfloat ey[8];
|
|
||||||
int n;
|
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);
|
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_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL,
|
||||||
CAIRO_FONT_WEIGHT_BOLD);
|
CAIRO_FONT_WEIGHT_BOLD);
|
||||||
cairo_set_font_size(cr, 5.0);
|
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_pop_group_to_source(cr);
|
||||||
cairo_paint(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_select_font_face(cr, "monospace", CAIRO_FONT_SLANT_NORMAL,
|
||||||
CAIRO_FONT_WEIGHT_NORMAL);
|
CAIRO_FONT_WEIGHT_NORMAL);
|
||||||
cairo_set_font_size(cr, 12.0);
|
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);
|
cairo_destroy(cr);
|
||||||
|
|
||||||
|
@ -514,6 +531,7 @@ cliptest_create(struct display *display)
|
||||||
struct cliptest *cliptest;
|
struct cliptest *cliptest;
|
||||||
|
|
||||||
cliptest = xzalloc(sizeof *cliptest);
|
cliptest = xzalloc(sizeof *cliptest);
|
||||||
|
cliptest->view.surface = &cliptest->surface;
|
||||||
cliptest->view.geometry = &cliptest->geometry;
|
cliptest->view.geometry = &cliptest->geometry;
|
||||||
cliptest->view.transform.enabled = 0;
|
cliptest->view.transform.enabled = 0;
|
||||||
geometry_init(&cliptest->geometry);
|
geometry_init(&cliptest->geometry);
|
||||||
|
@ -566,9 +584,10 @@ read_timer(void)
|
||||||
static int
|
static int
|
||||||
benchmark(void)
|
benchmark(void)
|
||||||
{
|
{
|
||||||
|
struct weston_surface surface;
|
||||||
struct weston_view view;
|
struct weston_view view;
|
||||||
struct geometry geom;
|
struct geometry geom;
|
||||||
GLfloat ex[8], ey[8];
|
struct weston_coord e[8];
|
||||||
int i;
|
int i;
|
||||||
double t;
|
double t;
|
||||||
const int N = 1000000;
|
const int N = 1000000;
|
||||||
|
@ -585,13 +604,14 @@ benchmark(void)
|
||||||
|
|
||||||
geometry_set_phi(&geom, 0.0);
|
geometry_set_phi(&geom, 0.0);
|
||||||
|
|
||||||
|
view.surface = &surface;
|
||||||
view.transform.enabled = 1;
|
view.transform.enabled = 1;
|
||||||
view.geometry = &geom;
|
view.geometry = &geom;
|
||||||
|
|
||||||
reset_timer();
|
reset_timer();
|
||||||
for (i = 0; i < N; i++) {
|
for (i = 0; i < N; i++) {
|
||||||
geometry_set_phi(&geom, (float)i / 360.0f);
|
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();
|
t = read_timer();
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ demo_clients = [
|
||||||
{ 'basename': 'clickdot' },
|
{ 'basename': 'clickdot' },
|
||||||
{
|
{
|
||||||
'basename': 'cliptest',
|
'basename': 'cliptest',
|
||||||
'dep_objs': dep_vertex_clipping
|
'dep_objs': [ dep_vertex_clipping, dep_matrix_c ]
|
||||||
},
|
},
|
||||||
{ 'basename': 'confine' },
|
{ 'basename': 'confine' },
|
||||||
{
|
{
|
||||||
|
|
|
@ -411,17 +411,22 @@ timeline_submit_render_sync(struct gl_renderer *gr,
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
|
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;
|
struct clip_context ctx;
|
||||||
int i, n;
|
int i, n;
|
||||||
GLfloat min_x, max_x, min_y, max_y;
|
GLfloat min_x, max_x, min_y, max_y;
|
||||||
struct polygon8 surf = {
|
struct weston_surface *es = ev->surface;
|
||||||
{ surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 },
|
struct weston_coord_surface tmp[4] = {
|
||||||
{ surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 },
|
weston_coord_surface(surf_rect->x1, surf_rect->y1, es),
|
||||||
4
|
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.x1 = rect->x1;
|
||||||
ctx.clip.y1 = rect->y1;
|
ctx.clip.y1 = rect->y1;
|
||||||
|
@ -429,25 +434,18 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
|
||||||
ctx.clip.y2 = rect->y2;
|
ctx.clip.y2 = rect->y2;
|
||||||
|
|
||||||
/* transform surface to screen space: */
|
/* transform surface to screen space: */
|
||||||
for (i = 0; i < surf.n; i++) {
|
for (i = 0; i < surf.n; i++)
|
||||||
struct weston_coord_global cg;
|
surf.pos[i] = weston_coord_surface_to_global(ev, tmp[i]).c;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find bounding box: */
|
/* find bounding box: */
|
||||||
min_x = max_x = surf.x[0];
|
min_x = max_x = surf.pos[0].x;
|
||||||
min_y = max_y = surf.y[0];
|
min_y = max_y = surf.pos[0].y;
|
||||||
|
|
||||||
for (i = 1; i < surf.n; i++) {
|
for (i = 1; i < surf.n; i++) {
|
||||||
min_x = MIN(min_x, surf.x[i]);
|
min_x = MIN(min_x, surf.pos[i].x);
|
||||||
max_x = MAX(max_x, surf.x[i]);
|
max_x = MAX(max_x, surf.pos[i].x);
|
||||||
min_y = MIN(min_y, surf.y[i]);
|
min_y = MIN(min_y, surf.pos[i].y);
|
||||||
max_y = MAX(max_y, surf.y[i]);
|
max_y = MAX(max_y, surf.pos[i].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First, simple bounding box check to discard early transformed
|
/* 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:
|
* vertices to the clip rect bounds:
|
||||||
*/
|
*/
|
||||||
if (!ev->transform.enabled)
|
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
|
/* Transformed case: use a general polygon clipping algorithm to
|
||||||
* clip the surface rectangle with each side of 'rect'.
|
* 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
|
* http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm
|
||||||
* but without looking at any of that code.
|
* but without looking at any of that code.
|
||||||
*/
|
*/
|
||||||
n = clip_transformed(&ctx, &surf, ex, ey);
|
n = clip_transformed(&ctx, &surf, e);
|
||||||
|
|
||||||
if (n < 3)
|
if (n < 3)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -566,7 +564,7 @@ texture_region(struct weston_paint_node *pnode,
|
||||||
pixman_box32_t *rect = &rects[i];
|
pixman_box32_t *rect = &rects[i];
|
||||||
for (j = 0; j < nsurf; j++) {
|
for (j = 0; j < nsurf; j++) {
|
||||||
pixman_box32_t *surf_rect = &surf_rects[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;
|
int n;
|
||||||
|
|
||||||
/* The transformed surface, after clipping to the clip region,
|
/* 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
|
* form the intersection of the clip rect and the transformed
|
||||||
* surface.
|
* surface.
|
||||||
*/
|
*/
|
||||||
n = calculate_edges(ev, rect, surf_rect, ex, ey);
|
n = calculate_edges(ev, rect, surf_rect, e);
|
||||||
if (n < 3)
|
if (n < 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* emit edge points: */
|
/* emit edge points: */
|
||||||
for (k = 0; k < n; k++) {
|
for (k = 0; k < n; k++) {
|
||||||
struct weston_coord_global cg;
|
struct weston_coord_global pos_g;
|
||||||
struct weston_coord_surface cs;
|
struct weston_coord_surface pos_s;
|
||||||
struct weston_coord_buffer cb;
|
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: */
|
/* position: */
|
||||||
*(v++) = ex[k];
|
*(v++) = pos_g.c.x;
|
||||||
*(v++) = ey[k];
|
*(v++) = pos_g.c.y;
|
||||||
|
|
||||||
/* texcoord: */
|
/* texcoord: */
|
||||||
cb = weston_coord_surface_to_buffer(ev->surface, cs);
|
pos_s = weston_coord_global_to_surface(ev, pos_g);
|
||||||
*(v++) = cb.c.x * inv_width;
|
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) {
|
if (buffer->buffer_origin == ORIGIN_TOP_LEFT) {
|
||||||
*(v++) = cb.c.y * inv_height;
|
*(v++) = pos_b.c.y * inv_height;
|
||||||
} else {
|
} else {
|
||||||
*(v++) = (buffer->height - cb.c.y) * inv_height;
|
*(v++) = (buffer->height - pos_b.c.y) * inv_height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,8 @@ enum path_transition {
|
||||||
static void
|
static void
|
||||||
clip_append_vertex(struct clip_context *ctx, float x, float y)
|
clip_append_vertex(struct clip_context *ctx, float x, float y)
|
||||||
{
|
{
|
||||||
*ctx->vertices.x++ = x;
|
*ctx->vertices = weston_coord(x, y);
|
||||||
*ctx->vertices.y++ = y;
|
ctx->vertices++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum path_transition
|
static enum path_transition
|
||||||
|
@ -195,17 +195,16 @@ clip_polygon_topbottom(struct clip_context *ctx,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clip_context_prepare(struct clip_context *ctx, const struct polygon8 *src,
|
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.x = src->pos[src->n - 1].x;
|
||||||
ctx->prev.y = src->y[src->n - 1];
|
ctx->prev.y = src->pos[src->n - 1].y;
|
||||||
ctx->vertices.x = dst_x;
|
ctx->vertices = dst;
|
||||||
ctx->vertices.y = dst_y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
clip_polygon_left(struct clip_context *ctx, const struct polygon8 *src,
|
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;
|
enum path_transition trans;
|
||||||
int i;
|
int i;
|
||||||
|
@ -213,18 +212,18 @@ clip_polygon_left(struct clip_context *ctx, const struct polygon8 *src,
|
||||||
if (src->n < 2)
|
if (src->n < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clip_context_prepare(ctx, src, dst_x, dst_y);
|
clip_context_prepare(ctx, src, dst);
|
||||||
for (i = 0; i < src->n; i++) {
|
for (i = 0; i < src->n; i++) {
|
||||||
trans = path_transition_left_edge(ctx, 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->x[i], src->y[i],
|
clip_polygon_leftright(ctx, trans, src->pos[i].x, src->pos[i].y,
|
||||||
ctx->clip.x1);
|
ctx->clip.x1);
|
||||||
}
|
}
|
||||||
return ctx->vertices.x - dst_x;
|
return ctx->vertices - dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
clip_polygon_right(struct clip_context *ctx, const struct polygon8 *src,
|
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;
|
enum path_transition trans;
|
||||||
int i;
|
int i;
|
||||||
|
@ -232,18 +231,18 @@ clip_polygon_right(struct clip_context *ctx, const struct polygon8 *src,
|
||||||
if (src->n < 2)
|
if (src->n < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clip_context_prepare(ctx, src, dst_x, dst_y);
|
clip_context_prepare(ctx, src, dst);
|
||||||
for (i = 0; i < src->n; i++) {
|
for (i = 0; i < src->n; i++) {
|
||||||
trans = path_transition_right_edge(ctx, 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->x[i], src->y[i],
|
clip_polygon_leftright(ctx, trans, src->pos[i].x, src->pos[i].y,
|
||||||
ctx->clip.x2);
|
ctx->clip.x2);
|
||||||
}
|
}
|
||||||
return ctx->vertices.x - dst_x;
|
return ctx->vertices - dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
clip_polygon_top(struct clip_context *ctx, const struct polygon8 *src,
|
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;
|
enum path_transition trans;
|
||||||
int i;
|
int i;
|
||||||
|
@ -251,18 +250,18 @@ clip_polygon_top(struct clip_context *ctx, const struct polygon8 *src,
|
||||||
if (src->n < 2)
|
if (src->n < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clip_context_prepare(ctx, src, dst_x, dst_y);
|
clip_context_prepare(ctx, src, dst);
|
||||||
for (i = 0; i < src->n; i++) {
|
for (i = 0; i < src->n; i++) {
|
||||||
trans = path_transition_top_edge(ctx, 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->x[i], src->y[i],
|
clip_polygon_topbottom(ctx, trans, src->pos[i].x, src->pos[i].y,
|
||||||
ctx->clip.y1);
|
ctx->clip.y1);
|
||||||
}
|
}
|
||||||
return ctx->vertices.x - dst_x;
|
return ctx->vertices - dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src,
|
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;
|
enum path_transition trans;
|
||||||
int i;
|
int i;
|
||||||
|
@ -270,25 +269,24 @@ clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src,
|
||||||
if (src->n < 2)
|
if (src->n < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clip_context_prepare(ctx, src, dst_x, dst_y);
|
clip_context_prepare(ctx, src, dst);
|
||||||
for (i = 0; i < src->n; i++) {
|
for (i = 0; i < src->n; i++) {
|
||||||
trans = path_transition_bottom_edge(ctx, 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->x[i], src->y[i],
|
clip_polygon_topbottom(ctx, trans, src->pos[i].x, src->pos[i].y,
|
||||||
ctx->clip.y2);
|
ctx->clip.y2);
|
||||||
}
|
}
|
||||||
return ctx->vertices.x - dst_x;
|
return ctx->vertices - dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
WESTON_EXPORT_FOR_TESTS int
|
WESTON_EXPORT_FOR_TESTS int
|
||||||
clip_simple(struct clip_context *ctx,
|
clip_simple(struct clip_context *ctx,
|
||||||
struct polygon8 *surf,
|
struct polygon8 *surf,
|
||||||
float *ex,
|
struct weston_coord *e)
|
||||||
float *ey)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < surf->n; i++) {
|
for (i = 0; i < surf->n; i++) {
|
||||||
ex[i] = CLIP(surf->x[i], ctx->clip.x1, ctx->clip.x2);
|
e[i].x = CLIP(surf->pos[i].x, ctx->clip.x1, ctx->clip.x2);
|
||||||
ey[i] = CLIP(surf->y[i], ctx->clip.y1, ctx->clip.y2);
|
e[i].y = CLIP(surf->pos[i].y, ctx->clip.y1, ctx->clip.y2);
|
||||||
}
|
}
|
||||||
return surf->n;
|
return surf->n;
|
||||||
}
|
}
|
||||||
|
@ -296,31 +294,28 @@ clip_simple(struct clip_context *ctx,
|
||||||
WESTON_EXPORT_FOR_TESTS int
|
WESTON_EXPORT_FOR_TESTS int
|
||||||
clip_transformed(struct clip_context *ctx,
|
clip_transformed(struct clip_context *ctx,
|
||||||
struct polygon8 *surf,
|
struct polygon8 *surf,
|
||||||
float *ex,
|
struct weston_coord *e)
|
||||||
float *ey)
|
|
||||||
{
|
{
|
||||||
struct polygon8 polygon;
|
struct polygon8 polygon;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
polygon.n = clip_polygon_left(ctx, surf, polygon.x, polygon.y);
|
polygon.n = clip_polygon_left(ctx, surf, polygon.pos);
|
||||||
surf->n = clip_polygon_right(ctx, &polygon, surf->x, surf->y);
|
surf->n = clip_polygon_right(ctx, &polygon, surf->pos);
|
||||||
polygon.n = clip_polygon_top(ctx, surf, polygon.x, polygon.y);
|
polygon.n = clip_polygon_top(ctx, surf, polygon.pos);
|
||||||
surf->n = clip_polygon_bottom(ctx, &polygon, surf->x, surf->y);
|
surf->n = clip_polygon_bottom(ctx, &polygon, surf->pos);
|
||||||
|
|
||||||
/* Get rid of duplicate vertices */
|
/* Get rid of duplicate vertices */
|
||||||
ex[0] = surf->x[0];
|
e[0] = surf->pos[0];
|
||||||
ey[0] = surf->y[0];
|
|
||||||
n = 1;
|
n = 1;
|
||||||
for (i = 1; i < surf->n; i++) {
|
for (i = 1; i < surf->n; i++) {
|
||||||
if (float_difference(ex[n - 1], surf->x[i]) == 0.0f &&
|
if (float_difference(e[n - 1].x, surf->pos[i].x) == 0.0f &&
|
||||||
float_difference(ey[n - 1], surf->y[i]) == 0.0f)
|
float_difference(e[n - 1].y, surf->pos[i].y) == 0.0f)
|
||||||
continue;
|
continue;
|
||||||
ex[n] = surf->x[i];
|
e[n] = surf->pos[i];
|
||||||
ey[n] = surf->y[i];
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
if (float_difference(ex[n - 1], surf->x[0]) == 0.0f &&
|
if (float_difference(e[n - 1].x, surf->pos[0].x) == 0.0f &&
|
||||||
float_difference(ey[n - 1], surf->y[0]) == 0.0f)
|
float_difference(e[n - 1].y, surf->pos[0].y) == 0.0f)
|
||||||
n--;
|
n--;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
|
|
@ -25,9 +25,10 @@
|
||||||
#ifndef _WESTON_VERTEX_CLIPPING_H
|
#ifndef _WESTON_VERTEX_CLIPPING_H
|
||||||
#define _WESTON_VERTEX_CLIPPING_H
|
#define _WESTON_VERTEX_CLIPPING_H
|
||||||
|
|
||||||
|
#include <libweston/matrix.h>
|
||||||
|
|
||||||
struct polygon8 {
|
struct polygon8 {
|
||||||
float x[8];
|
struct weston_coord pos[8];
|
||||||
float y[8];
|
|
||||||
int n;
|
int n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,10 +43,7 @@ struct clip_context {
|
||||||
float x2, y2;
|
float x2, y2;
|
||||||
} clip;
|
} clip;
|
||||||
|
|
||||||
struct {
|
struct weston_coord *vertices;
|
||||||
float *x;
|
|
||||||
float *y;
|
|
||||||
} vertices;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
float
|
float
|
||||||
|
@ -54,13 +52,11 @@ float_difference(float a, float b);
|
||||||
int
|
int
|
||||||
clip_simple(struct clip_context *ctx,
|
clip_simple(struct clip_context *ctx,
|
||||||
struct polygon8 *surf,
|
struct polygon8 *surf,
|
||||||
float *ex,
|
struct weston_coord *e);
|
||||||
float *ey);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
clip_transformed(struct clip_context *ctx,
|
clip_transformed(struct clip_context *ctx,
|
||||||
struct polygon8 *surf,
|
struct polygon8 *surf,
|
||||||
float *ex,
|
struct weston_coord *e);
|
||||||
float *ey);\
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -60,11 +60,10 @@ populate_clip_context (struct clip_context *ctx)
|
||||||
static int
|
static int
|
||||||
clip_polygon (struct clip_context *ctx,
|
clip_polygon (struct clip_context *ctx,
|
||||||
struct polygon8 *polygon,
|
struct polygon8 *polygon,
|
||||||
float *vertices_x,
|
struct weston_coord *pos)
|
||||||
float *vertices_y)
|
|
||||||
{
|
{
|
||||||
populate_clip_context(ctx);
|
populate_clip_context(ctx);
|
||||||
return clip_transformed(ctx, polygon, vertices_x, vertices_y);
|
return clip_transformed(ctx, polygon, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vertex_clip_test_data
|
struct vertex_clip_test_data
|
||||||
|
@ -78,94 +77,152 @@ const struct vertex_clip_test_data test_data[] =
|
||||||
/* All inside */
|
/* All inside */
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{ INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 },
|
.pos = {
|
||||||
{ INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = INSIDE_X1, .y = INSIDE_Y1 },
|
||||||
4
|
{ .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 },
|
.pos = {
|
||||||
{ INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = INSIDE_X1, .y = INSIDE_Y1 },
|
||||||
4
|
{ .x = INSIDE_X2, .y = INSIDE_Y1 },
|
||||||
|
{ .x = INSIDE_X2, .y = INSIDE_Y2 },
|
||||||
|
{ .x = INSIDE_X1, .y = INSIDE_Y2 },
|
||||||
|
},
|
||||||
|
.n = 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* Top outside */
|
/* Top outside */
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{ INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 },
|
.pos = {
|
||||||
{ INSIDE_Y1, INSIDE_Y1, OUTSIDE_Y2, OUTSIDE_Y2 },
|
{ .x = INSIDE_X1, .y = INSIDE_Y1 },
|
||||||
4
|
{ .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 },
|
.pos = {
|
||||||
{ BOUNDING_BOX_TOP_Y, INSIDE_Y1, INSIDE_Y1, BOUNDING_BOX_TOP_Y },
|
{ .x = INSIDE_X1, .y = BOUNDING_BOX_TOP_Y },
|
||||||
4
|
{ .x = INSIDE_X1, .y = INSIDE_Y1 },
|
||||||
|
{ .x = INSIDE_X2, .y = INSIDE_Y1 },
|
||||||
|
{ .x = INSIDE_X2, .y = BOUNDING_BOX_TOP_Y },
|
||||||
|
},
|
||||||
|
.n = 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* Bottom outside */
|
/* Bottom outside */
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{ INSIDE_X1, INSIDE_X2, INSIDE_X2, INSIDE_X1 },
|
.pos = {
|
||||||
{ OUTSIDE_Y1, OUTSIDE_Y1, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = INSIDE_X1, .y = OUTSIDE_Y1 },
|
||||||
4
|
{ .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 },
|
.pos = {
|
||||||
{ BOUNDING_BOX_BOTTOM_Y, BOUNDING_BOX_BOTTOM_Y, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = INSIDE_X1, .y = BOUNDING_BOX_BOTTOM_Y },
|
||||||
4
|
{ .x = INSIDE_X2, .y = BOUNDING_BOX_BOTTOM_Y },
|
||||||
|
{ .x = INSIDE_X2, .y = INSIDE_Y2 },
|
||||||
|
{ .x = INSIDE_X1, .y = INSIDE_Y2 },
|
||||||
|
},
|
||||||
|
.n = 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* Left outside */
|
/* Left outside */
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{ OUTSIDE_X1, INSIDE_X2, INSIDE_X2, OUTSIDE_X1 },
|
.pos = {
|
||||||
{ INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = OUTSIDE_X1, .y = INSIDE_Y1 },
|
||||||
4
|
{ .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 },
|
.pos = {
|
||||||
{ INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = BOUNDING_BOX_LEFT_X, .y = INSIDE_Y1 },
|
||||||
4
|
{ .x = INSIDE_X2, .y = INSIDE_Y1 },
|
||||||
|
{ .x = INSIDE_X2, .y = INSIDE_Y2 },
|
||||||
|
{ .x = BOUNDING_BOX_LEFT_X, .y = INSIDE_Y2 },
|
||||||
|
},
|
||||||
|
.n = 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* Right outside */
|
/* Right outside */
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{ INSIDE_X1, OUTSIDE_X2, OUTSIDE_X2, INSIDE_X1 },
|
.pos = {
|
||||||
{ INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = INSIDE_X1, .y = INSIDE_Y1 },
|
||||||
4
|
{ .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 },
|
.pos = {
|
||||||
{ INSIDE_Y1, INSIDE_Y1, INSIDE_Y2, INSIDE_Y2 },
|
{ .x = INSIDE_X1, .y = INSIDE_Y1 },
|
||||||
4
|
{ .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 */
|
/* 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 },
|
.pos = {
|
||||||
{ BOUNDING_BOX_BOTTOM_Y + 25, BOUNDING_BOX_TOP_Y + 25, BOUNDING_BOX_TOP_Y - 25, BOUNDING_BOX_BOTTOM_Y - 25 },
|
{ .x = BOUNDING_BOX_LEFT_X - 25, .y = BOUNDING_BOX_BOTTOM_Y + 25 },
|
||||||
4
|
{ .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 },
|
.pos = {
|
||||||
{ BOUNDING_BOX_BOTTOM_Y, BOUNDING_BOX_TOP_Y, BOUNDING_BOX_TOP_Y, BOUNDING_BOX_BOTTOM_Y },
|
{ .x = BOUNDING_BOX_LEFT_X, .y = BOUNDING_BOX_BOTTOM_Y },
|
||||||
4
|
{ .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 */
|
/* 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 },
|
.pos = {
|
||||||
{ BOUNDING_BOX_BOTTOM_Y + 25, BOUNDING_BOX_TOP_Y + 12.5, BOUNDING_BOX_TOP_Y - 25, BOUNDING_BOX_BOTTOM_Y - 12.5 },
|
{ .x = BOUNDING_BOX_LEFT_X - 12.5, .y = BOUNDING_BOX_BOTTOM_Y + 25 },
|
||||||
4
|
{ .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,
|
.pos = {
|
||||||
BOUNDING_BOX_RIGHT_X - 12.5, BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_RIGHT_X - 12.5 },
|
{ .x = BOUNDING_BOX_LEFT_X + 12.5, .y = BOUNDING_BOX_BOTTOM_Y },
|
||||||
{ BOUNDING_BOX_BOTTOM_Y, BOUNDING_BOX_BOTTOM_Y + 12.5, BOUNDING_BOX_TOP_Y - 12.5, BOUNDING_BOX_TOP_Y,
|
{ .x = BOUNDING_BOX_LEFT_X, .y = BOUNDING_BOX_BOTTOM_Y + 12.5 },
|
||||||
BOUNDING_BOX_TOP_Y, BOUNDING_BOX_TOP_Y - 12.5, BOUNDING_BOX_BOTTOM_Y + 12.5, BOUNDING_BOX_BOTTOM_Y },
|
{ .x = BOUNDING_BOX_LEFT_X, .y = BOUNDING_BOX_TOP_Y - 12.5 },
|
||||||
8
|
{ .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)
|
deep_copy_polygon8(const struct polygon8 *src, struct polygon8 *dst)
|
||||||
{
|
{
|
||||||
dst->n = src->n;
|
dst->n = src->n;
|
||||||
ARRAY_COPY(dst->x, src->x);
|
ARRAY_COPY(dst->pos, src->pos);
|
||||||
ARRAY_COPY(dst->y, src->y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(clip_polygon_n_vertices_emitted, test_data)
|
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 vertex_clip_test_data *tdata = data;
|
||||||
struct clip_context ctx;
|
struct clip_context ctx;
|
||||||
struct polygon8 polygon;
|
struct polygon8 polygon;
|
||||||
float vertices_x[8];
|
struct weston_coord vertices[8];
|
||||||
float vertices_y[8];
|
|
||||||
deep_copy_polygon8(&tdata->surface, &polygon);
|
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);
|
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 vertex_clip_test_data *tdata = data;
|
||||||
struct clip_context ctx;
|
struct clip_context ctx;
|
||||||
struct polygon8 polygon;
|
struct polygon8 polygon;
|
||||||
float vertices_x[8];
|
struct weston_coord vertices[8];
|
||||||
float vertices_y[8];
|
|
||||||
deep_copy_polygon8(&tdata->surface, &polygon);
|
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;
|
int i = 0;
|
||||||
|
|
||||||
for (; i < emitted; ++i)
|
for (; i < emitted; ++i)
|
||||||
{
|
{
|
||||||
assert(vertices_x[i] == tdata->expected.x[i]);
|
assert(vertices[i].x == tdata->expected.pos[i].x);
|
||||||
assert(vertices_y[i] == tdata->expected.y[i]);
|
assert(vertices[i].y == tdata->expected.pos[i].y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue