gl-renderer: Replace clip_transformed() context with a clipping box

Simplify clip_transformed() by replacing its context parameter with a
clipping box parameter. The context struct is still used internally to
pass data around.

Since clip_transformed() doesn't take a context anymore, the clipping
boxes are now declared per test and stored along with the other vertex
data. That prepares the ground to add new tests using different boxes.

Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
Loïc Molinari 2023-05-25 12:22:41 +02:00 committed by Pekka Paalanen
parent bf222f1897
commit f74c5a4102
3 changed files with 52 additions and 45 deletions

View File

@ -30,6 +30,12 @@
#include "shared/helpers.h" #include "shared/helpers.h"
#include "vertex-clipping.h" #include "vertex-clipping.h"
struct clip_context {
struct clip_vertex prev;
struct clip_vertex box[2];
struct clip_vertex *vertices;
};
WESTON_EXPORT_FOR_TESTS float WESTON_EXPORT_FOR_TESTS float
float_difference(float a, float b) float_difference(float a, float b)
{ {
@ -286,23 +292,25 @@ clip_polygon_bottom(struct clip_context *ctx, const struct polygon8 *src,
} }
WESTON_EXPORT_FOR_TESTS int WESTON_EXPORT_FOR_TESTS int
clip_transformed(struct clip_context *ctx, clip_transformed(const struct clip_vertex *polygon,
const struct clip_vertex *polygon,
size_t polygon_len, size_t polygon_len,
const struct clip_vertex box[2],
struct clip_vertex *restrict vertices) struct clip_vertex *restrict vertices)
{ {
struct clip_context ctx;
struct polygon8 p, tmp; struct polygon8 p, tmp;
int i, n; int i, n;
if (polygon_len > 8) if (polygon_len > 8)
return -1; return -1;
memcpy(ctx.box, box, 2 * sizeof *box);
memcpy(p.pos, polygon, polygon_len * sizeof *polygon); memcpy(p.pos, polygon, polygon_len * sizeof *polygon);
p.n = polygon_len; p.n = polygon_len;
tmp.n = clip_polygon_left(ctx, &p, tmp.pos); tmp.n = clip_polygon_left(&ctx, &p, tmp.pos);
p.n = clip_polygon_right(ctx, &tmp, p.pos); p.n = clip_polygon_right(&ctx, &tmp, p.pos);
tmp.n = clip_polygon_top(ctx, &p, tmp.pos); tmp.n = clip_polygon_top(&ctx, &p, tmp.pos);
p.n = clip_polygon_bottom(ctx, &tmp, p.pos); p.n = clip_polygon_bottom(&ctx, &tmp, p.pos);
/* Get rid of duplicate vertices */ /* Get rid of duplicate vertices */
vertices[0] = p.pos[0]; vertices[0] = p.pos[0];
@ -326,7 +334,6 @@ clip_quad(struct gl_quad *quad,
const struct clip_vertex box[2], const struct clip_vertex box[2],
struct clip_vertex *restrict vertices) struct clip_vertex *restrict vertices)
{ {
struct clip_context ctx;
int i, n; int i, n;
/* Simple case: quad edges are parallel to clipping box edges, there /* Simple case: quad edges are parallel to clipping box edges, there
@ -360,8 +367,7 @@ clip_quad(struct gl_quad *quad,
* https://www.codeguru.com/cplusplus/polygon-clipping/ * https://www.codeguru.com/cplusplus/polygon-clipping/
* but without looking at any of that code. * but without looking at any of that code.
*/ */
memcpy(&ctx.box, box, 2 * sizeof *box); n = clip_transformed(quad->polygon, 4, box, vertices);
n = clip_transformed(&ctx, quad->polygon, 4, vertices);
if (n < 3) if (n < 3)
return 0; return 0;

View File

@ -39,19 +39,13 @@ struct gl_quad {
bool axis_aligned; bool axis_aligned;
}; };
struct clip_context {
struct clip_vertex prev;
struct clip_vertex box[2];
struct clip_vertex *vertices;
};
float float
float_difference(float a, float b); float_difference(float a, float b);
int int
clip_transformed(struct clip_context *ctx, clip_transformed(const struct clip_vertex *polygon,
const struct clip_vertex *polygon,
size_t polygon_len, size_t polygon_len,
const struct clip_vertex box[2],
struct clip_vertex *restrict vertices); struct clip_vertex *restrict vertices);
/* /*

View File

@ -43,26 +43,8 @@
#define OUTSIDE_Y1 (BOUNDING_BOX_BOTTOM_Y - 1.0f) #define OUTSIDE_Y1 (BOUNDING_BOX_BOTTOM_Y - 1.0f)
#define OUTSIDE_Y2 (BOUNDING_BOX_TOP_Y + 1.0f) #define OUTSIDE_Y2 (BOUNDING_BOX_TOP_Y + 1.0f)
static void
populate_clip_context (struct clip_context *ctx)
{
ctx->box[0].x = BOUNDING_BOX_LEFT_X;
ctx->box[0].y = BOUNDING_BOX_BOTTOM_Y;
ctx->box[1].x = BOUNDING_BOX_RIGHT_X;
ctx->box[1].y = BOUNDING_BOX_TOP_Y;
}
static int
clip_polygon (struct clip_context *ctx,
struct clip_vertex *polygon,
int n,
struct clip_vertex *vertices)
{
populate_clip_context(ctx);
return clip_transformed(ctx, polygon, n, vertices);
}
struct vertex_clip_test_data { struct vertex_clip_test_data {
struct clip_vertex box[2];
struct clip_vertex polygon[8]; struct clip_vertex polygon[8];
struct clip_vertex clipped[8]; struct clip_vertex clipped[8];
int polygon_n; int polygon_n;
@ -72,6 +54,10 @@ struct vertex_clip_test_data {
const struct vertex_clip_test_data test_data[] = { const struct vertex_clip_test_data test_data[] = {
/* All inside */ /* All inside */
{ {
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = { .polygon = {
{ INSIDE_X1, INSIDE_Y1 }, { INSIDE_X1, INSIDE_Y1 },
{ INSIDE_X2, INSIDE_Y1 }, { INSIDE_X2, INSIDE_Y1 },
@ -90,6 +76,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Top outside */ /* Top outside */
{ {
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = { .polygon = {
{ INSIDE_X1, INSIDE_Y1 }, { INSIDE_X1, INSIDE_Y1 },
{ INSIDE_X2, INSIDE_Y1 }, { INSIDE_X2, INSIDE_Y1 },
@ -108,6 +98,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Bottom outside */ /* Bottom outside */
{ {
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = { .polygon = {
{ INSIDE_X1, OUTSIDE_Y1 }, { INSIDE_X1, OUTSIDE_Y1 },
{ INSIDE_X2, OUTSIDE_Y1 }, { INSIDE_X2, OUTSIDE_Y1 },
@ -126,6 +120,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Left outside */ /* Left outside */
{ {
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y }
},
.polygon = { .polygon = {
{ OUTSIDE_X1, INSIDE_Y1 }, { OUTSIDE_X1, INSIDE_Y1 },
{ INSIDE_X2, INSIDE_Y1 }, { INSIDE_X2, INSIDE_Y1 },
@ -144,6 +142,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Right outside */ /* Right outside */
{ {
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = { .polygon = {
{ INSIDE_X1, INSIDE_Y1 }, { INSIDE_X1, INSIDE_Y1 },
{ OUTSIDE_X2, INSIDE_Y1 }, { OUTSIDE_X2, INSIDE_Y1 },
@ -162,6 +164,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Diamond extending from bounding box edges */ /* Diamond extending from bounding box edges */
{ {
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = { .polygon = {
{ BOUNDING_BOX_LEFT_X - 25, BOUNDING_BOX_BOTTOM_Y + 25 }, { BOUNDING_BOX_LEFT_X - 25, BOUNDING_BOX_BOTTOM_Y + 25 },
{ BOUNDING_BOX_LEFT_X + 25, BOUNDING_BOX_TOP_Y + 25 }, { BOUNDING_BOX_LEFT_X + 25, BOUNDING_BOX_TOP_Y + 25 },
@ -180,6 +186,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Diamond inside of bounding box edges */ /* Diamond inside of bounding box edges */
{ {
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = { .polygon = {
{ BOUNDING_BOX_LEFT_X - 12.5, BOUNDING_BOX_BOTTOM_Y + 25 }, { BOUNDING_BOX_LEFT_X - 12.5, BOUNDING_BOX_BOTTOM_Y + 25 },
{ BOUNDING_BOX_LEFT_X + 25, BOUNDING_BOX_TOP_Y + 12.5 }, { BOUNDING_BOX_LEFT_X + 25, BOUNDING_BOX_TOP_Y + 12.5 },
@ -204,12 +214,11 @@ const struct vertex_clip_test_data test_data[] = {
TEST_P(clip_polygon_n_vertices_emitted, test_data) 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_vertex clipped[8]; struct clip_vertex clipped[8];
int clipped_n; int clipped_n;
clipped_n = clip_polygon(&ctx, tdata->polygon, tdata->polygon_n, clipped_n = clip_transformed(tdata->polygon, tdata->polygon_n,
clipped); tdata->box, clipped);
assert(clipped_n == tdata->clipped_n); assert(clipped_n == tdata->clipped_n);
} }
@ -217,12 +226,11 @@ TEST_P(clip_polygon_n_vertices_emitted, test_data)
TEST_P(clip_polygon_expected_vertices, test_data) 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_vertex clipped[8]; struct clip_vertex clipped[8];
int clipped_n, i; int clipped_n, i;
clipped_n = clip_polygon(&ctx, tdata->polygon, tdata->polygon_n, clipped_n = clip_transformed(tdata->polygon, tdata->polygon_n,
clipped); tdata->box, clipped);
for (i = 0; i < clipped_n; i++) { for (i = 0; i < clipped_n; i++) {
assert(clipped[i].x == tdata->clipped[i].x); assert(clipped[i].x == tdata->clipped[i].x);
@ -232,10 +240,9 @@ TEST_P(clip_polygon_expected_vertices, test_data)
TEST(clip_transformed_size_too_high) TEST(clip_transformed_size_too_high)
{ {
struct clip_context ctx; struct clip_vertex polygon[8] = {}, box[2] = {};
struct clip_vertex polygon[8] = {};
assert(clip_transformed(&ctx, polygon, 9, NULL) == -1); assert(clip_transformed(polygon, 9, box, NULL) == -1);
} }
TEST(float_difference_different) TEST(float_difference_different)