From 714e65fb2c79ed99fd251ef1a49bfc0b36c49bae Mon Sep 17 00:00:00 2001 From: Taekyun Kim Date: Fri, 12 Jun 2015 13:19:45 +0900 Subject: [PATCH] pepper: Basic matrix APIs Matrix initialization, multiplication and some utility functions. Change-Id: I3e40cc503d6d7109547e05739321ea64d393117b --- pepper/src/Makefile.am | 2 +- pepper/src/pepper-utils.h | 258 +++++++++++++++++++++++++++++++++++++++++++++- pepper/src/pepper.h | 63 ----------- pepper/src/view.c | 2 +- 4 files changed, 259 insertions(+), 66 deletions(-) diff --git a/pepper/src/Makefile.am b/pepper/src/Makefile.am index 2f2b86b..ec736b8 100644 --- a/pepper/src/Makefile.am +++ b/pepper/src/Makefile.am @@ -5,7 +5,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = pepper.pc libpepper_la_CFLAGS = $(PEPPER_CFLAGS) -Wall -libpepper_la_LIBADD = $(PEPPER_LIBS) +libpepper_la_LIBADD = $(PEPPER_LIBS) -lm libpepper_la_SOURCES = pepper.h \ pepper-internal.h \ diff --git a/pepper/src/pepper-utils.h b/pepper/src/pepper-utils.h index d8dde32..94a22ef 100644 --- a/pepper/src/pepper-utils.h +++ b/pepper/src/pepper-utils.h @@ -3,6 +3,8 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -25,7 +27,8 @@ typedef unsigned int pepper_bool_t; #define PEPPER_FALSE 0 #define PEPPER_TRUE 1 -typedef struct pepper_list pepper_list_t; +typedef struct pepper_list pepper_list_t; +typedef struct pepper_matrix pepper_matrix_t; #define PEPPER_LIST_FOR_EACH(head, pos) \ for (pos = (head)->next; \ @@ -183,6 +186,259 @@ pepper_create_anonymous_file(off_t size); PEPPER_API int pepper_log(const char* domain, int level, const char *format, ...); +struct pepper_matrix +{ + double m[16]; + uint32_t flags; +}; + +enum { + PEPPER_MATRIX_TRANSLATE = (1 << 0), + PEPPER_MATRIX_SCALE = (1 << 1), + PEPPER_MATRIX_ROTATE = (1 << 2), + PEPPER_MATRIX_COMPLEX = (1 << 3), +}; + +static inline double +pepper_reciprocal_sqrt(double x) +{ + union { + float f; + long i; + } u; + + u.f = x; + u.i = 0x5f3759df - (u.i >> 1); + return (double)(u.f * (1.5f - u.f * u.f * x * 0.5f)); +} + +static inline void +pepper_matrix_multiply(pepper_matrix_t *dst, const pepper_matrix_t *ma, const pepper_matrix_t *mb) +{ + pepper_matrix_t tmp; + double *d = tmp.m; + const double *a = ma->m; + const double *b = mb->m; + + if (!ma->flags) + { + memcpy(dst, mb, sizeof(pepper_matrix_t)); + return; + } + + if (!mb->flags) + { + memcpy(dst, ma, sizeof(pepper_matrix_t)); + return; + } + + d[ 0] = a[ 0] * b[ 0] + a[ 4] * b[ 1] + a[ 8] * b[ 2] + a[12] * b [3]; + d[ 4] = a[ 0] * b[ 4] + a[ 4] * b[ 5] + a[ 8] * b[ 6] + a[12] * b [7]; + d[ 8] = a[ 0] * b[ 8] + a[ 4] * b[ 9] + a[ 8] * b[10] + a[12] * b[11]; + d[12] = a[ 0] * b[12] + a[ 4] * b[13] + a[ 8] * b[14] + a[12] * b[15]; + + d[ 1] = a[ 1] * b[ 0] + a[ 5] * b[ 1] + a[ 9] * b[ 2] + a[13] * b [3]; + d[ 5] = a[ 1] * b[ 4] + a[ 5] * b[ 5] + a[ 9] * b[ 6] + a[13] * b [7]; + d[ 9] = a[ 1] * b[ 8] + a[ 5] * b[ 9] + a[ 9] * b[10] + a[13] * b[11]; + d[13] = a[ 1] * b[12] + a[ 5] * b[13] + a[ 9] * b[14] + a[13] * b[15]; + + d[ 2] = a[ 2] * b[ 0] + a[ 6] * b[ 1] + a[10] * b[ 2] + a[14] * b [3]; + d[ 6] = a[ 2] * b[ 4] + a[ 6] * b[ 5] + a[10] * b[ 6] + a[14] * b [7]; + d[10] = a[ 2] * b[ 8] + a[ 6] * b[ 9] + a[10] * b[10] + a[14] * b[11]; + d[14] = a[ 2] * b[12] + a[ 6] * b[13] + a[10] * b[14] + a[14] * b[15]; + + d[ 3] = a[ 3] * b[ 0] + a[ 7] * b[ 1] + a[11] * b[ 2] + a[15] * b [3]; + d[ 7] = a[ 3] * b[ 4] + a[ 7] * b[ 5] + a[11] * b[ 6] + a[15] * b [7]; + d[11] = a[ 3] * b[ 8] + a[ 7] * b[ 9] + a[11] * b[10] + a[15] * b[11]; + d[15] = a[ 3] * b[12] + a[ 7] * b[13] + a[11] * b[14] + a[15] * b[15]; + + tmp.flags = ma->flags | mb->flags; + memcpy(dst, &tmp, sizeof(pepper_matrix_t)); +} + +static inline void +pepper_matrix_init_identity(pepper_matrix_t *matrix) +{ + matrix->m[ 0] = 1.0f; + matrix->m[ 1] = 0.0f; + matrix->m[ 2] = 0.0f; + matrix->m[ 3] = 0.0f; + + matrix->m[ 4] = 0.0f; + matrix->m[ 5] = 1.0f; + matrix->m[ 6] = 0.0f; + matrix->m[ 7] = 0.0f; + + matrix->m[ 8] = 0.0f; + matrix->m[ 9] = 0.0f; + matrix->m[10] = 1.0f; + matrix->m[11] = 0.0f; + + matrix->m[12] = 0.0f; + matrix->m[13] = 0.0f; + matrix->m[14] = 0.0f; + matrix->m[15] = 1.0f; + + matrix->flags = 0; +} + +static inline void +pepper_matrix_init_translate(pepper_matrix_t *matrix, double x, double y, double z) +{ + pepper_matrix_init_identity(matrix); + + matrix->m[ 3] = x; + matrix->m[ 7] = y; + matrix->m[11] = z; + + matrix->flags |= PEPPER_MATRIX_TRANSLATE; +} + +static inline void +pepper_matrix_translate(pepper_matrix_t *matrix, double x, double y, double z) +{ + matrix->m[ 3] = matrix->m[0] * x + matrix->m[1] * y + matrix->m[ 2] * z; + matrix->m[ 7] = matrix->m[4] * x + matrix->m[5] * y + matrix->m[ 6] * z; + matrix->m[11] = matrix->m[8] * x + matrix->m[9] * y + matrix->m[10] * z; + + matrix->flags |= PEPPER_MATRIX_TRANSLATE; +} + +static inline void +pepper_matrix_init_scale(pepper_matrix_t *matrix, double x, double y, double z) +{ + pepper_matrix_init_identity(matrix); + + matrix->m[ 0] = x; + matrix->m[ 5] = y; + matrix->m[10] = z; + + matrix->flags |= PEPPER_MATRIX_SCALE; +} + +static inline void +pepper_matrix_scale(pepper_matrix_t *matrix, double x, double y, double z) +{ + matrix->m[ 0] *= x; + matrix->m[ 1] *= y; + matrix->m[ 2] *= z; + + matrix->m[ 4] *= x; + matrix->m[ 5] *= y; + matrix->m[ 6] *= z; + + matrix->m[ 8] *= x; + matrix->m[ 9] *= y; + matrix->m[10] *= z; + + matrix->flags |= PEPPER_MATRIX_SCALE; +} + +static inline void +pepper_matrix_init_rotate(pepper_matrix_t *matrix, double x, double y, double z, double angle) +{ + double c; + double s; + double invlen; + double xs; + double ys; + double zs; + double invc; + double xinvc; + double yinvc; + double zinvc; + + if (angle == 0.0f || (z == 0.0f && y == 0.0f && z == 0.0f)) + { + pepper_matrix_init_identity(matrix); + return; + } + + matrix->flags |= PEPPER_MATRIX_ROTATE; + + c = cos(angle); + s = sin(angle); + + if (x == 0.0f && y == 0.0f) + { + pepper_matrix_init_identity(matrix); + + matrix->m[ 0] = c; + matrix->m[ 1] = -s; + matrix->m[ 4] = -s; + matrix->m[ 5] = c; + } + else if (y == 0.0f && z == 0.0f) + { + pepper_matrix_init_identity(matrix); + + matrix->m[ 5] = c; + matrix->m[ 6] = -s; + matrix->m[ 9] = -s; + matrix->m[10] = c; + } + else if (x == 0.0f && z == 0.0f) + { + pepper_matrix_init_identity(matrix); + + matrix->m[ 2] = c; + matrix->m[ 0] = -s; + matrix->m[10] = -s; + matrix->m[ 8] = c; + } + else + { + invlen = pepper_reciprocal_sqrt(x * x + y * y + z * z); + + x *= invlen; + y *= invlen; + z *= invlen; + + xs = x * s; + ys = y * s; + zs = z * s; + invc = 1 - c; + xinvc = x * invc; + yinvc = y * invc; + zinvc = z * invc; + + matrix->m[ 0] = c + x * xinvc; + matrix->m[ 1] = x * yinvc - zs; + matrix->m[ 2] = x * zinvc + ys; + matrix->m[ 3] = 0.0f; + + matrix->m[ 4] = y * xinvc + zs; + matrix->m[ 5] = c + y * yinvc; + matrix->m[ 6] = y * zinvc - xs; + matrix->m[ 7] = 0.0f; + + matrix->m[ 8] = z * xinvc - ys; + matrix->m[ 9] = z * yinvc + xs; + matrix->m[10] = c + z * zinvc; + matrix->m[11] = 0.0f; + + matrix->m[12] = 0.0f; + matrix->m[13] = 0.0f; + matrix->m[14] = 0.0f; + matrix->m[15] = 1.0f; + } +} + +static inline void +pepper_matrix_rotate(pepper_matrix_t *matrix, double x, double y, double z, double angle) +{ + pepper_matrix_t rotate; + + pepper_matrix_init_rotate(&rotate, x, y, z, angle); + pepper_matrix_multiply(matrix, matrix, &rotate); +} + +static inline void +pepper_matrix_copy(pepper_matrix_t *dst, const pepper_matrix_t *src) +{ + memcpy(dst, src, sizeof(pepper_matrix_t)); +} + #ifdef __cplusplus } #endif diff --git a/pepper/src/pepper.h b/pepper/src/pepper.h index 1f5b1f7..99440ec 100644 --- a/pepper/src/pepper.h +++ b/pepper/src/pepper.h @@ -32,8 +32,6 @@ typedef struct pepper_surface pepper_surface_t; typedef struct pepper_view pepper_view_t; typedef struct pepper_buffer pepper_buffer_t; -typedef struct pepper_matrix pepper_matrix_t; - #define PEPPER_FORMAT(type, bpp, a, r, g, b) \ ((((type) & 0xff) << 24) | \ (( (bpp) & 0xff) << 16) | \ @@ -73,67 +71,6 @@ typedef enum PEPPER_FORMAT_ALPHA = PEPPER_FORMAT(PEPPER_FORMAT_TYPE_ARGB, 8, 8, 0, 0, 0), } pepper_format_t; -#define PEPPER_MATRIX_IS_IDENTITY 1 - -struct pepper_matrix -{ - float m[16]; - uint32_t flags; -}; - -static inline void -pepper_matrix_load_identity(pepper_matrix_t *matrix) -{ - matrix->m[ 0] = 1.0f; - matrix->m[ 1] = 0.0f; - matrix->m[ 2] = 0.0f; - matrix->m[ 3] = 0.0f; - - matrix->m[ 4] = 0.0f; - matrix->m[ 5] = 1.0f; - matrix->m[ 6] = 0.0f; - matrix->m[ 7] = 0.0f; - - matrix->m[ 8] = 0.0f; - matrix->m[ 9] = 0.0f; - matrix->m[10] = 1.0f; - matrix->m[11] = 0.0f; - - matrix->m[12] = 0.0f; - matrix->m[13] = 0.0f; - matrix->m[14] = 0.0f; - matrix->m[15] = 1.0f; - - matrix->flags = PEPPER_MATRIX_IS_IDENTITY; -} - -static inline pepper_bool_t -pepper_matrix_equal(const pepper_matrix_t *a, const pepper_matrix_t *b) -{ - return a->m[ 0] == b->m[ 0] && a->m[ 1] == b->m[ 1] && - a->m[ 2] == b->m[ 2] && a->m[ 3] && b->m[ 3] && - a->m[ 4] == b->m[ 4] && a->m[ 5] && b->m[ 5] && - a->m[ 6] == b->m[ 6] && a->m[ 7] && b->m[ 7] && - a->m[ 8] == b->m[ 8] && a->m[ 9] && b->m[ 9] && - a->m[10] == b->m[10] && a->m[11] && b->m[11] && - a->m[12] == b->m[12] && a->m[13] && b->m[13] && - a->m[14] == b->m[14] && a->m[15] && b->m[15]; -} - -static inline void -pepper_matrix_multiply(pepper_matrix_t *dst, const pepper_matrix_t *a, const pepper_matrix_t *b) -{ - /* TODO: */ -} - -static inline void -pepper_matrix_copy(pepper_matrix_t *dst, const pepper_matrix_t *src) -{ - memcpy(dst, src, sizeof(pepper_matrix_t)); -} - -/* TODO: Other matrix utility functions. */ - struct pepper_output_geometry { int32_t x; diff --git a/pepper/src/view.c b/pepper/src/view.c index 9e52403..49d01d4 100644 --- a/pepper/src/view.c +++ b/pepper/src/view.c @@ -64,7 +64,7 @@ pepper_compositor_add_view(pepper_compositor_t *compositor, view->parent = parent; wl_list_init(&view->child_list); - pepper_matrix_load_identity(&view->transform); + pepper_matrix_init_identity(&view->transform); view->alpha = 1.0f; view->surface = surface; -- 2.7.4