From 64d1c724c4cb0ff9a70fa9e1dc92f4fee2878bfe Mon Sep 17 00:00:00 2001 From: "Wonsik, Jung" Date: Tue, 12 Dec 2017 18:47:52 +0900 Subject: [PATCH] EvasGL: Add PreRotation Add PreRotation feature for Evas GL's direct rendering @TIZEN_ONLY Change-Id: I7548a8f7ec516aebc30df64cc2216dcb1dcd41a0 --- .../evas/engines/gl_common/evas_gl_common.h | 4 + src/modules/evas/engines/gl_common/evas_gl_core.c | 10 ++ .../evas/engines/gl_common/evas_gl_core_private.h | 4 + src/modules/evas/engines/gl_drm/evas_engine.c | 1 + src/modules/evas/engines/gl_sdl/evas_engine.c | 1 + src/modules/evas/engines/gl_tbm/evas_engine.c | 2 - src/modules/evas/engines/gl_x11/evas_engine.c | 1 + src/modules/evas/engines/wayland_egl/evas_engine.c | 115 ++++++++++++++++++++- src/modules/evas/engines/wayland_egl/evas_engine.h | 25 +++++ .../evas/engines/wayland_egl/evas_wl_main.c | 24 +++++ 10 files changed, 184 insertions(+), 3 deletions(-) diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 7b8189f..08acdf0 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -392,6 +392,10 @@ struct _Evas_Engine_GL_Context GLuint preserve_bit; int gles_version; + + //TIZEN_ONLY(20161121) + // If set, the driver will rotate the buffer itself + Eina_Bool pre_rotated : 1; }; struct _Evas_GL_Texture_Pool diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c index bcd286b..a899965 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -1650,6 +1650,16 @@ try_again: // Extra flags for render thread // TIZEN_ONLY(20171114) : EvasGL Render Thread sfc->thread_rendering = !!(cfg->options_bits & EVAS_GL_OPTIONS_THREAD); + //TIZEN_ONLY(20161121) + // Pre-rotation should be enabled only when direct rendering is set but client side rotation is not set + if ((sfc->direct_fb_opt) && + (!sfc->client_side_rotation) && + (evgl_engine->funcs->native_win_prerotation_set)) + { + if (!evgl_engine->funcs->native_win_prerotation_set(eng_data)) + DBG("Prerotation does not work"); + } + // cfg_index = i; break; diff --git a/src/modules/evas/engines/gl_common/evas_gl_core_private.h b/src/modules/evas/engines/gl_common/evas_gl_core_private.h index 8b8aaec..582fcf8 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h @@ -354,6 +354,10 @@ struct _EVGL_Interface // Check native window surface config for Evas GL Direct Rendering void (*native_win_surface_config_get)(void *data, int *win_depth, int *win_stencil, int *win_msaa); + //TIZEN_ONLY(20161121) Support PreRotation + int (*native_win_prerotation_set)(void *data); + + // TIZEN_ONLY(20171206) : Disable Partial Rendering On EvasGL // partial rendering enable void (*partial_rendering_enable)(); diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c index d294d41..e3419d9 100755 --- a/src/modules/evas/engines/gl_drm/evas_engine.c +++ b/src/modules/evas/engines/gl_drm/evas_engine.c @@ -119,6 +119,7 @@ static const EVGL_Interface evgl_funcs = NULL, // OpenGL-ES 1 NULL, // OpenGL-ES 1 NULL, // native_win_surface_config_get + NULL, // native_win_prerotation_set NULL, //partial_rendering_enable NULL, //partial_rendering_disable }; diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index c7c64d8..e6a968d 100755 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -259,6 +259,7 @@ static const EVGL_Interface evgl_funcs = NULL, // OpenGL-ES 1 NULL, // OpenGL-ES 1 NULL, // native_win_surface_config_get + NULL, // native_win_prerotation_set NULL, //partial_rendering_enable NULL, //partial_rendering_disable }; diff --git a/src/modules/evas/engines/gl_tbm/evas_engine.c b/src/modules/evas/engines/gl_tbm/evas_engine.c index 882ec41..5c1f716 100755 --- a/src/modules/evas/engines/gl_tbm/evas_engine.c +++ b/src/modules/evas/engines/gl_tbm/evas_engine.c @@ -896,9 +896,7 @@ static const EVGL_Interface evgl_funcs = NULL, // OpenGL-ES 1 NULL, // OpenGL-ES 1 evgl_eng_native_win_surface_config_get, -#if 0 NULL, // native_win_prerotation_set -#endif NULL, //partial_rendering_enable NULL, //partial_rendering_disable }; diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 50ee951..c13b0c3 100755 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -1261,6 +1261,7 @@ static const EVGL_Interface evgl_funcs = evgl_eng_indirect_surface_destroy, evgl_eng_gles_context_create, evgl_eng_native_win_surface_config_get, + NULL, // native_win_prerotation_set NULL, //partial_rendering_enable NULL, //partial_rendering_disable }; diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index 7139c6a..dbd0c5c 100755 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -76,6 +76,14 @@ unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGL unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL; unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, void *b, EGLint c, EGLint *d) = NULL; +//TIZEN_ONLY(20161121) : Support PreRotation +//////////////////////////////////// +//libwayland-client.so.0 +static void *wl_client_lib_handle = NULL; +wl_egl_win_get_capabilities glsym_wl_egl_win_get_capabilities = NULL; +wl_egl_win_set_rotation glsym_wl_egl_win_set_rotation = NULL; +// + /* local variables */ static Eina_Bool initted = EINA_FALSE; static int gl_wins = 0; @@ -185,6 +193,38 @@ eng_gl_symbols(EGLDisplay edsp) done = EINA_TRUE; } +//TIZEN_ONLY(20161121) : Support PreRotation +static void +pre_rotation_symbols(void) +{ + static Eina_Bool init_pre_rotation_syms = EINA_FALSE; + if (init_pre_rotation_syms) return; + init_pre_rotation_syms = EINA_TRUE; + +#ifdef GL_GLES + const char *wayland_egl_lib = LIBDIR"/libwayland-egl.so.1"; + wl_client_lib_handle = dlopen(wayland_egl_lib, RTLD_NOW); + if (!wl_client_lib_handle) + { + ERR("Unable to open libtbm: %s", dlerror()); + return; + } + +#define FIND_EGL_WL_SYM(dst, sym, typ) \ + if (!dst) dst = (typ)dlsym(wl_client_lib_handle, sym); \ + if (!dst) \ + { \ + ERR("Symbol not found %s\n", sym); \ + return; \ + } + + FIND_EGL_WL_SYM(glsym_wl_egl_win_set_rotation, "wl_egl_window_set_rotation", glsym_func_void); + FIND_EGL_WL_SYM(glsym_wl_egl_win_get_capabilities, "wl_egl_window_get_capabilities", glsym_func_int); + +#undef FIND_EGL_WL_SYM +#endif +} + static void gl_extn_veto(Render_Engine *re) { @@ -263,6 +303,43 @@ _re_winfree(Render_Engine *re) eng_window_unsurf(ob); } +//TIZEN_ONLY(20161121) : Support PreRotation +static void +_evas_native_win_pre_rotation_set(struct wl_egl_window *win, int angle) +{ + evas_wl_egl_window_rotation rot; + if (!win) return; + if (!glsym_wl_egl_win_set_rotation) + { + ERR("Not supported PreRotation"); + return; + } + + switch (angle) + { + case 270: + rot = EVAS_ROTATION_90; + break; + case 180: + rot = EVAS_ROTATION_180; + break; + case 90: + rot = EVAS_ROTATION_270; + break; + case 0: + rot = EVAS_ROTATION_0; + break; + default: + rot = EVAS_ROTATION_0; + break; + } + + if (glsym_wl_egl_win_set_rotation) + { + glsym_wl_egl_win_set_rotation(win, rot); + } +} + static void * evgl_eng_display_get(void *data) { @@ -589,6 +666,29 @@ evgl_eng_pbuffer_surface_destroy(void *data, void *surface) return 1; } +//TIZEN_ONLY(20161121) : Support PreRotation +static int +evgl_eng_native_win_prerotation_set(void *data) +{ + Render_Engine *re = data; + if (!re) return 0; + if (!(eng_get_ob(re)->support_pre_rotation)) return 0; + if (eng_get_ob(re)->gl_context->pre_rotated) return 0; + + _evas_native_win_pre_rotation_set(eng_get_ob(re)->win, eng_get_ob(re)->info->info.rotation); + + // re->win's h & w are not modified + eng_get_ob(re)->rot = 0; + + /* There maybe bad frame due to mismatch of surface and + * window size if orientation changes in the middle of + * rendering pipeline, therefore recreate the surface. + */ + eng_get_ob(re)->gl_context->pre_rotated = EINA_TRUE; + + return 1; +} + // TIZEN_ONLY(20171206) : Disable Partial Rendering On EvasGL static void evgl_eng_partial_rendering_enable() @@ -625,6 +725,7 @@ static const EVGL_Interface evgl_funcs = NULL, // OpenGL-ES 1 NULL, // OpenGL-ES 1 NULL, // native_win_surface_config_get + evgl_eng_native_win_prerotation_set, evgl_eng_partial_rendering_enable, evgl_eng_partial_rendering_disable, }; @@ -818,8 +919,16 @@ eng_output_update(void *engine EINA_UNUSED, void *data, void *info, unsigned int gl_wins++; } else if ((ob->w != (int)w) || (ob->h != (int)h) || - (ob->info->info.rotation != ob->rot)) + (ob->info->info.rotation != ob->rot) || + (ob->gl_context->pre_rotated)) { + //TIZEN_ONLY(20161121) : Support PreRotation + if (ob->support_pre_rotation && ob->gl_context->pre_rotated) + { + ob->gl_context->pre_rotated = EINA_FALSE; + evgl_eng_native_win_prerotation_set(re); + } + eng_outbuf_reconfigure(ob, w, h, ob->info->info.rotation, 0); } @@ -1550,6 +1659,10 @@ module_open(Evas_Module *em) evas_gl_thread_link_init(); symbols(); + //TIZEN_ONLY(20161121) : Support PreRotation + pre_rotation_symbols(); + // + /* advertise out which functions we support */ em->functions = (void *)(&func); diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.h b/src/modules/evas/engines/wayland_egl/evas_engine.h index f5aedbb..951c053 100755 --- a/src/modules/evas/engines/wayland_egl/evas_engine.h +++ b/src/modules/evas/engines/wayland_egl/evas_engine.h @@ -91,6 +91,9 @@ struct _Outbuf int depth_bits; int stencil_bits; int msaa_bits; + + //TIZEN_ONLY(20161121) : Support PreRotation + int support_pre_rotation; }; struct _Context_3D @@ -153,4 +156,26 @@ _re_wincheck(Outbuf *ob) return 0; } +enum evas_wl_egl_window_capability_rotation { + EVAS_WL_EGL_WINDOW_CAPABILITY_NONE = 0, + EVAS_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED = (1 << 0), + EVAS_WL_EGL_WINDOW_CAPABILITY_ROTATION_UNSUPPORTED = (1 << 1), + EVAS_WL_EGL_WINDOW_CAPABILITY_ROTATION_UNKNOWN = (1 << 2), +}; + +typedef enum { + EVAS_ROTATION_0 = 0, + EVAS_ROTATION_90 = 90, + EVAS_ROTATION_180 = 180, + EVAS_ROTATION_270 = 270 +} evas_wl_egl_window_rotation; + +//TIZEN_ONLY(20161121) : Support PreRotation +typedef int (*wl_egl_win_get_capabilities) (struct wl_egl_window *egl_window); +typedef void (*wl_egl_win_set_rotation) (struct wl_egl_window *egl_window, int rotation); + +extern wl_egl_win_get_capabilities glsym_wl_egl_win_get_capabilities; +extern wl_egl_win_set_rotation glsym_wl_egl_win_set_rotation; +// + #endif diff --git a/src/modules/evas/engines/wayland_egl/evas_wl_main.c b/src/modules/evas/engines/wayland_egl/evas_wl_main.c index 206cafd..51da9de 100755 --- a/src/modules/evas/engines/wayland_egl/evas_wl_main.c +++ b/src/modules/evas/engines/wayland_egl/evas_wl_main.c @@ -118,6 +118,10 @@ eng_window_new(Evas_Engine_Info_Wayland *einfo, int w, int h, Render_Output_Swap gw->stencil_bits = einfo->stencil_bits; gw->msaa_bits = einfo->msaa_bits; // +//TIZEN_ONLY(20161121):Support PreRotation + gw->support_pre_rotation = 0; +// + context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; context_attrs[1] = 2; context_attrs[2] = EGL_NONE; @@ -225,6 +229,26 @@ eng_window_new(Evas_Engine_Info_Wayland *einfo, int w, int h, Render_Output_Swap } // TIZEN_ONLY(20171123) +//TIZEN_ONLY(20161121):Support PreRotation + if (!getenv("EVAS_GL_PREROTATION_DISABLE") && glsym_wl_egl_win_get_capabilities) + { + int prerotation_cap = EVAS_WL_EGL_WINDOW_CAPABILITY_NONE; + prerotation_cap = glsym_wl_egl_win_get_capabilities(gw->win); + if (prerotation_cap == EVAS_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED) + { + gw->support_pre_rotation = 1; + } + else + { + gw->support_pre_rotation = 0; + } + } + else + { + DBG("PreRotation is invalid!!"); + } +//TIZEN_ONLY(20161121) + context = _tls_context_get(); gw->egl_context = GL_TH(eglCreateContext, gw->egl_disp, gw->egl_config, context, context_attrs); -- 2.7.4