matrix: Introduce weston_coord
All through weston we have code that passes int x, y or float x, y or wl_fixed_t x, y pairs. These pairs are frequently converted to/from wl_fixed_t and other types. We also have struct vec2d and struct weston_geometry which also contain coordinate pairs. Let's create a family of coordinate vector structures for coordinate pairs and use it anywhere we sensibly can. This has a few benefits - it helps remove intermediate conversion between fixed/float/int types. It lets us roll the homogenous coordinate normalization bits into helper functions instead of needing them open coded throughout the source. Possibly most importantly, it also allows us to do some compile time validation of what coordinate space we're working in. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
parent
fe4d5711bf
commit
e1b4ad7d0b
|
@ -1811,6 +1811,18 @@ void
|
|||
weston_view_to_global_float(struct weston_view *view,
|
||||
float sx, float sy, float *x, float *y);
|
||||
|
||||
struct weston_coord_global __attribute__ ((warn_unused_result))
|
||||
weston_coord_surface_to_global(const struct weston_view *view,
|
||||
struct weston_coord_surface coord);
|
||||
|
||||
struct weston_coord_surface __attribute__ ((warn_unused_result))
|
||||
weston_coord_global_to_surface(const struct weston_view *view,
|
||||
struct weston_coord_global coord);
|
||||
|
||||
struct weston_coord_buffer __attribute__ ((warn_unused_result))
|
||||
weston_coord_surface_to_buffer(const struct weston_surface *surface,
|
||||
struct weston_coord_surface coord);
|
||||
|
||||
void
|
||||
weston_view_from_global(struct weston_view *view,
|
||||
int32_t x, int32_t y, int32_t *vx, int32_t *vy);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef WESTON_MATRIX_H
|
||||
#define WESTON_MATRIX_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <wayland-server-protocol.h>
|
||||
|
@ -51,6 +52,28 @@ struct weston_vector {
|
|||
float f[4];
|
||||
};
|
||||
|
||||
/** Arbitrary coordinates in any space */
|
||||
struct weston_coord {
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
/** Coordinates in some weston_buffer (physical pixels) */
|
||||
struct weston_coord_buffer {
|
||||
struct weston_coord c;
|
||||
};
|
||||
|
||||
/** Coordinates in the global compositor space (logical pixels) */
|
||||
struct weston_coord_global {
|
||||
struct weston_coord c;
|
||||
};
|
||||
|
||||
/** surface-local coordinates on a specific surface */
|
||||
struct weston_coord_surface {
|
||||
struct weston_coord c;
|
||||
const struct weston_surface *coordinate_space_id;
|
||||
};
|
||||
|
||||
void
|
||||
weston_matrix_init(struct weston_matrix *matrix);
|
||||
void
|
||||
|
@ -66,6 +89,10 @@ void
|
|||
weston_matrix_transform(const struct weston_matrix *matrix,
|
||||
struct weston_vector *v);
|
||||
|
||||
struct weston_coord
|
||||
weston_matrix_transform_coord(const struct weston_matrix *matrix,
|
||||
struct weston_coord coord);
|
||||
|
||||
int
|
||||
weston_matrix_invert(struct weston_matrix *inverse,
|
||||
const struct weston_matrix *matrix);
|
||||
|
@ -83,6 +110,62 @@ weston_matrix_init_transform(struct weston_matrix *matrix,
|
|||
int x, int y, int width, int height,
|
||||
int scale);
|
||||
|
||||
static inline struct weston_coord __attribute__ ((warn_unused_result))
|
||||
weston_coord_from_fixed(wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
struct weston_coord out;
|
||||
|
||||
out.x = wl_fixed_to_double(x);
|
||||
out.y = wl_fixed_to_double(y);
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline struct weston_coord __attribute__ ((warn_unused_result))
|
||||
weston_coord(double x, double y)
|
||||
{
|
||||
return (struct weston_coord){ .x = x, .y = y };
|
||||
}
|
||||
|
||||
static inline struct weston_coord_surface __attribute__ ((warn_unused_result))
|
||||
weston_coord_surface(double x, double y, const struct weston_surface *surface)
|
||||
{
|
||||
struct weston_coord_surface out;
|
||||
|
||||
assert(surface);
|
||||
|
||||
out.c = weston_coord(x, y);
|
||||
out.coordinate_space_id = surface;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline struct weston_coord_surface __attribute__ ((warn_unused_result))
|
||||
weston_coord_surface_from_fixed(wl_fixed_t x, wl_fixed_t y,
|
||||
const struct weston_surface *surface)
|
||||
{
|
||||
struct weston_coord_surface out;
|
||||
|
||||
assert(surface);
|
||||
|
||||
out.c.x = wl_fixed_to_double(x);
|
||||
out.c.y = wl_fixed_to_double(y);
|
||||
out.coordinate_space_id = surface;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline struct weston_coord __attribute__ ((warn_unused_result))
|
||||
weston_coord_add(struct weston_coord a, struct weston_coord b)
|
||||
{
|
||||
return weston_coord(a.x + b.x, a.y + b.y);
|
||||
}
|
||||
|
||||
static inline struct weston_coord __attribute__ ((warn_unused_result))
|
||||
weston_coord_sub(struct weston_coord a, struct weston_coord b)
|
||||
{
|
||||
return weston_coord(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -165,6 +165,11 @@ int
|
|||
weston_output_mode_set_native(struct weston_output *output,
|
||||
struct weston_mode *mode,
|
||||
int32_t scale);
|
||||
|
||||
struct weston_coord_global
|
||||
weston_coord_global_from_output_point(double x, double y,
|
||||
const struct weston_output *output);
|
||||
|
||||
void
|
||||
weston_output_transform_coordinate(struct weston_output *output,
|
||||
double device_x, double device_y,
|
||||
|
|
|
@ -678,6 +678,46 @@ weston_view_to_global_float(struct weston_view *view,
|
|||
*y = v.f[1] / v.f[3];
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_coord_global
|
||||
weston_coord_surface_to_global(const struct weston_view *view,
|
||||
struct weston_coord_surface coord)
|
||||
{
|
||||
struct weston_coord_global out;
|
||||
|
||||
assert(!view->transform.dirty);
|
||||
assert(view->surface == coord.coordinate_space_id);
|
||||
|
||||
out.c = weston_matrix_transform_coord(&view->transform.matrix,
|
||||
coord.c);
|
||||
return out;
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_coord_surface
|
||||
weston_coord_global_to_surface(const struct weston_view *view,
|
||||
struct weston_coord_global coord)
|
||||
{
|
||||
struct weston_coord_surface out;
|
||||
|
||||
assert(!view->transform.dirty);
|
||||
out.c = weston_matrix_transform_coord(&view->transform.inverse,
|
||||
coord.c);
|
||||
out.coordinate_space_id = view->surface;
|
||||
return out;
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_coord_buffer
|
||||
weston_coord_surface_to_buffer(const struct weston_surface *surface,
|
||||
struct weston_coord_surface coord)
|
||||
{
|
||||
struct weston_coord_buffer tmp;
|
||||
|
||||
assert(surface == coord.coordinate_space_id);
|
||||
|
||||
tmp.c = weston_matrix_transform_coord(&surface->surface_to_buffer_matrix,
|
||||
coord.c);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
WL_EXPORT pixman_box32_t
|
||||
weston_matrix_transform_rect(struct weston_matrix *matrix,
|
||||
pixman_box32_t rect)
|
||||
|
@ -6421,6 +6461,32 @@ weston_compositor_add_output(struct weston_compositor *compositor,
|
|||
weston_view_geometry_dirty(view);
|
||||
}
|
||||
|
||||
/** Create a weston_coord_global from a point and a weston_output
|
||||
*
|
||||
* \param x x coordinate on the output
|
||||
* \param y y coordinate on the output
|
||||
* \param output the weston_output object
|
||||
* \return coordinate in global space corresponding to x, y on the output
|
||||
*
|
||||
* Transforms coordinates from the device coordinate space (physical pixel
|
||||
* units) to the global coordinate space (logical pixel units). This takes
|
||||
* into account output transform and scale.
|
||||
*
|
||||
* \ingroup output
|
||||
* \internal
|
||||
*/
|
||||
WL_EXPORT struct weston_coord_global
|
||||
weston_coord_global_from_output_point(double x, double y,
|
||||
const struct weston_output *output)
|
||||
{
|
||||
struct weston_coord c;
|
||||
struct weston_coord_global tmp;
|
||||
|
||||
c = weston_coord(x, y);
|
||||
tmp.c = weston_matrix_transform_coord(&output->inverse_matrix, c);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/** Transform device coordinates into global coordinates
|
||||
*
|
||||
* \param output the weston_output object
|
||||
|
|
|
@ -126,6 +126,22 @@ weston_matrix_transform(const struct weston_matrix *matrix,
|
|||
*v = t;
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_coord
|
||||
weston_matrix_transform_coord(const struct weston_matrix *matrix,
|
||||
struct weston_coord c)
|
||||
{
|
||||
struct weston_coord out;
|
||||
struct weston_vector t = { { c.x, c.y, 0.0, 1.0 } };
|
||||
|
||||
weston_matrix_transform(matrix, &t);
|
||||
|
||||
assert(fabsf(t.f[3]) > 1e-6);
|
||||
|
||||
out.x = t.f[0] / t.f[3];
|
||||
out.y = t.f[1] / t.f[3];
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline void
|
||||
swap_rows(double *a, double *b)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue