gl-renderer: Assume axis alignment using node's valid_transform
Assume axis alignment using node's valid_transform boolean instead of relying on the transform flags of the weston_view struct. This is more reliable since matrix flags could erroneously hang around after a series of transforms. Additionally, nodes with standard output transforms like translations, flips and rotations by 90° can now take the fast axis aligned path. Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
parent
287b3f1758
commit
d4fe0a42fd
|
@ -69,6 +69,7 @@ struct geometry {
|
||||||
float s; /* sin phi */
|
float s; /* sin phi */
|
||||||
float c; /* cos phi */
|
float c; /* cos phi */
|
||||||
float phi;
|
float phi;
|
||||||
|
bool axis_aligned;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_surface {
|
struct weston_surface {
|
||||||
|
@ -76,11 +77,6 @@ struct weston_surface {
|
||||||
|
|
||||||
struct weston_view {
|
struct weston_view {
|
||||||
struct weston_surface *surface;
|
struct weston_surface *surface;
|
||||||
struct {
|
|
||||||
int enabled;
|
|
||||||
struct weston_matrix matrix;
|
|
||||||
} transform;
|
|
||||||
|
|
||||||
struct geometry *geometry;
|
struct geometry *geometry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,21 +126,17 @@ global_to_surface(pixman_box32_t *rect, struct weston_view *ev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
node_axis_aligned(const struct weston_view *view)
|
|
||||||
{
|
|
||||||
return !view->transform.enabled ||
|
|
||||||
(view->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------- copied ends -----------------------*/
|
/* ---------------------- copied ends -----------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
geometry_set_phi(struct geometry *g, float phi)
|
geometry_set_phi(struct geometry *g, float phi)
|
||||||
{
|
{
|
||||||
|
float integer;
|
||||||
|
|
||||||
g->phi = phi;
|
g->phi = phi;
|
||||||
g->s = sin(phi);
|
g->s = sin(phi);
|
||||||
g->c = cos(phi);
|
g->c = cos(phi);
|
||||||
|
g->axis_aligned = fabs(modff(g->c, &integer)) < 0.0001f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -245,7 +237,7 @@ draw_box(cairo_t *cr, pixman_box32_t *box, struct weston_view *view)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_geometry(cairo_t *cr, struct weston_view *view,
|
draw_geometry(cairo_t *cr, struct weston_view *view,
|
||||||
struct clipper_vertex *v, int n)
|
struct clipper_vertex *v, int n, struct clipper_quad *quad)
|
||||||
{
|
{
|
||||||
struct geometry *g = view->geometry;
|
struct geometry *g = view->geometry;
|
||||||
float cx, cy;
|
float cx, cy;
|
||||||
|
@ -255,7 +247,7 @@ draw_geometry(cairo_t *cr, struct weston_view *view,
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
weston_view_from_global_float(view, g->quad.x1 - 4, g->quad.y1 - 4, &cx, &cy);
|
weston_view_from_global_float(view, g->quad.x1 - 4, g->quad.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 (!quad->axis_aligned)
|
||||||
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);
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
|
|
||||||
|
@ -286,8 +278,7 @@ redraw_handler(struct widget *widget, void *data)
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
global_to_surface(&g->quad, &cliptest->view, transformed_v);
|
global_to_surface(&g->quad, &cliptest->view, transformed_v);
|
||||||
clipper_quad_init(&quad, transformed_v,
|
clipper_quad_init(&quad, transformed_v, g->axis_aligned);
|
||||||
node_axis_aligned(&cliptest->view));
|
|
||||||
n = clipper_quad_clip_box32(&quad, &g->surf, v);
|
n = clipper_quad_clip_box32(&quad, &g->surf, v);
|
||||||
|
|
||||||
widget_get_allocation(cliptest->widget, &allocation);
|
widget_get_allocation(cliptest->widget, &allocation);
|
||||||
|
@ -322,7 +313,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, v, n);
|
draw_geometry(cr, &cliptest->view, v, n, &quad);
|
||||||
cairo_pop_group_to_source(cr);
|
cairo_pop_group_to_source(cr);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
@ -401,8 +392,6 @@ axis_handler(struct widget *widget, struct input *input, uint32_t time,
|
||||||
|
|
||||||
geometry_set_phi(geom, geom->phi +
|
geometry_set_phi(geom, geom->phi +
|
||||||
(M_PI / 12.0) * wl_fixed_to_double(value));
|
(M_PI / 12.0) * wl_fixed_to_double(value));
|
||||||
cliptest->view.transform.enabled = 1;
|
|
||||||
cliptest->view.transform.matrix.type = WESTON_MATRIX_TRANSFORM_ROTATE;
|
|
||||||
|
|
||||||
widget_schedule_redraw(cliptest->widget);
|
widget_schedule_redraw(cliptest->widget);
|
||||||
}
|
}
|
||||||
|
@ -452,20 +441,12 @@ key_handler(struct window *window, struct input *input, uint32_t time,
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_n:
|
case XKB_KEY_n:
|
||||||
geometry_set_phi(g, g->phi + (M_PI / 24.0));
|
geometry_set_phi(g, g->phi + (M_PI / 24.0));
|
||||||
cliptest->view.transform.enabled = 1;
|
|
||||||
cliptest->view.transform.matrix.type =
|
|
||||||
WESTON_MATRIX_TRANSFORM_ROTATE;
|
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_m:
|
case XKB_KEY_m:
|
||||||
geometry_set_phi(g, g->phi - (M_PI / 24.0));
|
geometry_set_phi(g, g->phi - (M_PI / 24.0));
|
||||||
cliptest->view.transform.enabled = 1;
|
|
||||||
cliptest->view.transform.matrix.type =
|
|
||||||
WESTON_MATRIX_TRANSFORM_ROTATE;
|
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_r:
|
case XKB_KEY_r:
|
||||||
geometry_set_phi(g, 0.0);
|
geometry_set_phi(g, 0.0);
|
||||||
cliptest->view.transform.enabled = 0;
|
|
||||||
cliptest->view.transform.matrix.type = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
@ -500,8 +481,6 @@ cliptest_create(struct display *display)
|
||||||
cliptest = xzalloc(sizeof *cliptest);
|
cliptest = xzalloc(sizeof *cliptest);
|
||||||
cliptest->view.surface = &cliptest->surface;
|
cliptest->view.surface = &cliptest->surface;
|
||||||
cliptest->view.geometry = &cliptest->geometry;
|
cliptest->view.geometry = &cliptest->geometry;
|
||||||
cliptest->view.transform.enabled = 0;
|
|
||||||
cliptest->view.transform.matrix.type = 0;
|
|
||||||
geometry_init(&cliptest->geometry);
|
geometry_init(&cliptest->geometry);
|
||||||
geometry_init(&cliptest->ui.geometry);
|
geometry_init(&cliptest->ui.geometry);
|
||||||
|
|
||||||
|
@ -574,16 +553,13 @@ benchmark(void)
|
||||||
geometry_set_phi(&geom, 0.0);
|
geometry_set_phi(&geom, 0.0);
|
||||||
|
|
||||||
view.surface = &surface;
|
view.surface = &surface;
|
||||||
view.transform.enabled = 1;
|
|
||||||
view.transform.matrix.type = WESTON_MATRIX_TRANSFORM_ROTATE;
|
|
||||||
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);
|
||||||
global_to_surface(&geom.quad, &view, transformed_v);
|
global_to_surface(&geom.quad, &view, transformed_v);
|
||||||
clipper_quad_init(&quad, transformed_v,
|
clipper_quad_init(&quad, transformed_v, geom.axis_aligned);
|
||||||
node_axis_aligned(&view));
|
|
||||||
clipper_quad_clip_box32(&quad, &geom.surf, v);
|
clipper_quad_clip_box32(&quad, &geom.surf, v);
|
||||||
}
|
}
|
||||||
t = read_timer();
|
t = read_timer();
|
||||||
|
|
|
@ -1419,13 +1419,6 @@ global_to_surface(pixman_box32_t *rect, struct weston_view *ev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
node_axis_aligned(const struct weston_view *view)
|
|
||||||
{
|
|
||||||
return !view->transform.enabled ||
|
|
||||||
(view->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Transform damage 'region' in global coordinates to damage 'quads' in surface
|
/* Transform damage 'region' in global coordinates to damage 'quads' in surface
|
||||||
* coordinates. 'quads' and 'nquads' are output arguments set if 'quads' is
|
* coordinates. 'quads' and 'nquads' are output arguments set if 'quads' is
|
||||||
* NULL, no transformation happens otherwise. Caller must free 'quads' if
|
* NULL, no transformation happens otherwise. Caller must free 'quads' if
|
||||||
|
@ -1456,8 +1449,15 @@ transform_damage(const struct weston_paint_node *pnode,
|
||||||
*quads = quads_alloc = malloc(nrects * sizeof *quads_alloc);
|
*quads = quads_alloc = malloc(nrects * sizeof *quads_alloc);
|
||||||
*nquads = nrects;
|
*nquads = nrects;
|
||||||
|
|
||||||
|
/* All the damage rects are axis-aligned in global space. This implies
|
||||||
|
* that all the horizontal and vertical edges are respectively parallel
|
||||||
|
* to each other. Because affine transformations preserve parallelism we
|
||||||
|
* can safely assume that if the node's output matrix is affine and
|
||||||
|
* stores standard output transforms (translations, flips and rotations
|
||||||
|
* by 90°), then all the transformed quads are axis-aligned in surface
|
||||||
|
* space. */
|
||||||
view = pnode->view;
|
view = pnode->view;
|
||||||
axis_aligned = node_axis_aligned(view);
|
axis_aligned = pnode->valid_transform;
|
||||||
for (i = 0; i < nrects; i++) {
|
for (i = 0; i < nrects; i++) {
|
||||||
global_to_surface(&rects[i], view, polygon);
|
global_to_surface(&rects[i], view, polygon);
|
||||||
clipper_quad_init(&quads_alloc[i], polygon, axis_aligned);
|
clipper_quad_init(&quads_alloc[i], polygon, axis_aligned);
|
||||||
|
|
Loading…
Reference in New Issue