From e31a5104bf9eb31ee1ca28230d99812c84e25818 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Wed, 9 Nov 2016 17:36:40 +0900 Subject: [PATCH] tpl: Add tpl_surface_get_rotation() / tpl_surface_set_rotation_capability() apis tpl_wayland_egl: implement getting of tpl_surface angle. implement getting of tpl_surface's capabilities wayland-egl: Add wl_egl_window_set_rotation() / wl_egl_window_get_capabilities() - tpl_surface_get_rotation() api used for getting the current rotation-angle of the given TPL surface. tpl_surface's angle can be in 0, 90, 180, 270. - wl_egl_window_set_rotation api used fo setting the current egl_window's angle. - wl_egl_window_get_capabilities api used for getting capabilities of egl_window. Change-Id: If051e890c040aff40097f88d26276b3b0b2bf4fd Signed-off-by: Mun, Gwan-gyeong --- src/tpl.h | 19 +++++++++++ src/tpl_internal.h | 2 ++ src/tpl_surface.c | 29 +++++++++++++++++ src/tpl_wayland_egl.c | 47 +++++++++++++++++++++++++++ src/wayland-egl/wayland-egl-priv.h | 5 +++ src/wayland-egl/wayland-egl.c | 65 +++++++++++++++++++++++++++++++++++++- 6 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/tpl.h b/src/tpl.h index 4d9145f..82cf601 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -426,6 +426,17 @@ tpl_result_t tpl_surface_get_size(tpl_surface_t *surface, int *width, int *height); /** + * Get the current rotation-angle of the given TPL surface. + * + * tpl_surface's angle can be in 0, 90, 180, 270. + * + * @param surface surface to get rotation-angle. + * @param rotation pointer to receive rotation-angle value. + */ +tpl_result_t +tpl_surface_get_rotation(tpl_surface_t *surface, int *rotation); + +/** * Validate current frame of the given TPL surface. * * Users should call this function before getting actual final render target @@ -730,6 +741,14 @@ tpl_surface_set_reset_cb(tpl_surface_t *surface, void* data, tpl_surface_cb_func_t reset_cb); /** + * Set rotation capability to the given tpl_surface + * @param surface surface used for set + * @param set TPL_TRUE if user want to set to enable / disable capability of rotation + */ +tpl_result_t +tpl_surface_set_rotation_capability(tpl_surface_t *surface, tpl_bool_t set); + +/** * Present mode types. * * @TPL_DISPLAY_MODE_IMMEDIATE_KHR: The presentation engine does not wait for diff --git a/src/tpl_internal.h b/src/tpl_internal.h index 2297db4..a881013 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -128,8 +128,10 @@ struct _tpl_surface { tpl_surface_type_t type; tbm_format format; int width, height; + int rotation; int post_interval; int dump_count; + tpl_bool_t rotation_capability; tpl_surface_backend_t backend; /*For frontbuffer extension*/ diff --git a/src/tpl_surface.c b/src/tpl_surface.c index ed8cc9f..c991868 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -119,6 +119,18 @@ tpl_surface_get_size(tpl_surface_t *surface, int *width, int *height) return TPL_ERROR_NONE; } +tpl_result_t +tpl_surface_get_rotation(tpl_surface_t *surface, int *rotation) +{ + if (!surface) { + TPL_ERR("Surface is NULL!"); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (rotation) *rotation = surface->rotation; + + return TPL_ERROR_NONE; +} tpl_bool_t tpl_surface_validate(tpl_surface_t *surface) @@ -425,3 +437,20 @@ tpl_surface_set_reset_cb(tpl_surface_t *surface, void *data, tpl_surface_cb_func return ret; } + +tpl_result_t +tpl_surface_set_rotation_capability(tpl_surface_t *surface, tpl_bool_t set) +{ + if (!surface || (surface->type != TPL_SURFACE_TYPE_WINDOW)) { + TPL_ERR("Invalid surface!"); + return TPL_ERROR_INVALID_PARAMETER; + } + + TPL_OBJECT_LOCK(surface); + + surface->rotation_capability = set; + + TPL_OBJECT_UNLOCK(surface); + + return TPL_ERROR_NONE; +} diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index d6c5cac..2b89173 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -373,6 +373,14 @@ static void __cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, void *private); +static void +__cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, + void *private); + +static int +__cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, + void *private); + static TPL_INLINE void __tpl_wayland_egl_buffer_set_reset_flag(tpl_list_t *tracking_list) { @@ -539,9 +547,13 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) surface->width = wl_egl_window->width; surface->height = wl_egl_window->height; + surface->rotation = wl_egl_window->rotation; + surface->rotation_capability = TPL_FALSE; wl_egl_window->private = surface; wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; + wl_egl_window->rotate_callback = (void *)__cb_client_window_rotate_callback; + wl_egl_window->get_rotation_capability = (void *)__cb_client_window_get_rotation_capability; /* tdm_vblank object decide to be maintained every tpl_wayland_egl_surface for the case where the several surfaces is created in one display connection. */ @@ -1212,6 +1224,41 @@ __cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, wayland_egl_surface->resized = TPL_TRUE; } +static void +__cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, + void *private) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + + int rotation; + tpl_surface_t *surface = (tpl_surface_t *)private; + + rotation = wl_egl_window->rotation; + + TPL_LOG_B("WL_EGL", "[ROTATE_CB] wl_egl_window(%p) (%d) -> (%d)", + wl_egl_window, surface->rotation, rotation); + /* Check whether the surface was resized by wayland_egl */ + surface->rotation = rotation; +} + +static int +__cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, + void *private) +{ + int rotation_capability = WL_EGL_WINDOW_CAPABILITY_NONE; + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + tpl_surface_t *surface = (tpl_surface_t *)private; + if (TPL_TRUE == surface->rotation_capability) + rotation_capability = WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED; + else + rotation_capability = WL_EGL_WINDOW_CAPABILITY_ROTATION_UNSUPPORTED; + + return rotation_capability; +} + + void __cb_resistry_global_callback(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, diff --git a/src/wayland-egl/wayland-egl-priv.h b/src/wayland-egl/wayland-egl-priv.h index da25be9..3c284fc 100644 --- a/src/wayland-egl/wayland-egl-priv.h +++ b/src/wayland-egl/wayland-egl-priv.h @@ -13,6 +13,7 @@ extern "C" { #endif #include +#include struct wl_egl_window { struct wl_surface *surface; @@ -25,8 +26,12 @@ struct wl_egl_window { int attached_width; int attached_height; + wl_egl_window_rotation rotation; + void *private; void (*resize_callback)(struct wl_egl_window *, void *); + void (*rotate_callback)(struct wl_egl_window *, void *); + int (*get_rotation_capability)(struct wl_egl_window *, void *); }; #ifdef __cplusplus diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index f577bcc..77e8e22 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -1,7 +1,6 @@ #include #include -#include "wayland-egl.h" #include "wayland-egl-priv.h" #define WL_EGL_DEBUG 1 @@ -98,6 +97,7 @@ wl_egl_window_create(struct wl_surface *surface, wl_egl_window_resize(egl_window, width, height, 0, 0); egl_window->attached_width = 0; egl_window->attached_height = 0; + egl_window->rotation = ROTATION_0; WL_EGL_LOG(2, "surf:%10p WxH:%dx%d egl_win:%10p priv:%10p", surface, width, height, egl_window, egl_window->private); @@ -131,3 +131,66 @@ wl_egl_window_get_attached_size(struct wl_egl_window *egl_window, egl_window, width, height, egl_window->attached_width, egl_window->attached_height); } + +WL_EGL_EXPORT void +wl_egl_window_set_rotation(struct wl_egl_window *egl_window, + wl_egl_window_rotation rotation) +{ + int resize = 0; + + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + if (egl_window->rotation == rotation) { + WL_EGL_ERR("rotation value is same"); + return; + } + + switch (rotation) { + case ROTATION_0: + case ROTATION_180: + if (egl_window->rotation == ROTATION_90 || egl_window->rotation == ROTATION_270) + resize = 1; + break; + case ROTATION_90: + case ROTATION_270: + if (egl_window->rotation == ROTATION_0 || egl_window->rotation == ROTATION_180) + resize = 1; + break; + default: + WL_EGL_ERR("Invalid rotation value"); + return; + } + + WL_EGL_LOG(2, "egl_win:%10p prev_rotation:%d curr_rotation: %d", + egl_window, egl_window->rotation, rotation); + + egl_window->rotation = rotation; + + if (egl_window->rotate_callback) + egl_window->rotate_callback(egl_window, egl_window->private); + + if (resize) { + wl_egl_window_resize(egl_window, egl_window->height, egl_window->width, + egl_window->dx, egl_window->dy); + } +} + +WL_EGL_EXPORT int +wl_egl_window_get_capabilities(struct wl_egl_window *egl_window) +{ + int capabilities = WL_EGL_WINDOW_CAPABILITY_NONE; + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return capabilities; + } + + if (egl_window->get_rotation_capability) + capabilities = egl_window->get_rotation_capability(egl_window, egl_window->private); + else + capabilities = WL_EGL_WINDOW_CAPABILITY_ROTATION_UNKNOWN; + + return capabilities; +} -- 2.7.4