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 "vertex-clipping.h"
struct clip_context {
struct clip_vertex prev;
struct clip_vertex box[2];
struct clip_vertex *vertices;
};
WESTON_EXPORT_FOR_TESTS float
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
clip_transformed(struct clip_context *ctx,
const struct clip_vertex *polygon,
clip_transformed(const struct clip_vertex *polygon,
size_t polygon_len,
const struct clip_vertex box[2],
struct clip_vertex *restrict vertices)
{
struct clip_context ctx;
struct polygon8 p, tmp;
int i, n;
if (polygon_len > 8)
return -1;
memcpy(ctx.box, box, 2 * sizeof *box);
memcpy(p.pos, polygon, polygon_len * sizeof *polygon);
p.n = polygon_len;
tmp.n = clip_polygon_left(ctx, &p, tmp.pos);
p.n = clip_polygon_right(ctx, &tmp, p.pos);
tmp.n = clip_polygon_top(ctx, &p, tmp.pos);
p.n = clip_polygon_bottom(ctx, &tmp, p.pos);
tmp.n = clip_polygon_left(&ctx, &p, tmp.pos);
p.n = clip_polygon_right(&ctx, &tmp, p.pos);
tmp.n = clip_polygon_top(&ctx, &p, tmp.pos);
p.n = clip_polygon_bottom(&ctx, &tmp, p.pos);
/* Get rid of duplicate vertices */
vertices[0] = p.pos[0];
@ -326,7 +334,6 @@ clip_quad(struct gl_quad *quad,
const struct clip_vertex box[2],
struct clip_vertex *restrict vertices)
{
struct clip_context ctx;
int i, n;
/* 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/
* but without looking at any of that code.
*/
memcpy(&ctx.box, box, 2 * sizeof *box);
n = clip_transformed(&ctx, quad->polygon, 4, vertices);
n = clip_transformed(quad->polygon, 4, box, vertices);
if (n < 3)
return 0;

View file

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

View file

@ -43,26 +43,8 @@
#define OUTSIDE_Y1 (BOUNDING_BOX_BOTTOM_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 clip_vertex box[2];
struct clip_vertex polygon[8];
struct clip_vertex clipped[8];
int polygon_n;
@ -72,6 +54,10 @@ struct vertex_clip_test_data {
const struct vertex_clip_test_data test_data[] = {
/* All inside */
{
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = {
{ INSIDE_X1, INSIDE_Y1 },
{ INSIDE_X2, INSIDE_Y1 },
@ -90,6 +76,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Top outside */
{
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = {
{ INSIDE_X1, INSIDE_Y1 },
{ INSIDE_X2, INSIDE_Y1 },
@ -108,6 +98,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Bottom outside */
{
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = {
{ INSIDE_X1, OUTSIDE_Y1 },
{ INSIDE_X2, OUTSIDE_Y1 },
@ -126,6 +120,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Left outside */
{
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y }
},
.polygon = {
{ OUTSIDE_X1, INSIDE_Y1 },
{ INSIDE_X2, INSIDE_Y1 },
@ -144,6 +142,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Right outside */
{
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = {
{ INSIDE_X1, INSIDE_Y1 },
{ OUTSIDE_X2, INSIDE_Y1 },
@ -162,6 +164,10 @@ const struct vertex_clip_test_data test_data[] = {
/* Diamond extending from bounding box edges */
{
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = {
{ BOUNDING_BOX_LEFT_X - 25, BOUNDING_BOX_BOTTOM_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 */
{
.box = {
{ BOUNDING_BOX_LEFT_X, BOUNDING_BOX_BOTTOM_Y },
{ BOUNDING_BOX_RIGHT_X, BOUNDING_BOX_TOP_Y },
},
.polygon = {
{ BOUNDING_BOX_LEFT_X - 12.5, BOUNDING_BOX_BOTTOM_Y + 25 },
{ 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)
{
struct vertex_clip_test_data *tdata = data;
struct clip_context ctx;
struct clip_vertex clipped[8];
int clipped_n;
clipped_n = clip_polygon(&ctx, tdata->polygon, tdata->polygon_n,
clipped);
clipped_n = clip_transformed(tdata->polygon, tdata->polygon_n,
tdata->box, clipped);
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)
{
struct vertex_clip_test_data *tdata = data;
struct clip_context ctx;
struct clip_vertex clipped[8];
int clipped_n, i;
clipped_n = clip_polygon(&ctx, tdata->polygon, tdata->polygon_n,
clipped);
clipped_n = clip_transformed(tdata->polygon, tdata->polygon_n,
tdata->box, clipped);
for (i = 0; i < clipped_n; i++) {
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)
{
struct clip_context ctx;
struct clip_vertex polygon[8] = {};
struct clip_vertex polygon[8] = {}, box[2] = {};
assert(clip_transformed(&ctx, polygon, 9, NULL) == -1);
assert(clip_transformed(polygon, 9, box, NULL) == -1);
}
TEST(float_difference_different)