AM_CONDITIONAL(HAVE_WAYLAND_ONLY, [test "x${have_wayland_only}" = xyes])
if test "x${have_wayland_only}" = "xyes"; then
- PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, dlog, wayland-server, screenshooter-server, tizen-extension-server, wayland-tbm-server, libtbm, libtdm, libpng, pixman-1, eom-server])
+ PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, dlog, wayland-server, tizen-extension-server])
PKG_CHECK_MODULES(WAYLAND_SCANNER, wayland-scanner)
else
PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, dlog, x11, utilX])
BuildRequires: pkgconfig(enlightenment)
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(ttrace)
-BuildRequires: pkgconfig(libtbm)
-BuildRequires: pkgconfig(libtdm)
-BuildRequires: pkgconfig(libpng)
-BuildRequires: pkgconfig(pixman-1)
BuildRequires: pkgconfig(wayland-server)
-BuildRequires: pkgconfig(screenshooter-server)
BuildRequires: pkgconfig(tizen-extension-server)
-BuildRequires: pkgconfig(wayland-tbm-server)
BuildRequires: pkgconfig(cynara-client)
BuildRequires: pkgconfig(cynara-creds-socket)
-BuildRequires: pkgconfig(eom-server)
+
%global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share}
pkg_LTLIBRARIES = module.la
module_la_SOURCES = \
e_mod_main.c \
- e_devicemgr_output.c \
e_devicemgr_input.c \
- e_devicemgr_scale.c \
e_devicemgr_conf.c
if HAVE_WAYLAND_ONLY
module_la_SOURCES += \
- e_devicemgr_dpms.c \
- e_devicemgr_screenshooter.c \
- e_devicemgr_video.c \
- e_devicemgr_viewport.c \
- e_devicemgr_tdm.c \
- e_devicemgr_buffer.c \
e_devicemgr_embedded_compositor.c \
- e_devicemgr_device.c \
- e_devicemgr_eom.c
+ e_devicemgr_device.c
endif
module_la_LIBADD =
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define E_COMP_WL
-#include <sys/mman.h>
-#include <e.h>
-#include <Ecore_Drm.h>
-#include <pixman.h>
-#include <png.h>
-#include <tdm_helper.h>
-#include "e_mod_main.h"
-#include "e_devicemgr_privates.h"
-#include "e_devicemgr_tdm.h"
-#include "e_devicemgr_buffer.h"
-
-//#define DEBUG_LIFECYCLE
-
-#define PNG_DEPTH 8
-
-#define BER(fmt,arg...) ERR("%d: "fmt, mbuf ? mbuf->stamp : 0, ##arg)
-#define BWR(fmt,arg...) WRN("%d: "fmt, mbuf ? mbuf->stamp : 0, ##arg)
-#define BIN(fmt,arg...) INF("%d: "fmt, mbuf ? mbuf->stamp : 0, ##arg)
-#define BDB(fmt,arg...) DBG("%d: "fmt, mbuf ? mbuf->stamp : 0, ##arg)
-
-#define MBUF_RETURN_IF_FAIL(cond) \
- {if (!(cond)) { BER("'%s' failed. (%s)", #cond, func); return; }}
-#define MBUF_RETURN_VAL_IF_FAIL(cond, val) \
- {if (!(cond)) { BER("'%s' failed. (%s)", #cond, func); return val; }}
-
-#ifdef DEBUG_LIFECYCLE
-#undef BDB
-#define BDB BIN
-#endif
-
-typedef struct _MBufFreeFuncInfo
-{
- MBuf_Free_Func func;
- void *data;
-} MBufFreeFuncInfo;
-
-static void _e_devmgr_buffer_cb_destroy(struct wl_listener *listener, void *data);
-static void _e_devmgr_buffer_free(E_Devmgr_Buf *mbuf, const char *func);
-#define e_devmgr_buffer_free(b) _e_devmgr_buffer_free(b,__FUNCTION__)
-
-static Eina_List *mbuf_lists;
-
-static E_Devmgr_Buf*
-_find_mbuf(uint stamp)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l;
-
- if (!mbuf_lists)
- return NULL;
-
- EINA_LIST_FOREACH(mbuf_lists, l, mbuf)
- {
- if (mbuf->stamp == stamp)
- return mbuf;
- }
-
- return NULL;
-}
-
-static tbm_bo
-_handle_to_bo(uint handle)
-{
- struct drm_gem_flink arg = {0,};
- tbm_bo bo;
-
- arg.handle = handle;
- if (drmIoctl(e_devmgr_dpy->drm_fd, DRM_IOCTL_GEM_FLINK, &arg))
- {
- ERR("failed flink id (gem:%d)\n", handle);
- return NULL;
- }
-
- bo = tbm_bo_import(e_devmgr_dpy->bufmgr, arg.name);
- if (!bo)
- {
- ERR("failed import (gem:%d, name:%d)\n", handle, arg.name);
- return NULL;
- }
-
- return bo;
-}
-
-static Eina_Bool
-_e_devicemgr_buffer_access_data_begin(E_Devmgr_Buf *mbuf)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, EINA_FALSE);
-
- mbuf->ptrs[0] = mbuf->ptrs[1] = mbuf->ptrs[2] = NULL;
-
- if (mbuf->type == TYPE_SHM)
- {
- struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(mbuf->resource);
- EINA_SAFETY_ON_NULL_RETURN_VAL(shm_buffer, EINA_FALSE);
- mbuf->ptrs[0] = wl_shm_buffer_get_data(shm_buffer);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf->ptrs[0], EINA_FALSE);
- return EINA_TRUE;
- }
- else if (mbuf->type == TYPE_TBM)
- {
- int i, j;
- tbm_bo bos[4] = {0,};
-
- for (i = 0; i < 3; i++)
- {
- tbm_bo_handle bo_handles;
-
- bos[i] = tbm_surface_internal_get_bo(mbuf->tbm_surface, i);
- if (!bos[i]) continue;
-
- bo_handles = tbm_bo_map(bos[i], TBM_DEVICE_CPU, TBM_OPTION_READ);
- if (!bo_handles.ptr)
- {
- for (j = 0; j < i; j++)
- tbm_bo_unmap(bos[j]);
- return EINA_FALSE;
- }
-
- mbuf->ptrs[i] = bo_handles.ptr;
- }
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf->ptrs[0], EINA_FALSE);
-
- switch(mbuf->tbmfmt)
- {
- case TBM_FORMAT_YVU420:
- case TBM_FORMAT_YUV420:
- if (!mbuf->ptrs[1])
- mbuf->ptrs[1] = mbuf->ptrs[0];
- if (!mbuf->ptrs[2])
- mbuf->ptrs[2] = mbuf->ptrs[1];
- break;
- case TBM_FORMAT_NV12:
- case TBM_FORMAT_NV21:
- if (!mbuf->ptrs[1])
- mbuf->ptrs[1] = mbuf->ptrs[0];
- break;
- default:
- break;
- }
-
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
-static void
-_e_devicemgr_buffer_access_data_end(E_Devmgr_Buf *mbuf)
-{
- EINA_SAFETY_ON_NULL_RETURN(mbuf);
-
- if (mbuf->type == TYPE_SHM)
- {
- mbuf->ptrs[0] = NULL;
- }
- else if (mbuf->type == TYPE_TBM)
- {
- int i;
- tbm_bo bos[4] = {0,};
-
- for (i = 0; i < 3; i++)
- {
- bos[i] = tbm_surface_internal_get_bo(mbuf->tbm_surface, i);
- if (!bos[i]) continue;
-
- tbm_bo_unmap(bos[i]);
- mbuf->ptrs[i] = NULL;
- }
- }
-}
-
-static E_Devmgr_Buf*
-_e_devmgr_buffer_create_res(struct wl_resource *resource, const char *func)
-{
- E_Devmgr_Buf *mbuf = NULL;
- struct wl_shm_buffer *shm_buffer;
- tbm_surface_h tbm_surface;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(resource, NULL);
-
- mbuf = calloc(1, sizeof(E_Devmgr_Buf));
- EINA_SAFETY_ON_FALSE_GOTO(mbuf != NULL, create_fail);
-
- mbuf->ref_cnt = 1;
- mbuf->stamp = e_devmgr_buffer_get_mills();
- while (_find_mbuf(mbuf->stamp))
- mbuf->stamp++;
- mbuf->func = strdup(func);
-
- mbuf->resource = resource;
-
- if ((shm_buffer = wl_shm_buffer_get(resource)))
- {
- uint32_t tbmfmt = wl_shm_buffer_get_format(shm_buffer);
-
- mbuf->type = TYPE_SHM;
-
- if (tbmfmt == WL_SHM_FORMAT_ARGB8888)
- mbuf->tbmfmt = TBM_FORMAT_ARGB8888;
- else if (tbmfmt == WL_SHM_FORMAT_XRGB8888)
- mbuf->tbmfmt = TBM_FORMAT_XRGB8888;
- else
- mbuf->tbmfmt = tbmfmt;
-
- mbuf->width = wl_shm_buffer_get_width(shm_buffer);
- mbuf->height = wl_shm_buffer_get_height(shm_buffer);
- mbuf->pitches[0] = wl_shm_buffer_get_stride(shm_buffer);
-
- mbuf->width_from_pitch = mbuf->width;
- mbuf->height_from_size = mbuf->height;;
- }
- else if ((tbm_surface = wayland_tbm_server_get_surface(e_comp->wl_comp_data->tbm.server, resource)))
- {
- int i;
-
- mbuf->type = TYPE_TBM;
- mbuf->tbm_surface = tbm_surface;
- tbm_surface_internal_ref(tbm_surface);
-
- mbuf->tbmfmt = tbm_surface_get_format(tbm_surface);
- mbuf->width = tbm_surface_get_width(tbm_surface);
- mbuf->height = tbm_surface_get_height(tbm_surface);
-
- for (i = 0; i < 3; i++)
- {
- uint32_t size = 0, offset = 0, pitch = 0;
- tbm_bo bo;
-
- bo = tbm_surface_internal_get_bo(tbm_surface, i);
- if (bo)
- {
- mbuf->handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
- EINA_SAFETY_ON_FALSE_GOTO(mbuf->handles[i] > 0, create_fail);
-
- mbuf->names[i] = tbm_bo_export(bo);
- EINA_SAFETY_ON_FALSE_GOTO(mbuf->names[i] > 0, create_fail);
- }
-
- tbm_surface_internal_get_plane_data(tbm_surface, i, &size, &offset, &pitch);
- mbuf->pitches[i] = pitch;
- mbuf->offsets[i] = offset;
- }
-
- tdm_helper_get_buffer_full_size(tbm_surface, &mbuf->width_from_pitch, &mbuf->height_from_size);
- }
- else
- {
- ERR("unknown buffer resource");
- goto create_fail;
- }
-
- mbuf_lists = eina_list_append(mbuf_lists, mbuf);
-
- BDB("type(%d) %dx%d(%dx%d), %c%c%c%c, name(%d,%d,%d) hnd(%d,%d,%d), pitch(%d,%d,%d), offset(%d,%d,%d): %s",
- mbuf->type, mbuf->width_from_pitch, mbuf->height_from_size,
- mbuf->width, mbuf->height, FOURCC_STR(mbuf->tbmfmt),
- mbuf->names[0], mbuf->names[1], mbuf->names[2],
- mbuf->handles[0], mbuf->handles[1], mbuf->handles[2],
- mbuf->pitches[0], mbuf->pitches[1], mbuf->pitches[2],
- mbuf->offsets[0], mbuf->offsets[1], mbuf->offsets[2],
- func);
-
- return mbuf;
-
-create_fail:
- e_devmgr_buffer_free(mbuf);
-
- return NULL;
-}
-
-E_Devmgr_Buf*
-_e_devmgr_buffer_create(struct wl_resource *resource, const char *func)
-{
- E_Devmgr_Buf *mbuf = _e_devmgr_buffer_create_res(resource, func);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, NULL);
-
- mbuf->destroy_listener.notify = _e_devmgr_buffer_cb_destroy;
- wl_resource_add_destroy_listener(resource, &mbuf->destroy_listener);
-
- return mbuf;
-}
-
-E_Devmgr_Buf*
-_e_devmgr_buffer_create_comp(E_Comp_Wl_Buffer *comp_buffer, const char *func)
-{
- E_Devmgr_Buf *mbuf;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(comp_buffer, NULL);
-
- mbuf = _e_devmgr_buffer_create_res(comp_buffer->resource, func);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, NULL);
-
- mbuf->comp_buffer = comp_buffer;
-
- mbuf->destroy_listener.notify = _e_devmgr_buffer_cb_destroy;
- wl_resource_add_destroy_listener(comp_buffer->resource, &mbuf->destroy_listener);
-
- return mbuf;
-}
-
-E_Devmgr_Buf*
-_e_devmgr_buffer_create_tbm(tbm_surface_h tbm_surface, const char *func)
-{
- E_Devmgr_Buf *mbuf;
- int i;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
-
- mbuf = calloc(1, sizeof(E_Devmgr_Buf));
- EINA_SAFETY_ON_FALSE_GOTO(mbuf != NULL, create_fail);
-
- mbuf->ref_cnt = 1;
- mbuf->stamp = e_devmgr_buffer_get_mills();
- while (_find_mbuf(mbuf->stamp))
- mbuf->stamp++;
- mbuf->func = strdup(func);
-
- mbuf->type = TYPE_TBM;
- mbuf->tbm_surface = tbm_surface;
- tbm_surface_internal_ref(tbm_surface);
-
- mbuf->tbmfmt = tbm_surface_get_format(tbm_surface);
- mbuf->width = tbm_surface_get_width(tbm_surface);
- mbuf->height = tbm_surface_get_height(tbm_surface);
-
- for (i = 0; i < 3; i++)
- {
- uint32_t size = 0, offset = 0, pitch = 0;
- tbm_bo bo;
-
- bo = tbm_surface_internal_get_bo(tbm_surface, i);
- if (bo)
- {
- mbuf->handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
- EINA_SAFETY_ON_FALSE_GOTO(mbuf->handles[i] > 0, create_fail);
-
- mbuf->names[i] = tbm_bo_export(bo);
- EINA_SAFETY_ON_FALSE_GOTO(mbuf->names[i] > 0, create_fail);
- }
-
- tbm_surface_internal_get_plane_data(tbm_surface, i, &size, &offset, &pitch);
- mbuf->pitches[i] = pitch;
- mbuf->offsets[i] = offset;
- }
-
- tdm_helper_get_buffer_full_size(tbm_surface, &mbuf->width_from_pitch, &mbuf->height_from_size);
-
- mbuf_lists = eina_list_append(mbuf_lists, mbuf);
-
- BDB("type(%d) %dx%d(%dx%d), %c%c%c%c, name(%d,%d,%d) hnd(%d,%d,%d), pitch(%d,%d,%d), offset(%d,%d,%d): %s",
- mbuf->type, mbuf->width_from_pitch, mbuf->height_from_size,
- mbuf->width, mbuf->height, FOURCC_STR(mbuf->tbmfmt),
- mbuf->names[0], mbuf->names[1], mbuf->names[2],
- mbuf->handles[0], mbuf->handles[1], mbuf->handles[2],
- mbuf->pitches[0], mbuf->pitches[1], mbuf->pitches[2],
- mbuf->offsets[0], mbuf->offsets[1], mbuf->offsets[2],
- func);
-
- return mbuf;
-
-create_fail:
- e_devmgr_buffer_free(mbuf);
-
- return NULL;
-}
-
-E_Devmgr_Buf*
-_e_devmgr_buffer_create_hnd(uint handle, int width, int height, int pitch, const char *func)
-{
- E_Devmgr_Buf *mbuf = NULL;
- tbm_surface_h tbm_surface;
- tbm_surface_info_s info = {0,};
- tbm_bo bo = NULL;
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL(handle > 0, NULL);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(width > 0, NULL);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(height > 0, NULL);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(pitch > 0, NULL);
-
- mbuf = calloc(1, sizeof(E_Devmgr_Buf));
- EINA_SAFETY_ON_NULL_GOTO(mbuf, create_fail);
-
- mbuf->ref_cnt = 1;
- mbuf->stamp = e_devmgr_buffer_get_mills();
- while (_find_mbuf(mbuf->stamp))
- mbuf->stamp++;
- mbuf->func = strdup(func);
-
- bo = _handle_to_bo(handle);
- EINA_SAFETY_ON_NULL_GOTO(bo, create_fail);
-
- info.width = width;
- info.height = height;
- info.format = TBM_FORMAT_ARGB8888;
- info.bpp = tbm_surface_internal_get_bpp(info.format);
- info.num_planes = 1;
- info.planes[0].stride = pitch;
-
- tbm_surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
- EINA_SAFETY_ON_NULL_GOTO(tbm_surface, create_fail);
-
- mbuf->type = TYPE_TBM;
- mbuf->tbm_surface = tbm_surface;
-
- mbuf->tbmfmt = info.format;
- mbuf->width = info.width;
- mbuf->height = info.height;
- mbuf->pitches[0] = info.planes[0].stride;
- mbuf->handles[0] = handle;
-
- mbuf->width_from_pitch = mbuf->pitches[0]>>2;
-
- mbuf->names[0] = tbm_bo_export(bo);
- EINA_SAFETY_ON_FALSE_GOTO(mbuf->names[0] > 0, create_fail);
-
- tbm_bo_unref(bo);
-
- mbuf_lists = eina_list_append(mbuf_lists, mbuf);
-
- BDB("type(%d) %dx%d %c%c%c%c nm(%d,%d,%d) hnd(%d,%d,%d) pitch(%d,%d,%d) offset(%d,%d,%d): %s",
- mbuf->type, mbuf->width, mbuf->height, FOURCC_STR(mbuf->tbmfmt),
- mbuf->names[0], mbuf->names[1], mbuf->names[2],
- mbuf->handles[0], mbuf->handles[1], mbuf->handles[2],
- mbuf->pitches[0], mbuf->pitches[1], mbuf->pitches[2],
- mbuf->offsets[0], mbuf->offsets[1], mbuf->offsets[2],
- func);
-
- return mbuf;
-
-create_fail:
- if (bo)
- tbm_bo_unref(bo);
- e_devmgr_buffer_free(mbuf);
- return NULL;
-}
-
-E_Devmgr_Buf*
-_e_devmgr_buffer_alloc(int width, int height, tbm_format tbmfmt, Eina_Bool scanout, const char *func)
-{
- E_Devmgr_Buf *mbuf = NULL;
- tbm_surface_h tbm_surface = NULL;
- int i;
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL(width > 0, NULL);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(height > 0, NULL);
-
- mbuf = calloc(1, sizeof(E_Devmgr_Buf));
- EINA_SAFETY_ON_FALSE_GOTO(mbuf != NULL, alloc_fail);
-
- mbuf->ref_cnt = 1;
- mbuf->stamp = e_devmgr_buffer_get_mills();
- while (_find_mbuf(mbuf->stamp))
- mbuf->stamp++;
- mbuf->func = strdup(func);
-
- if (scanout)
- tbm_surface = tbm_surface_internal_create_with_flags(width, height, tbmfmt, TBM_BO_SCANOUT);
- else
- tbm_surface = tbm_surface_internal_create_with_flags(width, height, tbmfmt, TBM_BO_DEFAULT);
- EINA_SAFETY_ON_NULL_GOTO(tbm_surface, alloc_fail);
-
- mbuf->type = TYPE_TBM;
- mbuf->tbm_surface = tbm_surface;
- tbm_surface_internal_ref(tbm_surface);
-
- mbuf->tbmfmt = tbmfmt;
- mbuf->width = width;
- mbuf->height = height;
-
- for (i = 0; i < 3; i++)
- {
- uint32_t size = 0, offset = 0, pitch = 0;
- tbm_bo bo;
-
- bo = tbm_surface_internal_get_bo(tbm_surface, i);
- if (bo)
- {
- mbuf->handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
- EINA_SAFETY_ON_FALSE_GOTO(mbuf->handles[i] > 0, alloc_fail);
-
- mbuf->names[i] = tbm_bo_export(bo);
- EINA_SAFETY_ON_FALSE_GOTO(mbuf->names[i] > 0, alloc_fail);
- }
-
- tbm_surface_internal_get_plane_data(tbm_surface, i, &size, &offset, &pitch);
- mbuf->pitches[i] = pitch;
- mbuf->offsets[i] = offset;
- }
-
- tdm_helper_get_buffer_full_size(tbm_surface, &mbuf->width_from_pitch, &mbuf->height_from_size);
-
- tbm_surface_internal_unref(tbm_surface);
-
- mbuf_lists = eina_list_append(mbuf_lists, mbuf);
-
- BDB("type(%d) %dx%d(%dx%d) %c%c%c%c nm(%d,%d,%d) hnd(%d,%d,%d) pitch(%d,%d,%d) offset(%d,%d,%d): %s",
- mbuf->type, mbuf->width_from_pitch, mbuf->height_from_size,
- mbuf->width, mbuf->height, FOURCC_STR(mbuf->tbmfmt),
- mbuf->names[0], mbuf->names[1], mbuf->names[2],
- mbuf->handles[0], mbuf->handles[1], mbuf->handles[2],
- mbuf->pitches[0], mbuf->pitches[1], mbuf->pitches[2],
- mbuf->offsets[0], mbuf->offsets[1], mbuf->offsets[2],
- func);
-
- return mbuf;
-
-alloc_fail:
- if (tbm_surface)
- tbm_surface_internal_unref(tbm_surface);
- e_devmgr_buffer_free(mbuf);
- return NULL;
-}
-
-E_Devmgr_Buf*
-_e_devmgr_buffer_ref(E_Devmgr_Buf *mbuf, const char *func)
-{
- if (!mbuf)
- return NULL;
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL(MBUF_IS_VALID(mbuf), NULL);
-
- mbuf->ref_cnt++;
- BDB("count(%d) ref: %s", mbuf->ref_cnt, func);
-
- return mbuf;
-}
-
-void
-_e_devmgr_buffer_unref(E_Devmgr_Buf *mbuf, const char *func)
-{
- if (!mbuf)
- return;
-
- MBUF_RETURN_IF_FAIL(_e_devmgr_buffer_valid(mbuf, func));
-
- mbuf->ref_cnt--;
- BDB("count(%d) unref: %s", mbuf->ref_cnt, func);
-
- if (!mbuf->buffer_destroying && mbuf->ref_cnt == 0)
- _e_devmgr_buffer_free(mbuf, func);
-}
-
-static void
-_e_devmgr_buffer_free(E_Devmgr_Buf *mbuf, const char *func)
-{
- MBufFreeFuncInfo *info;
- Eina_List *l, *ll;
-
- if (!mbuf)
- return;
-
- MBUF_RETURN_IF_FAIL(_e_devmgr_buffer_valid(mbuf, func));
-
- BDB("mbuf(%p) tbm_surface(%p) freed: %s", mbuf, mbuf->tbm_surface, func);
-
- mbuf->buffer_destroying = EINA_TRUE;
-
- if (mbuf->destroy_listener.notify)
- {
- wl_list_remove(&mbuf->destroy_listener.link);
- mbuf->destroy_listener.notify = NULL;
- }
-
- EINA_LIST_FOREACH_SAFE(mbuf->free_funcs, l, ll, info)
- {
- /* call before tmb_bo_unref */
- mbuf->free_funcs = eina_list_remove_list(mbuf->free_funcs, l);
- if (info->func)
- info->func(mbuf, info->data);
- free(info);
- }
-
-#if 0
- /* DO not check ref_count here. Even if ref_count is not 0, mbuf can be
- * be destroyed by wl_buffer_destroy forcely. video or screenmirror should add
- * the mbuf free function and handle the destroying mbuf situation.
- */
- if (!mbuf->buffer_destroying)
- MBUF_RETURN_IF_FAIL(mbuf->ref_cnt == 0);
-#endif
-
- /* make sure all operation is done */
- MBUF_RETURN_IF_FAIL(mbuf->in_use == EINA_FALSE);
-
- if (mbuf->type == TYPE_TBM && mbuf->tbm_surface)
- {
- tbm_surface_internal_unref(mbuf->tbm_surface);
- mbuf->tbm_surface = NULL;
- }
-
- mbuf_lists = eina_list_remove(mbuf_lists, mbuf);
-
- mbuf->stamp = 0;
-
- if (mbuf->func)
- {
- free(mbuf->func);
- }
-
- free(mbuf);
-}
-
-static void
-_e_devmgr_buffer_cb_destroy(struct wl_listener *listener, void *data)
-{
- E_Devmgr_Buf *mbuf = container_of(listener, E_Devmgr_Buf, destroy_listener);
-
- if (!mbuf) return;
-
- mbuf->comp_buffer = NULL;
-
- if (mbuf->buffer_destroying == EINA_FALSE)
- {
- mbuf->destroy_listener.notify = NULL;
- e_devmgr_buffer_free(mbuf);
- }
-}
-
-void
-e_devmgr_buffer_clear(E_Devmgr_Buf *mbuf)
-{
- EINA_SAFETY_ON_NULL_RETURN(mbuf);
-
- if (!_e_devicemgr_buffer_access_data_begin(mbuf))
- {
- BER("can't access ptr");
- return;
- }
-
- switch(mbuf->tbmfmt)
- {
- case TBM_FORMAT_ARGB8888:
- case TBM_FORMAT_XRGB8888:
- memset(mbuf->ptrs[0], 0, mbuf->pitches[0] * mbuf->height);
- break;
- case TBM_FORMAT_YVU420:
- case TBM_FORMAT_YUV420:
- memset((char*)mbuf->ptrs[0] + mbuf->offsets[0], 0x10, mbuf->pitches[0] * mbuf->height);
- memset((char*)mbuf->ptrs[1] + mbuf->offsets[1], 0x80, mbuf->pitches[1] * (mbuf->height >> 1));
- memset((char*)mbuf->ptrs[2] + mbuf->offsets[2], 0x80, mbuf->pitches[2] * (mbuf->height >> 1));
- break;
- case TBM_FORMAT_NV12:
- case TBM_FORMAT_NV21:
- memset((char*)mbuf->ptrs[0] + mbuf->offsets[0], 0x10, mbuf->pitches[0] * mbuf->height);
- memset((char*)mbuf->ptrs[1] + mbuf->offsets[1], 0x80, mbuf->pitches[1] * (mbuf->height >> 1));
- break;
- case TBM_FORMAT_YUYV:
- {
- int *ibuf = (int*)mbuf->ptrs[0];
- int i, size = mbuf->pitches[0] * mbuf->height / 4;
-
- for (i = 0 ; i < size ; i++)
- ibuf[i] = 0x10801080;
- }
- break;
- case TBM_FORMAT_UYVY:
- {
- int *ibuf = (int*)mbuf->ptrs[0];
- int i, size = mbuf->pitches[0] * mbuf->height / 4;
-
- for (i = 0 ; i < size ; i++)
- ibuf[i] = 0x80108010; /* YUYV -> 0xVYUY */
- }
- break;
- default:
- BWR("can't clear %c%c%c%c buffer", FOURCC_STR(mbuf->tbmfmt));
- break;
- }
-
- _e_devicemgr_buffer_access_data_end(mbuf);
-}
-
-Eina_Bool
-_e_devmgr_buffer_valid(E_Devmgr_Buf *mbuf, const char *func)
-{
- E_Devmgr_Buf *temp;
- Eina_List *l;
-
- MBUF_RETURN_VAL_IF_FAIL(mbuf != NULL, EINA_FALSE);
- MBUF_RETURN_VAL_IF_FAIL(mbuf->stamp != 0, EINA_FALSE);
-
- EINA_LIST_FOREACH(mbuf_lists, l, temp)
- {
- if (temp->stamp == mbuf->stamp)
- return EINA_TRUE;
- }
-
- BDB("mbuf(%p) invalid", mbuf);
-
- return EINA_FALSE;
-}
-
-static MBufFreeFuncInfo*
-_e_devmgr_buffer_free_func_find(E_Devmgr_Buf *mbuf, MBuf_Free_Func func, void *data)
-{
- MBufFreeFuncInfo *info;
- Eina_List *l;
-
- EINA_LIST_FOREACH(mbuf->free_funcs, l, info)
- {
- if (info->func == func && info->data == data)
- return info;
- }
-
- return NULL;
-}
-
-void
-e_devmgr_buffer_free_func_add(E_Devmgr_Buf *mbuf, MBuf_Free_Func func, void *data)
-{
- MBufFreeFuncInfo *info;
-
- EINA_SAFETY_ON_FALSE_RETURN(MBUF_IS_VALID(mbuf));
- EINA_SAFETY_ON_NULL_RETURN(func);
-
- info = _e_devmgr_buffer_free_func_find(mbuf, func, data);
- if (info)
- return;
-
- info = calloc(1, sizeof(MBufFreeFuncInfo));
- EINA_SAFETY_ON_NULL_RETURN(info);
-
- info->func = func;
- info->data = data;
-
- mbuf->free_funcs = eina_list_append(mbuf->free_funcs, info);
-}
-
-void
-e_devmgr_buffer_free_func_del(E_Devmgr_Buf *mbuf, MBuf_Free_Func func, void *data)
-{
- MBufFreeFuncInfo *info;
-
- EINA_SAFETY_ON_FALSE_RETURN(MBUF_IS_VALID(mbuf));
- EINA_SAFETY_ON_NULL_RETURN(func);
-
- info = _e_devmgr_buffer_free_func_find(mbuf, func, data);
- if (!info)
- return;
-
- mbuf->free_funcs = eina_list_remove(mbuf->free_funcs, info);
-
- free(info);
-}
-
-static pixman_format_code_t
-_e_devmgr_buffer_pixman_format_get(E_Devmgr_Buf *mbuf)
-{
- switch(mbuf->tbmfmt)
- {
- case TBM_FORMAT_ARGB8888:
- return PIXMAN_a8r8g8b8;
- case TBM_FORMAT_XRGB8888:
- return PIXMAN_x8r8g8b8;
- default:
- return 0;
- }
- return 0;
-}
-
-void
-e_devmgr_buffer_convert(E_Devmgr_Buf *srcbuf, E_Devmgr_Buf *dstbuf,
- int sx, int sy, int sw, int sh,
- int dx, int dy, int dw, int dh,
- Eina_Bool over, int rotate, int hflip, int vflip)
-{
- pixman_image_t *src_img = NULL, *dst_img = NULL;
- pixman_format_code_t src_format, dst_format;
- double scale_x, scale_y;
- int rotate_step;
- pixman_transform_t t;
- struct pixman_f_transform ft;
- pixman_op_t op;
- int src_stride, dst_stride;
- int buf_width;
-
- EINA_SAFETY_ON_FALSE_RETURN(MBUF_IS_VALID(srcbuf));
- EINA_SAFETY_ON_FALSE_RETURN(MBUF_IS_VALID(dstbuf));
-
- if (!_e_devicemgr_buffer_access_data_begin(srcbuf))
- return;
- if (!_e_devicemgr_buffer_access_data_begin(dstbuf))
- {
- _e_devicemgr_buffer_access_data_end(srcbuf);
- return;
- }
-
- /* not handle buffers which have 2 more gem handles */
- EINA_SAFETY_ON_NULL_GOTO(srcbuf->ptrs[0], cant_convert);
- EINA_SAFETY_ON_NULL_GOTO(dstbuf->ptrs[0], cant_convert);
- EINA_SAFETY_ON_FALSE_RETURN(!srcbuf->ptrs[1]);
- EINA_SAFETY_ON_FALSE_RETURN(!dstbuf->ptrs[1]);
-
- src_format = _e_devmgr_buffer_pixman_format_get(srcbuf);
- EINA_SAFETY_ON_FALSE_GOTO(src_format > 0, cant_convert);
- dst_format = _e_devmgr_buffer_pixman_format_get(dstbuf);
- EINA_SAFETY_ON_FALSE_GOTO(dst_format > 0, cant_convert);
-
- buf_width = IS_RGB(srcbuf->tbmfmt)?(srcbuf->pitches[0]/4):srcbuf->pitches[0];
- src_stride = IS_RGB(srcbuf->tbmfmt)?(srcbuf->pitches[0]):buf_width * (PIXMAN_FORMAT_BPP(src_format) / 8);
- src_img = pixman_image_create_bits(src_format, buf_width, srcbuf->height,
- (uint32_t*)srcbuf->ptrs[0], src_stride);
- EINA_SAFETY_ON_NULL_GOTO(src_img, cant_convert);
-
- buf_width = IS_RGB(dstbuf->tbmfmt)?(dstbuf->pitches[0]/4):dstbuf->pitches[0];
- dst_stride = IS_RGB(srcbuf->tbmfmt)?(dstbuf->pitches[0]):buf_width * (PIXMAN_FORMAT_BPP(dst_format) / 8);
- dst_img = pixman_image_create_bits(dst_format, buf_width, dstbuf->height,
- (uint32_t*)dstbuf->ptrs[0], dst_stride);
- EINA_SAFETY_ON_NULL_GOTO(dst_img, cant_convert);
-
- pixman_f_transform_init_identity(&ft);
-
- if (hflip)
- {
- pixman_f_transform_scale(&ft, NULL, -1, 1);
- pixman_f_transform_translate(&ft, NULL, dw, 0);
- }
-
- if (vflip)
- {
- pixman_f_transform_scale(&ft, NULL, 1, -1);
- pixman_f_transform_translate(&ft, NULL, 0, dh);
- }
-
- rotate_step = (rotate + 360) / 90 % 4;
- if (rotate_step > 0)
- {
- int c, s, tx = 0, ty = 0;
- switch (rotate_step)
- {
- case 1:
- c = 0, s = -1, tx = -dw;
- break;
- case 2:
- c = -1, s = 0, tx = -dw, ty = -dh;
- break;
- case 3:
- c = 0, s = 1, ty = -dh;
- break;
- }
- pixman_f_transform_translate(&ft, NULL, tx, ty);
- pixman_f_transform_rotate(&ft, NULL, c, s);
- }
-
- if (rotate_step % 2 == 0)
- {
- scale_x = (double)sw / dw;
- scale_y = (double)sh / dh;
- }
- else
- {
- scale_x = (double)sw / dh;
- scale_y = (double)sh / dw;
- }
-
- pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
- pixman_f_transform_translate(&ft, NULL, sx, sy);
- pixman_transform_from_pixman_f_transform(&t, &ft);
- pixman_image_set_transform(src_img, &t);
-
- if (!over) op = PIXMAN_OP_SRC;
- else op = PIXMAN_OP_OVER;
-
- pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0,
- dx, dy, dw, dh);
-cant_convert:
- if (src_img) pixman_image_unref(src_img);
- if (dst_img) pixman_image_unref(dst_img);
-
- _e_devicemgr_buffer_access_data_end(srcbuf);
- _e_devicemgr_buffer_access_data_end(dstbuf);
-}
-
-Eina_Bool
-e_devmgr_buffer_copy(E_Devmgr_Buf *srcbuf, E_Devmgr_Buf *dstbuf)
-{
- int i, j, c_height;
- unsigned char *s, *d;
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL(MBUF_IS_VALID(srcbuf), EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(MBUF_IS_VALID(dstbuf), EINA_FALSE);
-
- if (!_e_devicemgr_buffer_access_data_begin(srcbuf))
- return EINA_FALSE;
- if (!_e_devicemgr_buffer_access_data_begin(dstbuf))
- {
- _e_devicemgr_buffer_access_data_end(srcbuf);
- return EINA_FALSE;
- }
-
- switch (srcbuf->tbmfmt)
- {
- case TBM_FORMAT_ARGB8888:
- case TBM_FORMAT_XRGB8888:
- case TBM_FORMAT_YUV422:
- case TBM_FORMAT_YVU422:
- s = (unsigned char*)srcbuf->ptrs[0];
- d = (unsigned char*)dstbuf->ptrs[0];
- for (i = 0; i < srcbuf->height; i++)
- {
- memcpy(d, s, srcbuf->pitches[0]);
- s += srcbuf->pitches[0];
- d += dstbuf->pitches[0];
- }
- break;
- case TBM_FORMAT_YUV420:
- case TBM_FORMAT_YVU420:
- for (i = 0; i < 3; i++)
- {
- s = (unsigned char*)srcbuf->ptrs[i] + srcbuf->offsets[i];
- d = (unsigned char*)dstbuf->ptrs[i] + dstbuf->offsets[i];
- c_height = (i == 0) ? srcbuf->height : srcbuf->height / 2;
- for (j = 0; j < c_height; j++)
- {
- memcpy(d, s, srcbuf->pitches[i]);
- s += srcbuf->pitches[i];
- d += dstbuf->pitches[i];
- }
- }
- break;
- case TBM_FORMAT_NV12:
- case TBM_FORMAT_NV21:
- for (i = 0; i < 2; i++)
- {
- s = (unsigned char*)srcbuf->ptrs[i] + srcbuf->offsets[i];
- d = (unsigned char*)dstbuf->ptrs[i] + dstbuf->offsets[i];
- c_height = (i == 0) ? srcbuf->height : srcbuf->height / 2;
- for (j = 0; j < c_height; j++)
- {
- memcpy(d, s, srcbuf->pitches[i]);
- s += srcbuf->pitches[i];
- d += dstbuf->pitches[i];
- }
- }
- break;
- default:
- ERR("not implemented for %c%c%c%c", FOURCC_STR(srcbuf->tbmfmt));
- _e_devicemgr_buffer_access_data_end(srcbuf);
- _e_devicemgr_buffer_access_data_end(dstbuf);
-
- return EINA_FALSE;
- }
-
- _e_devicemgr_buffer_access_data_end(srcbuf);
- _e_devicemgr_buffer_access_data_end(dstbuf);
-
- return EINA_TRUE;
-}
-
-typedef struct _ColorTable
-{
- tbm_format tbmfmt;
- E_Devmgr_Buf_Color_Type type;
-} ColorTable;
-
-static ColorTable color_table[] =
-{
- { TBM_FORMAT_ARGB8888, TYPE_RGB },
- { TBM_FORMAT_XRGB8888, TYPE_RGB },
- { TBM_FORMAT_YVU420, TYPE_YUV420 },
- { TBM_FORMAT_YUV420, TYPE_YUV420 },
- { TBM_FORMAT_NV12MT, TYPE_YUV420 },
- { TBM_FORMAT_NV12, TYPE_YUV420 },
- { TBM_FORMAT_NV21, TYPE_YUV420 },
- { TBM_FORMAT_YUYV, TYPE_YUV422 },
- { TBM_FORMAT_UYVY, TYPE_YUV422 },
-};
-
-E_Devmgr_Buf_Color_Type
-e_devmgr_buffer_color_type(tbm_format tbmfmt)
-{
- int i, size;
-
- size = sizeof(color_table) / sizeof(ColorTable);
-
- for (i = 0; i < size; i++)
- if (color_table[i].tbmfmt == tbmfmt)
- return color_table[i].type;
-
- return TYPE_NONE;
-}
-
-static void
-_dump_raw(const char * file, void *data1, int size1, void *data2, int size2, void *data3, int size3)
-{
- unsigned int * blocks;
- FILE * fp = fopen(file, "w+");
- EINA_SAFETY_ON_NULL_RETURN(fp);
-
- blocks = (unsigned int*)data1;
- fwrite(blocks, 1, size1, fp);
-
- if (size2 > 0)
- {
- blocks = (unsigned int*)data2;
- fwrite(blocks, 1, size2, fp);
- }
-
- if (size3 > 0)
- {
- blocks = (unsigned int*)data3;
- fwrite(blocks, 1, size3, fp);
- }
-
- fclose(fp);
-}
-
-static void
-_dump_png(const char* file, const void * data, int width, int height)
-{
- FILE *fp = fopen(file, "wb");
- EINA_SAFETY_ON_NULL_RETURN(fp);
-
- png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!pPngStruct)
- {
- fclose(fp);
- return;
- }
-
- png_infop pPngInfo = png_create_info_struct(pPngStruct);
- if (!pPngInfo)
- {
- png_destroy_write_struct(&pPngStruct, NULL);
- fclose(fp);
- return;
- }
-
- png_init_io(pPngStruct, fp);
- png_set_IHDR(pPngStruct,
- pPngInfo,
- width,
- height,
- PNG_DEPTH,
- PNG_COLOR_TYPE_RGBA,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT);
-
- png_set_bgr(pPngStruct);
- png_write_info(pPngStruct, pPngInfo);
-
- const int pixel_size = 4; // RGBA
- png_bytep *row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
-
- unsigned int* blocks = (unsigned int*)data;
- int y = 0;
- int x = 0;
-
- for (; y < height; ++y)
- {
- png_bytep row = png_malloc(pPngStruct, sizeof(png_byte)*width * pixel_size);
- row_pointers[y] = (png_bytep)row;
- for (x = 0; x < width; ++x)
- {
- unsigned int curBlock = blocks[y * width + x];
- row[x * pixel_size] = (curBlock & 0xFF);
- row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
- row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
- row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
- }
- }
-
- png_write_image(pPngStruct, row_pointers);
- png_write_end(pPngStruct, pPngInfo);
-
- for (y = 0; y < height; y++)
- png_free(pPngStruct, row_pointers[y]);
- png_free(pPngStruct, row_pointers);
-
- png_destroy_write_struct(&pPngStruct, &pPngInfo);
-
- fclose(fp);
-}
-
-void
-e_devmgr_buffer_dump(E_Devmgr_Buf *mbuf, const char *prefix, int nth, Eina_Bool raw)
-{
- char path[128];
- const char *dir = "/tmp/dump";
-
- if (!mbuf) return;
-
- if (!_e_devicemgr_buffer_access_data_begin(mbuf))
- {
- BER("can't access ptr");
- return;
- }
-
- if (IS_RGB(mbuf->tbmfmt))
- snprintf(path, sizeof(path), "%s/%s_%c%c%c%c_%dx%d_%03d.%s", dir, prefix,
- FOURCC_STR(mbuf->tbmfmt), mbuf->width_from_pitch, mbuf->height,
- nth, raw?"raw":"png");
- else
- snprintf(path, sizeof(path), "%s/%s_%c%c%c%c_%dx%d_%03d.yuv", dir, prefix,
- FOURCC_STR(mbuf->tbmfmt), mbuf->pitches[0], mbuf->height, nth);
-
- BDB("dump %s", path);
-
- switch(mbuf->tbmfmt)
- {
- case TBM_FORMAT_ARGB8888:
- case TBM_FORMAT_XRGB8888:
- if (raw)
- _dump_raw(path, mbuf->ptrs[0], mbuf->pitches[0] * mbuf->height, NULL, 0, NULL, 0);
- else
- _dump_png(path, mbuf->ptrs[0], mbuf->width_from_pitch, mbuf->height);
- break;
- case TBM_FORMAT_YVU420:
- case TBM_FORMAT_YUV420:
- _dump_raw(path,
- (char*)mbuf->ptrs[0] + mbuf->offsets[0], mbuf->pitches[0] * mbuf->height,
- (char*)mbuf->ptrs[1] + mbuf->offsets[1], mbuf->pitches[1] * (mbuf->height >> 1),
- (char*)mbuf->ptrs[2] + mbuf->offsets[2], mbuf->pitches[2] * (mbuf->height >> 1));
- break;
- case TBM_FORMAT_NV12:
- case TBM_FORMAT_NV21:
- _dump_raw(path,
- (char*)mbuf->ptrs[0] + mbuf->offsets[0], mbuf->pitches[0] * mbuf->height,
- (((char*)mbuf->ptrs[1]) + mbuf->offsets[1]), mbuf->pitches[1] * (mbuf->height >> 1),
- NULL, 0);
- break;
- case TBM_FORMAT_YUYV:
- case TBM_FORMAT_UYVY:
- _dump_raw(path,
- (char*)mbuf->ptrs[0] + mbuf->offsets[0], mbuf->pitches[0] * mbuf->height,
- NULL, 0,
- NULL, 0);
- break;
- default:
- BWR("can't clear %c%c%c%c buffer", FOURCC_STR(mbuf->tbmfmt));
- break;
- }
-
- _e_devicemgr_buffer_access_data_end(mbuf);
-}
-
-uint
-e_devmgr_buffer_get_mills(void)
-{
- struct timespec tp;
-
- clock_gettime(CLOCK_MONOTONIC, &tp);
-
- return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
-}
-
-int
-e_devmgr_buffer_list_length(void)
-{
- return eina_list_count(mbuf_lists);
-}
-
-void
-e_devmgr_buffer_list_print(const char *log_path)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l;
- FILE *log_fl;
-
- log_fl = fopen(log_path, "a");
- if (!log_fl)
- {
- ERR("failed: open file(%s)", log_path);
- return;
- }
-
- setvbuf(log_fl, NULL, _IOLBF, 512);
-
- fprintf(log_fl, "* Devicemgr Buffers:\n");
- fprintf(log_fl, "stamp\tsize\tformat\thandles\tpitches\toffsets\tcreator\tin_use\n");
- EINA_LIST_FOREACH(mbuf_lists, l, mbuf)
- {
- fprintf(log_fl, "%d\t%dx%d\t%c%c%c%c\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%s\t%d\n",
- mbuf->stamp, mbuf->width, mbuf->height, FOURCC_STR(mbuf->tbmfmt),
- mbuf->handles[0], mbuf->handles[1], mbuf->handles[2],
- mbuf->pitches[0], mbuf->pitches[1], mbuf->pitches[2],
- mbuf->offsets[0], mbuf->offsets[1], mbuf->offsets[2],
- mbuf->func, mbuf->in_use);
- }
-
- fclose(log_fl);
-}
-
-void
-e_devmgr_buffer_size_get(E_Client *ec, int *bw, int *bh)
-{
- E_Comp_Wl_Buffer *buffer = e_pixmap_resource_get(ec->pixmap);
-
- *bw = *bh = 0;
-
- if (!buffer)
- {
- INF("no buffer. using ec(%p) size(%dx%d)", ec, ec->w, ec->h);
- *bw = ec->w;
- *bh = ec->h;
- return;
- }
-
- if (buffer->type == E_COMP_WL_BUFFER_TYPE_VIDEO)
- {
- tbm_surface_h tbm_surface = wayland_tbm_server_get_surface(NULL, buffer->resource);
-
- *bw = tbm_surface_get_width(tbm_surface);
- *bh = tbm_surface_get_height(tbm_surface);
- }
- else
- {
- *bw = buffer->w;
- *bh = buffer->h;
- }
-}
-
-void
-e_devmgr_buffer_transform_scale_size_get(E_Client *ec, int *bw, int *bh)
-{
- E_Comp_Wl_Buffer *buffer = e_pixmap_resource_get(ec->pixmap);
- E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
- int w, h, transform;
-
- *bw = *bh = 0;
-
- if (!buffer)
- {
- INF("no buffer. using ec(%p) size(%dx%d)", ec, ec->w, ec->h);
- *bw = ec->w;
- *bh = ec->h;
- return;
- }
-
- if (buffer->type == E_COMP_WL_BUFFER_TYPE_VIDEO)
- {
- tbm_surface_h tbm_surface = wayland_tbm_server_get_surface(NULL, buffer->resource);
-
- w = tbm_surface_get_width(tbm_surface);
- h = tbm_surface_get_height(tbm_surface);
- }
- else
- {
- w = buffer->w;
- h = buffer->h;
- }
-
- transform = e_comp_wl_output_buffer_transform_get(ec);
-
- switch (transform)
- {
- case WL_OUTPUT_TRANSFORM_90:
- case WL_OUTPUT_TRANSFORM_270:
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- *bw = h / vp->buffer.scale;
- *bh = w / vp->buffer.scale;
- break;
- default:
- *bw = w / vp->buffer.scale;
- *bh = h / vp->buffer.scale;
- break;
- }
-}
+++ /dev/null
-#ifndef __E_DEVICEMGR_BUFFER_H__
-#define __E_DEVICEMGR_BUFFER_H__
-
-#define E_COMP_WL
-#include <e.h>
-#include <e_comp_wl_tbm.h>
-#include <wayland-tbm-server.h>
-#include <tizen-extension-server-protocol.h>
-#include <tdm.h>
-#include "e_devicemgr_tdm.h"
-#include "e_devicemgr_privates.h"
-
-typedef enum _E_Devmgr_Buf_Type
-{
- TYPE_SHM,
- TYPE_TBM,
-} E_Devmgr_Buf_Type;
-
-typedef struct _E_Devmgr_Buf
-{
- /* to manage lifecycle */
- uint ref_cnt;
-
- /* to check valid */
- uint stamp;
- char *func;
-
- /* to manage wl_resource */
- struct wl_resource *resource;
- struct wl_listener destroy_listener;
-
- Eina_Bool buffer_destroying;
-
- E_Devmgr_Buf_Type type;
- tbm_surface_h tbm_surface;
-
- /* pitch contains the full buffer width.
- * width indicates the content area width.
- */
- tbm_format tbmfmt;
- int width;
- int height;
- uint handles[4];
- uint pitches[4];
- uint offsets[4];
- int names[4];
- void *ptrs[4];
-
- int width_from_pitch;
- int height_from_size;
-
- /* to avoid reading & write at same time */
- Eina_Bool in_use;
-
- Eina_List *free_funcs;
-
- /* for wl_buffer.release event */
- E_Comp_Wl_Buffer *comp_buffer;
- E_Comp_Wl_Buffer_Ref buffer_ref;
- Eina_Rectangle content_r; /* content rect */
- unsigned int content_t; /* content transform */
-} E_Devmgr_Buf;
-
-E_Devmgr_Buf* _e_devmgr_buffer_create (struct wl_resource *resource, const char *func);
-E_Devmgr_Buf* _e_devmgr_buffer_create_comp(E_Comp_Wl_Buffer *comp_buffer, const char *func);
-E_Devmgr_Buf* _e_devmgr_buffer_create_tbm (tbm_surface_h tbm_surface, const char *func);
-E_Devmgr_Buf* _e_devmgr_buffer_create_hnd (uint handle, int width, int height, int pitch, const char *func);
-E_Devmgr_Buf* _e_devmgr_buffer_alloc (int width, int height, tbm_format tbmfmt, Eina_Bool scanout, const char *func);
-E_Devmgr_Buf* _e_devmgr_buffer_ref (E_Devmgr_Buf *mbuf, const char *func);
-void _e_devmgr_buffer_unref (E_Devmgr_Buf *mbuf, const char *func);
-Eina_Bool _e_devmgr_buffer_valid (E_Devmgr_Buf *mbuf, const char *func);
-
-#define e_devmgr_buffer_create(r) _e_devmgr_buffer_create(r,__FUNCTION__)
-#define e_devmgr_buffer_create_comp(c) _e_devmgr_buffer_create_comp(c,__FUNCTION__)
-#define e_devmgr_buffer_create_tbm(t) _e_devmgr_buffer_create_tbm(t,__FUNCTION__)
-#define e_devmgr_buffer_create_hnd(d,w,h,p) _e_devmgr_buffer_create_hnd(d,w,h,p,__FUNCTION__)
-#define e_devmgr_buffer_alloc(w,h,f,s) _e_devmgr_buffer_alloc(w,h,f,s,__FUNCTION__)
-#define e_devmgr_buffer_ref(b) _e_devmgr_buffer_ref(b,__FUNCTION__)
-#define e_devmgr_buffer_unref(b) _e_devmgr_buffer_unref(b,__FUNCTION__)
-#define MBUF_IS_VALID(b) _e_devmgr_buffer_valid(b,__FUNCTION__)
-#define MSTAMP(b) ((b)?(b)->stamp:0)
-
-#define e_devmgr_buffer_set_use(b, v) \
- do { \
- if (b) b->in_use = v; \
- } while (0)
-
-typedef void (*MBuf_Free_Func) (E_Devmgr_Buf *mbuf, void *data);
-void e_devmgr_buffer_free_func_add(E_Devmgr_Buf *mbuf, MBuf_Free_Func func, void *data);
-void e_devmgr_buffer_free_func_del(E_Devmgr_Buf *mbuf, MBuf_Free_Func func, void *data);
-
-void e_devmgr_buffer_clear(E_Devmgr_Buf *mbuf);
-Eina_Bool e_devmgr_buffer_copy(E_Devmgr_Buf *srcbuf, E_Devmgr_Buf *dstbuf);
-void e_devmgr_buffer_convert(E_Devmgr_Buf *srcbuf, E_Devmgr_Buf *dstbuf,
- int sx, int sy, int sw, int sh,
- int dx, int dy, int dw, int dh,
- Eina_Bool over, int rotate, int hflip, int vflip);
-
-/* utility */
-typedef enum
-{
- TYPE_NONE,
- TYPE_RGB,
- TYPE_YUV422,
- TYPE_YUV420,
-} E_Devmgr_Buf_Color_Type;
-
-E_Devmgr_Buf_Color_Type e_devmgr_buffer_color_type(tbm_format tbmfmt);
-void e_devmgr_buffer_dump(E_Devmgr_Buf *mbuf, const char *prefix, int nth, Eina_Bool raw);
-uint e_devmgr_buffer_get_mills(void);
-int e_devmgr_buffer_list_length(void);
-void e_devmgr_buffer_list_print(const char *log_path);
-
-void e_devmgr_buffer_size_get(E_Client *ec, int *bw, int *bh);
-void e_devmgr_buffer_transform_scale_size_get(E_Client *ec, int *bw, int *bh);
-
-#endif
#define D dconfig->conf_edd
E_CONFIG_VAL(D, T, input.button_remap_enable, CHAR);
E_CONFIG_VAL(D, T, input.back_keycode, INT);
- E_CONFIG_VAL(D, T, eom_enable, CHAR);
#undef T
#undef D
+++ /dev/null
-#include <e.h>
-#include <Ecore_Drm.h>
-#include "e_mod_main.h"
-#include "e_devicemgr_privates.h"
-#include "e_devicemgr_dpms.h"
-
-typedef enum _E_Devicemgr_Dpms_Mode
-{
- E_DEVICEMGR_DPMS_MODE_ON = 0,
- E_DEVICEMGR_DPMS_MODE_STANDBY = 1,
- E_DEVICEMGR_DPMS_MODE_SUSPEND = 2,
- E_DEVICEMGR_DPMS_MODE_OFF = 3
-} E_Devicemgr_Dpms_Mode;
-
-#define BUS "org.enlightenment.wm"
-#define PATH "/org/enlightenment/wm"
-#define INTERFACE "org.enlightenment.wm.dpms"
-
-static Ecore_Drm_Output *dpms_output;
-static unsigned int dpms_value;
-
-static Eldbus_Connection *conn;
-static Eldbus_Service_Interface *iface;
-
-static Eldbus_Message *
-_e_devicemgr_dpms_set_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
-{
- Eldbus_Message *reply = eldbus_message_method_return_new(msg);
- unsigned int uint32 = -1;
- int result = -1;
-
- DBG("[devicemgr] got DPMS request");
-
- if (eldbus_message_arguments_get(msg, "u", &uint32) && uint32< 4)
- {
- Ecore_Drm_Device *dev;
- Ecore_Drm_Output *output;
- Eina_List *devs, *l, *ll;
- E_Zone *zone;
- Eina_List *zl;
-
- DBG("[devicemgr] DPMS value: %d", uint32);
-
- devs = eina_list_clone(ecore_drm_devices_get());
- EINA_LIST_FOREACH(devs, l, dev)
- EINA_LIST_FOREACH(dev->outputs, ll, output)
- {
- int x;
- ecore_drm_output_position_get(output, &x, NULL);
-
- EINA_LIST_FOREACH(e_comp->zones, zl, zone)
- {
- if (uint32 == E_DEVICEMGR_DPMS_MODE_ON)
- e_zone_display_state_set(zone, E_ZONE_DISPLAY_STATE_ON);
- else if (uint32 == E_DEVICEMGR_DPMS_MODE_OFF)
- e_zone_display_state_set(zone, E_ZONE_DISPLAY_STATE_OFF);
- }
-
- /* only for main output */
- if (x != 0)
- continue;
-
- DBG("[devicemgr] set DPMS");
-
- dpms_output = output;
- dpms_value = uint32;
- ecore_drm_output_dpms_set(output, uint32);
- }
-
- result = uint32;
- if (devs) eina_list_free(devs);
- }
-
- eldbus_message_arguments_append(reply, "i", result);
-
- return reply;
-}
-
-static Eldbus_Message *
-_e_devicemgr_dpms_get_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
-{
- Eldbus_Message *reply = eldbus_message_method_return_new(msg);
-
- DBG("[devicemgr] got DPMS 'get' request");
-
- eldbus_message_arguments_append(reply, "i", dpms_value);
-
- return reply;
-}
-
-static const Eldbus_Method methods[] = {
- {"set", ELDBUS_ARGS({"u", "uint32"}), ELDBUS_ARGS({"i", "int32"}), _e_devicemgr_dpms_set_cb, 0},
- {"get", NULL, ELDBUS_ARGS({"i", "int32"}), _e_devicemgr_dpms_get_cb, 0},
- {}
-};
-
-static const Eldbus_Service_Interface_Desc iface_desc = {
- INTERFACE, methods, NULL, NULL, NULL, NULL
-};
-
-static void
-_e_devicemgr_dpms_name_request_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
-{
- unsigned int reply;
-
- if (eldbus_message_error_get(msg, NULL, NULL))
- {
- printf("error on on_name_request\n");
- return;
- }
-
- if (!eldbus_message_arguments_get(msg, "u", &reply))
- {
- printf("error geting arguments on on_name_request\n");
- return;
- }
-}
-
-static Eina_Bool
-_e_devicemgr_dpms_dbus_init(void *data)
-{
- if (conn)
- return ECORE_CALLBACK_CANCEL;
-
- if (!conn)
- conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
-
- if (!conn)
- {
- ERR("eldbus_connection_get fail..");
- ecore_timer_add(1.0, _e_devicemgr_dpms_dbus_init, NULL);
- return ECORE_CALLBACK_CANCEL;
- }
-
- INF("eldbus_connection_get success..");
-
- iface = eldbus_service_interface_register(conn, PATH, &iface_desc);
- EINA_SAFETY_ON_NULL_GOTO(iface, failed);
-
- eldbus_name_request(conn, BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
- _e_devicemgr_dpms_name_request_cb, NULL);
-
- return ECORE_CALLBACK_CANCEL;
-failed:
- if (conn)
- {
- eldbus_name_release(conn, BUS, NULL, NULL);
- eldbus_connection_unref(conn);
- conn = NULL;
- }
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-int
-e_devicemgr_dpms_init(void)
-{
- if (eldbus_init() == 0) return 0;
-
- _e_devicemgr_dpms_dbus_init(NULL);
-
- return 1;
-}
-
-void
-e_devicemgr_dpms_fini(void)
-{
- if (iface)
- {
- eldbus_service_interface_unregister(iface);
- iface = NULL;
- }
- if (conn)
- {
- eldbus_name_release(conn, BUS, NULL, NULL);
- eldbus_connection_unref(conn);
- conn = NULL;
- }
-
- eldbus_shutdown();
-}
-
-unsigned int
-e_devicemgr_dpms_get(Ecore_Drm_Output *output)
-{
- if (dpms_output == output)
- return dpms_value;
-
- return DRM_MODE_DPMS_ON;
-}
+++ /dev/null
-#ifndef __E_DEVICEMGR_DPMS_H__
-#define __E_DEVICEMGR_DPMS_H__
-
-#include "e.h"
-#include <Ecore_Drm.h>
-
-int e_devicemgr_dpms_init(void);
-void e_devicemgr_dpms_fini(void);
-
-unsigned int e_devicemgr_dpms_get(Ecore_Drm_Output *output);
-
-#endif
+++ /dev/null
-#include "e.h"
-#include "e_mod_main.h"
-#include "e_devicemgr_privates.h"
-#include "e_devicemgr_buffer.h"
-#include "e_devicemgr_tdm.h"
-#include "e_devicemgr_video.h"
-#include "e_devicemgr_eom.h"
-#include <eom-server-protocol.h>
-#include <Ecore_Drm.h>
-#include <tdm.h>
-#include <eom.h>
-#include <tbm_bufmgr.h>
-#include <tbm_surface.h>
-#include <wayland-tbm-server.h>
-#ifdef FRAMES
-#include <time.h>
-#endif
-
-/*
-#define EOM_DUMP_MIRROR_BUFFERS
-#define EOM_DUMP_PRESENTATION_BUFFERS
-*/
-
-#define ALEN(array) (sizeof(array) / sizeof(array)[0])
-
-#define EOMER(msg, ARG...) ERR("[eom module][ERR] " msg, ##ARG)
-#define EOMWR(msg, ARG...) WRN("[eom module][WRN] " msg, ##ARG)
-#define EOMIN(msg, ARG...) INF("[eom module][INF] " msg, ##ARG)
-#define EOMDB(msg, ARG...) DBG("[eom module][DBG] " msg, ##ARG)
-#define EOMDBG(msg, ARG...) ;
-
-#define EOM_NUM_ATTR 3
-#define EOM_CONNECT_CHECK_TIMEOUT 7.0
-#define EOM_DELAY_CHECK_TIMEOUT 4.0
-#define EOM_ROTATE_DELAY_TIMEOUT 0.4
-
-typedef struct _E_Eom E_Eom, *E_EomPtr;
-typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr;
-typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr;
-typedef struct _E_Eom_Client E_EomClient, *E_EomClientPtr;
-typedef struct _E_Eom_Comp_Object_Intercept_Hook_Data E_EomCompObjectInterceptHookData;
-typedef struct _E_Eom_Output_Buffer E_EomOutputBuffer, *E_EomOutputBufferPtr;
-typedef struct _E_Eom_Buffer E_EomBuffer, *E_EomBufferPtr;
-typedef void(*E_EomEndShowingEventPtr)(E_EomOutputPtr eom_output, tbm_surface_h srfc, void * user_data);
-
-typedef enum {
- NONE,
- MIRROR,
- PRESENTATION,
- WAIT_PRESENTATION, /* It is used for delayed runnig of Presentation mode */
-} E_EomOutputState;
-
-typedef enum {
- ROTATE_NONE,
- ROTATE_INIT,
- ROTATE_PENDING,
- ROTATE_CANCEL,
- ROTATE_DONE
-} E_EomOutputRotate;
-
-struct _E_Eom
-{
- struct wl_global *global;
-
- tdm_display *dpy;
- tbm_bufmgr bufmgr;
- int fd;
-
- unsigned int output_count;
- Eina_List *outputs;
- Eina_List *clients;
- Eina_List *handlers;
- Eina_List *hooks;
- Eina_List *comp_object_intercept_hooks;
-
- /* Internal output data */
- int main_output_state;
- char *main_output_name;
- int width;
- int height;
- char check_first_boot;
- Ecore_Timer *timer;
-
- /* Rotation data */
- int angle; /* 0, 90, 180, 270 */
- E_EomOutputRotate rotate_state;
- E_EomOutput *rotate_output;
- Ecore_Timer *rotate_timer;
-};
-
-struct _E_Eom_Output
-{
- unsigned int id;
- eom_output_type_e type;
- eom_output_mode_e mode;
- unsigned int width;
- unsigned int height;
- unsigned int phys_width;
- unsigned int phys_height;
-
- const char *name;
-
- tdm_output *output;
- tdm_layer *layer;
- tdm_pp *pp;
-
- E_EomOutputState state;
- tdm_output_conn_status status;
- eom_output_attribute_e attribute;
- eom_output_attribute_state_e attribute_state;
- enum wl_eom_status connection;
-
- /* mirror mode data */
- tbm_surface_queue_h pp_queue;
- /* dst surface in current pp process*/
- tbm_surface_h pp_dst_surface;
- /* src surface in current pp process*/
- tbm_surface_h pp_src_surface;
-
- /* output buffers*/
- Eina_List * pending_buff; /* can be deleted any time */
- E_EomOutputBufferPtr wait_buff; /* wait end of commit, can't be deleted */
- E_EomOutputBufferPtr show_buff; /* current showed buffer, can be deleted only after commit event with different buff */
-
- /* If attribute has been set while external output is disconnected
- * then show black screen and wait until EOM client start sending
- * buffers. After expiring of the delay start mirroring */
- Ecore_Timer *delay;
- Ecore_Timer *watchdog;
-};
-
-struct _E_Eom_Client
-{
- struct wl_resource *resource;
- Eina_Bool current;
-
- /* EOM output the client related to */
- int output_id;
- /* E_Client the client related to */
- E_Client *ec;
-};
-
-struct _E_Eom_Output_Buffer
-{
- E_EomOutputPtr eom_output;
- tbm_surface_h tbm_surface;
- E_EomEndShowingEventPtr cb_func;
- void *cb_user_data;
-};
-
-struct _E_Eom_Buffer
-{
- E_Comp_Wl_Buffer *wl_buffer;
- E_Comp_Wl_Buffer_Ref comp_wl_buffer_ref;
-
- /* double reference to avoid sigterm crash */
- E_Comp_Wl_Buffer_Ref comp_wl_buffer_ref_2;
-};
-
-struct _E_Eom_Comp_Object_Intercept_Hook_Data
-{
- E_Client *ec;
- E_Comp_Object_Intercept_Hook *hook;
-};
-
-/*
- * EOM Output Attributes
- * +-----------------+------------+-----------------+------------+
- * | | normal | exclusive_share | exclusive |
- * +-----------------+------------+-----------------+------------+
- * | normal | possible | possible | possible |
- * +-----------------+------------+-----------------+------------+
- * | exclusive_share | impossible | possible | possible |
- * +-----------------+------------+-----------------+------------+
- * | exclusive | impossible | impossible | impossible |
- * +-----------------+------------+-----------------+------------+
- *
- * possible = 1
- * impossible = 0
- */
-static int eom_output_attributes[EOM_NUM_ATTR][EOM_NUM_ATTR] =
-{
- {1, 1, 1},
- {0, 1, 1},
- {0, 0, 0},
-};
-
-static const char *eom_conn_types[] =
-{
- "None", "VGA", "DVI-I", "DVI-D", "DVI-A",
- "Composite", "S-Video", "LVDS", "Component", "DIN",
- "DisplayPort", "HDMI-A", "HDMI-B", "TV", "eDP", "Virtual",
- "DSI",
-};
-
-static E_EomPtr g_eom = NULL;
-
-static void _e_eom_cb_dequeuable(tbm_surface_queue_h queue, void *user_data);
-static void _e_eom_cb_pp(tbm_surface_h surface, void *user_data);
-static E_EomOutputPtr _e_eom_output_get_by_id(int id);
-
-static E_EomOutputBufferPtr
-_e_eom_output_buff_create( E_EomOutputPtr eom_output, tbm_surface_h tbm_surface, E_EomEndShowingEventPtr cb_func, void *cb_user_data)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
- E_EomOutputBufferPtr outbuff = E_NEW(E_EomOutputBuffer, 1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(outbuff, NULL);
-
- EOMDB("Allocate output buffer:%p", outbuff);
-
- outbuff->eom_output = eom_output;
-
- tbm_surface_internal_ref(tbm_surface);
- outbuff->tbm_surface = tbm_surface;
-
- outbuff->cb_func = cb_func;
- outbuff->cb_user_data = cb_user_data;
-
- return outbuff;
-}
-
-static void
-_e_eom_output_buff_delete( E_EomOutputBufferPtr buff)
-{
- if (buff)
- {
- tbm_surface_internal_unref(buff->tbm_surface);
- if (buff->cb_func)
- buff->cb_func(buff->eom_output, buff->tbm_surface, buff->cb_user_data);
- E_FREE(buff);
- }
-}
-
-static E_EomBuffer *
-_e_eom_buffer_create(E_Comp_Wl_Buffer *wl_buffer)
-{
- E_EomBuffer * eom_buffer = E_NEW(E_EomBuffer, 1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(eom_buffer, NULL);
-
- eom_buffer->wl_buffer = wl_buffer;
-
- /* Forbid E sending 'wl_buffer_send_release' event to external clients */
- e_comp_wl_buffer_reference(&eom_buffer->comp_wl_buffer_ref, wl_buffer);
-
- /* double reference to avoid sigterm crash */
- e_comp_wl_buffer_reference(&eom_buffer->comp_wl_buffer_ref_2, wl_buffer);
-
- EOMDB("E_EomBuffer:%p wl_buffer:%p busy:%d", eom_buffer, wl_buffer, wl_buffer->busy);
- return eom_buffer;
-}
-
-static void
-_e_eom_buffer_destroy(E_EomBuffer * eom_buffer)
-{
- EINA_SAFETY_ON_NULL_RETURN(eom_buffer);
-
- EOMDB("wl_buffer:%p busy:%d", eom_buffer->wl_buffer, eom_buffer->wl_buffer->busy);
-
- eom_buffer->wl_buffer = NULL;
-
- e_comp_wl_buffer_reference(&eom_buffer->comp_wl_buffer_ref, NULL);
-
- /* double reference to avoid sigterm crash */
- e_comp_wl_buffer_reference(&eom_buffer->comp_wl_buffer_ref_2, NULL);
-
- E_FREE(eom_buffer);
-}
-
-static inline eom_output_mode_e
-_e_eom_output_state_get_mode(E_EomOutputPtr output)
-{
- if (output == NULL)
- return EOM_OUTPUT_MODE_NONE;
- return output->mode;
-}
-
-static inline void
-_e_eom_output_state_set_mode(E_EomOutputPtr output, eom_output_mode_e mode)
-{
- if (output == NULL)
- return;
- output->mode = mode;
-}
-
-static inline eom_output_attribute_e
-_e_eom_output_state_get_attribute_state(E_EomOutputPtr output)
-{
- if (output == NULL)
- return EOM_OUTPUT_ATTRIBUTE_STATE_NONE;
- return output->attribute_state;
-}
-
-static inline void
-_e_eom_output_attribute_state_set(E_EomOutputPtr output, eom_output_attribute_e attribute_state)
-{
- if (output == NULL)
- return;
- output->attribute_state = attribute_state;
-}
-
-static inline eom_output_attribute_e
-_e_eom_output_state_get_attribute(E_EomOutputPtr output)
-{
- if (output == NULL)
- return EOM_OUTPUT_ATTRIBUTE_NONE;
- return output->attribute;
-}
-
-static inline void
-_e_eom_output_state_set_force_attribute(E_EomOutputPtr output, eom_output_attribute_e attribute)
-{
- if (output == NULL)
- return;
- output->attribute = attribute;
-}
-
-static inline Eina_Bool
-_e_eom_output_state_set_attribute(E_EomOutputPtr output, eom_output_attribute_e attribute)
-{
- if (output == NULL)
- return EINA_FALSE;
-
- if (attribute == EOM_OUTPUT_ATTRIBUTE_NONE || output->attribute == EOM_OUTPUT_ATTRIBUTE_NONE)
- {
- output->attribute = attribute;
- return EINA_TRUE;
- }
-
- if (eom_output_attributes[output->attribute - 1][attribute - 1] == 1)
- {
- output->attribute = attribute;
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
-static inline tdm_output_conn_status
-_e_eom_output_state_get_status(E_EomOutputPtr output)
-{
- if (output == NULL)
- return TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
- return output->status;
-}
-
-static inline void
-_e_eom_output_state_set_status(E_EomOutputPtr output, tdm_output_conn_status status)
-{
- if (output == NULL)
- return;
- output->status = status;
-}
-
-static tdm_layer *
-_e_eom_output_get_layer(E_EomOutputPtr eom_output)
-{
- int i = 0;
- int count = 0;
- tdm_layer *layer = NULL;
- tdm_error err = TDM_ERROR_NONE;
- tdm_layer_capability capa;
- tdm_info_layer layer_info;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(eom_output, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(eom_output->output, NULL);
-
- err = tdm_output_get_layer_count(eom_output->output, &count);
- if (err != TDM_ERROR_NONE)
- {
- EOMDB ("tdm_output_get_layer_count fail(%d)", err);
- return NULL;
- }
-
- for (i = 0; i < count; i++)
- {
- layer = (tdm_layer *)tdm_output_get_layer(eom_output->output, i, &err);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, NULL);
-
- err = tdm_layer_get_capabilities(layer, &capa);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, NULL);
-
- if (capa & TDM_LAYER_CAPABILITY_PRIMARY)
- {
- EOMDB("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d", i);
- break;
- }
- }
-
- memset(&layer_info, 0x0, sizeof(tdm_info_layer));
- layer_info.src_config.size.h = eom_output->width;
- layer_info.src_config.size.v = eom_output->height;
- layer_info.src_config.pos.x = 0;
- layer_info.src_config.pos.y = 0;
- layer_info.src_config.pos.w = eom_output->width;
- layer_info.src_config.pos.h = eom_output->height;
- layer_info.src_config.format = TBM_FORMAT_ARGB8888;
- layer_info.dst_pos.x = 0;
- layer_info.dst_pos.y = 0;
- layer_info.dst_pos.w = eom_output->width;
- layer_info.dst_pos.h = eom_output->height;
- layer_info.transform = TDM_TRANSFORM_NORMAL;
-
- err = tdm_layer_set_info(layer, &layer_info);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, NULL);
-
- return layer;
-}
-
-static tbm_surface_h
-_e_eom_util_get_output_surface(const char *name)
-{
- Ecore_Drm_Output *primary_output = NULL;
- Ecore_Drm_Device *dev;
- const Eina_List *l;
- tbm_surface_h tbm = NULL;
- tdm_output *tdm_output_obj = NULL;
- tdm_layer *layer = NULL;
- tdm_layer_capability capabilities = 0;
- tdm_error err = TDM_ERROR_NONE;
- int count = 0, i = 0;
-
- EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev)
- {
- primary_output = ecore_drm_device_output_name_find(dev, name);
- if (primary_output != NULL)
- break;
- }
-
- if (primary_output == NULL)
- {
- EOMER("Get primary output.(%s)", name);
- EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev)
- {
- primary_output = ecore_drm_output_primary_get(dev);
- if (primary_output != NULL)
- break;
- }
-
- if (primary_output == NULL)
- {
- EOMER("Get primary output.(%s)", name);
- return NULL;
- }
- }
-
- tdm_output_obj = tdm_display_get_output(g_eom->dpy, 0, &err);
- if (tdm_output_obj == NULL || err != TDM_ERROR_NONE)
- {
- EOMER("tdm_display_get_output 0 fail");
- return NULL;
- }
- err = tdm_output_get_layer_count(tdm_output_obj, &count);
- if (err != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_get_layer_count fail");
- return NULL;
- }
-
- for (i = 0; i < count; i++)
- {
- layer = tdm_output_get_layer(tdm_output_obj, i, NULL);
- tdm_layer_get_capabilities(layer, &capabilities);
- if (capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
- {
- tbm = tdm_layer_get_displaying_buffer(layer, &err);
- if (err != TDM_ERROR_NONE)
- {
- EOMER("tdm_layer_get_displaying_buffer fail");
- return NULL;
- }
- break;
- }
- }
-
- return tbm;
-}
-
-static Eina_Bool
-_e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h)
-{
- if (src_w != dst_w)
- return EINA_TRUE;
-
- if (src_h != dst_h)
- return EINA_TRUE;
-
- return EINA_FALSE;
-}
-
-static void
-_e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v,
- int *dst_x, int *dst_y, int *dst_w, int *dst_h)
-{
- double h_ratio, v_ratio;
-
- h_ratio = src_h / dst_size_h;
- v_ratio = src_v / dst_size_v;
-
- if (h_ratio == v_ratio)
- {
- *dst_x = 0;
- *dst_y = 0;
- *dst_w = dst_size_h;
- *dst_h = dst_size_v;
- }
- else if (h_ratio < v_ratio)
- {
- *dst_y = 0;
- *dst_h = dst_size_v;
- *dst_w = dst_size_v * src_h / src_v;
- *dst_x = (dst_size_h - *dst_w) / 2;
- }
- else /* (h_ratio > v_ratio) */
- {
- *dst_x = 0;
- *dst_w = dst_size_h;
- *dst_h = dst_size_h * src_h / src_v;
- *dst_y = (dst_size_v - *dst_h) / 2;
- }
-}
-
-static void
-_e_eom_tbm_buffer_release_mirror_mod(E_EomOutputPtr eom_output, tbm_surface_h surface, void * unused)
-{
- EOMDB("release eom_output:%p, tbm_surface_h:%p data:%p", eom_output, surface, unused);
- tbm_surface_queue_release(eom_output->pp_queue, surface);
-}
-
-static void
-_e_eom_cb_layer_commit(tdm_layer *layer EINA_UNUSED, unsigned int sequence EINA_UNUSED,
- unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED,
- void *user_data)
-{
- E_EomOutputBufferPtr outbuff = NULL;
- E_EomOutputPtr eom_output = NULL;
- tdm_error err = TDM_ERROR_NONE;
-
- EINA_SAFETY_ON_NULL_RETURN(user_data);
- outbuff = (E_EomOutputBufferPtr)user_data;
-
- eom_output = outbuff->eom_output;
- EINA_SAFETY_ON_NULL_RETURN(eom_output);
-
- EOMDB("========================> CM END tbm_buff:%p", outbuff->tbm_surface);
-
- /*it means that eom_output has been canceled*/
- if(eom_output->wait_buff == NULL)
- {
- _e_eom_output_buff_delete(outbuff);
- return;
- }
-
- EINA_SAFETY_ON_FALSE_RETURN(eom_output->wait_buff == outbuff);
-
- EOMDB("commit finish tbm_surface_h:%p", outbuff->tbm_surface);
-
- /* check if show buffer is present */
- if(eom_output->show_buff != NULL)
- {
- EOMDB("delete show buffer tbm_surface_h:%p", eom_output->show_buff->tbm_surface);
- _e_eom_output_buff_delete(eom_output->show_buff);
- eom_output->show_buff = NULL;
- }
-
- /* set wait_buffer as show_buff; */
- EOMDB("set wait_buffer as show_buff tbm_surface_h:%p", outbuff->tbm_surface);
- eom_output->wait_buff = NULL;
- eom_output->show_buff = outbuff;
-
- /* check if pending buffer is present */
- outbuff = eina_list_nth(eom_output->pending_buff, 0);
- if (outbuff != NULL)
- {
- eom_output->pending_buff = eina_list_remove(eom_output->pending_buff, outbuff);
-
- EOMDB("========================> CM- START tbm_buff:%p", outbuff->tbm_surface);
- EOMDB("do commit tdm_output:%p tdm_layer:%p tbm_surface_h:%p", eom_output->output,
- eom_output->layer, outbuff->tbm_surface);
- err = tdm_layer_set_buffer(eom_output->layer, outbuff->tbm_surface);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, error);
-
- err = tdm_layer_commit(eom_output->layer, _e_eom_cb_layer_commit, outbuff);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, error);
-
- eom_output->wait_buff = outbuff;
- }
-
- return;
-
-error:
-
- if (outbuff)
- {
- EOMDB("========================> CM- ENDERR tbm_buff:%p", outbuff);
- _e_eom_output_buff_delete(outbuff);
- }
-}
-
-static Eina_Bool
-_e_eom_output_show(E_EomOutputPtr eom_output, tbm_surface_h tbm_srfc,
- E_EomEndShowingEventPtr cb_func, void *cb_user_data)
-{
- tdm_error err = TDM_ERROR_NONE;
-
- /* create new output buffer */
- E_EomOutputBufferPtr outbuff = _e_eom_output_buff_create(eom_output, tbm_srfc, cb_func, cb_user_data);
- EINA_SAFETY_ON_NULL_RETURN_VAL(outbuff, EINA_FALSE);
-
- /* check if output free to commit */
- if (eom_output->wait_buff == NULL) /* do commit */
- {
- EOMDB("========================> CM START tbm_buff:%p", tbm_srfc);
- EOMDB("do commit tdm_output:%p tdm_layer:%p tbm_surface_h:%p", eom_output->output,
- eom_output->layer, outbuff->tbm_surface);
- err = tdm_layer_set_buffer(eom_output->layer, outbuff->tbm_surface);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, error);
-
- err = tdm_layer_commit(eom_output->layer, _e_eom_cb_layer_commit, outbuff);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, error2);
-
- eom_output->wait_buff = outbuff;
- }
- else /* add to pending queue */
- {
- eom_output->pending_buff = eina_list_append(eom_output->pending_buff , outbuff);
-
- EOMDB("add to pending list tdm_output:%p tdm_layer:%p tbm_surface_h:%p",
- eom_output->output, eom_output->layer, outbuff->tbm_surface);
- }
-
- return EINA_TRUE;
-
-error2:
-
- tdm_layer_unset_buffer(eom_output->layer);
-
-error:
-
- if (outbuff)
- _e_eom_output_buff_delete(outbuff);
- EOMDB("========================> CM ENDERR tbm_buff:%p", tbm_srfc);
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_eom_pp_info_set(E_EomOutputPtr eom_output, tbm_surface_h src, tbm_surface_h dst)
-{
- tdm_error err = TDM_ERROR_NONE;
- tdm_info_pp pp_info;
- int x = 0, y = 0, w = 0, h = 0;
-
- memset(&pp_info, 0, sizeof(tdm_info_pp));
-
- if (g_eom->angle == 0 || g_eom->angle == 180)
- {
- _e_eom_util_calculate_fullsize(g_eom->width, g_eom->height,
- eom_output->width, eom_output->height,
- &x, &y, &w, &h);
- }
- else if (g_eom->angle == 90 || g_eom->angle == 270)
- {
- _e_eom_util_calculate_fullsize(g_eom->height, g_eom->width,
- eom_output->width, eom_output->height,
- &x, &y, &w, &h);
- }
-
- EOMDB("PP: angle:%d", g_eom->angle);
- EOMDB("PP: src:%dx%d, dst:%dx%d", g_eom->width, g_eom->height,
- eom_output->width, eom_output->height);
- EOMDB("PP calculation: x:%d, y:%d, w:%d, h:%d", x, y, w, h);
-
- pp_info.src_config.size.h = g_eom->width;
- pp_info.src_config.size.v = g_eom->height;
- pp_info.src_config.pos.x = 0;
- pp_info.src_config.pos.y = 0;
- pp_info.src_config.pos.w = g_eom->width;
- pp_info.src_config.pos.h = g_eom->height;
- pp_info.src_config.format = TBM_FORMAT_ARGB8888;
-
- pp_info.dst_config.size.h = eom_output->width;
- pp_info.dst_config.size.v = eom_output->height;
- pp_info.dst_config.pos.x = x;
- pp_info.dst_config.pos.y = y;
- pp_info.dst_config.pos.w = w;
- pp_info.dst_config.pos.h = h;
- pp_info.dst_config.format = TBM_FORMAT_ARGB8888;
-
- switch (g_eom->angle)
- {
- case 0:
- pp_info.transform = TDM_TRANSFORM_NORMAL;
- break;
- case 90:
- pp_info.transform = TDM_TRANSFORM_90;
- break;
- case 180:
- pp_info.transform = TDM_TRANSFORM_180;
- break;
- case 270:
- pp_info.transform = TDM_TRANSFORM_270;
- break;
- default:
- EOMDB("Never get here");
- break;
- }
-
- pp_info.sync = 0;
- pp_info.flags = 0;
-
- err = tdm_pp_set_info(eom_output->pp, &pp_info);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, EINA_FALSE);
-
- return EINA_TRUE;
-}
-
-void _e_eom_clear_surfaces(E_EomOutputPtr eom_output, tbm_surface_queue_h queue)
-{
- int num, pitch;
- int i = 0;
- tbm_bo bo;
- tbm_bo_handle hndl;
- tbm_surface_h surface[3];
- tbm_surface_queue_error_e err = TBM_SURFACE_QUEUE_ERROR_NONE;
-
- err = tbm_surface_queue_get_surfaces(queue, surface, &num);
- if (err != TBM_SURFACE_QUEUE_ERROR_NONE)
- {
- EOMDB("get surfaces");
- return;
- }
-
- for (i = 0; i < num; i++)
- {
- /* XXX: should be cleared all the bos of the surface? */
- bo = tbm_surface_internal_get_bo(surface[i], 0);
- if (!bo)
- {
- EOMDB("bo get error");
- return;
- }
-
- hndl = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ | TBM_OPTION_WRITE);
- if (!hndl.ptr)
- {
- EOMDB("handle get error");
- return;
- }
-
- /* TODO: take correct picth */
- pitch = eom_output->width * 4;
- memset(hndl.ptr, 0x00, pitch*eom_output->height);
-
- tbm_bo_unmap(bo);
- }
-}
-
-static E_Client *
-_e_eom_top_visible_ec_get()
-{
- E_Client *ec;
- Evas_Object *o;
- E_Comp_Wl_Client_Data *cdata;
-
- for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
- {
- ec = evas_object_data_get(o, "E_Client");
-
- /* check e_client and skip e_clients not intersects with zone */
- if (!ec) continue;
- if (e_object_is_del(E_OBJECT(ec))) continue;
- if (e_client_util_ignored_get(ec)) continue;
- if (ec->iconic) continue;
- if (ec->visible == 0) continue;
- if (!(ec->visibility.obscured == 0 || ec->visibility.obscured == 1)) continue;
- if (!ec->frame) continue;
- if (!evas_object_visible_get(ec->frame)) continue;
- /* if ec is subsurface, skip this */
- cdata = (E_Comp_Wl_Client_Data *)ec->comp_data;
- if (cdata && cdata->sub.data) continue;
-
- return ec;
- }
-
- return NULL;
-}
-
-static Eina_Bool
-_e_eom_pp_rotate_check()
-{
- E_Client *ec;
-
- ec = _e_eom_top_visible_ec_get();
- if (ec == NULL)
- return EINA_FALSE;
-
- if (g_eom->angle != ec->e.state.rot.ang.curr)
- {
- g_eom->angle = ec->e.state.rot.ang.curr;
- EOMDB("rotate check: rotate angle:%d", g_eom->angle);
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
-static void
-_e_eom_pp_run(E_EomOutputPtr eom_output, Eina_Bool first_run)
-{
- tdm_error tdm_err = TDM_ERROR_NONE;
- tbm_surface_h dst_surface = NULL;
- tbm_surface_h src_surface = NULL;
- Eina_Bool ret = EINA_FALSE;
-
- if (g_eom->main_output_state == 0)
- return;
-
- /* If a client has committed its buffer stop mirror mode */
- if (eom_output->state != MIRROR)
- {
- g_eom->rotate_state = ROTATE_NONE;
- g_eom->rotate_output = NULL;
- return;
- }
-
- if (!eom_output->pp || !eom_output->pp_queue)
- return;
-
- if (g_eom->rotate_state == ROTATE_INIT || g_eom->rotate_state == ROTATE_PENDING)
- {
- g_eom->rotate_output = eom_output;
- if (!first_run)
- return;
- }
-
- if (g_eom->rotate_state == ROTATE_CANCEL)
- g_eom->rotate_state = ROTATE_NONE;
-
- if (tbm_surface_queue_can_dequeue(eom_output->pp_queue, 0) )
- {
- tdm_err = tbm_surface_queue_dequeue(eom_output->pp_queue, &dst_surface);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, error);
-
- EOMDB("============================> PP START tbm_buff:%p", dst_surface);
-
- src_surface = _e_eom_util_get_output_surface(g_eom->main_output_name);
- tdm_err = TDM_ERROR_OPERATION_FAILED;
- EINA_SAFETY_ON_NULL_GOTO(src_surface, error);
-
- /* Is set to TRUE if device has been recently rotated */
- if (g_eom->rotate_state == ROTATE_DONE || first_run || _e_eom_pp_rotate_check())
- {
- g_eom->rotate_state = ROTATE_NONE;
- g_eom->rotate_output = NULL;
-
- /* TODO: it has to be implemented in better way */
- _e_eom_clear_surfaces(eom_output, eom_output->pp_queue);
-
- ret = _e_eom_pp_info_set(eom_output, src_surface, dst_surface);
- EINA_SAFETY_ON_FALSE_GOTO(ret == EINA_TRUE, error);
- }
-
- tdm_err = tdm_buffer_add_release_handler(dst_surface, _e_eom_cb_pp, eom_output);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, error);
-
- eom_output->pp_dst_surface = dst_surface;
- tbm_surface_internal_ref(dst_surface);
- eom_output->pp_src_surface = src_surface;
- tbm_surface_internal_ref(src_surface);
- tdm_err = tdm_pp_attach(eom_output->pp, src_surface, dst_surface);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, error);
-
- tdm_err = tdm_pp_commit(eom_output->pp);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, error);
-
- EOMDB("do pp commit tdm_output:%p tbm_surface_h(src:%p dst:%p)", eom_output->output, src_surface, dst_surface);
- }
- else
- {
- EOMDB("all pp buffers are busy, wait release queue");
- tbm_surface_queue_add_dequeuable_cb(eom_output->pp_queue, _e_eom_cb_dequeuable, eom_output);
- }
-
- return;
-
-error:
-
- EOMER("failed run pp tdm error: %d", tdm_err);
-
- if (eom_output->pp_src_surface)
- {
- tbm_surface_internal_unref(eom_output->pp_src_surface);
- eom_output->pp_src_surface = NULL;
- }
- if (eom_output->pp_dst_surface)
- {
- tbm_surface_internal_unref(eom_output->pp_dst_surface);
- eom_output->pp_dst_surface = NULL;
- }
-
- if (dst_surface)
- {
- EOMDB("============================> PP ENDERR tbm_buff:%p", dst_surface);
- tdm_buffer_remove_release_handler(dst_surface, _e_eom_cb_pp, eom_output);
- tbm_surface_queue_release(eom_output->pp_queue, dst_surface);
- }
-}
-
-static void
-_e_eom_cb_pp(tbm_surface_h surface, void *user_data)
-{
- E_EomOutputPtr eom_output = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN(user_data);
- eom_output = (E_EomOutputPtr)user_data;
-
- tdm_buffer_remove_release_handler(surface, _e_eom_cb_pp, eom_output);
-
- if (eom_output->pp_src_surface)
- {
- tbm_surface_internal_unref(eom_output->pp_src_surface);
- eom_output->pp_src_surface = NULL;
- }
- if (eom_output->pp_dst_surface)
- {
- tbm_surface_internal_unref(eom_output->pp_dst_surface);
- eom_output->pp_dst_surface = NULL;
- }
-
- EOMDB("==============================> PP END tbm_buff:%p", surface);
-
- if (eom_output->pp_queue == NULL)
- return;
-
- if (g_eom->main_output_state == 0)
- {
- tbm_surface_queue_release(eom_output->pp_queue, surface);
- return;
- }
-
- /* If a client has committed its buffer stop mirror mode */
- if (eom_output->state != MIRROR)
- {
- tbm_surface_queue_release(eom_output->pp_queue, surface);
- return;
- }
-
-#ifdef EOM_DUMP_MIRROR_BUFFERS
- E_Devmgr_Buf *mbuf = e_devmgr_buffer_create_tbm(surface);
- EINA_SAFETY_ON_NULL_RETURN(mbuf);
- static int i;
- e_devmgr_buffer_dump(mbuf, "eom_mirror", i++, 0);
- e_devmgr_buffer_unref(mbuf);
-#endif
-
- if(!_e_eom_output_show(eom_output, surface, _e_eom_tbm_buffer_release_mirror_mod, NULL))
- {
- EOMER("_e_eom_add_buff_to_show fail");
- tbm_surface_queue_release(eom_output->pp_queue, surface);
- }
-
- _e_eom_pp_run(eom_output, EINA_FALSE);
-
- EOMDB("==============================< PP");
-}
-
-static void
-_e_eom_cb_dequeuable(tbm_surface_queue_h queue, void *user_data)
-{
- E_EomOutputPtr eom_output = (E_EomOutputPtr)user_data;
- EINA_SAFETY_ON_NULL_RETURN(user_data);
-
- EOMDB("release before in queue");
-
- tbm_surface_queue_remove_dequeuable_cb(eom_output->pp_queue, _e_eom_cb_dequeuable, eom_output);
-
- _e_eom_pp_run(eom_output, EINA_FALSE);
-}
-
-static Eina_Bool
-_e_eom_pp_init(E_EomOutputPtr eom_output)
-{
- tdm_error err = TDM_ERROR_NONE;
- tdm_pp *pp = NULL;
-
- if (eom_output->pp == NULL)
- {
- /* TODO: Add support for other formats */
- eom_output->pp_queue = tbm_surface_queue_create(3, eom_output->width,eom_output->height,
- TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
- EINA_SAFETY_ON_NULL_RETURN_VAL(eom_output->pp_queue, EINA_FALSE);
-
- pp = tdm_display_create_pp(g_eom->dpy, &err);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, EINA_FALSE);
-
- eom_output->pp = pp;
- }
-
- _e_eom_pp_run(eom_output, EINA_TRUE);
-
- return EINA_TRUE;
-}
-
-static void
-_e_eom_pp_deinit(E_EomOutputPtr eom_output)
-{
- if (eom_output->pp_queue)
- {
- EOMDB("flush and destroy queue");
- tbm_surface_queue_flush(eom_output->pp_queue);
- tbm_surface_queue_destroy(eom_output->pp_queue);
- eom_output->pp_queue = NULL;
- }
-
- if (eom_output->pp)
- {
- tdm_pp_destroy(eom_output->pp);
- eom_output->pp = NULL;
- }
-}
-
-static E_EomClientPtr
-_e_eom_client_get_current_by_id(int id)
-{
- Eina_List *l;
- E_EomClientPtr client;
-
- EINA_LIST_FOREACH(g_eom->clients, l, client)
- {
- if (client &&
- client->current == EINA_TRUE &&
- client->output_id == id)
- return client;
- }
-
- return NULL;
-}
-
-static Eina_Bool
-_e_eom_output_start_mirror(E_EomOutputPtr eom_output)
-{
- tdm_layer *hal_layer;
- tdm_info_layer layer_info;
- tdm_error tdm_err = TDM_ERROR_NONE;
- int ret = 0;
-
- if (eom_output->state == MIRROR)
- return EINA_TRUE;
-
- hal_layer = _e_eom_output_get_layer(eom_output);
- EINA_SAFETY_ON_NULL_GOTO(hal_layer, err);
-
- if (!_e_eom_pp_is_needed(g_eom->width, g_eom->height, eom_output->width, eom_output->height))
- {
- /* TODO: Internal and external outputs are equal */
- EOMDB("internal and external outputs are equal");
- }
-
- tdm_err = tdm_layer_get_info(hal_layer, &layer_info);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, err);
-
- EOMDB("layer info: %dx%d, pos (x:%d, y:%d, w:%d, h:%d, dpos (x:%d, y:%d, w:%d, h:%d))",
- layer_info.src_config.size.h, layer_info.src_config.size.v,
- layer_info.src_config.pos.x, layer_info.src_config.pos.y,
- layer_info.src_config.pos.w, layer_info.src_config.pos.h,
- layer_info.dst_pos.x, layer_info.dst_pos.y,
- layer_info.dst_pos.w, layer_info.dst_pos.h);
-
- eom_output->layer = hal_layer;
-
- tdm_err = tdm_output_set_dpms(eom_output->output, TDM_OUTPUT_DPMS_ON);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, err);
-
- _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_MIRROR);
- eom_output->state = MIRROR;
-
- ret = _e_eom_pp_init(eom_output);
- EINA_SAFETY_ON_FALSE_GOTO(ret == EINA_TRUE, err);
-
- return EINA_TRUE;
-
-err:
-
- _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_NONE);
- eom_output->state = NONE;
-
- return EINA_FALSE;
-}
-
-static void
-_e_eom_output_start_presentation(E_EomOutputPtr eom_output)
-{
- tdm_layer *hal_layer;
- tdm_info_layer layer_info;
- tdm_error tdm_err = TDM_ERROR_NONE;
-
- hal_layer = _e_eom_output_get_layer(eom_output);
- EINA_SAFETY_ON_NULL_GOTO(hal_layer, err);
-
- tdm_err = tdm_layer_get_info(hal_layer, &layer_info);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, err);
-
- EOMDB("layer info: %dx%d, pos (x:%d, y:%d, w:%d, h:%d, dpos (x:%d, y:%d, w:%d, h:%d))",
- layer_info.src_config.size.h, layer_info.src_config.size.v,
- layer_info.src_config.pos.x, layer_info.src_config.pos.y,
- layer_info.src_config.pos.w, layer_info.src_config.pos.h,
- layer_info.dst_pos.x, layer_info.dst_pos.y,
- layer_info.dst_pos.w, layer_info.dst_pos.h);
-
- eom_output->layer = hal_layer;
-
- _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_PRESENTATION);
-
- tdm_err = tdm_output_set_dpms(eom_output->output, TDM_OUTPUT_DPMS_ON);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, err);
-
- return;
-
-err:
-
- _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_NONE);
- eom_output->state = NONE;
-
- return;
-}
-
-static void
-_e_eom_output_all_buff_release(E_EomOutputPtr eom_output)
-{
- Eina_List *l, *ll;
- E_EomOutputBufferPtr buff = NULL;
-
- EINA_LIST_FOREACH_SAFE(eom_output->pending_buff, l, ll, buff)
- {
- EOMDB("delete pending tbm_buff:%p", buff->tbm_surface);
- eom_output->pending_buff = eina_list_remove_list(eom_output->pending_buff, l);
- _e_eom_output_buff_delete(buff);
- }
-
- eom_output->wait_buff = NULL;
-
- EOMDB("delete show tbm_buff:%p", eom_output->show_buff ? eom_output->show_buff->tbm_surface : NULL);
- _e_eom_output_buff_delete(eom_output->show_buff);
- eom_output->show_buff = NULL;
-}
-
-static void
-_e_eom_output_deinit(E_EomOutputPtr eom_output)
-{
- tdm_error err = TDM_ERROR_NONE;
-
- if (eom_output->state == NONE)
- return;
-
- _e_eom_output_state_set_status(eom_output, TDM_OUTPUT_CONN_STATUS_DISCONNECTED);
- _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_NONE);
-
- if (_e_eom_client_get_current_by_id(eom_output->id))
- eom_output->state = WAIT_PRESENTATION;
- else
- eom_output->state = NONE;
-
- if (eom_output->layer)
- {
- err = tdm_layer_unset_buffer(eom_output->layer);
- if (err != TDM_ERROR_NONE)
- EOMDB("fail unset buffer:%d", err);
-
- err = tdm_layer_commit(eom_output->layer, NULL, eom_output);
- if (err != TDM_ERROR_NONE)
- EOMDB ("fail commit on deleting output err:%d", err);
- }
-
- _e_eom_output_all_buff_release(eom_output);
-
- _e_eom_pp_deinit(eom_output);
-
- err = tdm_output_set_dpms(eom_output->output, TDM_OUTPUT_DPMS_OFF);
- if (err != TDM_ERROR_NONE)
- EOMER("set DPMS off:%d", err);
-}
-
-static const tdm_output_mode *
-_e_eom_output_get_best_mode(tdm_output *output)
-{
- tdm_error ret = TDM_ERROR_NONE;
- const tdm_output_mode *modes;
- const tdm_output_mode *mode = NULL;
- const tdm_output_mode *preferred_mode = NULL;
- const tdm_output_mode *best_mode = NULL;
- unsigned int best_value = 0;
- unsigned int best_refresh = 0;
- unsigned int value;
- int i, count = 0;
-
- ret = tdm_output_get_available_modes(output, &modes, &count);
- if (ret != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_get_available_modes fail(%d)", ret);
- return NULL;
- }
-
- for (i = 0; i < count; i++)
- {
- if (modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
- preferred_mode = &modes[i];
-
- value = modes[i].vdisplay + modes[i].hdisplay;
- if (value > best_value)
- {
- best_value = value;
- best_refresh = modes[i].vrefresh;
- best_mode = &modes[i];
- }
- else if (value == best_value)
- {
- if (modes[i].vrefresh > best_refresh)
- {
- best_value = value;
- best_refresh = modes[i].vrefresh;
- best_mode = &modes[i];
- }
- }
- }
-
- if (preferred_mode)
- mode = preferred_mode;
- else if (best_mode)
- mode = best_mode;
-
- if (mode)
- EOMDB("bestmode : %s, (%dx%d) r(%d), f(%d), t(%d)",
- mode->name, mode->hdisplay, mode->vdisplay,
- mode->vrefresh, mode->flags, mode->type);
-
- return mode;
-}
-
-static Eina_Bool
-_e_eom_timer_delayed_presentation_mode(void *data)
-{
- E_EomOutputPtr eom_output = NULL;
-
- EOMDB("timer called %s", __FUNCTION__);
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_CANCEL);
-
- eom_output = (E_EomOutputPtr )data;
- eom_output->delay = NULL;
-
- _e_eom_output_start_mirror(eom_output);
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-static int
-_e_eom_output_connected(E_EomOutputPtr eom_output)
-{
- tdm_output *output;
- tdm_error ret = TDM_ERROR_NONE;
- E_EomClientPtr iterator = NULL;
- Eina_List *l;
- const tdm_output_mode *mode;
- unsigned int mmWidth, mmHeight;
-
- output = eom_output->output;
-
- ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, -1);
-
- /* XXX: TMD returns not correct Primary mode for external output,
- * therefore we have to find it by ourself */
- mode = _e_eom_output_get_best_mode(output);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mode, -1);
-
- ret = tdm_output_set_mode(output, mode);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, -1);
-
- /* update eom_output connect */
- eom_output->width = mode->hdisplay;
- eom_output->height = mode->vdisplay;
- eom_output->phys_width = mmWidth;
- eom_output->phys_height = mmHeight;
-
- EOMDB("Setup new output: %s", eom_output->name);
-
- /* TODO: check output mode(presentation set) and HDMI type */
-
- if (eom_output->state == WAIT_PRESENTATION)
- {
- EOMDB("Start Presentation");
-
- if (eom_output->delay)
- ecore_timer_del(eom_output->delay);
- eom_output->delay = ecore_timer_add(EOM_DELAY_CHECK_TIMEOUT, _e_eom_timer_delayed_presentation_mode, eom_output);
-
- _e_eom_output_start_presentation(eom_output);
- }
- else
- {
- EOMDB("Start Mirroring");
- _e_eom_output_start_mirror(eom_output);
- }
-
- eom_output->connection = WL_EOM_STATUS_CONNECTION;
-
- /* If there were previously connected clients to the output - notify them */
- EINA_LIST_FOREACH(g_eom->clients, l, iterator)
- {
- if (iterator && iterator->resource)
- {
- EOMDB("Send MIRROR ON notification to clients");
-
- if (iterator->current)
- wl_eom_send_output_info(iterator->resource, eom_output->id,
- eom_output->type, eom_output->mode,
- eom_output->width, eom_output->height,
- eom_output->phys_width, eom_output->phys_height,
- eom_output->connection,
- 0,
- _e_eom_output_state_get_attribute(eom_output),
- EOM_OUTPUT_ATTRIBUTE_STATE_ACTIVE,
- EOM_ERROR_NONE);
- else
- wl_eom_send_output_info(iterator->resource, eom_output->id,
- eom_output->type, eom_output->mode,
- eom_output->width, eom_output->height,
- eom_output->phys_width, eom_output->phys_height,
- eom_output->connection,
- 1, 0, 0, 0);
- }
- }
-
- return 0;
-}
-
-static void
-_e_eom_output_disconnected(E_EomOutputPtr eom_output)
-{
- E_EomClientPtr iterator = NULL;
- Eina_List *l;
-
- if (eom_output->delay)
- ecore_timer_del(eom_output->delay);
-
- if (eom_output->watchdog)
- ecore_timer_del(eom_output->watchdog);
-
- if (g_eom->rotate_output == eom_output)
- {
- if (g_eom->rotate_timer)
- ecore_timer_del(g_eom->rotate_timer);
- g_eom->rotate_timer = NULL;
- g_eom->rotate_output = NULL;
- }
-
- /* update eom_output disconnect */
- eom_output->width = 0;
- eom_output->height = 0;
- eom_output->phys_width = 0;
- eom_output->phys_height = 0;
- eom_output->connection = WL_EOM_STATUS_DISCONNECTION;
-
- _e_eom_output_deinit(eom_output);
-
- /* If there were previously connected clients to the output - notify them */
- EINA_LIST_FOREACH(g_eom->clients, l, iterator)
- {
- if (iterator && iterator->resource)
- {
- EOMDB("Send MIRROR OFF notification to client: %p", iterator);
- if (iterator->current)
- wl_eom_send_output_info(iterator->resource, eom_output->id,
- eom_output->type, eom_output->mode,
- eom_output->width, eom_output->height,
- eom_output->phys_width, eom_output->phys_height,
- eom_output->connection,
- 0,
- _e_eom_output_state_get_attribute(eom_output),
- EOM_OUTPUT_ATTRIBUTE_STATE_INACTIVE,
- EOM_ERROR_NONE);
- else
- wl_eom_send_output_info(iterator->resource, eom_output->id,
- eom_output->type, eom_output->mode,
- eom_output->width, eom_output->height,
- eom_output->phys_width, eom_output->phys_height,
- eom_output->connection,
- 1, 0, 0, 0);
- }
- }
-
- EOMDB("Destory output: %s", eom_output->name);
- eina_stringshare_del(eom_output->name);
- eom_output->name = NULL;
-}
-
-static void
-_e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data)
-{
- tdm_output_type tdm_type;
- tdm_output_conn_status status, status_check;
- tdm_error ret = TDM_ERROR_NONE;
- const char *tmp_name;
- char new_name[DRM_CONNECTOR_NAME_LEN];
- E_EomOutputPtr eom_output = NULL, eom_output_tmp = NULL;
- Eina_List *l;
-
- g_eom->check_first_boot = 1;
-
- if (type == TDM_OUTPUT_CHANGE_DPMS || g_eom->main_output_state == 0)
- return;
-
- if (g_eom->outputs)
- {
- EINA_LIST_FOREACH(g_eom->outputs, l, eom_output_tmp)
- {
- if (eom_output_tmp->output == output)
- eom_output = eom_output_tmp;
- }
- }
-
- EINA_SAFETY_ON_NULL_RETURN(eom_output);
-
- ret = tdm_output_get_output_type(output, &tdm_type);
- EINA_SAFETY_ON_FALSE_RETURN(ret == TDM_ERROR_NONE);
-
- ret = tdm_output_get_conn_status(output, &status_check);
- EINA_SAFETY_ON_FALSE_RETURN(ret == TDM_ERROR_NONE);
-
- status = value.u32;
-
- EOMDB("id (%d), type(%d, %d), status(%d, %d)", eom_output->id, type, tdm_type, status_check, status);
-
- eom_output->type = (eom_output_type_e)tdm_type;
- eom_output->status = status;
-
- if (status == TDM_OUTPUT_CONN_STATUS_CONNECTED)
- {
- if (tdm_type < ALEN(eom_conn_types))
- tmp_name = eom_conn_types[tdm_type];
- else
- tmp_name = "unknown";
-
- /* TODO: What if there will more then one output of same type.
- * e.g. "HDMI and HDMI" "LVDS and LVDS"*/
- snprintf(new_name, sizeof(new_name), "%s-%d", tmp_name, 0);
-
- eom_output->name = eina_stringshare_add(new_name);
-
- e_comp_override_add();
-
- _e_eom_output_connected(eom_output);
- }
- else if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
- {
- e_comp_override_del();
-
- _e_eom_output_disconnected(eom_output);
- }
-}
-
-static Eina_Bool
-_e_eom_output_init(tdm_display *dpy)
-{
- E_EomOutputPtr new_output = NULL;
- tdm_output *output = NULL;
- tdm_output_type type;
- tdm_output_conn_status status;
- const tdm_output_mode *mode = NULL;
- tdm_error ret = TDM_ERROR_NONE;
- unsigned int mmWidth, mmHeight;
- int i, count;
-
- ret = tdm_display_get_output_count(dpy, &count);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(count > 1, EINA_FALSE);
-
- g_eom->output_count = count - 1;
- EOMDB("external output count : %d", g_eom->output_count);
-
- /* skip main output id:0 */
- /* start from 1 */
- for (i = 1; i < count; i++)
- {
- output = tdm_display_get_output(dpy, i, &ret);
- EINA_SAFETY_ON_FALSE_GOTO(ret == TDM_ERROR_NONE, err);
- EINA_SAFETY_ON_NULL_GOTO(output, err);
-
- ret = tdm_output_get_output_type(output, &type);
- EINA_SAFETY_ON_FALSE_GOTO(ret == TDM_ERROR_NONE, err);
-
- new_output = E_NEW(E_EomOutput, 1);
- EINA_SAFETY_ON_NULL_GOTO(new_output, err);
-
- ret = tdm_output_get_conn_status(output, &status);
- if (ret != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_get_conn_status fail(%d)", ret);
- free(new_output);
- goto err;
- }
-
- new_output->id = i;
- new_output->type = type;
- new_output->status = status;
- new_output->mode = EOM_OUTPUT_MODE_NONE;
- new_output->connection = WL_EOM_STATUS_NONE;
- new_output->output = output;
-
- ret = tdm_output_add_change_handler(output, _e_eom_cb_tdm_output_status_change, NULL);
- if (ret != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_add_change_handler fail(%d)", ret);
- free(new_output);
- goto err;
- }
-
- if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
- {
- EOMDB("create(%d)output, type:%d, status:%d",
- new_output->id, new_output->type, new_output->status);
- g_eom->outputs = eina_list_append(g_eom->outputs, new_output);
- continue;
- }
-
- new_output->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
-
- ret = tdm_output_get_mode(output, &mode);
- if (ret != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_get_mode fail(%d)", ret);
- free(new_output);
- goto err;
- }
-
- if (mode == NULL)
- {
- new_output->width = 0;
- new_output->height = 0;
- }
- else
- {
- new_output->width = mode->hdisplay;
- new_output->height = mode->vdisplay;
- }
-
- ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight);
- if (ret != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_get_conn_status fail(%d)", ret);
- free(new_output);
- goto err;
- }
-
- new_output->phys_width = mmWidth;
- new_output->phys_height = mmHeight;
-
- EOMDB("create(%d)output, type:%d, status:%d, w:%d, h:%d, mm_w:%d, mm_h:%d",
- new_output->id, new_output->type, new_output->status,
- new_output->width, new_output->height, new_output->phys_width, new_output->phys_height);
-
- g_eom->outputs = eina_list_append(g_eom->outputs, new_output);
- }
-
- return EINA_TRUE;
-
-err:
- if (g_eom->outputs)
- {
- Eina_List *l;
- E_EomOutputPtr output;
-
- EINA_LIST_FOREACH(g_eom->outputs, l, output)
- free(output);
-
- eina_list_free(g_eom->outputs);
-
- g_eom->outputs = NULL;
- }
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_eom_init_internal()
-{
- g_eom->dpy = e_devmgr_dpy->tdm;
- EINA_SAFETY_ON_NULL_GOTO(g_eom->dpy, err);
-
- g_eom->bufmgr = e_devmgr_dpy->bufmgr;
- EINA_SAFETY_ON_NULL_GOTO(g_eom->bufmgr, err);
-
- if (_e_eom_output_init(g_eom->dpy) != EINA_TRUE)
- {
- EOMER("_e_eom_output_init fail");
- goto err;
- }
-
- return EINA_TRUE;
-
-err:
-
- if (g_eom->bufmgr)
- g_eom->bufmgr = NULL;
-
- if (g_eom->dpy)
- g_eom->dpy = NULL;
-
- return EINA_FALSE;
-}
-
-static void
-_e_eom_deinit()
-{
- Ecore_Event_Handler *h = NULL;
-
- if (g_eom == NULL) return;
-
- if (g_eom->handlers)
- {
- EINA_LIST_FREE(g_eom->handlers, h)
- ecore_event_handler_del(h);
-
- g_eom->handlers = NULL;
- }
-
- if (g_eom->outputs)
- {
- Eina_List *l;
- E_EomOutputPtr output;
-
- EINA_LIST_FOREACH(g_eom->outputs, l, output)
- free(output);
-
- eina_list_free(g_eom->outputs);
-
- g_eom->outputs = NULL;
- }
-
- if (g_eom->dpy)
- g_eom->dpy = NULL;
-
- if (g_eom->bufmgr)
- g_eom->bufmgr = NULL;
-
- if (g_eom->global)
- wl_global_destroy(g_eom->global);
- g_eom->global = NULL;
-
- E_FREE(g_eom);
-}
-
-static E_EomClientPtr
-_e_eom_client_get_by_resource(struct wl_resource *resource)
-{
- Eina_List *l;
- E_EomClientPtr client;
-
- EINA_LIST_FOREACH(g_eom->clients, l, client)
- {
- if (client && client->resource == resource)
- return client;
- }
-
- return NULL;
-}
-
-static E_EomOutputPtr
-_e_eom_output_get_by_id(int id)
-{
- Eina_List *l;
- E_EomOutputPtr output;
-
- EINA_LIST_FOREACH(g_eom->outputs, l, output)
- {
- if (output && output->id == id)
- return output;
- }
-
- return NULL;
-}
-
-static E_EomOutputPtr
-_e_eom_output_by_ec_child_get(E_Client *ec)
-{
- E_EomOutputPtr eom_output = NULL;
- E_EomClientPtr eom_client = NULL;
- E_Client *parent = NULL;
- Eina_List *l;
-
- EINA_LIST_FOREACH(g_eom->outputs, l, eom_output)
- {
- eom_client = _e_eom_client_get_current_by_id(eom_output->id);
- if (!eom_client)
- continue;
-
- if (eom_client->ec == ec)
- return eom_output;
-
- if (!ec->comp_data || !ec->comp_data->sub.data)
- continue;
-
- parent = ec->comp_data->sub.data->parent;
- while (parent)
- {
- if (parent == eom_client->ec)
- return eom_output;
-
- if (!parent->comp_data || !parent->comp_data->sub.data)
- break;
-
- parent = parent->comp_data->sub.data->parent;
- }
- }
-
- return NULL;
-}
-
-static void
-_e_eom_output_hide_layers(E_EomOutputPtr eom_output)
-{
- tdm_layer * layer = NULL;
-
- if (!eom_output || eom_output->state == NONE)
- return;
-
- layer = e_devicemgr_video_layer_get(eom_output->output);
- if (!layer)
- return;
-
- /* XXX: sometimes video buffers are keep showing on a layer, therefore
- * we have to clear those stuck buffers from a layer */
- tdm_layer_unset_buffer(layer);
-}
-
-static void
-_e_eom_top_ec_angle_get(void)
-{
- E_Client *ec;
-
- ec = _e_eom_top_visible_ec_get();
- if (ec)
- {
- g_eom->angle = ec->e.state.rot.ang.curr;
- EOMDB("top ec rotate angle:%d", g_eom->angle);
- }
-}
-
-static void
-_e_eom_cb_wl_eom_client_destory(struct wl_resource *resource)
-{
- E_EomClientPtr client = NULL, iterator = NULL;
- E_EomOutputPtr output = NULL;
- Eina_List *l = NULL;
- Eina_Bool ret;
-
- EOMDB("=======================> CLENT UNBIND");
-
- EINA_SAFETY_ON_NULL_RETURN(resource);
-
- client = _e_eom_client_get_by_resource(resource);
- EINA_SAFETY_ON_NULL_RETURN(client);
-
- g_eom->clients = eina_list_remove(g_eom->clients, client);
-
- if (client->current == EINA_FALSE)
- goto end2;
-
- output = _e_eom_output_get_by_id(client->output_id);
- EINA_SAFETY_ON_NULL_GOTO(output, end2);
-
- ret = _e_eom_output_state_set_attribute(output, EOM_OUTPUT_ATTRIBUTE_NONE);
- (void)ret;
-
- if (output->state == NONE)
- goto end;
-
- if (output->state == WAIT_PRESENTATION)
- {
- output->state = NONE;
- goto end;
- }
-
- /* If a client has been disconnected and mirror mode has not
- * been restored, start mirror mode
- */
- _e_eom_top_ec_angle_get();
- _e_eom_output_start_mirror(output);
-
-end:
-
- /* Notify eom clients which are binded to a concrete output that the
- * state and mode of the output has been changed */
- EINA_LIST_FOREACH(g_eom->clients, l, iterator)
- {
- if (iterator && iterator != client && iterator->output_id == output->id)
- {
- wl_eom_send_output_attribute(iterator->resource, output->id,
- _e_eom_output_state_get_attribute(output),
- _e_eom_output_state_get_attribute_state(output),
- EOM_OUTPUT_MODE_NONE);
-
- wl_eom_send_output_mode(iterator->resource, output->id,
- _e_eom_output_state_get_mode(output));
- }
- }
-
-end2:
-
- free(client);
-}
-
-static void
-_e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute)
-{
- eom_error_e eom_error = EOM_ERROR_NONE;
- E_EomClientPtr eom_client = NULL, current_eom_client = NULL, iterator = NULL;
- E_EomOutputPtr eom_output = NULL;
- Eina_Bool ret = EINA_FALSE;
- Eina_List *l;
-
- eom_client = _e_eom_client_get_by_resource(resource);
- EINA_SAFETY_ON_NULL_RETURN(eom_client);
-
- /* Bind the client with a concrete output */
- eom_client->output_id = output_id;
-
- eom_output = _e_eom_output_get_by_id(output_id);
- EINA_SAFETY_ON_NULL_GOTO(eom_output, no_output);
-
- EOMDB("Set attribute:%d", attribute);
-
- if (eom_client->current == EINA_TRUE && eom_output->id == eom_client->output_id)
- {
- /* Current client can set any flag it wants */
- _e_eom_output_state_set_force_attribute(eom_output, attribute);
- }
- else if (eom_output->id == eom_client->output_id)
- {
- /* A client is trying to set new attribute */
- ret = _e_eom_output_state_set_attribute(eom_output, attribute);
- if (ret == EINA_FALSE)
- {
- EOMDB("set attribute FAILED");
-
- eom_error = EOM_ERROR_INVALID_PARAMETER;
- goto end;
- }
- }
- else
- return;
-
- /* If client has set EOM_OUTPUT_ATTRIBUTE_NONE switching to mirror mode */
- if (attribute == EOM_OUTPUT_ATTRIBUTE_NONE && eom_output->state != MIRROR)
- {
- eom_client->current = EINA_FALSE;
-
- _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_NONE);
- _e_eom_output_state_set_attribute(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE);
-
- if (eom_output->status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
- {
- EOMDB("output:%d is disconnected", output_id);
- goto end;
- }
-
- ret = _e_eom_output_start_mirror(eom_output);
- EINA_SAFETY_ON_FALSE_GOTO(ret == EINA_TRUE, end);
-
- /* If mirror mode has been ran notify all clients about that */
- EOMDB("client set NONE attribute, send new info to previous current client");
- EINA_LIST_FOREACH(g_eom->clients, l, iterator)
- {
- if (iterator && iterator->output_id == output_id)
- {
- wl_eom_send_output_attribute(iterator->resource, eom_output->id,
- _e_eom_output_state_get_attribute(eom_output),
- _e_eom_output_state_get_attribute_state(eom_output),
- EOM_ERROR_NONE);
-
- wl_eom_send_output_mode(iterator->resource, eom_output->id,
- _e_eom_output_state_get_mode(eom_output));
- }
- }
-
- return;
- }
-
-end:
-
- /* If client was not able to set attribute send LOST event to it */
- if (eom_error == EOM_ERROR_INVALID_PARAMETER)
- {
- EOMDB("client failed to set attribute");
-
- wl_eom_send_output_attribute(eom_client->resource, eom_output->id,
- _e_eom_output_state_get_attribute(eom_output),
- EOM_OUTPUT_ATTRIBUTE_STATE_LOST,
- eom_error);
- return;
- }
-
- /* Send changes to the caller-client */
- wl_eom_send_output_attribute(eom_client->resource, eom_output->id,
- _e_eom_output_state_get_attribute(eom_output),
- _e_eom_output_state_get_attribute_state(eom_output),
- eom_error);
-
- current_eom_client = _e_eom_client_get_current_by_id(eom_output->id);
- EOMDB("Substitute current client: new:%p, old:%p",eom_client, current_eom_client );
-
- /* Send changes to previous current client */
- if (eom_client->current == EINA_FALSE && current_eom_client)
- {
- current_eom_client->current = EINA_FALSE;
-
- /* Actually deleting of buffers right here is a hack intended to
- * send release events of buffers to current client, since it could
- * be locked until it get 'release' event */
- EOMDB("Send changes to previous current client, and delete buffers");
- _e_eom_output_all_buff_release(eom_output);
-
- wl_eom_send_output_attribute(current_eom_client->resource, eom_output->id,
- _e_eom_output_state_get_attribute(eom_output),
- EOM_OUTPUT_ATTRIBUTE_STATE_LOST,
- EOM_ERROR_NONE);
- }
-
- /* Set the client as current client of the eom_output */
- eom_client->current= EINA_TRUE;
-
- _e_eom_output_hide_layers(eom_output);
-
- if (eom_output->status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
- eom_output->state = WAIT_PRESENTATION;
-
- return;
-
-/* Get here if EOM does not have output referred by output_id */
-no_output:
-
- wl_eom_send_output_attribute(eom_client->resource, output_id,
- EOM_OUTPUT_ATTRIBUTE_NONE,
- EOM_OUTPUT_ATTRIBUTE_STATE_NONE,
- EOM_ERROR_NO_SUCH_DEVICE);
-
- wl_eom_send_output_mode(eom_client->resource, output_id,
- EOM_OUTPUT_MODE_NONE);
-
- wl_eom_send_output_type(eom_client->resource, output_id,
- EOM_OUTPUT_ATTRIBUTE_STATE_NONE,
- TDM_OUTPUT_CONN_STATUS_DISCONNECTED);
- return;
-}
-
-static Eina_Bool
-_e_eom_cb_comp_object_redirected(void *data, E_Client *ec)
-{
- E_EomCompObjectInterceptHookData *hook_data;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_TRUE);
-
- hook_data = (E_EomCompObjectInterceptHookData* )data;
-
- if (!hook_data->ec || !hook_data->hook)
- return EINA_TRUE;
-
- if (hook_data->ec != ec)
- return EINA_TRUE;
-
- /* Hide the window from Enlightenment main screen */
- e_client_redirected_set(ec, EINA_FALSE);
-
- e_comp_object_intercept_hook_del(hook_data->hook);
-
- g_eom->comp_object_intercept_hooks = eina_list_remove(g_eom->comp_object_intercept_hooks, hook_data);
-
- free(hook_data);
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_eom_util_add_comp_object_redirected_hook(E_Client *ec)
-{
- E_EomCompObjectInterceptHookData *hook_data = NULL;
- E_Comp_Object_Intercept_Hook *hook = NULL;
-
- hook_data = E_NEW(E_EomCompObjectInterceptHookData, 1);
- EINA_SAFETY_ON_NULL_GOTO(hook_data, err);
-
- hook_data->ec = ec;
-
- hook = e_comp_object_intercept_hook_add(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER,
- _e_eom_cb_comp_object_redirected, hook_data);
- EINA_SAFETY_ON_NULL_GOTO(hook, err);
-
- hook_data->hook = hook;
-
- g_eom->comp_object_intercept_hooks = eina_list_append(g_eom->comp_object_intercept_hooks, hook_data);
-
- EOMDB("_e_eom_redirected_hook have been added");
- return EINA_TRUE;
-
-err:
-
- if (hook_data)
- free(hook_data);
- return EINA_FALSE;
-}
-
-static void
-_e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client *ec)
-{
- E_EomOutputPtr eom_output = NULL;
- E_EomClientPtr eom_client = NULL;
- E_Comp_Client_Data *cdata = NULL;
- Eina_Bool ret = EINA_FALSE;
-
- if (resource == NULL || output_id <= 0 || ec == NULL)
- return;
-
- cdata = ec->comp_data;
- EINA_SAFETY_ON_NULL_RETURN(cdata);
- EINA_SAFETY_ON_NULL_RETURN(cdata->shell.configure_send);
-
- eom_client = _e_eom_client_get_by_resource(resource);
- EINA_SAFETY_ON_NULL_RETURN(eom_client);
-
- eom_output = _e_eom_output_get_by_id(output_id);
- if (eom_output == NULL)
- {
- wl_eom_send_output_set_window(resource, output_id, WL_EOM_ERROR_NO_OUTPUT);
- return;
- }
-
- ret = _e_eom_util_add_comp_object_redirected_hook(ec);
- EINA_SAFETY_ON_FALSE_RETURN(ret == EINA_TRUE);
-
- EOMDB("e_comp_object_redirected_set (ec:%p)(ec->frame:%p)\n", ec, ec->frame);
-
-/* Send reconfigure event to a client which will resize its window to
- * external output resolution in respond */
- cdata->shell.configure_send(ec->comp_data->shell.surface, 0, eom_output->width, eom_output->height);
-
-/* ec is used in buffer_change callback for distinguishing external ec and its buffers */
- eom_client->ec = ec;
-
- if (eom_client->current == EINA_TRUE)
- wl_eom_send_output_set_window(resource, eom_output->id, WL_EOM_ERROR_NONE);
- else
- wl_eom_send_output_set_window(resource, eom_output->id, WL_EOM_ERROR_OUTPUT_OCCUPIED);
-}
-
-static void
-_e_eom_cb_wl_request_set_xdg_window(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, struct wl_resource *surface)
-{
- E_Client *ec = NULL;
-
- if (resource == NULL || output_id <= 0 || surface == NULL)
- return;
-
- EOMDB("set xdg output id:%d resource:%p surface:%p", output_id, resource, surface);
-
- if (!(ec = wl_resource_get_user_data(surface)))
- {
- wl_resource_post_error(surface,WL_DISPLAY_ERROR_INVALID_OBJECT, "No Client For Shell Surface");
- return;
- }
-
- _e_eom_window_set_internal(resource, output_id, ec);
-}
-
-static void
-_e_eom_cb_wl_request_set_shell_window(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, struct wl_resource *surface)
-{
- E_Client *ec = NULL;
-
- if (resource == NULL || output_id <= 0 || surface == NULL)
- return;
-
- EOMDB("set shell output id:%d resource:%p surface:%p", output_id, resource, surface);
-
- if (!(ec = wl_resource_get_user_data(surface)))
- {
- wl_resource_post_error(surface,WL_DISPLAY_ERROR_INVALID_OBJECT, "No Client For Shell Surface");
- return;
- }
-
- _e_eom_window_set_internal(resource, output_id, ec);
-}
-
-static void
-_e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resource *resource, uint32_t output_id)
-{
- EOMDB("output:%d", output_id);
-
- if (g_eom->outputs)
- {
- Eina_List *l;
- E_EomOutputPtr output = NULL;
-
- EINA_LIST_FOREACH(g_eom->outputs, l, output)
- {
- if (output->id == output_id)
- {
- EOMDB("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d",
- output->id, output->type, output->mode, output->width, output->height,
- output->phys_width, output->phys_height, output->status);
-
- wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->width, output->height,
- output->phys_width, output->phys_height, output->connection,
- 1, 0, 0, 0);
- }
- }
- }
-}
-
-static const struct wl_eom_interface _e_eom_wl_implementation =
-{
- _e_eom_cb_wl_request_set_attribute,
- _e_eom_cb_wl_request_set_xdg_window,
- _e_eom_cb_wl_request_set_shell_window,
- _e_eom_cb_wl_request_get_output_info
-};
-
-static void
-_e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
-{
- struct wl_resource *resource = NULL;
- E_EomClientPtr new_client = NULL;
- E_EomPtr eom = NULL;
- E_EomOutputPtr output = NULL;
- Eina_List *l;
-
- EINA_SAFETY_ON_NULL_RETURN(data);
- eom = data;
-
- resource = wl_resource_create(client, &wl_eom_interface, MIN(version, 1), id);
- if (resource == NULL)
- {
- EOMER("resource is null. (version :%d, id:%d)", version, id);
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(resource, &_e_eom_wl_implementation, eom, _e_eom_cb_wl_eom_client_destory);
-
- EOMDB("send - output count : %d", g_eom->output_count);
-
- wl_eom_send_output_count(resource, g_eom->output_count);
-
- if (g_eom->outputs)
- {
- EINA_LIST_FOREACH(g_eom->outputs, l, output)
- {
- EOMDB("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d",
- output->id, output->type, output->mode, output->width, output->height,
- output->phys_width, output->phys_height, output->status);
- wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->width, output->height,
- output->phys_width, output->phys_height, output->connection,
- 1, 0, 0, 0);
- }
- }
-
- new_client = E_NEW(E_EomClient, 1);
- EINA_SAFETY_ON_NULL_RETURN(new_client);
-
- new_client->resource = resource;
- new_client->current = EINA_FALSE;
- new_client->output_id = -1;
- new_client->ec = NULL;
-
- g_eom->clients = eina_list_append(g_eom->clients, new_client);
-
- EOMDB("=======================> BIND CLENT");
-}
-
-static Eina_Bool
-_e_eom_cb_ecore_drm_activate(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
-
- Ecore_Drm_Event_Activate *e = NULL;
-
- if ((!event) || (!data))
- return ECORE_CALLBACK_PASS_ON;
-
- e = event;
- (void) e;
-
- EOMDB("e->active:%d", e->active);
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_eom_boot_connection_check(void *data)
-{
- E_EomOutputPtr eom_output;
- tdm_output *output = NULL;
- tdm_output_type tdm_type = TDM_OUTPUT_TYPE_Unknown;
- tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
- tdm_error ret = TDM_ERROR_NONE;
- const char *tmp_name;
- char new_name[DRM_CONNECTOR_NAME_LEN];
- Eina_List *l;
-
- if (g_eom->check_first_boot != 0)
- {
- g_eom->timer = NULL;
- return ECORE_CALLBACK_CANCEL;
- }
-
- g_eom->check_first_boot = 1;
-
- if (g_eom->outputs)
- {
- EINA_LIST_FOREACH(g_eom->outputs, l, eom_output)
- {
- if (eom_output->id == 0)
- continue;
-
- output = eom_output->output;
- if (output == NULL)
- {
- EOMER("output is null fail");
- continue;
- }
-
- ret = tdm_output_get_conn_status(output, &status);
- if (ret != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_get_conn_status fail(%d)", ret);
- continue;
- }
-
- if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
- continue;
-
- ret = tdm_output_get_output_type(output, &tdm_type);
- if (ret != TDM_ERROR_NONE)
- {
- EOMER("tdm_output_get_output_type fail(%d)", ret);
- continue;
- }
-
- if (tdm_type < ALEN(eom_conn_types))
- tmp_name = eom_conn_types[tdm_type];
- else
- tmp_name = "unknown";
- /* TODO: What if there will more then one output of same type.
- * e.g. "HDMI and HDMI" "LVDS and LVDS"*/
- snprintf(new_name, sizeof(new_name), "%s-%d", tmp_name, 0);
-
- eom_output->type = (eom_output_type_e)tdm_type;
- eom_output->name = eina_stringshare_add(new_name);
- eom_output->status = status;
-
- _e_eom_output_connected(eom_output);
- }
- }
- g_eom->timer = NULL;
- return ECORE_CALLBACK_CANCEL;
-}
-
-static Eina_Bool
-_e_eom_cb_ecore_drm_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
- Ecore_Drm_Event_Output *e = NULL;
- char buff[PATH_MAX];
-
- if (!(e = event)) return ECORE_CALLBACK_PASS_ON;
-
- EOMDB("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d",
- e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug);
-
- snprintf(buff, sizeof(buff), "%s", e->name);
-
- /* main output */
- if (e->id == 0)
- {
- if (e->plug == 1)
- {
- g_eom->width = e->w;
- g_eom->height = e->h;
- if (g_eom->main_output_name == NULL)
- g_eom->main_output_name = strdup(buff);
-
- g_eom->main_output_state = 1;
-
- if (g_eom->check_first_boot == 0)
- {
- if (g_eom->timer)
- ecore_timer_del(g_eom->timer);
- g_eom->timer = ecore_timer_add(EOM_CONNECT_CHECK_TIMEOUT, _e_eom_boot_connection_check, NULL);
- }
- }
- else
- {
- g_eom->width = -1;
- g_eom->height = -1;
- if (g_eom->main_output_name)
- free(g_eom->main_output_name);
-
- g_eom->main_output_state = 0;
- }
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static E_EomClientPtr
-_e_eom_client_get_current_by_ec(E_Client *ec)
-{
- Eina_List *l;
- E_EomClientPtr client;
-
- EINA_LIST_FOREACH(g_eom->clients, l, client)
- {
- if (client && client->current == EINA_TRUE && client->ec == ec)
- return client;
- }
-
- return NULL;
-}
-
-static void
-_e_eom_tbm_buffer_release_ext_mod(E_EomOutputPtr eom_output, tbm_surface_h srfc, void * eom_buff)
-{
- EOMDB("============> EXT END tbm_buff:%p E_EomBuffer:%p", srfc, eom_buff);
- _e_eom_buffer_destroy(eom_buff);
-}
-
-static Eina_Bool
-_e_eom_cb_client_buffer_change(void *data, int type, void *event)
-{
- E_Comp_Wl_Buffer *wl_buffer = NULL;
- E_EomClientPtr eom_client = NULL, eom_client_itr = NULL;
- E_EomOutputPtr eom_output = NULL;
- E_Event_Client *ev = event;
- E_Client *ec = NULL;
- tbm_surface_h tbm_buffer = NULL;
- Eina_List *l;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
-
- ec = ev->ec;
- EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)),
- ECORE_CALLBACK_PASS_ON);
-
- eom_client = _e_eom_client_get_current_by_ec(ec);
- if (eom_client == NULL)
- return ECORE_CALLBACK_PASS_ON;
-
- eom_output = _e_eom_output_get_by_id(eom_client->output_id);
- EINA_SAFETY_ON_NULL_RETURN_VAL(eom_output, ECORE_CALLBACK_PASS_ON);
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(ec->pixmap, ECORE_CALLBACK_PASS_ON);
-
- wl_buffer = e_pixmap_resource_get(ec->pixmap);
- EINA_SAFETY_ON_NULL_RETURN_VAL(wl_buffer, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(wl_buffer->resource, ECORE_CALLBACK_PASS_ON);
-
- /* Since Enlightenment client has reconfigured its window to fit
- * external output resolution and Enlightenment no nothing about
- * external outputs Enlightenment sees that client's resolution
- * differs form main screen resolution. Therefore, Enlightenment
- * is trying to resize it back to main screen resolution. It uses
- * timer for that purpose. To forbid it just delte the timer */
-
- /* TODO: It works but maybe there is better solution exists ?
- * Also I do not know how it affects on performance */
- if (ec->map_timer)
- {
- EOMDB("delete map_timer");
- E_FREE_FUNC(ec->map_timer, ecore_timer_del);
- }
-
- /* TODO: Support buffers smaller then output resolution */
- if (wl_buffer->w != eom_output->width ||
- wl_buffer->h != eom_output->height )
- {
- EOMER("tbm_buffer does not fit output's resolution");
- return ECORE_CALLBACK_PASS_ON;
- }
-
- /* TODO: support different SHMEM buffers etc. */
- tbm_buffer = wayland_tbm_server_get_surface(e_comp->wl_comp_data->tbm.server, wl_buffer->resource);
- EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_buffer, ECORE_CALLBACK_PASS_ON);
-
- E_EomBufferPtr eom_buff = _e_eom_buffer_create(wl_buffer);
- EINA_SAFETY_ON_NULL_RETURN_VAL(eom_buff, ECORE_CALLBACK_PASS_ON);
-
- EOMDB("===============> EXT START tbm_buff:%p", tbm_buffer);
-
-#ifdef EOM_DUMP_PRESENTATION_BUFFERS
- E_Devmgr_Buf *mbuf = e_devmgr_buffer_create_tbm(tbm_buffer);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, ECORE_CALLBACK_PASS_ON);
- static int i;
- e_devmgr_buffer_dump(mbuf, "eom_external", i++, 0);
- e_devmgr_buffer_unref(mbuf);
-#endif
-
- if(!_e_eom_output_show(eom_output, tbm_buffer, _e_eom_tbm_buffer_release_ext_mod, eom_buff))
- {
- EOMDB("===============> EXT ENDERR tbm_buff:%p", tbm_buffer);
- EOMDB("_e_eom_add_buff_to_show fail");
- _e_eom_buffer_destroy(eom_buff);
- return ECORE_CALLBACK_PASS_ON;
- }
-
- if (eom_output->state == WAIT_PRESENTATION)
- {
- EOMDB("remove delayed presentation timer");
- if (eom_output->delay)
- ecore_timer_del(eom_output->delay);
- }
-
- if (eom_output->state != PRESENTATION)
- {
- _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_PRESENTATION);
-
- EINA_LIST_FOREACH(g_eom->clients, l, eom_client_itr)
- {
- if (eom_client_itr->output_id == eom_output->id)
- wl_eom_send_output_mode(eom_client_itr->resource, eom_output->id,
- _e_eom_output_state_get_mode(eom_output));
- }
-
- eom_output->state = PRESENTATION;
- }
-
- EOMDB("===============< EXT START");
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_eom_cb_rotation_effect_ready(void *data, int type, void *event)
-{
- E_EomPtr eom = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(event, ECORE_CALLBACK_PASS_ON);
-
- eom = data;
-
- eom->rotate_state = ROTATE_INIT;
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_eom_rotate(void *data)
-{
- g_eom->rotate_state = ROTATE_DONE;
-
- _e_eom_top_ec_angle_get();
-
- if (g_eom->rotate_output)
- _e_eom_pp_run(g_eom->rotate_output, EINA_FALSE);
-
- g_eom->rotate_timer = NULL;
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-static Eina_Bool
-_e_eom_cb_rotation_effect_cancel(void *data, int type, void *event)
-{
- E_EomPtr eom = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(event, ECORE_CALLBACK_PASS_ON);
-
- eom = data;
-
- eom->rotate_state = ROTATE_CANCEL;
-
- if (eom->rotate_timer)
- ecore_timer_del(eom->rotate_timer);
-
- if (g_eom->rotate_output)
- eom->rotate_timer = ecore_timer_add(EOM_ROTATE_DELAY_TIMEOUT, _e_eom_rotate, NULL);
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_eom_cb_rotation_effect_done(void *data, int type, void *event)
-{
- E_Event_Zone_Rotation_Effect_Done *ev;
- E_EomPtr eom = NULL;
- E_Zone *zone;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(event, ECORE_CALLBACK_PASS_ON);
-
- ev = event;
- eom = data;
-
- zone = ev->zone;
- EINA_SAFETY_ON_NULL_RETURN_VAL(zone, ECORE_CALLBACK_PASS_ON);
-
- EOMDB("-----------------------------------------------------");
-
- EOMDB("effect END: angles: prev:%d curr:%d next:%d sub:%d",
- zone->rot.prev, zone->rot.curr,
- zone->rot.next, zone->rot.sub);
-
- EOMDB("effect END: rotate angle:%d", eom->angle);
-
- EOMDB("-----------------------------------------------------");
-
- eom->angle = zone->rot.curr;
-
- if (eom->rotate_timer)
- ecore_timer_del(eom->rotate_timer);
-
- if (g_eom->rotate_output)
- eom->rotate_timer = ecore_timer_add(EOM_ROTATE_DELAY_TIMEOUT, _e_eom_rotate, NULL);
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_eom_cb_rotation_end(void *data, int evtype EINA_UNUSED, void *event)
-{
- E_Client *ec = NULL;
- E_Event_Client *ev = NULL;
- E_EomPtr eom = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(event, ECORE_CALLBACK_PASS_ON);
-
- ev = event;
- eom = data;
- ec = ev->ec;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
-
- /* As I understand E sends rotate events to all visible apps, thus EOM's
- * "_e_eom_cb_rotation_end" will be called for each visible E_Client.
- * Therefore we are interested only in the first change of angle, other
- * events with the same angle value will be ignored. */
- if (eom->angle == ec->e.state.rot.ang.curr)
- return ECORE_CALLBACK_PASS_ON;
-
- if (eom->rotate_state == ROTATE_NONE)
- {
- eom->angle = ec->e.state.rot.ang.curr;
- eom->rotate_state = ROTATE_DONE;
-
- EOMDB("-----------------------------------------------------");
- EOMDB("END: ec:%p", ec);
-
- EOMDB("END: angles: prev:%d curr:%d next:%d res:%d",
- ec->e.state.rot.ang.prev, ec->e.state.rot.ang.curr,
- ec->e.state.rot.ang.next, ec->e.state.rot.ang.reserve);
-
- EOMDB("END: rotate angle:%d", eom->angle);
- EOMDB("END: ec:%dx%d", ec->w, ec->h);
-
- EOMDB("-----------------------------------------------------");
- }
- else if (eom->rotate_state == ROTATE_INIT)
- {
- eom->angle = ec->e.state.rot.ang.curr;
- eom->rotate_state = ROTATE_PENDING;
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_eom_init()
-{
- Eina_Bool ret = EINA_FALSE;
-
- EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err);
-
- g_eom = E_NEW(E_Eom, 1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(g_eom, EINA_FALSE);
-
- g_eom->global = wl_global_create(e_comp_wl->wl.disp, &wl_eom_interface, 1, g_eom, _e_eom_cb_wl_bind);
- EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err);
-
- g_eom->angle = 0;
- g_eom->rotate_state = ROTATE_NONE;
- g_eom->main_output_name = NULL;
-
- ret = _e_eom_init_internal();
- EINA_SAFETY_ON_FALSE_GOTO(ret == EINA_TRUE, err);
-
- E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_ACTIVATE, _e_eom_cb_ecore_drm_activate, g_eom);
- E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_OUTPUT, _e_eom_cb_ecore_drm_output, g_eom);
- E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_CLIENT_BUFFER_CHANGE, _e_eom_cb_client_buffer_change, NULL);
- /* TODO: add if def _F_ZONE_WINDOW_ROTATION_ */
- E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_ZONE_ROTATION_EFFECT_READY, _e_eom_cb_rotation_effect_ready, g_eom);
- E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_ZONE_ROTATION_EFFECT_CANCEL, _e_eom_cb_rotation_effect_cancel, g_eom);
- E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_ZONE_ROTATION_EFFECT_DONE, _e_eom_cb_rotation_effect_done, g_eom);
- E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_CLIENT_ROTATION_CHANGE_END, _e_eom_cb_rotation_end, g_eom);
-
- return EINA_TRUE;
-
-err:
-
- _e_eom_deinit();
- return EINA_FALSE;
-}
-
-int
-e_devicemgr_eom_init(void)
-{
- Eina_Bool ret = EINA_FALSE;
-
- ret = _e_eom_init();
-
- if (ret == EINA_FALSE)
- return 0;
-
- return 1;
-}
-
-void
-e_devicemgr_eom_fini(void)
-{
- if (!g_eom) return;
-
- _e_eom_deinit();
-}
-
-Eina_Bool
-e_devicemgr_eom_is_ec_external(E_Client *ec)
-{
- E_EomOutputPtr eom_output;
-
- if (!g_eom) return EINA_FALSE;
-
- eom_output = _e_eom_output_by_ec_child_get(ec);
- if (!eom_output)
- return EINA_FALSE;
- return EINA_TRUE;
-}
-
-tdm_output*
-e_devicemgr_eom_tdm_output_by_ec_get(E_Client *ec)
-{
- E_EomOutputPtr eom_output;
-
- if (!g_eom) return NULL;
-
- eom_output = _e_eom_output_by_ec_child_get(ec);
- if (!eom_output)
- return NULL;
- return eom_output->output;
-}
+++ /dev/null
-#ifndef __E_DEVICEMGR_EOM_H__
-#define __E_DEVICEMGR_EOM_H__
-
-#include "e.h"
-
-int e_devicemgr_eom_init(void);
-void e_devicemgr_eom_fini(void);
-Eina_Bool e_devicemgr_eom_is_ec_external(E_Client *ec);
-tdm_output* e_devicemgr_eom_tdm_output_by_ec_get(E_Client *ec);
-
-#endif
+++ /dev/null
-#include "e.h"
-#include "e_mod_main.h"\r
-#include "e_devicemgr_privates.h"\r
-#include "e_devicemgr_output.h"\r
-\r
-int\r
-e_devicemgr_output_init(void)\r
-{\r
- return 1;\r
-}\r
-\r
-void\r
-e_devicemgr_output_fini(void)\r
-{\r
-}
\ No newline at end of file
+++ /dev/null
-#ifndef __E_DEVICEMGR_OUTPUT_H__\r
-#define __E_DEVICEMGR_OUTPUT_H__\r
-
-#include "e.h"
-\r
-int e_devicemgr_output_init(void);\r
-void e_devicemgr_output_fini(void);\r
-\r
-#endif\r
Eina_Bool button_remap_enable;
int back_keycode;
} input;
- Eina_Bool eom_enable;
};
struct _E_Devicemgr_Config_Data
+++ /dev/null
-#include "e.h"
-#include "e_mod_main.h"\r
-#include "e_devicemgr_privates.h"\r
-#include "e_devicemgr_scale.h"\r
-\r
-int\r
-e_devicemgr_scale_init(void)\r
-{\r
- return 1;\r
-}\r
-\r
-void\r
-e_devicemgr_scale_fini(void)\r
-{\r
-}
\ No newline at end of file
+++ /dev/null
-#ifndef __E_DEVICEMGR_SCALE_H__\r
-#define __E_DEVICEMGR_SCALE_H__\r
-\r
-#include "config.h"\r
-\r
-#include "e.h"\r
-\r
-int e_devicemgr_scale_init(void);\r
-void e_devicemgr_scale_fini(void);\r
-\r
-#endif\r
+++ /dev/null
-#define E_COMP_WL
-#include "e.h"
-#include <wayland-server.h>
-#include <Ecore_Wayland.h>
-#include <Ecore_Drm.h>
-#include <screenshooter-server-protocol.h>
-#include <tizen-extension-server-protocol.h>
-#include <tdm.h>
-#include "e_devicemgr_screenshooter.h"
-#include "e_devicemgr_video.h"
-#include "e_devicemgr_buffer.h"
-#include "e_devicemgr_dpms.h"
-#ifdef ENABLE_CYNARA
-#include <cynara-session.h>
-#include <cynara-client.h>
-#include <cynara-creds-socket.h>
-#endif
-
-#define DUMP_FPS 30
-
-typedef struct _E_Mirror
-{
- struct wl_resource *resource;
- struct wl_resource *shooter;
- struct wl_resource *output;
-
- Eina_Bool started;
- enum tizen_screenmirror_stretch stretch;
-
- Eina_List *buffer_queue;
- E_Comp_Wl_Output *wl_output;
- Ecore_Drm_Output *drm_output;
- Ecore_Drm_Device *drm_device;
-
- tdm_display *tdm_dpy;
- tdm_output *tdm_output;
- tdm_layer *tdm_primary_layer;
- tdm_capture *capture;
- Ecore_Timer *capture_timer;
-
- /* vblank info */
- int per_vblank;
- Eina_Bool wait_vblank;
-
- /* timer info when dpms off */
- Ecore_Timer *timer;
-
- /* converter info */
- tdm_pp *pp;
- Eina_List *ui_buffer_list;
- Eina_List *buffer_clear_check;
-
- /* rotation info */
- int eout_rotate;
- int angle;
- Eina_Bool rotate_change;
-
- struct wl_listener client_destroy_listener;
-
- Eina_Bool oneshot_client_destroy;
-#ifdef ENABLE_CYNARA
- cynara *p_cynara;
- Eina_Bool cynara_initialized;
-#endif
-} E_Mirror;
-
-typedef struct _E_Mirror_Buffer
-{
- E_Devmgr_Buf *mbuf;
- E_Devmgr_Buf *tmp;
-
- E_Mirror *mirror;
-
- Eina_Bool in_use;
- Eina_Bool dirty;
-
- /* in case of shm buffer */
- struct wl_listener destroy_listener;
-} E_Mirror_Buffer;
-
-static uint mirror_format_table[] =
-{
- TBM_FORMAT_ARGB8888,
- TBM_FORMAT_XRGB8888,
- TBM_FORMAT_NV12,
- TBM_FORMAT_NV21,
-};
-
-#define NUM_MIRROR_FORMAT (sizeof(mirror_format_table) / sizeof(mirror_format_table[0]))
-
-static E_Mirror *keep_stream_mirror;
-static Eina_Bool screenshot_auto_rotation;
-static Eina_List *mirror_list;
-
-static void _e_tz_screenmirror_destroy(E_Mirror *mirror);
-static void _e_tz_screenmirror_buffer_dequeue(E_Mirror_Buffer *buffer);
-static void _e_tz_screenmirror_buffer_cb_free(E_Devmgr_Buf *mbuf, void *data);
-static void _e_tz_screenmirror_vblank_handler(void *data);
-
-#ifdef ENABLE_CYNARA
-static void _e_screenmirror_cynara_log(const char *func_name, int err);
-
-#define PRIVILEGE_SCREENSHOT "http://tizen.org/privilege/screenshot"
-#define SMACK_LABEL_LEN 255
-#define PATH_MAX_LEN 64
-#define CYNARA_BUFSIZE 128
-#define E_SCREENMIRROR_CYNARA_ERROR_CHECK_GOTO(func_name, ret, label) \
- do \
- { \
- if (EINA_UNLIKELY(ret != CYNARA_API_SUCCESS)) \
- { \
- _e_screenmirror_cynara_log(func_name, ret); \
- goto label; \
- } \
- } \
- while (0)
-
-static void
-_e_screenmirror_cynara_log(const char *func_name, int err)
-{
- char buf[CYNARA_BUFSIZE] = "\0";
- int ret;
-
- ret = cynara_strerror(err, buf, CYNARA_BUFSIZE);
- if (ret != CYNARA_API_SUCCESS)
- {
- DBG("Failed to cynara_strerror: %d (error log about %s: %d)\n", ret, func_name, err);
- return;
- }
- DBG("%s is failed: %s\n", func_name, buf);
-}
-
-static Eina_Bool
-_e_screenmirror_su_check(struct wl_client *client)
-{
- uid_t uid;
-
- wl_client_get_credentials(client, NULL, &uid, NULL);
-
- if (uid == 0) /* DBG("pass privilege check if super user"); */
- return EINA_TRUE;
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_screenmirror_privilege(struct wl_client *client, cynara *p_cynara, int socket_fd, const char *rule)
-{
- int ret, pid;
- char *clientSmack = NULL, *uid = NULL, *client_session = NULL;
- Eina_Bool res = EINA_FALSE;
-
- ret = cynara_creds_socket_get_user(socket_fd, USER_METHOD_UID, &uid);
- E_SCREENMIRROR_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_user", ret, finish);
-
- ret = cynara_creds_socket_get_pid(socket_fd, &pid);
- E_SCREENMIRROR_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_pid", ret, finish);
-
- client_session = cynara_session_from_pid(pid);
-
- ret = cynara_creds_socket_get_client(socket_fd, CLIENT_METHOD_SMACK, &clientSmack);
- E_SCREENMIRROR_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_client", ret, finish);
-
- ret = cynara_check(p_cynara, clientSmack, client_session, uid, rule);
-
- if (ret == CYNARA_API_ACCESS_ALLOWED)
- res = EINA_TRUE;
-
-finish:
- E_FREE(client_session);
- E_FREE(clientSmack);
- E_FREE(uid);
-
- return res;
-}
-#endif
-
-static Eina_Bool
-_e_screenmirror_privilege_check(struct wl_client *client, E_Mirror *mirror, int socket_fd, const char *rule)
-{
-#ifdef ENABLE_CYNARA
- Eina_Bool res = EINA_FALSE;
-
- if (mirror->p_cynara == NULL && !mirror->cynara_initialized) return EINA_TRUE;
-
- if (_e_screenmirror_su_check(client) == EINA_TRUE) return EINA_TRUE;
-
- res = _e_screenmirror_privilege(client, mirror->p_cynara, socket_fd, rule);
-
- return res;
-#else
- return EINA_TRUE;
-#endif
-}
-
-static Eina_Bool
-_e_screenmirror_privilege_check_with_cynara_init(struct wl_client *client, int socket_fd, const char *rule)
-{
-#ifdef ENABLE_CYNARA
- int ret;
- Eina_Bool res = EINA_FALSE;
- cynara *p_cynara;
-
- if (_e_screenmirror_su_check(client) == EINA_TRUE) return EINA_TRUE;
-
- ret = cynara_initialize(&p_cynara, NULL);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == CYNARA_API_SUCCESS, EINA_FALSE);
-
- res = _e_screenmirror_privilege(client, p_cynara, socket_fd, rule);
-
- if (p_cynara) cynara_finish(p_cynara);
-
- return res;
-#else
- return EINA_TRUE;
-#endif
-}
-
-static void
-_e_tz_screenmirror_center_rect (int src_w, int src_h, int dst_w, int dst_h, Eina_Rectangle *fit)
-{
- float rw, rh;
-
- if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !fit)
- return;
-
- rw = (float)src_w / dst_w;
- rh = (float)src_h / dst_h;
-
- if (rw > rh)
- {
- fit->w = dst_w;
- fit->h = src_h / rw;
- fit->x = 0;
- fit->y = (dst_h - fit->h) / 2;
- }
- else if (rw < rh)
- {
- fit->w = src_w / rh;
- fit->h = dst_h;
- fit->x = (dst_w - fit->w) / 2;
- fit->y = 0;
- }
- else
- {
- fit->w = dst_w;
- fit->h = dst_h;
- fit->x = 0;
- fit->y = 0;
- }
-
- if (fit->x % 2)
- fit->x = fit->x - 1;
-}
-
-void
-_e_tz_screenmirror_rect_scale (int src_w, int src_h, int dst_w, int dst_h, Eina_Rectangle *scale)
-{
- float ratio;
- Eina_Rectangle center;
-
- if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !scale)
- return;
-
- _e_tz_screenmirror_center_rect(src_w, src_h, dst_w, dst_h, ¢er);
-
- ratio = (float)center.w / src_w;
-
- scale->x = scale->x * ratio + center.x;
- scale->y = scale->y * ratio + center.y;
- scale->w = scale->w * ratio;
- scale->h = scale->h * ratio;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_cb_timeout(void *data)
-{
- E_Mirror *mirror = data;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(mirror, ECORE_CALLBACK_RENEW);
-
- _e_tz_screenmirror_vblank_handler((void*)mirror);
-
- return ECORE_CALLBACK_RENEW;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_watch_vblank(E_Mirror *mirror)
-{
- if (mirror != keep_stream_mirror)
- return EINA_FALSE;
-
- /* If not DPMS_ON, we call vblank handler directly to dump screen */
- if (e_devicemgr_dpms_get(mirror->drm_output))
- {
- if (!mirror->timer)
- mirror->timer = ecore_timer_add((double)1/DUMP_FPS,
- _e_tz_screenmirror_cb_timeout, mirror);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mirror->timer, EINA_FALSE);
-
- return EINA_TRUE;
- }
- else if (mirror->timer)
- {
- ecore_timer_del(mirror->timer);
- mirror->timer = NULL;
- }
-
- if (mirror->wait_vblank)
- return EINA_TRUE;
-
- if (!ecore_drm_output_wait_vblank(mirror->drm_output, mirror->per_vblank,
- _e_tz_screenmirror_vblank_handler, mirror))
- {
- ERR("failed: ecore_drm_output_wait_vblank");
- return EINA_FALSE;
- }
-
- mirror->wait_vblank = EINA_TRUE;
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_buffer_check(struct wl_resource *resource)
-{
- if (wl_shm_buffer_get(resource) ||
- wayland_tbm_server_get_surface(e_comp->wl_comp_data->tbm.server, resource))
- return EINA_TRUE;
-
- ERR("unrecognized buffer");
-
- return EINA_FALSE;
-}
-
-static void
-_e_tz_screenmirror_ui_buffer_cb_free(E_Devmgr_Buf *mbuf, void *data)
-{
- E_Mirror *mirror = (E_Mirror*)data;
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
- mirror->ui_buffer_list = eina_list_remove(mirror->ui_buffer_list, mbuf);
-}
-
-static E_Devmgr_Buf*
-_e_tz_screenmirror_ui_buffer_get(E_Mirror *mirror)
-{
- E_Devmgr_Buf *mbuf;
- tbm_surface_h buffer;
- Eina_List *l;
- tdm_error err = TDM_ERROR_NONE;
-
- buffer = tdm_layer_get_displaying_buffer(mirror->tdm_primary_layer, &err);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, NULL);
-
- EINA_LIST_FOREACH(mirror->ui_buffer_list, l, mbuf)
- if (mbuf->tbm_surface == buffer)
- return mbuf;
-
- mbuf = e_devmgr_buffer_create_tbm(buffer);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, NULL);
-
- e_devmgr_buffer_free_func_add(mbuf, _e_tz_screenmirror_ui_buffer_cb_free, mirror);
- mirror->ui_buffer_list = eina_list_append(mirror->ui_buffer_list, mbuf);
-
- return mbuf;
-}
-
-static E_Devmgr_Buf*
-_e_tz_screenmirror_devicemgr_buffer_by_tbm_surface_get(E_Mirror *mirror, tbm_surface_h buffer)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l;
-
- EINA_LIST_FOREACH(mirror->ui_buffer_list, l, mbuf)
- if (mbuf->tbm_surface == buffer)
- return mbuf;
-
- mbuf = e_devmgr_buffer_create_tbm(buffer);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, NULL);
-
- e_devmgr_buffer_free_func_add(mbuf, _e_tz_screenmirror_ui_buffer_cb_free, mirror);
- mirror->ui_buffer_list = eina_list_append(mirror->ui_buffer_list, mbuf);
-
- return mbuf;
-}
-
-static void
-_e_tz_screenmirror_pp_destroy(E_Mirror *mirror)
-{
- if (!mirror->pp)
- return;
-
- tdm_pp_destroy(mirror->pp);
- mirror->pp = NULL;
-}
-
-static void
-_e_tz_screenmirror_drm_buffer_clear_check(E_Mirror_Buffer *buffer)
-{
- E_Mirror *mirror = buffer->mirror;
- E_Devmgr_Buf *mbuf, *dst;
- Eina_List *l;
- uint32_t buf_id;
-
- dst = buffer->mbuf;
- buf_id = wl_resource_get_id(dst->resource);
-
- EINA_LIST_FOREACH(mirror->buffer_clear_check, l, mbuf)
- {
- uint32_t id;
-
- id = wl_resource_get_id(mbuf->resource);
- if (id == buf_id)
- return;
- }
-
- e_devmgr_buffer_clear(dst);
- mirror->buffer_clear_check = eina_list_append(mirror->buffer_clear_check, dst);
-}
-
-static Eina_Bool
-_e_tz_screenmirror_tmp_buffer_create(E_Mirror_Buffer *buffer)
-{
- tbm_surface_h tbm_surface = NULL;
- E_Devmgr_Buf *mbuf = NULL;
-
- tbm_surface = tbm_surface_create(buffer->mbuf->width, buffer->mbuf->height, buffer->mbuf->tbmfmt);
- EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, EINA_FALSE);
-
- mbuf = e_devmgr_buffer_create_tbm(tbm_surface);
- if (mbuf == NULL)
- {
- tbm_surface_destroy(tbm_surface);
- return EINA_FALSE;
- }
-
- e_devmgr_buffer_clear(mbuf);
- buffer->tmp = mbuf;
-
- return EINA_TRUE;
-}
-
-static void
-_e_tz_screenmirror_copy_tmp_buffer(E_Mirror_Buffer *buffer)
-{
- tbm_surface_h tbm_surface = NULL;
-
- e_devmgr_buffer_copy(buffer->tmp, buffer->mbuf);
-
- tbm_surface = buffer->tmp->tbm_surface;
-
- e_devmgr_buffer_unref(buffer->tmp);
- buffer->tmp = NULL;
-
- tbm_surface_destroy(tbm_surface);
-}
-
-static void
-_e_tz_screenmirror_showing_rect_get(Eina_Rectangle *out_rect, Eina_Rectangle *dst_rect, Eina_Rectangle *showing_rect)
-{
- showing_rect->x = dst_rect->x;
- showing_rect->y = dst_rect->y;
-
- if (dst_rect->x >= out_rect->w)
- showing_rect->w = 0;
- else if (dst_rect->x + dst_rect->w > out_rect->w)
- showing_rect->w = out_rect->w - dst_rect->x;
- else
- showing_rect->w = dst_rect->w;
-
- if (dst_rect->y >= out_rect->h)
- showing_rect->h = 0;
- else if (dst_rect->y + dst_rect->h > out_rect->h)
- showing_rect->h = out_rect->h - dst_rect->y;
- else
- showing_rect->h = dst_rect->h;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_src_crop_get(E_Mirror *mirror, tdm_layer *layer, Eina_Rectangle *fit, Eina_Rectangle *showing_rect)
-{
- tdm_info_layer info;
- tdm_error err = TDM_ERROR_NONE;
- const tdm_output_mode *mode = NULL;
- float ratio_x, ratio_y;
- Eina_Rectangle out_rect;
- Eina_Rectangle dst_rect;
-
- fit->x = 0;
- fit->y = 0;
- fit->w = 0;
- fit->h = 0;
-
- tdm_output_get_mode(mirror->tdm_output, &mode);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, EINA_FALSE);
-
- out_rect.x = 0;
- out_rect.y = 0;
- out_rect.w = mode->hdisplay;
- out_rect.h = mode->vdisplay;
-
- err = tdm_layer_get_info(layer, &info);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, EINA_FALSE);
-
- dst_rect.x = info.dst_pos.x;
- dst_rect.y = info.dst_pos.y;
- dst_rect.w = info.dst_pos.w;
- dst_rect.h = info.dst_pos.h;
-
- _e_tz_screenmirror_showing_rect_get(&out_rect, &dst_rect, showing_rect);
-
- fit->x = info.src_config.pos.x;
- fit->y = info.src_config.pos.y;
-
- if (info.transform % 2 == 0)
- {
- ratio_x = (float)info.src_config.pos.w / dst_rect.w;
- ratio_y = (float)info.src_config.pos.h / dst_rect.h;
-
- fit->w = showing_rect->w * ratio_x;
- fit->h = showing_rect->h * ratio_y;
- }
- else
- {
- ratio_x = (float)info.src_config.pos.w / dst_rect.h;
- ratio_y = (float)info.src_config.pos.h / dst_rect.w;
-
- fit->w = showing_rect->h * ratio_x;
- fit->h = showing_rect->w * ratio_y;
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_position_get(E_Mirror *mirror, E_Devmgr_Buf *mbuf, Eina_Rectangle *fit)
-{
- E_Devmgr_Buf *ui = NULL;
-
- ui = _e_tz_screenmirror_ui_buffer_get(mirror);
- if (ui == NULL)
- {
- ERR("_e_tz_screenmirror_position_get: get ui buf failed");
- return EINA_FALSE;
- }
-
- if (screenshot_auto_rotation &&
- ((mirror->angle + mirror->eout_rotate) % 360 == 90 || (mirror->angle + mirror->eout_rotate) % 360 == 270))
- _e_tz_screenmirror_center_rect(ui->height, ui->width, mbuf->width, mbuf->height, fit);
- else
- _e_tz_screenmirror_center_rect(ui->width, ui->height, mbuf->width, mbuf->height, fit);
-
- return EINA_TRUE;
-}
-
-static void
-_e_tz_screenmirror_dump_still_get_cropinfo(E_Devmgr_Buf *tmp, E_Devmgr_Buf *dst, tdm_layer *layer,
- int w, int h, Eina_Rectangle *pos, Eina_Rectangle *showing_pos,
- Eina_Rectangle *dst_crop, int rotate)
-{
- tdm_info_layer info;
- tdm_error err = TDM_ERROR_NONE;
-
- dst_crop->x = 0;
- dst_crop->y = 0;
- dst_crop->w = 0;
- dst_crop->h = 0;
-
- err = tdm_layer_get_info(layer, &info);
- EINA_SAFETY_ON_FALSE_RETURN(err == TDM_ERROR_NONE);
-
- if (info.src_config.pos.w == w && info.src_config.pos.h == h &&
- pos->x == 0 && pos->y == 0 && pos->w == tmp->width && pos->h == tmp->height)
- {
- dst_crop->x = pos->x;
- dst_crop->y = pos->y;
- dst_crop->w = pos->w;
- dst_crop->h = pos->h;
- }
- else if ((w == pos->w) && (h == pos->h) && (showing_pos->w == pos->w) && (showing_pos->h == pos->h))
- {
- dst_crop->x = info.dst_pos.x + pos->x;
- dst_crop->y = info.dst_pos.y + pos->y;
- dst_crop->w = info.dst_pos.w;
- dst_crop->h = info.dst_pos.h;
- }
- else if (rotate == 0)
- {
- dst_crop->x = showing_pos->x * pos->w / w + pos->x;
- dst_crop->y = showing_pos->y * pos->h / h + pos->y;
- dst_crop->w = showing_pos->w * pos->w / w;
- dst_crop->h = showing_pos->h * pos->h / h;
- }
- else if (rotate == 90)
- {
- dst_crop->x = (h - showing_pos->y - showing_pos->h) * pos->w / h + pos->x;
- dst_crop->y = showing_pos->x * pos->h / w + pos->y;
- dst_crop->w = showing_pos->h * pos->w / h;
- dst_crop->h = showing_pos->w * pos->h / w;
- }
- else if (rotate == 180)
- {
- dst_crop->x = (w - showing_pos->x - showing_pos->w) * pos->w / w + pos->x;
- dst_crop->y = (h - showing_pos->y - showing_pos->h) * pos->h / h + pos->y;
- dst_crop->w = showing_pos->w * pos->w / w;
- dst_crop->h = showing_pos->h * pos->h / h;
- }
- else if (rotate == 270)
- {
- dst_crop->x = showing_pos->y * pos->w / h + pos->x;
- dst_crop->y = (w - showing_pos->x - showing_pos->w) * pos->h / w + pos->y;
- dst_crop->w = showing_pos->h * pos->w / h;
- dst_crop->h = showing_pos->w * pos->h / w;
- }
- else
- {
- dst_crop->x = pos->x;
- dst_crop->y = pos->y;
- dst_crop->w = pos->w;
- dst_crop->h = pos->h;
- ERR("_e_tz_screenmirror_dump_still_get_cropinfo: unknown case error");
- }
-}
-
-static void
-_e_tz_screenmirror_dump_still(E_Mirror_Buffer *buffer)
-{
- E_Mirror *mirror = buffer->mirror;
- E_Devmgr_Buf *ui, *dst;
- tdm_error err = TDM_ERROR_NONE;
- int count;
- int i;
- int rotate = 0;
-
- if (buffer->mbuf->type == TYPE_SHM)
- {
- if (!_e_tz_screenmirror_tmp_buffer_create(buffer))
- {
- ERR("_e_tz_screenmirror_dump_still: tmp buffer create fail");
- return;
- }
-
- dst = buffer->tmp;
- }
- else
- dst = buffer->mbuf;
- EINA_SAFETY_ON_NULL_RETURN(dst);
-
- e_devmgr_buffer_clear(dst);
-
- ui = _e_tz_screenmirror_ui_buffer_get(mirror);
- EINA_SAFETY_ON_NULL_RETURN(ui);
-
- if (mirror->rotate_change)
- {
- int angle = 0;
-
- angle = (mirror->angle + mirror->eout_rotate) % 360;
- if (angle == 90)
- rotate = 90;
- else if (angle == 180)
- rotate = 180;
- else if (angle == 270)
- rotate = 270;
- }
- else if (screenshot_auto_rotation && mirror->eout_rotate == 90)
- rotate = 90;
- else if (screenshot_auto_rotation && mirror->eout_rotate == 180)
- rotate = 180;
- else if (screenshot_auto_rotation && mirror->eout_rotate == 270)
- rotate = 270;
-
- err = tdm_output_get_layer_count(mirror->tdm_output, &count);
- EINA_SAFETY_ON_FALSE_RETURN(err == TDM_ERROR_NONE);
- EINA_SAFETY_ON_FALSE_RETURN(count >= 0);
-
- for (i = 0; i < count; i++)
- {
- tdm_layer *layer;
- tdm_layer_capability capability;
- tbm_surface_h surface = NULL;
- E_Devmgr_Buf *tmp = NULL;
- Eina_Rectangle dst_pos = {0, };
- Eina_Rectangle showing_pos = {0, };
- Eina_Rectangle src_crop = {0, };
- Eina_Rectangle dst_crop = {0, };
-
- layer = tdm_output_get_layer(mirror->tdm_output, i, &err);
- EINA_SAFETY_ON_FALSE_RETURN(err == TDM_ERROR_NONE);
-
- if (layer != mirror->tdm_primary_layer)
- {
- err = tdm_layer_get_capabilities(layer, &capability);
- EINA_SAFETY_ON_FALSE_RETURN(err == TDM_ERROR_NONE);
- if (capability & TDM_LAYER_CAPABILITY_VIDEO)
- continue;
-
- surface = tdm_layer_get_displaying_buffer(layer, &err);
- if (surface == NULL)
- continue;
-
- tmp = _e_tz_screenmirror_devicemgr_buffer_by_tbm_surface_get(mirror, surface);
- if (tmp == NULL)
- continue;
-
- _e_tz_screenmirror_src_crop_get(mirror, layer, &src_crop, &showing_pos);
- }
- else
- {
- tmp = ui;
- src_crop.x = showing_pos.x = 0;
- src_crop.y = showing_pos.y = 0;
- src_crop.w = showing_pos.w = tmp->width;
- src_crop.h = showing_pos.h = tmp->height;
- }
-
- _e_tz_screenmirror_position_get(mirror, buffer->mbuf, &dst_pos);
-
- _e_tz_screenmirror_dump_still_get_cropinfo(tmp, dst, layer, ui->width, ui->height,
- &dst_pos, &showing_pos, &dst_crop, rotate);
- e_devmgr_buffer_convert(tmp, dst,
- src_crop.x, src_crop.y, src_crop.w, src_crop.h,
- dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h,
- EINA_TRUE, rotate, 0, 0);
-
- }
-
- if (buffer->mbuf->type == TYPE_SHM)
- _e_tz_screenmirror_copy_tmp_buffer(buffer);
-}
-
-static void
-_e_tz_screenmirror_buffer_free(E_Mirror_Buffer *buffer)
-{
- E_Mirror *mirror = buffer->mirror;
-
- if (buffer->tmp)
- _e_tz_screenmirror_copy_tmp_buffer(buffer);
-
- /* then, dequeue and send dequeue event */
- _e_tz_screenmirror_buffer_dequeue(buffer);
-
- if (buffer->destroy_listener.notify)
- {
- wl_list_remove(&buffer->destroy_listener.link);
- buffer->destroy_listener.notify = NULL;
- }
-
- if (buffer->mbuf)
- {
- e_devmgr_buffer_free_func_del(buffer->mbuf, _e_tz_screenmirror_buffer_cb_free, buffer);
- e_devmgr_buffer_unref(buffer->mbuf);
-
- mirror->buffer_clear_check = eina_list_remove(mirror->buffer_clear_check, buffer->mbuf);
- }
-
- E_FREE(buffer);
-}
-
-static void
-_e_tz_screenmirror_capture_oneshot_done_handler(tdm_capture *capture, tbm_surface_h buffer, void *user_data)
-{
- E_Mirror_Buffer *mirror_buffer = user_data;
- E_Mirror *mirror = mirror_buffer->mirror;
-
- if (mirror_buffer->mbuf->type == TYPE_SHM)
- _e_tz_screenmirror_copy_tmp_buffer(mirror_buffer);
-
- _e_tz_screenmirror_destroy(mirror);
-
- DBG("_e_tz_screenmirror_capture_oneshot_done");
-}
-
-static Eina_Bool
-_e_tz_screenmirror_capture_stream_done(void *data)
-{
- E_Mirror *mirror = data;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(mirror, ECORE_CALLBACK_CANCEL);
-
- if (mirror != keep_stream_mirror)
- return ECORE_CALLBACK_CANCEL;
-
- if (mirror->capture)
- {
- tdm_capture_destroy(mirror->capture);
- mirror->capture = NULL;
- }
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-static E_Mirror_Buffer *
-_e_tz_screenmirror_mirrorbuf_find(E_Mirror *mirror, tbm_surface_h surf)
-{
- Eina_List *l;
- E_Mirror_Buffer *buffer = NULL;
-
- if (!mirror->buffer_queue)
- return NULL;
-
- EINA_LIST_FOREACH(mirror->buffer_queue, l, buffer)
- {
- if (!buffer || !buffer->mbuf)
- continue;
-
- if (buffer->mbuf->type == TYPE_SHM)
- {
- if (!buffer->tmp || !buffer->tmp->tbm_surface)
- continue;
-
- if (buffer->tmp->tbm_surface == surf)
- {
- _e_tz_screenmirror_copy_tmp_buffer(buffer);
- return buffer;
- }
- }
- else
- {
- if (!buffer->mbuf->tbm_surface)
- continue;
-
- if (buffer->mbuf->tbm_surface == surf)
- return buffer;
- }
- }
-
- return NULL;
-}
-
-static void
-_e_tz_screenmirror_capture_stream_done_handler(tdm_capture *capture, tbm_surface_h surf, void *user_data)
-{
- E_Mirror *mirror = user_data;
- E_Mirror_Buffer *buffer = NULL;
-
- if (mirror != keep_stream_mirror)
- return;
-
- buffer = _e_tz_screenmirror_mirrorbuf_find(mirror, surf);
- if (buffer == NULL)
- {
- ERR("_e_tz_screenmirror_capture_stream_done_handler: find mirror buffer failed");
- return;
- }
-
- _e_tz_screenmirror_buffer_dequeue(buffer);
-
- if (mirror->started == EINA_FALSE)
- {
- if (eina_list_count(mirror->buffer_queue) == 0)
- mirror->capture_timer = ecore_timer_add((double)1/DUMP_FPS, _e_tz_screenmirror_capture_stream_done, mirror);
- }
-}
-
-static E_Client *
-_e_tz_screenmirror_top_visible_ec_get()
-{
- E_Client *ec;
- Evas_Object *o;
- E_Comp_Wl_Client_Data *cdata;
-
- for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
- {
- ec = evas_object_data_get(o, "E_Client");
-
- /* check e_client and skip e_clients not intersects with zone */
- if (!ec) continue;
- if (e_object_is_del(E_OBJECT(ec))) continue;
- if (e_client_util_ignored_get(ec)) continue;
- if (ec->iconic) continue;
- if (ec->visible == 0) continue;
- if (!(ec->visibility.obscured == 0 || ec->visibility.obscured == 1)) continue;
- if (!ec->frame) continue;
- if (!evas_object_visible_get(ec->frame)) continue;
- /* if ec is subsurface, skip this */
- cdata = (E_Comp_Wl_Client_Data *)ec->comp_data;
- if (cdata && cdata->sub.data) continue;
-
- return ec;
- }
-
- return NULL;
-}
-
-static void
-_e_tz_screenmirror_get_angle(E_Mirror *mirror)
-{
- E_Client *ec = NULL;
- E_Output *eout = NULL;
-
- mirror->eout_rotate = 0;
- mirror->angle = 0;
-
- ec = _e_tz_screenmirror_top_visible_ec_get();
- if (ec)
- {
- mirror->angle = ec->e.state.rot.ang.curr;
-
- eout = e_output_find(ec->zone->output_id);
- if (eout)
- mirror->eout_rotate = eout->config.rotation;
- }
-}
-
-static Eina_Bool
-_e_tz_screenmirror_tdm_capture_handle_set(E_Mirror_Buffer *buffer, tdm_capture *capture, tdm_capture_capability cap)
-{
- E_Mirror *mirror = buffer->mirror;
- tdm_error err = TDM_ERROR_NONE;
-
- if (cap == TDM_CAPTURE_CAPABILITY_ONESHOT)
- err = tdm_capture_set_done_handler(capture, _e_tz_screenmirror_capture_oneshot_done_handler, buffer);
- else
- err = tdm_capture_set_done_handler(capture, _e_tz_screenmirror_capture_stream_done_handler, mirror);
- if (err != TDM_ERROR_NONE)
- {
- ERR("_e_tz_screenmirror_tdm_capture_support: tdm_capture set_handler failed");
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_tdm_capture_support(E_Mirror_Buffer *buffer, tdm_capture_capability cap)
-{
- E_Mirror *mirror = buffer->mirror;
- tdm_error err = TDM_ERROR_NONE;
- tdm_capture *capture = NULL;
- tdm_info_capture capture_info;
- tdm_capture_capability capabilities;
- Eina_Rectangle dst_pos;
-
- err = tdm_display_get_capture_capabilities(mirror->tdm_dpy, &capabilities);
- EINA_SAFETY_ON_TRUE_RETURN_VAL(err == TDM_ERROR_NO_CAPABILITY, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, EINA_FALSE);
-
- if (capabilities & cap)
- {
- if (mirror->capture)
- return EINA_TRUE;
-
- capture = tdm_output_create_capture(mirror->tdm_output, &err);
- if (err != TDM_ERROR_NONE)
- {
- ERR("_e_tz_screenmirror_tdm_capture_support: create tdm_capture failed");
- return EINA_FALSE;
- }
-
- CLEAR(capture_info);
- capture_info.dst_config.size.h = buffer->mbuf->width_from_pitch;
- capture_info.dst_config.size.v = buffer->mbuf->height;
- capture_info.dst_config.pos.x = 0;
- capture_info.dst_config.pos.y = 0;
- capture_info.dst_config.pos.w = buffer->mbuf->width;
- capture_info.dst_config.pos.h = buffer->mbuf->height;
- capture_info.dst_config.format = buffer->mbuf->tbmfmt;
- capture_info.transform = TDM_TRANSFORM_NORMAL;
- if (cap == TDM_CAPTURE_CAPABILITY_ONESHOT)
- capture_info.type = TDM_CAPTURE_TYPE_ONESHOT;
- else
- capture_info.type = TDM_CAPTURE_TYPE_STREAM;
-
- if (_e_tz_screenmirror_position_get(mirror, buffer->mbuf, &dst_pos))
- {
- capture_info.dst_config.pos.x = dst_pos.x;
- capture_info.dst_config.pos.y = dst_pos.y;
- capture_info.dst_config.pos.w = dst_pos.w;
- capture_info.dst_config.pos.h = dst_pos.h;
-
- if (mirror->rotate_change)
- {
- int tmp;
-
- tmp = (mirror->angle + mirror->eout_rotate) % 360;
- if (tmp == 90)
- capture_info.transform = TDM_TRANSFORM_90;
- else if (tmp == 180)
- capture_info.transform = TDM_TRANSFORM_180;
- else if (tmp == 270)
- capture_info.transform = TDM_TRANSFORM_270;
- }
- else if (screenshot_auto_rotation && mirror->eout_rotate == 90)
- capture_info.transform = TDM_TRANSFORM_90;
- else if (screenshot_auto_rotation && mirror->eout_rotate == 180)
- capture_info.transform = TDM_TRANSFORM_180;
- else if (screenshot_auto_rotation && mirror->eout_rotate == 270)
- capture_info.transform = TDM_TRANSFORM_270;
- }
-
- err = tdm_capture_set_info(capture, &capture_info);
- if (err != TDM_ERROR_NONE)
- {
- ERR("_e_tz_screenmirror_tdm_capture_support: tdm_capture set_info failed");
- tdm_capture_destroy(capture);
- return EINA_FALSE;
- }
-
- if (_e_tz_screenmirror_tdm_capture_handle_set(buffer, capture, cap) == EINA_FALSE)
- {
- tdm_capture_destroy(capture);
- return EINA_FALSE;
- }
- mirror->capture = capture;
-
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_capture_cb_timeout(void *data)
-{
- E_Mirror *mirror = data;
- E_Mirror_Buffer *buffer;
- Eina_List *l;
-
- EINA_SAFETY_ON_NULL_GOTO(mirror, done);
-
- EINA_LIST_FOREACH(mirror->buffer_queue, l, buffer)
- {
- if (!buffer->in_use) break;
- }
-
- /* can be null when client doesn't queue a buffer previously */
- if (!buffer)
- goto done;
-
- buffer->in_use = EINA_TRUE;
-
- _e_tz_screenmirror_buffer_dequeue(buffer);
-
-done:
- return ECORE_CALLBACK_RENEW;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_tdm_capture_attach(E_Mirror *mirror, E_Mirror_Buffer *buffer)
-{
- tdm_error err = TDM_ERROR_NONE;
-
- if (buffer->mbuf->type == TYPE_SHM)
- {
- if (!_e_tz_screenmirror_tmp_buffer_create(buffer))
- {
- ERR("_e_tz_screenmirror_tdm_capture_attach: tmp buffer create fail");
- return EINA_FALSE;
- }
-
- err = tdm_capture_attach(mirror->capture, buffer->tmp->tbm_surface);
- if (err != TDM_ERROR_NONE)
- {
- e_devmgr_buffer_unref(buffer->tmp);
- buffer->tmp = NULL;
- return EINA_FALSE;
- }
- }
- else
- {
- err = tdm_capture_attach(mirror->capture, buffer->mbuf->tbm_surface);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, EINA_FALSE);
- }
-
- return EINA_TRUE;
-}
-
-static void
-_e_tz_screenmirror_buffer_queue(E_Mirror_Buffer *buffer)
-{
- E_Mirror *mirror = buffer->mirror;
- tdm_error err = TDM_ERROR_NONE;
- E_Mirror_Buffer *buffer_list;
- Eina_List *l;
-
- mirror->buffer_queue = eina_list_append(mirror->buffer_queue, buffer);
-
- if (mirror->started)
- {
- if (_e_tz_screenmirror_tdm_capture_support(buffer, TDM_CAPTURE_CAPABILITY_STREAM))
- {
- _e_tz_screenmirror_drm_buffer_clear_check(buffer);
-
- if (e_devicemgr_dpms_get(mirror->drm_output))
- {
- if (!mirror->timer)
- {
- eina_list_free(mirror->buffer_clear_check);
- mirror->buffer_clear_check = NULL;
- _e_tz_screenmirror_drm_buffer_clear_check(buffer);
- mirror->timer = ecore_timer_add((double)1/DUMP_FPS, _e_tz_screenmirror_capture_cb_timeout, mirror);
- }
- EINA_SAFETY_ON_NULL_RETURN(mirror->timer);
- return;
- }
- else if (mirror->timer)
- {
- ecore_timer_del(mirror->timer);
- mirror->timer = NULL;
- EINA_LIST_FOREACH(mirror->buffer_queue, l, buffer_list)
- {
- if (!buffer_list->in_use)
- {
- buffer_list->in_use = EINA_TRUE;
-
- if (!_e_tz_screenmirror_tdm_capture_attach(mirror, buffer_list))
- {
- ERR("_e_tz_screenmirror_buffer_queue: attach fail");
- return;
- }
- }
- }
- err = tdm_capture_commit(mirror->capture);
- EINA_SAFETY_ON_FALSE_RETURN(err == TDM_ERROR_NONE);
- }
- else
- {
- buffer->in_use = EINA_TRUE;
-
- if (!_e_tz_screenmirror_tdm_capture_attach(mirror, buffer))
- {
- ERR("_e_tz_screenmirror_buffer_queue: attach fail");
- return;
- }
- err = tdm_capture_commit(mirror->capture);
- EINA_SAFETY_ON_FALSE_RETURN(err == TDM_ERROR_NONE);
- }
- }
- else
- {
- if (buffer->mbuf->type == TYPE_SHM)
- {
- if (!_e_tz_screenmirror_tmp_buffer_create(buffer))
- {
- ERR("_e_tz_screenmirror_buffer_queue: tmp buffer create fail");
- return;
- }
- }
- _e_tz_screenmirror_watch_vblank(mirror);
- }
- }
- else
- {
- if (_e_tz_screenmirror_tdm_capture_support(buffer, TDM_CAPTURE_CAPABILITY_STREAM))
- {
- _e_tz_screenmirror_drm_buffer_clear_check(buffer);
-
- if (e_devicemgr_dpms_get(mirror->drm_output))
- return;
-
- if (!_e_tz_screenmirror_tdm_capture_attach(mirror, buffer))
- {
- ERR("_e_tz_screenmirror_buffer_queue: attach fail");
- return;
- }
- }
- else
- {
- if (buffer->mbuf->type == TYPE_SHM)
- {
- if (!_e_tz_screenmirror_tmp_buffer_create(buffer))
- {
- ERR("_e_tz_screenmirror_buffer_queue: tmp buffer create fail");
- return;
- }
- }
- }
- }
-}
-
-static void
-_e_tz_screenmirror_buffer_dequeue(E_Mirror_Buffer *buffer)
-{
- E_Mirror *mirror = buffer->mirror;
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
- if (!mirror->buffer_queue || !eina_list_data_find_list(mirror->buffer_queue, buffer))
- return;
-
- buffer->in_use = EINA_FALSE;
- mirror->buffer_queue = eina_list_remove(mirror->buffer_queue, buffer);
-
- /* resource == shooter means that we're using weston screenshooter
- * In case of wetson screenshooter, send a done event. Otherwise, send
- * a dequeued event for tizen_screenmirror.
- */
- if (mirror->resource == mirror->shooter)
- {
- if (!mirror->oneshot_client_destroy)
- screenshooter_send_done(mirror->resource);
- }
- else
- tizen_screenmirror_send_dequeued(mirror->resource, buffer->mbuf->resource);
-}
-
-static Eina_Bool
-_e_tz_screenmirror_tdm_capture_oneshot(E_Mirror *mirror, E_Mirror_Buffer *buffer)
-{
- tdm_error err = TDM_ERROR_NONE;
-
- if (!_e_tz_screenmirror_tdm_capture_attach(mirror, buffer))
- {
- ERR("_e_tz_screenmirror_tdm_capture_oneshot: attach fail");
- return EINA_FALSE;
- }
- err = tdm_capture_commit(mirror->capture);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(err == TDM_ERROR_NONE, EINA_FALSE);
-
- return EINA_TRUE;
-}
-
-static void
-_e_tz_screenmirror_buffer_cb_destroy(struct wl_listener *listener, void *data)
-{
- E_Mirror_Buffer *buffer = container_of(listener, E_Mirror_Buffer, destroy_listener);
-
- if (buffer->destroy_listener.notify)
- {
- wl_list_remove(&buffer->destroy_listener.link);
- buffer->destroy_listener.notify = NULL;
- }
-}
-
-static void
-_e_tz_screenmirror_buffer_cb_free(E_Devmgr_Buf *mbuf, void *data)
-{
- E_Mirror_Buffer *buffer = data;
- E_Mirror *mirror = buffer->mirror;
-
- if (mirror->resource == mirror->shooter)
- mirror->oneshot_client_destroy = EINA_TRUE;
-
- _e_tz_screenmirror_buffer_free(buffer);
-}
-
-static E_Mirror_Buffer*
-_e_tz_screenmirror_buffer_get(E_Mirror *mirror, struct wl_resource *resource)
-{
- E_Mirror_Buffer *buffer = NULL;
- struct wl_listener *listener;
-
- listener = wl_resource_get_destroy_listener(resource, _e_tz_screenmirror_buffer_cb_destroy);
- if (listener)
- return container_of(listener, E_Mirror_Buffer, destroy_listener);
-
- if (!(buffer = E_NEW(E_Mirror_Buffer, 1)))
- return NULL;
-
- /* FIXME: this is very tricky. DON'T add listner after e_devmgr_buffer_create. */
- buffer->destroy_listener.notify = _e_tz_screenmirror_buffer_cb_destroy;
- wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
-
- buffer->mbuf = e_devmgr_buffer_create(resource);
- EINA_SAFETY_ON_NULL_GOTO(buffer->mbuf, fail_get);
-
- buffer->mirror = mirror;
-
- DBG("capture buffer: %c%c%c%c %dx%d (%d,%d,%d) (%d,%d,%d)",
- FOURCC_STR(buffer->mbuf->tbmfmt),
- buffer->mbuf->width, buffer->mbuf->height,
- buffer->mbuf->pitches[0], buffer->mbuf->pitches[1], buffer->mbuf->pitches[2],
- buffer->mbuf->offsets[0], buffer->mbuf->offsets[1], buffer->mbuf->offsets[2]);
-
- e_devmgr_buffer_free_func_add(buffer->mbuf, _e_tz_screenmirror_buffer_cb_free, buffer);
-
- return buffer;
-fail_get:
- E_FREE(buffer);
- return NULL;
-}
-
-static void
-_e_tz_screenmirror_vblank_handler(void *data)
-{
- E_Mirror *mirror = data;
- E_Mirror_Buffer *buffer;
- Eina_List *l;
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
- if (mirror != keep_stream_mirror)
- return;
-
- mirror->wait_vblank = EINA_FALSE;
-
- EINA_LIST_FOREACH(mirror->buffer_queue, l, buffer)
- {
- if (!buffer->in_use) break;
- }
-
- /* can be null when client doesn't queue a buffer previously */
- if (!buffer)
- return;
-
- _e_tz_screenmirror_dump_still(buffer);
- _e_tz_screenmirror_buffer_dequeue(buffer);
-
- /* timer is a substitution for vblank during dpms off. so if timer is running,
- * we don't watch vblank events recursively.
- */
- if (!mirror->timer)
- _e_tz_screenmirror_watch_vblank(mirror);
-}
-
-static void
-_e_tz_screenmirror_cb_client_destroy(struct wl_listener *listener, void *data)
-{
- E_Mirror *mirror = container_of(listener, E_Mirror, client_destroy_listener);
-
- if (mirror->resource == mirror->shooter)
- {
- mirror->oneshot_client_destroy = EINA_TRUE;
- return;
- }
- _e_tz_screenmirror_destroy(mirror);
-}
-
-static E_Mirror*
-_e_tz_screenmirror_create(struct wl_client *client, struct wl_resource *shooter_resource, struct wl_resource *output_resource)
-{
- E_Mirror *mirror = NULL;
- Ecore_Drm_Output *drm_output;
- Ecore_Drm_Device *dev;
- Eina_List *devs;
- Eina_List *l, *ll;
- tdm_error err = TDM_ERROR_NONE;
- int count, i, ret;
- unsigned int crtc_id;
-
- mirror = E_NEW(E_Mirror, 1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mirror, NULL);
-
- mirror->stretch = TIZEN_SCREENMIRROR_STRETCH_KEEP_RATIO;
- mirror->shooter = shooter_resource;
- mirror->output = output_resource;
- mirror->wl_output = wl_resource_get_user_data(mirror->output);
- EINA_SAFETY_ON_NULL_GOTO(mirror->wl_output, fail_create);
-
- mirror->per_vblank = (mirror->wl_output->refresh / (DUMP_FPS * 1000));
-
- devs = eina_list_clone(ecore_drm_devices_get());
- EINA_LIST_FOREACH(devs, l, dev)
- EINA_LIST_FOREACH(dev->outputs, ll, drm_output)
- {
- int x, y;
- ecore_drm_output_position_get(drm_output, &x, &y);
- if (x != mirror->wl_output->x || y != mirror->wl_output->y) continue;
- mirror->drm_output = drm_output;
- mirror->drm_device = dev;
- break;
- }
- eina_list_free(devs);
- EINA_SAFETY_ON_NULL_GOTO(mirror->drm_output, fail_create);
-
- mirror->tdm_dpy = tdm_display_init(&err);
- EINA_SAFETY_ON_NULL_GOTO(mirror->tdm_dpy, fail_create);
-
- crtc_id = ecore_drm_output_crtc_id_get(mirror->drm_output);
-
- mirror->tdm_output = tdm_display_get_output(mirror->tdm_dpy, crtc_id, &err);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, fail_create);
-
- err = tdm_output_get_layer_count(mirror->tdm_output, &count);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, fail_create);
- EINA_SAFETY_ON_FALSE_GOTO(count >= 0, fail_create);
-
- for (i = 0; i < count; i++)
- {
- tdm_layer *layer;
- tdm_layer_capability capability;
-
- layer = tdm_output_get_layer(mirror->tdm_output, i, &err);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, fail_create);
-
- err = tdm_layer_get_capabilities(layer, &capability);
- EINA_SAFETY_ON_FALSE_GOTO(err == TDM_ERROR_NONE, fail_create);
-
- if (capability & TDM_LAYER_CAPABILITY_PRIMARY)
- {
- mirror->tdm_primary_layer = layer;
- break;
- }
- }
- EINA_SAFETY_ON_NULL_GOTO(mirror->tdm_primary_layer, fail_create);
-
- INF("per_vblank(%d)", mirror->per_vblank);
-
-#ifdef ENABLE_CYNARA
- ret = cynara_initialize(&mirror->p_cynara, NULL);
- EINA_SAFETY_ON_FALSE_GOTO(ret == CYNARA_API_SUCCESS, fail_create);
- mirror->cynara_initialized = EINA_TRUE;
-#endif
-
- mirror_list = eina_list_append(mirror_list, mirror);
-
- mirror->client_destroy_listener.notify = _e_tz_screenmirror_cb_client_destroy;
- wl_client_add_destroy_listener(client, &mirror->client_destroy_listener);
-
- mirror->oneshot_client_destroy = EINA_FALSE;
-
- return mirror;
-fail_create:
-#ifdef ENABLE_CYNARA
- mirror->p_cynara = NULL;
-#endif
-
- if (mirror->tdm_dpy)
- tdm_display_deinit(mirror->tdm_dpy);
-
- E_FREE(mirror);
-
- return NULL;
-}
-
-static Eina_Bool
-_e_tz_screenmirror_find_mirror(E_Mirror *mirror)
-{
- if (!eina_list_data_find(mirror_list, mirror))
- return EINA_FALSE;
- else
- return EINA_TRUE;
-}
-
-static void
-_e_tz_screenmirror_destroy(E_Mirror *mirror)
-{
- E_Mirror_Buffer *buffer;
- Eina_List *l, *ll;
- E_Devmgr_Buf *mbuf;
-
- if (!mirror)
- return;
-
- if (!_e_tz_screenmirror_find_mirror(mirror))
- return;
- mirror_list = eina_list_remove(mirror_list, mirror);
-
-#ifdef ENABLE_CYNARA
- if (mirror->p_cynara) cynara_finish(mirror->p_cynara);
- mirror->p_cynara = NULL;
- mirror->cynara_initialized = EINA_FALSE;
-#endif
-
- if (mirror->capture_timer)
- ecore_timer_del(mirror->capture_timer);
- mirror->capture_timer = NULL;
-
- if (mirror->timer)
- ecore_timer_del(mirror->timer);
- mirror->timer = NULL;
-
- if (mirror->client_destroy_listener.notify)
- wl_list_remove(&mirror->client_destroy_listener.link);
- mirror->client_destroy_listener.notify = NULL;
-
- wl_resource_set_destructor(mirror->resource, NULL);
-
- _e_tz_screenmirror_pp_destroy(mirror);
-
- eina_list_free(mirror->buffer_clear_check);
- mirror->buffer_clear_check = NULL;
-
- EINA_LIST_FOREACH_SAFE(mirror->buffer_queue, l, ll, buffer)
- _e_tz_screenmirror_buffer_free(buffer);
- mirror->buffer_queue = NULL;
-
- EINA_LIST_FOREACH_SAFE(mirror->ui_buffer_list, l, ll, mbuf)
- e_devmgr_buffer_unref(mbuf);
- mirror->ui_buffer_list = NULL;
-
- if (mirror->capture)
- tdm_capture_destroy(mirror->capture);
- mirror->capture = NULL;
-
- if (mirror->tdm_dpy)
- tdm_display_deinit(mirror->tdm_dpy);
- mirror->tdm_dpy = NULL;
-
- if (keep_stream_mirror == mirror)
- keep_stream_mirror = NULL;
-
- free(mirror);
-#if 0
- if (e_devmgr_buffer_list_length() > 0)
- e_devmgr_buffer_list_print(NULL);
-#endif
-}
-
-static void
-destroy_tz_screenmirror(struct wl_resource *resource)
-{
- E_Mirror *mirror = wl_resource_get_user_data(resource);
-
- _e_tz_screenmirror_destroy(mirror);
-}
-
-static void
-_e_tz_screenmirror_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-_e_tz_screenmirror_cb_set_stretch(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t stretch)
-{
- E_Mirror *mirror = wl_resource_get_user_data(resource);
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
-
- if (_e_screenmirror_privilege_check(client, mirror, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_FALSE)
- {
- ERR("_e_tz_screenmirror_cb_set_stretch: priv check failed");
- return;
- }
-
- if (mirror->stretch == stretch)
- return;
-
- mirror->stretch = stretch;
-}
-
-static void
-_e_tz_screenmirror_cb_queue(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource)
-{
- E_Mirror *mirror = wl_resource_get_user_data(resource);
- E_Mirror_Buffer *buffer;
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
-
- if (_e_screenmirror_privilege_check(client, mirror, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_FALSE)
- {
- ERR("_e_tz_screenmirror_cb_queue: priv check failed");
- return;
- }
-
- if (!_e_tz_screenmirror_buffer_check(buffer_resource))
- {
- wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
- "tizen_screenshooter failed: wrong buffer resource");
- return;
- }
-
- buffer = _e_tz_screenmirror_buffer_get(mirror, buffer_resource);
- if (!buffer)
- {
- wl_resource_post_no_memory(resource);
- return;
- }
-
- _e_tz_screenmirror_buffer_queue(buffer);
-}
-
-static void
-_e_tz_screenmirror_cb_dequeue(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource)
-{
- E_Mirror *mirror = wl_resource_get_user_data(resource);
- E_Mirror_Buffer *buffer;
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
-
- if (_e_screenmirror_privilege_check(client, mirror, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_FALSE)
- {
- ERR("_e_tz_screenmirror_cb_dequeue: priv check failed");
- return;
- }
-
- if (!_e_tz_screenmirror_buffer_check(buffer_resource))
- {
- wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
- "tizen_screenshooter failed: wrong buffer resource");
- return;
- }
-
- buffer = _e_tz_screenmirror_buffer_get(mirror, buffer_resource);
- if (!buffer || !eina_list_data_find_list(mirror->buffer_queue, buffer))
- return;
-
- _e_tz_screenmirror_buffer_dequeue(buffer);
-}
-
-static void
-_e_tz_screenmirror_cb_start(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
- E_Mirror *mirror = wl_resource_get_user_data(resource);
- tdm_error err = TDM_ERROR_NONE;
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
-
- if (_e_screenmirror_privilege_check(client, mirror, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_FALSE)
- {
- ERR("_e_tz_screenmirror_cb_start: priv check failed");
- return;
- }
-
- if (mirror->started) return;
-
- mirror->started = EINA_TRUE;
-
- if (!mirror->buffer_queue)
- return;
-
- if (mirror->capture)
- {
- if (e_devicemgr_dpms_get(mirror->drm_output))
- {
- if (!mirror->timer)
- mirror->timer = ecore_timer_add((double)1/DUMP_FPS, _e_tz_screenmirror_capture_cb_timeout, mirror);
- EINA_SAFETY_ON_NULL_RETURN(mirror->timer);
- return;
- }
-
- err = tdm_capture_commit(mirror->capture);
- EINA_SAFETY_ON_FALSE_RETURN(err == TDM_ERROR_NONE);
- }
- else
- _e_tz_screenmirror_watch_vblank(mirror);
-}
-
-static void
-_e_tz_screenmirror_cb_stop(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
-{
- E_Mirror *mirror = wl_resource_get_user_data(resource);
-
- EINA_SAFETY_ON_NULL_RETURN(mirror);
-
- if (_e_screenmirror_privilege_check(client, mirror, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_FALSE)
- {
- ERR("_e_tz_screenmirror_cb_stop: priv check failed");
- return;
- }
-
- if (!mirror->started) return;
-
- mirror->started = EINA_FALSE;
-
- _e_tz_screenmirror_pp_destroy(mirror);
- tizen_screenmirror_send_stop(resource);
-}
-
-static const struct tizen_screenmirror_interface _e_tz_screenmirror_interface = {
- _e_tz_screenmirror_cb_destroy,
- _e_tz_screenmirror_cb_set_stretch,
- _e_tz_screenmirror_cb_queue,
- _e_tz_screenmirror_cb_dequeue,
- _e_tz_screenmirror_cb_start,
- _e_tz_screenmirror_cb_stop
-};
-
-static void
-_e_tz_screenshooter_get_screenmirror(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t id,
- struct wl_resource *output)
-{
- int version = wl_resource_get_version(resource);
- E_Mirror *mirror;
-
- if (keep_stream_mirror != NULL)
- {
- wl_resource_post_no_memory(resource);
- return;
- }
-
- mirror = _e_tz_screenmirror_create(client, resource, output);
- if (!mirror)
- {
- wl_resource_post_no_memory(resource);
- return;
- }
- keep_stream_mirror = mirror;
-
- mirror->resource = wl_resource_create(client, &tizen_screenmirror_interface, version, id);
- if (mirror->resource == NULL)
- {
- _e_tz_screenmirror_destroy(mirror);
- wl_client_post_no_memory(client);
- keep_stream_mirror = NULL;
- return;
- }
-
- wl_resource_set_implementation(mirror->resource, &_e_tz_screenmirror_interface,
- mirror, destroy_tz_screenmirror);
-
- if (_e_screenmirror_privilege_check(client, mirror, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_TRUE)
- DBG("_e_tz_screenshooter_get_screenmirror: priv check success");
- else
- DBG("_e_tz_screenshooter_get_screenmirror: priv check failed");
-
- tizen_screenmirror_send_content(mirror->resource, TIZEN_SCREENMIRROR_CONTENT_NORMAL);
-}
-
-static void
-_e_tz_screenshooter_set_oneshot_auto_rotation(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t set)
-{
- DBG("_e_tz_screenshooter_set_oneshot_auto_rotation: %d", set);
-
- if (set)
- screenshot_auto_rotation = EINA_TRUE;
- else
- screenshot_auto_rotation = EINA_FALSE;
-}
-
-static const struct tizen_screenshooter_interface _e_tz_screenshooter_interface =
-{
- _e_tz_screenshooter_get_screenmirror,
- _e_tz_screenshooter_set_oneshot_auto_rotation
-};
-
-static void
-_e_tz_screenshooter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
-{
- struct wl_resource *res;
- int i;
-
- if (!(res = wl_resource_create(client, &tizen_screenshooter_interface, MIN(version, 1), id)))
- {
- ERR("Could not create tizen_screenshooter resource: %m");
- wl_client_post_no_memory(client);
- return;
- }
-
- if (_e_screenmirror_privilege_check_with_cynara_init(client, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_TRUE)
- tizen_screenshooter_send_screenshooter_notify(res, EINA_TRUE);
- else
- tizen_screenshooter_send_screenshooter_notify(res, EINA_FALSE);
-
- wl_resource_set_implementation(res, &_e_tz_screenshooter_interface, NULL, NULL);
-
- for (i = 0; i < NUM_MIRROR_FORMAT; i++)
- tizen_screenshooter_send_format(res, mirror_format_table[i]);
-}
-
-static void
-_e_screenshooter_cb_shoot(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *output_resource,
- struct wl_resource *buffer_resource)
-{
- E_Mirror *mirror;
- E_Mirror_Buffer *buffer;
-
- if (!_e_tz_screenmirror_buffer_check(buffer_resource))
- {
- wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
- "tizen_screenshooter failed: wrong buffer resource");
- return;
- }
-
- mirror = _e_tz_screenmirror_create(client, resource, output_resource);
- if (!mirror)
- {
- wl_resource_post_no_memory(resource);
- return;
- }
-
- /* resource == shooter means that we're using weston screenshooter */
- mirror->resource = mirror->shooter;
-
- if (_e_screenmirror_privilege_check(client, mirror, wl_client_get_fd(client),
- PRIVILEGE_SCREENSHOT) == EINA_FALSE)
- {
- ERR("_e_screenshooter_cb_shoot: priv check failed");
- screenshooter_send_done(mirror->resource);
- goto privilege_fail;
- }
-
- buffer = _e_tz_screenmirror_buffer_get(mirror, buffer_resource);
- if (!buffer)
- {
- wl_resource_post_no_memory(resource);
- _e_tz_screenmirror_destroy(mirror);
- return;
- }
- e_devmgr_buffer_clear(buffer->mbuf);
-
- mirror->buffer_queue = eina_list_append(mirror->buffer_queue, buffer);
-
- if (e_devicemgr_dpms_get(mirror->drm_output))
- {
- ERR("_e_screenshooter_cb_shoot: dpms on fail");
- goto dump_done;
- }
-
- _e_tz_screenmirror_get_angle(mirror);
- if (screenshot_auto_rotation)
- if (mirror->angle == 90 || mirror->angle == 270)
- mirror->rotate_change = EINA_TRUE;
-
- if (_e_tz_screenmirror_tdm_capture_support(buffer, TDM_CAPTURE_CAPABILITY_ONESHOT))
- {
- if (_e_tz_screenmirror_tdm_capture_oneshot(mirror, buffer) == EINA_TRUE)
- return;
- else
- {
- tdm_capture_destroy(mirror->capture);
- mirror->capture = NULL;
- }
- }
- else
- _e_tz_screenmirror_dump_still(buffer);
-
-dump_done:
- _e_tz_screenmirror_buffer_free(buffer);
-
-privilege_fail:
- _e_tz_screenmirror_destroy(mirror);
-}
-
-static const struct screenshooter_interface _e_screenshooter_interface =
-{
- _e_screenshooter_cb_shoot
-};
-
-static void
-_e_screenshooter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
-{
- struct wl_resource *res;
-
- if (!(res = wl_resource_create(client, &screenshooter_interface, MIN(version, 1), id)))
- {
- ERR("Could not create screenshooter resource");
- wl_client_post_no_memory(client);
- return;
- }
-
- screenshot_auto_rotation = EINA_TRUE;
-
- wl_resource_set_implementation(res, &_e_screenshooter_interface, NULL, NULL);
-}
-
-int
-e_devicemgr_screenshooter_init(void)
-{
- if (!e_comp_wl) return 0;
- if (!e_comp_wl->wl.disp) return 0;
-
- /* try to add screenshooter to wayland globals */
- if (!wl_global_create(e_comp_wl->wl.disp, &screenshooter_interface, 1,
- NULL, _e_screenshooter_cb_bind))
- {
- ERR("Could not add screenshooter to wayland globals");
- return 0;
- }
-
- /* try to add tizen_screenshooter to wayland globals */
- if (!wl_global_create(e_comp_wl->wl.disp, &tizen_screenshooter_interface, 1,
- NULL, _e_tz_screenshooter_cb_bind))
- {
- ERR("Could not add tizen_screenshooter to wayland globals");
- return 0;
- }
-
- return 1;
-}
-
-void
-e_devicemgr_screenshooter_fini(void)
-{
-}
+++ /dev/null
-#ifndef E_TIZEN_SCREENSHOOTER_SERVER_H
-#define E_TIZEN_SCREENSHOOTER_SERVER_H
-
-int e_devicemgr_screenshooter_init(void);
-void e_devicemgr_screenshooter_fini(void);
-
-#endif
+++ /dev/null
-#define E_COMP_WL
-#include <e.h>
-#include <Ecore_Drm.h>
-#include <tdm_helper.h>
-#include "e_mod_main.h"
-#include "e_devicemgr_privates.h"
-#include "e_devicemgr_tdm.h"
-#include "e_devicemgr_dpms.h"
-
-#define CHECKING_PRIMARY_ZPOS
-
-E_DevMgr_Display *e_devmgr_dpy;
-static Eina_List *e_devmgr_dpy_layers;
-
-static int
-_e_devicemgr_drm_fd_get(void)
-{
- int fd;
- Eina_List *devs;
- Ecore_Drm_Device *dev;
-
- devs = eina_list_clone(ecore_drm_devices_get());
- EINA_SAFETY_ON_NULL_RETURN_VAL(devs, -1);
-
- if ((dev = eina_list_nth(devs, 0)))
- {
- fd = ecore_drm_device_fd_get(dev);
- if (fd >= 0)
- {
- eina_list_free(devs);
- return fd;
- }
- }
-
- eina_list_free(devs);
- return -1;
-}
-
-int
-e_devicemgr_tdm_init(void)
-{
- tdm_display_capability capabilities;
- tdm_error ret;
-
- if (e_devmgr_dpy)
- {
- ERR("tdm already init");
- return 1;
- }
-
- e_devmgr_dpy = calloc(1, sizeof(E_DevMgr_Display));
- if (!e_devmgr_dpy)
- return 0;
-
- e_devmgr_dpy->drm_fd = _e_devicemgr_drm_fd_get();
- if (e_devmgr_dpy->drm_fd < 0)
- {
- e_devicemgr_tdm_fini();
- return 0;
- }
-
- e_devmgr_dpy->bufmgr = tbm_bufmgr_init(e_devmgr_dpy->drm_fd);
- if (!e_devmgr_dpy->bufmgr)
- {
- ERR("bufmgr init failed");
- e_devicemgr_tdm_fini();
- return 0;
- }
-
- e_devmgr_dpy->tdm = tdm_display_init(NULL);
- if (!e_devmgr_dpy->tdm)
- {
- ERR("tdm init failed");
- e_devicemgr_tdm_fini();
- return 0;
- }
-
- ret = tdm_display_get_capabilities(e_devmgr_dpy->tdm, &capabilities);
- if (ret != TDM_ERROR_NONE)
- {
- ERR("tdm get_capabilities failed");
- e_devicemgr_tdm_fini();
- return 0;
- }
-
- if (capabilities & TDM_DISPLAY_CAPABILITY_PP)
- e_devmgr_dpy->pp_available = EINA_TRUE;
-
- if (capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)
- e_devmgr_dpy->capture_available = EINA_TRUE;
-
- e_comp->wl_comp_data->available_hw_accel.underlay = EINA_TRUE;
- DBG("enable HW underlay");
-
- e_comp->wl_comp_data->available_hw_accel.scaler = EINA_TRUE;
- DBG("enable HW scaler");
-
- return 1;
-}
-
-void
-e_devicemgr_tdm_fini(void)
-{
- e_comp->wl_comp_data->available_hw_accel.underlay = EINA_FALSE;
- e_comp->wl_comp_data->available_hw_accel.scaler = EINA_FALSE;
-
- if (e_devmgr_dpy->tdm)
- tdm_display_deinit(e_devmgr_dpy->tdm);
-
- if (e_devmgr_dpy->bufmgr)
- tbm_bufmgr_deinit(e_devmgr_dpy->bufmgr);
-
- if (e_devmgr_dpy->drm_fd >= 0)
- close(e_devmgr_dpy->drm_fd);
-
- free(e_devmgr_dpy);
- e_devmgr_dpy = NULL;
-}
-
-void
-e_devicemgr_tdm_update(void)
-{
- if (!e_devmgr_dpy || !e_devmgr_dpy->tdm)
- return;
-
- tdm_display_update(e_devmgr_dpy->tdm);
-}
-
-tdm_output*
-e_devicemgr_tdm_output_get(Ecore_Drm_Output *output)
-{
- Ecore_Drm_Device *dev;
- Ecore_Drm_Output *o;
- Eina_List *devs;
- Eina_List *l, *ll;
- int pipe = 0;
-
- if (!output)
- {
- int i, count = 0;
- tdm_display_get_output_count(e_devmgr_dpy->tdm, &count);
- for (i = 0; i < count; i++)
- {
- tdm_output *toutput = tdm_display_get_output(e_devmgr_dpy->tdm, i, NULL);
- tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-
- if (!toutput)
- continue;
-
- tdm_output_get_conn_status(toutput, &status);
- if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
- {
- tdm_output_type type;
- tdm_output_get_output_type(toutput, &type);
- INF("found tdm output: type(%d)", type);
- return toutput;
- }
- }
-
- ERR("not found tdm output");
-
- return NULL;
- }
-
- devs = eina_list_clone(ecore_drm_devices_get());
- EINA_LIST_FOREACH(devs, l, dev)
- {
- pipe = 0;
- EINA_LIST_FOREACH(dev->outputs, ll, o)
- {
- if (o == output)
- goto found;
- pipe++;
- }
- }
-found:
- eina_list_free(devs);
-
- return tdm_display_get_output(e_devmgr_dpy->tdm, pipe, NULL);
-}
-
-tdm_layer*
-e_devicemgr_tdm_video_layer_get(tdm_output *output)
-{
- int i, count = 0;
-#ifdef CHECKING_PRIMARY_ZPOS
- int primary_idx = 0, primary_zpos = 0;
- tdm_layer *primary_layer;
-#endif
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
-
- tdm_output_get_layer_count(output, &count);
- for (i = 0; i < count; i++)
- {
- tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
- tdm_layer_capability capabilities = 0;
- EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
-
- tdm_layer_get_capabilities(layer, &capabilities);
- if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
- return layer;
- }
-
-#ifdef CHECKING_PRIMARY_ZPOS
- tdm_output_get_primary_index(output, &primary_idx);
- primary_layer = tdm_output_get_layer(output, primary_idx, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(primary_layer, NULL);
- tdm_layer_get_zpos(primary_layer, &primary_zpos);
-#endif
-
- for (i = 0; i < count; i++)
- {
- tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
- tdm_layer_capability capabilities = 0;
- EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
-
- tdm_layer_get_capabilities(layer, &capabilities);
- if (capabilities & TDM_LAYER_CAPABILITY_OVERLAY)
- {
-#ifdef CHECKING_PRIMARY_ZPOS
- int zpos = 0;
- tdm_layer_get_zpos(layer, &zpos);
- if (zpos >= primary_zpos) continue;
-#endif
- return layer;
- }
- }
-
- return NULL;
-}
-
-tdm_layer*
-e_devicemgr_tdm_avaiable_video_layer_get(tdm_output *output)
-{
- Eina_Bool has_video_layer = EINA_FALSE;
- int i, count = 0;
-#ifdef CHECKING_PRIMARY_ZPOS
- int primary_idx = 0, primary_zpos = 0;
- tdm_layer *primary_layer;
-#endif
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
-
- /* check video layers first */
- tdm_output_get_layer_count(output, &count);
- for (i = 0; i < count; i++)
- {
- tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
- tdm_layer_capability capabilities = 0;
- EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
-
- tdm_layer_get_capabilities(layer, &capabilities);
- if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
- {
- has_video_layer = EINA_TRUE;
- if (!e_devicemgr_tdm_get_layer_usable(layer)) continue;
- return layer;
- }
- }
-
- /* if a output has video layers, it means that there is no available video layer for video */
- if (has_video_layer)
- return NULL;
-
- /* check graphic layers second */
-#ifdef CHECKING_PRIMARY_ZPOS
- tdm_output_get_primary_index(output, &primary_idx);
- primary_layer = tdm_output_get_layer(output, primary_idx, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(primary_layer, NULL);
- tdm_layer_get_zpos(primary_layer, &primary_zpos);
-#endif
-
- for (i = 0; i < count; i++)
- {
- tdm_layer *layer = tdm_output_get_layer(output, i, NULL);
- tdm_layer_capability capabilities = 0;
- EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
-
- tdm_layer_get_capabilities(layer, &capabilities);
- if (capabilities & TDM_LAYER_CAPABILITY_OVERLAY)
- {
-#ifdef CHECKING_PRIMARY_ZPOS
- int zpos = 0;
- tdm_layer_get_zpos(layer, &zpos);
- if (zpos >= primary_zpos) continue;
-#endif
- if (!e_devicemgr_tdm_get_layer_usable(layer)) continue;
- return layer;
- }
- }
-
- return NULL;
-}
-
-void
-e_devicemgr_tdm_set_layer_usable(tdm_layer *layer, Eina_Bool usable)
-{
- if (usable)
- e_devmgr_dpy_layers = eina_list_remove(e_devmgr_dpy_layers, layer);
- else
- {
- tdm_layer *used_layer;
- Eina_List *l = NULL;
- EINA_LIST_FOREACH(e_devmgr_dpy_layers, l, used_layer)
- if (used_layer == layer) return;
- e_devmgr_dpy_layers = eina_list_append(e_devmgr_dpy_layers, layer);
- }
-}
-
-Eina_Bool
-e_devicemgr_tdm_get_layer_usable(tdm_layer *layer)
-{
- tdm_layer *used_layer;
- Eina_List *l = NULL;
- EINA_LIST_FOREACH(e_devmgr_dpy_layers, l, used_layer)
- if (used_layer == layer)
- return EINA_FALSE;
- return EINA_TRUE;
-}
+++ /dev/null
-#ifndef __E_DEVICEMGR_TDM_H__
-#define __E_DEVICEMGR_TDM_H__
-
-#include <tdm.h>
-#include <tbm_bufmgr.h>
-#include <tbm_surface.h>
-#include <tbm_surface_internal.h>
-
-#define C(b,m) (((b) >> (m)) & 0xFF)
-#define B(c,s) ((((unsigned int)(c)) & 0xff) << (s))
-#define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0))
-#define FOURCC_STR(id) C(id,0), C(id,8), C(id,16), C(id,24)
-#define FOURCC_ID(str) FOURCC(((char*)str)[0],((char*)str)[1],((char*)str)[2],((char*)str)[3])
-
-#define IS_RGB(f) ((f) == TBM_FORMAT_XRGB8888 || (f) == TBM_FORMAT_ARGB8888)
-#define ROUNDUP(s,c) (((s) + (c-1)) & ~(c-1))
-#define ALIGN_TO_16B(x) ((((x) + (1 << 4) - 1) >> 4) << 4)
-#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5)
-#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7)
-#define ALIGN_TO_2KB(x) ((((x) + (1 << 11) - 1) >> 11) << 11)
-#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13)
-#define ALIGN_TO_64KB(x) ((((x) + (1 << 16) - 1) >> 16) << 16)
-
-typedef struct _E_DevMgr_Display
-{
- int drm_fd;
- tbm_bufmgr bufmgr;
- tdm_display *tdm;
-
- Eina_Bool pp_available;
- Eina_Bool capture_available;
-} E_DevMgr_Display;
-
-extern E_DevMgr_Display *e_devmgr_dpy;
-
-int e_devicemgr_tdm_init(void);
-void e_devicemgr_tdm_fini(void);
-void e_devicemgr_tdm_update(void);
-
-tdm_output *e_devicemgr_tdm_output_get(Ecore_Drm_Output *output);
-tdm_layer *e_devicemgr_tdm_video_layer_get(tdm_output *output);
-tdm_layer *e_devicemgr_tdm_avaiable_video_layer_get(tdm_output *output);
-void e_devicemgr_tdm_set_layer_usable(tdm_layer *layer, Eina_Bool usable);
-Eina_Bool e_devicemgr_tdm_get_layer_usable(tdm_layer *layer);
-
-#endif
+++ /dev/null
-#include <tdm.h>
-#include <values.h>
-#include "e_devicemgr_video.h"
-#include "e_devicemgr_dpms.h"
-#include "e_devicemgr_viewport.h"
-#include "e_devicemgr_eom.h"
-
-//#define DUMP_BUFFER
-
-static int _video_detail_log_dom = -1;
-static Eina_Bool video_to_primary;
-static Eina_Bool video_punch;
-
-#define BUFFER_MAX_COUNT 5
-#define MIN_WIDTH 32
-
-#define VER(fmt,arg...) ERR("window(0x%08"PRIxPTR") ec(%p): "fmt, video->window, video->ec, ##arg)
-#define VWR(fmt,arg...) WRN("window(0x%08"PRIxPTR") ec(%p): "fmt, video->window, video->ec, ##arg)
-#define VIN(fmt,arg...) INF("window(0x%08"PRIxPTR") ec(%p): "fmt, video->window, video->ec, ##arg)
-#define VDB(fmt,arg...) DBG("window(0x%08"PRIxPTR") ec(%p): "fmt, video->window, video->ec, ##arg)
-
-#define DET(...) EINA_LOG_DOM_DBG(_video_detail_log_dom, __VA_ARGS__)
-#define VDT(fmt,arg...) DET("window(0x%08"PRIxPTR"): "fmt, video->window, ##arg)
-
-#define GEO_FMT "%dx%d(%dx%d+%d+%d) -> (%dx%d+%d+%d) transform(%d)"
-#define GEO_ARG(g) \
- (g)->input_w, (g)->input_h, \
- (g)->input_r.w, (g)->input_r.h, (g)->input_r.x, (g)->input_r.y, \
- (g)->output_r.w, (g)->output_r.h, (g)->output_r.x, (g)->output_r.y, \
- (g)->transform
-
-struct _E_Video
-{
- struct wl_resource *video_object;
- struct wl_resource *surface;
- E_Client *ec;
- Ecore_Window window;
- Ecore_Drm_Output *drm_output;
- tdm_output *output;
- E_Output *e_output;
- tdm_layer *layer;
- E_Plane *e_plane;
- Eina_Bool external_video;
-
- /* input info */
- tbm_format tbmfmt;
- Eina_List *input_buffer_list;
-
- /* in screen coordinates */
- struct
- {
- int input_w, input_h; /* input buffer's size */
- Eina_Rectangle input_r; /* input buffer's content rect */
- Eina_Rectangle output_r; /* video plane rect */
- uint transform; /* rotate, flip */
-
- Eina_Rectangle tdm_output_r; /* video plane rect in physical output coordinates */
- uint tdm_transform; /* rotate, flip in physical output coordinates */
- } geo, old_geo;
-
- E_Comp_Wl_Buffer *old_comp_buffer;
-
- /* converter info */
- tbm_format pp_tbmfmt;
- tdm_pp *pp;
- Eina_Rectangle pp_r; /* converter dst content rect */
- Eina_List *pp_buffer_list;
- Eina_List *next_buffer;
-
- int output_align;
- int pp_align;
- int pp_minw, pp_minh, pp_maxw, pp_maxh;
- int video_align;
-
- /* When a video buffer be attached, it will be appended to the end of waiting_list .
- * And when it's committed, it will be moved to committed_list.
- * Finally when the commit handler is called, it will become current_fb.
- */
- Eina_List *waiting_list; /* buffers which are not committed yet */
- Eina_List *committed_list; /* buffers which are committed, but not shown on screen yet */
- E_Devmgr_Buf *current_fb; /* buffer which is showing on screen currently */
- Eina_Bool waiting_vblank;
-
- /* attributes */
- Eina_List *tdm_prop_list;
- Eina_List *late_tdm_prop_list;
- int tdm_mute_id;
-
- Eina_Bool cb_registered;
- Eina_Bool need_force_render;
- Eina_Bool follow_topmost_visibility;
- Eina_Bool allowed_attribute;
-
- Eina_Bool waiting_video_set;
- E_Plane_Hook *video_set_hook;
-};
-
-typedef struct _Tdm_Prop_Value
-{
- unsigned int id;
- char name[TDM_NAME_LEN];
- tdm_value value;
-} Tdm_Prop_Value;
-
-static Eina_List *video_list;
-
-static void _e_video_set(E_Video *video, E_Client *ec);
-static void _e_video_destroy(E_Video *video);
-static void _e_video_render(E_Video *video, const char *func);
-static Eina_Bool _e_video_frame_buffer_show(E_Video *video, E_Devmgr_Buf *mbuf);
-static void _e_video_pp_buffer_cb_release(tbm_surface_h surface, void *user_data);
-static void _e_video_video_set_hook(void *data, E_Plane *plane);
-
-static int
-gcd(int a, int b)
-{
- if (a % b == 0)
- return b;
- return gcd(b, a % b);
-}
-
-static int
-lcm(int a, int b)
-{
- return a * b / gcd(a, b);
-}
-
-static void
-buffer_transform(int width, int height, uint32_t transform, int32_t scale,
- int sx, int sy, int *dx, int *dy)
-{
- switch (transform)
- {
- case WL_OUTPUT_TRANSFORM_NORMAL:
- default:
- *dx = sx, *dy = sy;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- *dx = width - sx, *dy = sy;
- break;
- case WL_OUTPUT_TRANSFORM_90:
- *dx = height - sy, *dy = sx;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- *dx = height - sy, *dy = width - sx;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- *dx = width - sx, *dy = height - sy;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- *dx = sx, *dy = height - sy;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- *dx = sy, *dy = width - sx;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- *dx = sy, *dy = sx;
- break;
- }
-
- *dx *= scale;
- *dy *= scale;
-}
-
-static E_Video*
-find_video_with_surface(struct wl_resource *surface)
-{
- E_Video *video;
- Eina_List *l;
- EINA_LIST_FOREACH(video_list, l, video)
- {
- if (video->surface == surface)
- return video;
- }
- return NULL;
-}
-
-static E_Client*
-find_video_child_get(E_Client *ec)
-{
- E_Client *subc = NULL;
- Eina_List *l;
- if (!ec) return NULL;
- if (e_object_is_del(E_OBJECT(ec))) return NULL;
- if (!ec->comp_data) return NULL;
-
- if (ec->comp_data->video_client) return ec;
-
- EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
- {
- E_Client *temp= NULL;
- if (!subc->comp_data || e_object_is_del(E_OBJECT(subc))) continue;
- temp = find_video_child_get(subc);
- if(temp) return temp;
- }
-
- return NULL;
-}
-
-static E_Client*
-find_topmost_parent_get(E_Client *ec)
-{
- E_Client *parent = NULL;
-
- if (!ec->comp_data || !ec->comp_data->sub.data)
- return ec;
-
- parent = ec->comp_data->sub.data->parent;
- while (parent)
- {
- if (!parent->comp_data || !parent->comp_data->sub.data)
- return parent;
-
- parent = parent->comp_data->sub.data->parent;
- }
-
- return ec;
-}
-
-static E_Client*
-find_offscreen_parent_get(E_Client *ec)
-{
- E_Client *parent = NULL;
-
- if (!ec->comp_data || !ec->comp_data->sub.data)
- return NULL;
-
- parent = ec->comp_data->sub.data->parent;
- while (parent)
- {
- if (!parent->comp_data || !parent->comp_data->sub.data)
- return NULL;
-
- if (parent->comp_data->sub.data->remote_surface.offscreen_parent)
- return parent->comp_data->sub.data->remote_surface.offscreen_parent;
-
- parent = parent->comp_data->sub.data->parent;
- }
-
- return NULL;
-}
-
-static E_Devmgr_Buf*
-_e_video_mbuf_find(Eina_List *list, tbm_surface_h buffer)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l = NULL;
-
- EINA_LIST_FOREACH(list, l, mbuf)
- {
- if (mbuf->tbm_surface == buffer)
- return mbuf;
- }
-
- return NULL;
-}
-
-static E_Devmgr_Buf*
-_e_video_mbuf_find_with_comp_buffer(Eina_List *list, E_Comp_Wl_Buffer *comp_buffer)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l = NULL;
-
- EINA_LIST_FOREACH(list, l, mbuf)
- {
- if (mbuf->comp_buffer == comp_buffer)
- return mbuf;
- }
-
- return NULL;
-}
-
-static Eina_Bool
-_e_video_set_layer(E_Video *video, Eina_Bool set)
-{
- if (!set)
- {
- unsigned int usable = 1;
- if (!video->layer) return EINA_TRUE;
- tdm_layer_is_usable(video->layer, &usable);
- if (!usable && !video->waiting_video_set)
- {
- VIN("stop video");
- tdm_layer_unset_buffer(video->layer);
- tdm_layer_commit(video->layer, NULL, NULL);
- }
- VIN("release layer: %p", video->layer);
- e_devicemgr_tdm_set_layer_usable(video->layer, EINA_TRUE);
- video->layer = NULL;
- video->old_comp_buffer = NULL;
-
- e_plane_video_set(video->e_plane, EINA_FALSE, NULL);
- video->e_plane = NULL;
- video->waiting_video_set = EINA_FALSE;
- if (video->video_set_hook)
- {
- e_plane_hook_del(video->video_set_hook);
- video->video_set_hook = NULL;
- }
- }
- else
- {
- if (video->layer) return EINA_TRUE;
- if (!video->layer)
- {
- int zpos;
- tdm_error ret;
-
- video->layer = e_devicemgr_tdm_avaiable_video_layer_get(video->output);
-
- ret = tdm_layer_get_zpos(video->layer, &zpos);
- if (ret == TDM_ERROR_NONE)
- video->e_plane = e_output_plane_get_by_zpos(video->e_output, zpos);
-
- if (!video->e_plane)
- {
- VWR("fail get e_plane");
- video->layer = NULL;
- return EINA_FALSE;
- }
- }
- if (!video->layer)
- {
- VWR("no available layer for video");
- return EINA_FALSE;
- }
- if (!e_plane_video_set(video->e_plane, EINA_TRUE, &video->waiting_video_set))
- {
- VWR("fail set video to e_plane");
- video->layer = NULL;
- video->e_plane = NULL;
- return EINA_FALSE;
- }
- if (video->waiting_video_set)
- {
- if (!video->video_set_hook)
- video->video_set_hook = e_plane_hook_add(E_PLANE_HOOK_VIDEO_SET, _e_video_video_set_hook, video);
- }
-
- VIN("assign layer: %p", video->layer);
- e_devicemgr_tdm_set_layer_usable(video->layer, EINA_FALSE);
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_video_is_visible(E_Video *video)
-{
- E_Client *offscreen_parent;
-
- if (e_object_is_del(E_OBJECT(video->ec))) return EINA_FALSE;
-
- if (!e_pixmap_resource_get(video->ec->pixmap))
- {
- VDB("no comp buffer");
- return EINA_FALSE;
- }
-
- if (video->ec->comp_data->sub.data && video->ec->comp_data->sub.data->stand_alone)
- return EINA_TRUE;
-
- offscreen_parent = find_offscreen_parent_get(video->ec);
- if (offscreen_parent && offscreen_parent->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED)
- {
- VDB("video surface invisible: offscreen fully obscured");
- return EINA_FALSE;
- }
-
- if (!evas_object_visible_get(video->ec->frame))
- {
- VDB("evas obj invisible");
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_video_parent_is_viewable(E_Video *video)
-{
- E_Client *topmost_parent;
-
- if (e_object_is_del(E_OBJECT(video->ec))) return EINA_FALSE;
-
- topmost_parent = find_topmost_parent_get(video->ec);
-
- if (!topmost_parent)
- return EINA_FALSE;
-
- if (topmost_parent == video->ec)
- {
- VDB("There is no video parent surface");
- return EINA_FALSE;
- }
-
- if (!topmost_parent->visible)
- {
- VDB("parent(0x%08"PRIxPTR") not viewable", (Ecore_Window)e_client_util_win_get(topmost_parent));
- return EINA_FALSE;
- }
-
- if (!e_pixmap_resource_get(topmost_parent->pixmap))
- {
- VDB("parent(0x%08"PRIxPTR") no comp buffer", (Ecore_Window)e_client_util_win_get(topmost_parent));
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-static void
-_e_video_input_buffer_cb_free(E_Devmgr_Buf *mbuf, void *data)
-{
- E_Video *video = data;
- Eina_Bool need_hide = EINA_FALSE;
-
- VDT("Buffer(%p) to be free, refcnt(%d)", mbuf, mbuf->ref_cnt);
-
- video->input_buffer_list = eina_list_remove(video->input_buffer_list, mbuf);
-
- if (mbuf->comp_buffer)
- e_comp_wl_buffer_reference(&mbuf->buffer_ref, NULL);
-
- if (video->current_fb == mbuf)
- {
- VIN("current fb destroyed");
- e_devmgr_buffer_set_use(video->current_fb, EINA_FALSE);
- video->current_fb = NULL;
- need_hide = EINA_TRUE;
- }
-
- if (eina_list_data_find(video->committed_list, mbuf))
- {
- VIN("committed fb destroyed");
- video->committed_list = eina_list_remove(video->committed_list, mbuf);
- e_devmgr_buffer_set_use(mbuf, EINA_FALSE);
- need_hide = EINA_TRUE;
- }
-
- if (eina_list_data_find(video->waiting_list, mbuf))
- {
- VIN("waiting fb destroyed");
- video->waiting_list = eina_list_remove(video->waiting_list, mbuf);
- }
-
- if (need_hide && video->layer)
- _e_video_frame_buffer_show(video, NULL);
-}
-
-static E_Devmgr_Buf*
-_e_video_input_buffer_get(E_Video *video, E_Comp_Wl_Buffer *comp_buffer, Eina_Bool scanout)
-{
- E_Devmgr_Buf *mbuf;
-
- mbuf = _e_video_mbuf_find_with_comp_buffer(video->input_buffer_list, comp_buffer);
- if (mbuf)
- {
- mbuf->content_r = video->geo.input_r;
- return mbuf;
- }
-
- mbuf = e_devmgr_buffer_create_comp(comp_buffer);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, NULL);
-
- if (video->pp)
- {
- if (video->pp_align != -1 && (mbuf->width_from_pitch % video->pp_align))
- {
- E_Devmgr_Buf *temp, *temp2;
- int aligned_width = ROUNDUP(mbuf->width_from_pitch, video->pp_align);
-
- temp = e_devmgr_buffer_alloc(aligned_width, mbuf->height, mbuf->tbmfmt, scanout);
- if (!temp)
- {
- e_devmgr_buffer_unref(mbuf);
- return NULL;
- }
-
- VDB("copy mbuf(%d,%dx%d) => mbuf(%d,%dx%d)",
- MSTAMP(mbuf), mbuf->width_from_pitch, mbuf->height,
- MSTAMP(temp), temp->width, temp->height);
-
- e_devmgr_buffer_copy(mbuf, temp);
- temp2 = mbuf;
- mbuf = temp;
- e_devmgr_buffer_unref(temp2);
-
- video->geo.input_w = mbuf->width_from_pitch;
-#ifdef DUMP_BUFFER
- static int i;
- e_devmgr_buffer_dump(mbuf, "copy", i++, 0);
-#endif
- }
- }
-
- mbuf->content_r = video->geo.input_r;
-
- video->input_buffer_list = eina_list_append(video->input_buffer_list, mbuf);
- e_devmgr_buffer_free_func_add(mbuf, _e_video_input_buffer_cb_free, video);
-
- VDT("Client(%s):PID(%d) RscID(%d), Buffer(%p) created, refcnt:%d"
- " scanout=%d", e_client_util_name_get(video->ec) ?: "No Name" ,
- video->ec->netwm.pid, wl_resource_get_id(video->surface), mbuf,
- mbuf->ref_cnt, scanout);
-
- return mbuf;
-}
-
-static void
-_e_video_input_buffer_valid(E_Video *video, E_Comp_Wl_Buffer *comp_buffer)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l;
-
- EINA_LIST_FOREACH(video->input_buffer_list, l, mbuf)
- {
- tbm_surface_h tbm_surf;
- tbm_bo bo;
- uint32_t size = 0, offset = 0, pitch = 0;
-
- if (!mbuf->comp_buffer) continue;
- if (mbuf->resource == comp_buffer->resource)
- {
- WRN("got wl_buffer@%d twice", wl_resource_get_id(comp_buffer->resource));
- return;
- }
-
- tbm_surf = wayland_tbm_server_get_surface(e_comp->wl_comp_data->tbm.server, comp_buffer->resource);
- bo = tbm_surface_internal_get_bo(tbm_surf, 0);
- tbm_surface_internal_get_plane_data(tbm_surf, 0, &size, &offset, &pitch);
-
- if (mbuf->names[0] == tbm_bo_export(bo) && mbuf->offsets[0] == offset)
- {
- WRN("can tearing: wl_buffer@%d, wl_buffer@%d are same. gem_name(%d)",
- wl_resource_get_id(mbuf->resource),
- wl_resource_get_id(comp_buffer->resource), mbuf->names[0]);
- return;
- }
- }
-}
-
-static void
-_e_video_pp_buffer_cb_free(E_Devmgr_Buf *mbuf, void *data)
-{
- E_Video *video = data;
-
- e_devmgr_buffer_set_use(mbuf, EINA_FALSE);
-
- if (video->current_fb == mbuf)
- video->current_fb = NULL;
-
- video->committed_list = eina_list_remove(video->committed_list, mbuf);
-
- video->waiting_list = eina_list_remove(video->waiting_list, mbuf);
-
- video->pp_buffer_list = eina_list_remove(video->pp_buffer_list, mbuf);
-}
-
-static E_Devmgr_Buf*
-_e_video_pp_buffer_get(E_Video *video, int width, int height)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l;
- int i = 0;
- int aligned_width;
-
- if (video->video_align != -1)
- aligned_width = ROUNDUP(width, video->video_align);
- else
- aligned_width = width;
-
- if (video->pp_buffer_list)
- {
- mbuf = eina_list_data_get(video->pp_buffer_list);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, NULL);
-
- /* if we need bigger pp_buffers, destroy all pp_buffers and create */
- if (aligned_width > mbuf->width_from_pitch || height != mbuf->height)
- {
- Eina_List *ll;
-
- VIN("pp buffer changed: %dx%d => %dx%d",
- mbuf->width_from_pitch, mbuf->height,
- aligned_width, height);
-
- EINA_LIST_FOREACH_SAFE(video->pp_buffer_list, l, ll, mbuf)
- {
- tdm_buffer_remove_release_handler(mbuf->tbm_surface,
- _e_video_pp_buffer_cb_release, mbuf);
- /* free forcely */
- e_devmgr_buffer_set_use(mbuf, EINA_FALSE);
- e_devmgr_buffer_unref(mbuf);
- }
- if (video->pp_buffer_list)
- NEVER_GET_HERE();
-
- if (video->waiting_list)
- NEVER_GET_HERE();
- }
- }
-
- if (!video->pp_buffer_list)
- {
- for (i = 0; i < BUFFER_MAX_COUNT; i++)
- {
- mbuf = e_devmgr_buffer_alloc(aligned_width, height, video->pp_tbmfmt, EINA_TRUE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, NULL);
-
- e_devmgr_buffer_free_func_add(mbuf, _e_video_pp_buffer_cb_free, video);
- video->pp_buffer_list = eina_list_append(video->pp_buffer_list, mbuf);
-
- }
-
- VIN("pp buffer created: %dx%d, %c%c%c%c",
- mbuf->width_from_pitch, height, FOURCC_STR(video->pp_tbmfmt));
-
- video->next_buffer = video->pp_buffer_list;
- }
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(video->pp_buffer_list, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(video->next_buffer, NULL);
-
- l = video->next_buffer;
- while ((mbuf = video->next_buffer->data))
- {
- video->next_buffer = (video->next_buffer->next) ? video->next_buffer->next : video->pp_buffer_list;
-
- if (!mbuf->in_use)
- return mbuf;
-
- if (l == video->next_buffer)
- {
- VWR("all video framebuffers in use (max:%d)", BUFFER_MAX_COUNT);
- return NULL;
- }
- }
-
- return NULL;
-}
-
-static Ecore_Drm_Output*
-_e_video_drm_output_find(E_Client *ec)
-{
- Ecore_Drm_Device *dev;
- Ecore_Drm_Output *output;
- Eina_List *devs;
- Eina_List *l, *ll;
-
- devs = eina_list_clone(ecore_drm_devices_get());
- EINA_LIST_FOREACH(devs, l, dev)
- EINA_LIST_FOREACH(dev->outputs, ll, output)
- {
- int x, y, w, h;
- ecore_drm_output_position_get(output, &x, &y);
- ecore_drm_output_current_resolution_get(output, &w, &h, NULL);
- if (x <= ec->x && y <= ec->y && ec->x < x + w && ec->y < y + h)
- {
- eina_list_free(devs);
- return output;
- }
- }
- eina_list_free(devs);
- return NULL;
-}
-
-/* convert from logical screen to physical output */
-static void
-_e_video_geometry_cal_physical(E_Video *video)
-{
- E_Zone *zone;
- E_Comp_Wl_Output *output;
- E_Client *topmost;
- int tran, flip;
- int transform;
-
- topmost = find_topmost_parent_get(video->ec);
- output = e_comp_wl_output_find(topmost);
- EINA_SAFETY_ON_NULL_GOTO(output, normal);
-
- zone = e_comp_zone_xy_get(topmost->x, topmost->y);
- EINA_SAFETY_ON_NULL_GOTO(zone, normal);
-
- tran = video->geo.transform & 0x3;
- flip = video->geo.transform & 0x4;
- transform = flip + (tran + output->transform) % 4;
- switch(transform)
- {
- case WL_OUTPUT_TRANSFORM_90:
- video->geo.tdm_transform = TDM_TRANSFORM_270;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- video->geo.tdm_transform = TDM_TRANSFORM_180;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- video->geo.tdm_transform = TDM_TRANSFORM_90;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED_270;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED_180;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED_90;
- break;
- case WL_OUTPUT_TRANSFORM_NORMAL:
- default:
- video->geo.tdm_transform = TDM_TRANSFORM_NORMAL;
- break;
- }
-
- if (output->transform % 2)
- {
- if (video->geo.tdm_transform == TDM_TRANSFORM_FLIPPED)
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED_180;
- else if (video->geo.tdm_transform == TDM_TRANSFORM_FLIPPED_90)
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED_270;
- else if (video->geo.tdm_transform == TDM_TRANSFORM_FLIPPED_180)
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED;
- else if (video->geo.tdm_transform == TDM_TRANSFORM_FLIPPED_270)
- video->geo.tdm_transform = TDM_TRANSFORM_FLIPPED_90;
- }
-
- if (output->transform == 0)
- video->geo.tdm_output_r = video->geo.output_r;
- else
- e_comp_wl_rect_convert(zone->w, zone->h, output->transform, 1,
- video->geo.output_r.x, video->geo.output_r.y,
- video->geo.output_r.w, video->geo.output_r.h,
- &video->geo.tdm_output_r.x, &video->geo.tdm_output_r.y,
- &video->geo.tdm_output_r.w, &video->geo.tdm_output_r.h);
-
- VDB("geomtry: screen(%d,%d %dx%d | %d) => %d => physical(%d,%d %dx%d | %d)",
- EINA_RECTANGLE_ARGS(&video->geo.output_r), video->geo.transform, transform,
- EINA_RECTANGLE_ARGS(&video->geo.tdm_output_r), video->geo.tdm_transform);
-
- return;
-normal:
- video->geo.tdm_output_r = video->geo.output_r;
- video->geo.tdm_transform = video->geo.transform;
-}
-
-static Eina_Bool
-_e_video_geometry_cal_viewport(E_Video *video)
-{
- E_Client *ec = video->ec;
- E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
- E_Comp_Wl_Subsurf_Data *sdata;
- int x1, y1, x2, y2;
- int tx1, ty1, tx2, ty2;
- E_Comp_Wl_Buffer *comp_buffer;
- tbm_surface_h tbm_surf;
- uint32_t size = 0, offset = 0, pitch = 0;
- int bw, bh;
- int width_from_buffer, height_from_buffer;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
-
- comp_buffer = e_pixmap_resource_get(video->ec->pixmap);
- EINA_SAFETY_ON_NULL_RETURN_VAL(comp_buffer, EINA_FALSE);
-
- tbm_surf = wayland_tbm_server_get_surface(e_comp->wl_comp_data->tbm.server, comp_buffer->resource);
- EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surf, EINA_FALSE);
-
- tbm_surface_internal_get_plane_data(tbm_surf, 0, &size, &offset, &pitch);
-
- /* input geometry */
- if (IS_RGB(video->tbmfmt))
- video->geo.input_w = pitch / 4;
- else
- video->geo.input_w = pitch;
-
- video->geo.input_h = tbm_surface_get_height(tbm_surf);
-
- bw = tbm_surface_get_width(tbm_surf);
- bh = tbm_surface_get_height(tbm_surf);
-
- switch (vp->buffer.transform)
- {
- case WL_OUTPUT_TRANSFORM_90:
- case WL_OUTPUT_TRANSFORM_270:
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- width_from_buffer = bh / vp->buffer.scale;
- height_from_buffer = bw / vp->buffer.scale;
- break;
- default:
- width_from_buffer = bw / vp->buffer.scale;
- height_from_buffer = bh / vp->buffer.scale;
- break;
- }
-
-
- if (vp->buffer.src_width == wl_fixed_from_int(-1))
- {
- x1 = 0.0;
- y1 = 0.0;
- x2 = width_from_buffer;
- y2 = height_from_buffer;
- }
- else
- {
- x1 = wl_fixed_to_int(vp->buffer.src_x);
- y1 = wl_fixed_to_int(vp->buffer.src_y);
- x2 = wl_fixed_to_int(vp->buffer.src_x + vp->buffer.src_width);
- y2 = wl_fixed_to_int(vp->buffer.src_y + vp->buffer.src_height);
- }
-
-#if 0
- VDB("transform(%d) scale(%d) buffer(%dx%d) src(%d,%d %d,%d) viewport(%dx%d)",
- vp->buffer.transform, vp->buffer.scale,
- width_from_buffer, height_from_buffer,
- x1, y1, x2 - x1, y2 - y1,
- ec->comp_data->width_from_viewport, ec->comp_data->height_from_viewport);
-#endif
-
- buffer_transform(width_from_buffer, height_from_buffer,
- vp->buffer.transform, vp->buffer.scale, x1, y1, &tx1, &ty1);
- buffer_transform(width_from_buffer, height_from_buffer,
- vp->buffer.transform, vp->buffer.scale, x2, y2, &tx2, &ty2);
-
- video->geo.input_r.x = (tx1 <= tx2) ? tx1 : tx2;
- video->geo.input_r.y = (ty1 <= ty2) ? ty1 : ty2;
- video->geo.input_r.w = (tx1 <= tx2) ? tx2 - tx1 : tx1 - tx2;
- video->geo.input_r.h = (ty1 <= ty2) ? ty2 - ty1 : ty1 - ty2;
-
- /* output geometry */
- if ((sdata = ec->comp_data->sub.data))
- {
- if (sdata->parent)
- {
- video->geo.output_r.x = sdata->parent->x + sdata->position.x;
- video->geo.output_r.y = sdata->parent->y + sdata->position.y;
- }
- else
- {
- video->geo.output_r.x = sdata->position.x;
- video->geo.output_r.y = sdata->position.y;
- }
- }
- else
- {
- video->geo.output_r.x = ec->x;
- video->geo.output_r.y = ec->y;
- }
-
- video->geo.output_r.w = ec->comp_data->width_from_viewport;
- video->geo.output_r.w = (video->geo.output_r.w + 1) & ~1;
- video->geo.output_r.h = ec->comp_data->height_from_viewport;
-
- e_comp_object_frame_xy_unadjust(ec->frame,
- video->geo.output_r.x, video->geo.output_r.y,
- &video->geo.output_r.x, &video->geo.output_r.y);
- e_comp_object_frame_wh_unadjust(ec->frame,
- video->geo.output_r.w, video->geo.output_r.h,
- &video->geo.output_r.w, &video->geo.output_r.h);
-
- video->geo.transform = vp->buffer.transform;
-
- _e_video_geometry_cal_physical(video);
-
-#if 0
- VDB("geometry(%dx%d %d,%d %dx%d %d,%d %dx%d %d)",
- video->geo.input_w, video->geo.input_h,
- EINA_RECTANGLE_ARGS(&video->geo.input_r),
- EINA_RECTANGLE_ARGS(&video->geo.output_r),
- video->geo.transform);
-#endif
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_video_geometry_cal_map(E_Video *video)
-{
- E_Client *ec;
- const Evas_Map *m;
- Evas_Coord x1, x2, y1, y2;
- Eina_Rectangle output_r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(video, EINA_FALSE);
-
- ec = video->ec;
- EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
-
- m = evas_object_map_get(ec->frame);
- if (!m) return EINA_TRUE;
-
- /* If frame has map, it means that ec's geometry is decided by map's geometry.
- * ec->x,y,w,h and ec->client.x,y,w,h is not useful.
- */
-
- evas_map_point_coord_get(m, 0, &x1, &y1, NULL);
- evas_map_point_coord_get(m, 2, &x2, &y2, NULL);
-
- output_r.x = x1;
- output_r.y = y1;
- output_r.w = x2 - x1;
- output_r.w = (output_r.w + 1) & ~1;
- output_r.h = y2 - y1;
- output_r.h = (output_r.h + 1) & ~1;
-
- if (!memcmp(&video->geo.output_r, &output_r, sizeof(Eina_Rectangle)))
- return EINA_FALSE;
-
- VDB("frame(%p) m(%p) output(%d,%d %dx%d) => (%d,%d %dx%d)", ec->frame, m,
- EINA_RECTANGLE_ARGS(&video->geo.output_r), EINA_RECTANGLE_ARGS(&output_r));
-
- video->geo.output_r = output_r;
-
- _e_video_geometry_cal_physical(video);
-
- return EINA_TRUE;
-}
-
-static void
-_e_video_geometry_cal_to_input(int output_w, int output_h, int input_w, int input_h,
- tdm_transform trasnform, int ox, int oy, int *ix, int *iy)
-{
- float ratio_w, ratio_h;
-
- switch(trasnform)
- {
- case WL_OUTPUT_TRANSFORM_NORMAL:
- default:
- *ix = ox, *iy = oy;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- *ix = oy, *iy = output_w - ox;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- *ix = output_w - ox, *iy = output_h - oy;
- break;
- case WL_OUTPUT_TRANSFORM_90:
- *ix = output_h - oy, *iy = ox;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- *ix = output_w - ox, *iy = oy;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- *ix = oy, *iy = ox;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- *ix = ox, *iy = output_h - oy;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- *ix = output_h - oy, *iy = output_w - ox;
- break;
- }
- if (trasnform & 0x1)
- {
- ratio_w = (float)input_w / output_h;
- ratio_h = (float)input_h / output_w;
- }
- else
- {
- ratio_w = (float)input_w / output_w;
- ratio_h = (float)input_h / output_h;
- }
- *ix *= ratio_w;
- *iy *= ratio_h;
-}
-
-static void
-_e_video_geometry_cal_to_input_rect(E_Video * video, Eina_Rectangle *srect, Eina_Rectangle *drect)
-{
- int xf1, yf1, xf2, yf2;
-
- /* first transform box coordinates if the scaler is set */
-
- xf1 = srect->x;
- yf1 = srect->y;
- xf2 = srect->x + srect->w;
- yf2 = srect->y + srect->h;
-
- _e_video_geometry_cal_to_input(video->geo.output_r.w, video->geo.output_r.h,
- video->geo.input_r.w, video->geo.input_r.h,
- video->geo.transform, xf1, yf1, &xf1, &yf1);
- _e_video_geometry_cal_to_input(video->geo.output_r.w, video->geo.output_r.h,
- video->geo.input_r.w, video->geo.input_r.h,
- video->geo.transform, xf2, yf2, &xf2, &yf2);
-
- drect->x = MIN(xf1, xf2);
- drect->y = MIN(yf1, yf2);
- drect->w = MAX(xf1, xf2) - drect->x;
- drect->h = MAX(yf1, yf2) - drect->y;
-}
-
-static Eina_Bool
-_e_video_geometry_cal(E_Video * video)
-{
- Eina_Rectangle screen = {0,};
- Eina_Rectangle output_r = {0,}, input_r = {0,};
- const tdm_output_mode *mode = NULL;
- tdm_error tdm_err = TDM_ERROR_NONE;
-
- /* get geometry information with buffer scale, transform and viewport. */
- if (!_e_video_geometry_cal_viewport(video))
- return EINA_FALSE;
-
- _e_video_geometry_cal_map(video);
-
- if (dconfig->conf->eom_enable == EINA_TRUE && video->external_video)
- {
- tdm_err = tdm_output_get_mode(video->output, &mode);
- if (tdm_err != TDM_ERROR_NONE)
- return EINA_FALSE;
-
- if (mode == NULL)
- return EINA_FALSE;
-
- screen.w = mode->hdisplay;
- screen.h = mode->vdisplay;
- }
- else
- {
- E_Zone *zone;
- E_Client *topmost;
-
- topmost = find_topmost_parent_get(video->ec);
- EINA_SAFETY_ON_NULL_RETURN_VAL(topmost, EINA_FALSE);
-
- zone = e_comp_zone_xy_get(topmost->x, topmost->y);
- EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
-
- screen.w = zone->w;
- screen.h = zone->h;
- }
-
- e_devmgr_buffer_size_get(video->ec, &input_r.w, &input_r.h);
- // when topmost is not mapped, input size can be abnormal.
- // in this case, it will be render by topmost showing.
- if (!eina_rectangle_intersection(&video->geo.input_r, &input_r) || (video->geo.input_r.w <= 10 || video->geo.input_r.h <= 10))
- {
- VER("input area is empty");
- return EINA_FALSE;
- }
-
- if (video->geo.output_r.x >= 0 && video->geo.output_r.y >= 0 &&
- (video->geo.output_r.x + video->geo.output_r.w) <= screen.w &&
- (video->geo.output_r.y + video->geo.output_r.h) <= screen.h)
- return EINA_TRUE;
-
- /* TODO: need to improve */
-
- output_r = video->geo.output_r;
- if (!eina_rectangle_intersection(&output_r, &screen))
- {
- VER("output_r(%d,%d %dx%d) screen(%d,%d %dx%d) => intersect(%d,%d %dx%d)",
- EINA_RECTANGLE_ARGS(&video->geo.output_r),
- EINA_RECTANGLE_ARGS(&screen), EINA_RECTANGLE_ARGS(&output_r));
- return EINA_TRUE;
- }
-
- output_r.x -= video->geo.output_r.x;
- output_r.y -= video->geo.output_r.y;
-
- if (output_r.w <= 0 || output_r.h <= 0)
- {
- VER("output area is empty");
- return EINA_FALSE;
- }
-
- VDB("output(%d,%d %dx%d) input(%d,%d %dx%d)",
- EINA_RECTANGLE_ARGS(&output_r), EINA_RECTANGLE_ARGS(&input_r));
-
- _e_video_geometry_cal_to_input_rect(video, &output_r, &input_r);
-
- VDB("output(%d,%d %dx%d) input(%d,%d %dx%d)",
- EINA_RECTANGLE_ARGS(&output_r), EINA_RECTANGLE_ARGS(&input_r));
-
- output_r.x += video->geo.output_r.x;
- output_r.y += video->geo.output_r.y;
-
- input_r.x += video->geo.input_r.x;
- input_r.y += video->geo.input_r.y;
-
- output_r.x = output_r.x & ~1;
- output_r.w = (output_r.w + 1) & ~1;
-
- input_r.x = input_r.x & ~1;
- input_r.w = (input_r.w + 1) & ~1;
-
- video->geo.output_r = output_r;
- video->geo.input_r = input_r;
-
- _e_video_geometry_cal_physical(video);
-
- return EINA_TRUE;
-}
-
-static void
-_e_video_format_info_get(E_Video *video)
-{
- E_Comp_Wl_Buffer *comp_buffer;
- tbm_surface_h tbm_surf;
-
- comp_buffer = e_pixmap_resource_get(video->ec->pixmap);
- EINA_SAFETY_ON_NULL_RETURN(comp_buffer);
-
- tbm_surf = wayland_tbm_server_get_surface(e_comp->wl_comp_data->tbm.server, comp_buffer->resource);
- EINA_SAFETY_ON_NULL_RETURN(tbm_surf);
-
- video->tbmfmt = tbm_surface_get_format(tbm_surf);
-}
-
-static Eina_Bool
-_e_video_can_commit(E_Video *video)
-{
- if (dconfig->conf->eom_enable == EINA_TRUE)
- {
- if (!video->external_video && e_devicemgr_dpms_get(video->drm_output))
- return EINA_FALSE;
- }
- else
- if (e_devicemgr_dpms_get(video->drm_output))
- return EINA_FALSE;
-
- if (!_e_video_is_visible(video))
- return EINA_FALSE;
-
- return EINA_TRUE;
-}
-
-static void
-_e_video_commit_handler(tdm_layer *layer, unsigned int sequence,
- unsigned int tv_sec, unsigned int tv_usec,
- void *user_data)
-{
- E_Video *video;
- Eina_List *l;
- E_Devmgr_Buf *mbuf;
-
- EINA_LIST_FOREACH(video_list, l, video)
- {
- if (video == user_data) break;
- }
-
- if (!video) return;
- if (!video->committed_list) return;
-
- if (_e_video_can_commit(video))
- {
- tbm_surface_h displaying_buffer = tdm_layer_get_displaying_buffer(video->layer, NULL);
-
- EINA_LIST_FOREACH(video->committed_list, l, mbuf)
- {
- if (mbuf->tbm_surface == displaying_buffer) break;
- }
- if (!mbuf) return;
- }
- else
- mbuf = eina_list_nth(video->committed_list, 0);
-
- video->committed_list = eina_list_remove(video->committed_list, mbuf);
-
- /* client can attachs the same wl_buffer twice. */
- if (video->current_fb && MBUF_IS_VALID(video->current_fb) && mbuf != video->current_fb)
- {
- e_devmgr_buffer_set_use(video->current_fb, EINA_FALSE);
-
- if (video->current_fb->comp_buffer)
- e_comp_wl_buffer_reference(&video->current_fb->buffer_ref, NULL);
- }
-
- video->current_fb = mbuf;
-
- VDB("current_fb(%d)", MSTAMP(video->current_fb));
-}
-
-static void
-_e_video_vblank_handler(tdm_output *output, unsigned int sequence,
- unsigned int tv_sec, unsigned int tv_usec,
- void *user_data)
-{
- E_Video *video;
- Eina_List *l;
- E_Devmgr_Buf *mbuf;
-
- EINA_LIST_FOREACH(video_list, l, video)
- {
- if (video == user_data) break;
- }
-
- if (!video) return;
-
- video->waiting_vblank = EINA_FALSE;
-
- if (!video->waiting_list) return;
-
- mbuf = eina_list_nth(video->waiting_list, 0);
-
- video->waiting_list = eina_list_remove(video->waiting_list, mbuf);
- video->committed_list = eina_list_append(video->committed_list, mbuf);
-
- if (!_e_video_can_commit(video))
- goto no_commit;
-
- if (!_e_video_frame_buffer_show(video, mbuf))
- goto no_commit;
-
- goto done;
-
-no_commit:
- _e_video_commit_handler(NULL, 0, 0, 0, video);
- _e_video_vblank_handler(NULL, 0, 0, 0, video);
-done:
- return;
-}
-
-static void
-_e_video_video_set_hook(void *data, E_Plane *plane)
-{
- E_Devmgr_Buf *mbuf = NULL;
- E_Video *video = (E_Video *)data;
-
- if (video->e_plane != plane) return;
- if (!video->waiting_video_set) return;
-
- video->waiting_video_set = EINA_FALSE;
-
- if (!video->waiting_list) return;
-
- mbuf = eina_list_nth(video->waiting_list, 0);
-
- video->waiting_list = eina_list_remove(video->waiting_list, mbuf);
- video->committed_list = eina_list_append(video->committed_list, mbuf);
-
- if (!_e_video_can_commit(video))
- goto no_commit;
-
- if (!_e_video_frame_buffer_show(video, mbuf))
- goto no_commit;
-
- goto done;
-
-no_commit:
- _e_video_commit_handler(NULL, 0, 0, 0, video);
- _e_video_vblank_handler(NULL, 0, 0, 0, video);
-done:
- return;
-}
-
-static Eina_Bool
-_e_video_frame_buffer_show(E_Video *video, E_Devmgr_Buf *mbuf)
-{
- tdm_info_layer info, old_info;
- tdm_error ret;
- E_Client *topmost;
- Tdm_Prop_Value *prop;
-
- if (!mbuf)
- {
- if (video->layer)
- {
- VIN("unset layer: hide");
- _e_video_set_layer(video, EINA_FALSE);
- }
- return EINA_TRUE;
- }
-
- if (!video->layer)
- {
- VIN("set layer: show");
- if (!_e_video_set_layer(video, EINA_TRUE))
- {
- VER("set layer failed");
- return EINA_FALSE;
- }
- // need call tdm property in list
- Tdm_Prop_Value *prop;
- EINA_LIST_FREE(video->tdm_prop_list, prop)
- {
- VIN("call property(%s), value(%d)", prop->name, (unsigned int)prop->value.u32);
- tdm_layer_set_property(video->layer, prop->id, prop->value);
- free(prop);
- }
- }
-
- CLEAR(old_info);
- ret = tdm_layer_get_info(video->layer, &old_info);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
-
- CLEAR(info);
- info.src_config.size.h = mbuf->width_from_pitch;
- info.src_config.size.v = mbuf->height_from_size;
- info.src_config.pos.x = mbuf->content_r.x;
- info.src_config.pos.y = mbuf->content_r.y;
- info.src_config.pos.w = mbuf->content_r.w;
- info.src_config.pos.h = mbuf->content_r.h;
- info.dst_pos.x = video->geo.tdm_output_r.x;
- info.dst_pos.y = video->geo.tdm_output_r.y;
- info.dst_pos.w = video->geo.tdm_output_r.w;
- info.dst_pos.h = video->geo.tdm_output_r.h;
- info.transform = mbuf->content_t;
-
- if (memcmp(&old_info, &info, sizeof(tdm_info_layer)))
- {
- ret = tdm_layer_set_info(video->layer, &info);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
- }
-
- ret = tdm_layer_set_buffer(video->layer, mbuf->tbm_surface);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
-
- ret = tdm_layer_commit(video->layer, _e_video_commit_handler, video);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
-
- ret = tdm_output_wait_vblank(video->output, 1, 0, _e_video_vblank_handler, video);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
-
- video->waiting_vblank = EINA_TRUE;
-
- EINA_LIST_FREE(video->late_tdm_prop_list, prop)
- {
- VIN("call property(%s), value(%d)", prop->name, (unsigned int)prop->value.u32);
- tdm_layer_set_property(video->layer, prop->id, prop->value);
- free(prop);
- }
-
- topmost = find_topmost_parent_get(video->ec);
- if (topmost && (topmost->argb || topmost->comp_data->sub.below_obj) &&
- !e_comp_object_mask_has(video->ec->frame))
- {
- Eina_Bool do_punch = EINA_TRUE;
-
- /* FIXME: the mask obj can be drawn at the wrong position in the beginnig
- * time. It happens caused by window manager policy.
- */
- if ((topmost->fullscreen || topmost->maximized) &&
- (video->geo.output_r.x == 0 || video->geo.output_r.y == 0))
- {
- int bw, bh;
-
- e_pixmap_size_get(topmost->pixmap, &bw, &bh);
-
- if (bw > 100 && bh > 100 &&
- video->geo.output_r.w < 100 && video->geo.output_r.h < 100)
- {
- VIN("don't punch. (%dx%d, %dx%d)",
- bw, bh, video->geo.output_r.w, video->geo.output_r.h);
- do_punch = EINA_FALSE;
- }
- }
-
- if (do_punch)
- {
- e_comp_object_mask_set(video->ec->frame, EINA_TRUE);
- VIN("punched");
- }
- }
-
- if (video_punch)
- {
- e_comp_object_mask_set(video->ec->frame, EINA_TRUE);
- VIN("punched");
- }
-
- VDT("Client(%s):PID(%d) RscID(%d), Buffer(%p, refcnt:%d) is shown."
- "Geometry details are : buffer size(%dx%d) src(%d,%d, %dx%d)"
- " dst(%d,%d, %dx%d), transform(%d)",
- e_client_util_name_get(video->ec) ?: "No Name" , video->ec->netwm.pid,
- wl_resource_get_id(video->surface), mbuf, mbuf->ref_cnt,
- info.src_config.size.h, info.src_config.size.v, info.src_config.pos.x,
- info.src_config.pos.y, info.src_config.pos.w, info.src_config.pos.h,
- info.dst_pos.x, info.dst_pos.y, info.dst_pos.w, info.dst_pos.h, info.transform);
-
-
- return EINA_TRUE;
-}
-
-static void
-_e_video_buffer_show(E_Video *video, E_Devmgr_Buf *mbuf, unsigned int transform)
-{
- mbuf->content_t = transform;
-
- e_devmgr_buffer_set_use(mbuf, EINA_TRUE);
-
- if (mbuf->comp_buffer)
- e_comp_wl_buffer_reference(&mbuf->buffer_ref, mbuf->comp_buffer);
-
- if (!video->waiting_vblank || !video->waiting_video_set)
- video->committed_list = eina_list_append(video->committed_list, mbuf);
- else
- {
- video->waiting_list = eina_list_append(video->waiting_list, mbuf);
- VDB("There are waiting fbs more than 1");
- return;
- }
-
- if (!_e_video_can_commit(video))
- goto no_commit;
-
- if (!_e_video_frame_buffer_show(video, mbuf))
- goto no_commit;
-
- return;
-
-no_commit:
- _e_video_commit_handler(NULL, 0, 0, 0, video);
- _e_video_vblank_handler(NULL, 0, 0, 0, video);
- return;
-}
-
-static void
-_e_video_cb_evas_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- E_Video *video = data;
-
- if (_e_video_geometry_cal_map(video))
- _e_video_render(video, __FUNCTION__);
-}
-
-static void
-_e_video_cb_evas_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
-{
- E_Video *video = data;
-
- if (_e_video_geometry_cal_map(video))
- _e_video_render(video, __FUNCTION__);
-}
-
-static void
-_e_video_cb_evas_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
-{
- E_Video *video = data;
-
- if (e_object_is_del(E_OBJECT(video->ec))) return;
-
- if (video->need_force_render)
- {
- VIN("video forcely rendering..");
- _e_video_render(video, __FUNCTION__);
- }
-
- /* if stand_alone is true, not show */
- if ((video->ec->comp_data->sub.data && video->ec->comp_data->sub.data->stand_alone) ||
- (video->ec->comp_data->sub.data && video->follow_topmost_visibility))
- {
-#if 0 //mute off is managed by client. mute off in server made many issues.
- if (!video->layer) return;
-
- if (video->tdm_mute_id != -1)
- {
- tdm_value v = {.u32 = 0};
- VIN("video surface show. mute off (ec:%p)", video->ec);
- tdm_layer_set_property(video->layer, video->tdm_mute_id, v);
- }
-#endif
- return;
- }
-
- VIN("evas show (ec:%p)", video->ec);
- if (video->current_fb)
- _e_video_frame_buffer_show(video, video->current_fb);
-}
-
-static void
-_e_video_cb_evas_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
-{
- E_Video *video = data;
-
- if (e_object_is_del(E_OBJECT(video->ec))) return;
-
- /* if stand_alone is true, not hide */
- if (video->ec->comp_data->sub.data && video->ec->comp_data->sub.data->stand_alone)
- {
- if (!video->layer) return;
-
- if (video->tdm_mute_id != -1)
- {
- tdm_value v = {.u32 = 1};
- VIN("video surface hide. mute on (ec:%p)", video->ec);
- tdm_layer_set_property(video->layer, video->tdm_mute_id, v);
- }
- return;
- }
-
- VIN("evas hide (ec:%p)", video->ec);
- _e_video_frame_buffer_show(video, NULL);
-}
-
-static E_Video*
-_e_video_create(struct wl_resource *video_object, struct wl_resource *surface)
-{
- E_Video *video;
- E_Client *ec;
-
- ec = wl_resource_get_user_data(surface);
- EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
-
- video = calloc(1, sizeof *video);
- EINA_SAFETY_ON_NULL_RETURN_VAL(video, NULL);
-
- video->video_object = video_object;
- video->surface = surface;
- video->output_align = -1;
- video->pp_align = -1;
- video->video_align = -1;
- video->tdm_mute_id = -1;
-
- VIN("create. ec(%p) wl_surface@%d", ec, wl_resource_get_id(video->surface));
-
- video_list = eina_list_append(video_list, video);
-
- _e_video_set(video, ec);
-
- return video;
-}
-
-static void
-_e_video_set(E_Video *video, E_Client *ec)
-{
- int ominw = -1, ominh = -1, omaxw = -1, omaxh = -1;
- int i, count = 0;
- tdm_display_capability disp_capabilities;
- tdm_layer_capability lyr_capabilities = 0;
- const tdm_prop *props;
- tdm_layer *layer;
- unsigned int pipe;
- tdm_error ret;
-
- if (!video || !ec)
- return;
-
- if (video->ec)
- {
- VWR("already has ec");
- return;
- }
-
- EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(ec)));
-
- video->ec = ec;
- video->window = e_client_util_win_get(ec);
-
- evas_object_event_callback_add(video->ec->frame, EVAS_CALLBACK_HIDE,
- _e_video_cb_evas_hide, video);
- evas_object_event_callback_add(video->ec->frame, EVAS_CALLBACK_SHOW,
- _e_video_cb_evas_show, video);
-
- if (dconfig->conf->eom_enable == EINA_TRUE)
- {
- video->external_video = e_devicemgr_eom_is_ec_external(ec);
- if (video->external_video)
- {
- /* TODO: support screenmirror for external video */
- video->drm_output = NULL;
-
- video->output = e_devicemgr_eom_tdm_output_by_ec_get(ec);
- EINA_SAFETY_ON_NULL_RETURN(video->output);
- }
- else
- {
- video->drm_output = _e_video_drm_output_find(video->ec);
- EINA_SAFETY_ON_NULL_RETURN(video->drm_output);
-
- /* TODO: find proper output */
- video->output = e_devicemgr_tdm_output_get(video->drm_output);
- EINA_SAFETY_ON_NULL_RETURN(video->output);
- }
- }
- else
- {
- video->drm_output = _e_video_drm_output_find(video->ec);
- EINA_SAFETY_ON_NULL_RETURN(video->drm_output);
-
- /* TODO: find proper output */
- video->output = e_devicemgr_tdm_output_get(video->drm_output);
- EINA_SAFETY_ON_NULL_RETURN(video->output);
- }
-
- ret = tdm_output_get_pipe(video->output, &pipe);
- if (ret == TDM_ERROR_NONE)
- video->e_output = e_output_find_by_index(pipe);
-
- layer = e_devicemgr_tdm_video_layer_get(video->output);
- tdm_layer_get_capabilities(layer, &lyr_capabilities);
-
- if (lyr_capabilities & TDM_LAYER_CAPABILITY_VIDEO)
- {
- /* If tdm offers video layers, we will assign a tdm layer when showing */
- VIN("video client");
- ec->comp_data->video_client = 1;
- }
- else
- {
- /* If tdm doesn't offer video layers, we assign a tdm layer now. If failed,
- * video will be displayed via the UI rendering path.
- */
- if (_e_video_set_layer(video, EINA_TRUE))
- {
- VIN("video client");
- ec->comp_data->video_client = 1;
- }
- else
- {
- VIN("no video client");
- ec->comp_data->video_client = 0;
- ec->animatable = 0;
- }
- }
-
- if (video_to_primary)
- {
- VIN("show video to primary layer");
- ec->comp_data->video_client = 0;
- ec->animatable = 0;
- }
-
- tdm_output_get_available_size(video->output, &ominw, &ominh, &omaxw, &omaxh, &video->output_align);
-
- tdm_display_get_capabilities(e_devmgr_dpy->tdm, &disp_capabilities);
-
- if (!(disp_capabilities & TDM_DISPLAY_CAPABILITY_PP))
- {
- video->video_align = video->output_align;
- tizen_video_object_send_size(video->video_object,
- ominw, ominh, omaxw, omaxh, video->output_align);
- }
- else
- {
- int minw = -1, minh = -1, maxw = -1, maxh = -1;
- int pminw = -1, pminh = -1, pmaxw = -1, pmaxh = -1;
-
- tdm_display_get_pp_available_size(e_devmgr_dpy->tdm, &pminw, &pminh, &pmaxw, &pmaxh, &video->pp_align);
-
- minw = MAX(ominw, pminw);
- minh = MAX(ominh, pminh);
-
- if (omaxw != -1 && pmaxw == -1)
- maxw = omaxw;
- else if (omaxw == -1 && pmaxw != -1)
- maxw = pmaxw;
- else
- maxw = MIN(omaxw, pmaxw);
-
- if (omaxh != -1 && pmaxh == -1)
- maxw = omaxh;
- else if (omaxh == -1 && pmaxh != -1)
- maxw = pmaxh;
- else
- maxh = MIN(omaxh, pmaxh);
-
- if (video->output_align != -1 && video->pp_align == -1)
- video->video_align = video->output_align;
- else if (video->output_align == -1 && video->pp_align != -1)
- video->video_align = video->pp_align;
- else if (video->output_align == -1 && video->pp_align == -1)
- video->video_align = video->pp_align;
- else if (video->output_align > 0 && video->pp_align > 0)
- video->video_align = lcm(video->output_align, video->pp_align);
- else
- ERR("invalid align: %d, %d", video->output_align, video->pp_align);
-
- tizen_video_object_send_size(video->video_object,
- minw, minh, maxw, maxh, video->video_align);
- VIN("align width: output(%d) pp(%d) video(%d)",
- video->output_align, video->pp_align, video->video_align);
- }
-
- tdm_layer_get_available_properties(layer, &props, &count);
- for (i = 0; i < count; i++)
- {
- tdm_value value;
- tdm_layer_get_property(layer, props[i].id, &value);
- tizen_video_object_send_attribute(video->video_object, props[i].name, value.u32);
-
- if (!strncmp(props[i].name, "mute", TDM_NAME_LEN))
- video->tdm_mute_id = props[i].id;
- }
-}
-
-static void
-_e_video_hide(E_Video *video)
-{
- E_Devmgr_Buf *mbuf;
-
- if (video->current_fb || video->committed_list)
- _e_video_frame_buffer_show(video, NULL);
-
- if (video->current_fb)
- {
- e_devmgr_buffer_set_use(video->current_fb, EINA_FALSE);
- video->current_fb = NULL;
- }
-
- EINA_LIST_FREE(video->committed_list, mbuf)
- e_devmgr_buffer_set_use(mbuf, EINA_FALSE);
-
- EINA_LIST_FREE(video->waiting_list, mbuf)
- e_devmgr_buffer_set_use(mbuf, EINA_FALSE);
-}
-
-static void
-_e_video_destroy(E_Video *video)
-{
- E_Devmgr_Buf *mbuf;
- Eina_List *l = NULL, *ll = NULL;
-
- if (!video)
- return;
-
- VIN("destroy");
-
- if (video->cb_registered)
- {
- evas_object_event_callback_del_full(video->ec->frame, EVAS_CALLBACK_RESIZE,
- _e_video_cb_evas_resize, video);
- evas_object_event_callback_del_full(video->ec->frame, EVAS_CALLBACK_MOVE,
- _e_video_cb_evas_move, video);
- }
-
- evas_object_event_callback_del_full(video->ec->frame, EVAS_CALLBACK_HIDE,
- _e_video_cb_evas_hide, video);
- evas_object_event_callback_del_full(video->ec->frame, EVAS_CALLBACK_SHOW,
- _e_video_cb_evas_show, video);
-
- wl_resource_set_destructor(video->video_object, NULL);
-
- _e_video_hide(video);
-
- /* others */
- EINA_LIST_FOREACH_SAFE(video->input_buffer_list, l, ll, mbuf)
- {
- e_devmgr_buffer_set_use(mbuf, EINA_FALSE);
- e_devmgr_buffer_unref(mbuf);
- }
-
- EINA_LIST_FOREACH_SAFE(video->pp_buffer_list, l, ll, mbuf)
- {
- tdm_buffer_remove_release_handler(mbuf->tbm_surface,
- _e_video_pp_buffer_cb_release, mbuf);
- e_devmgr_buffer_set_use(mbuf, EINA_FALSE);
- e_devmgr_buffer_unref(mbuf);
- }
-
- if(video->tdm_prop_list)
- {
- Tdm_Prop_Value *tdm_prop;
- EINA_LIST_FREE(video->tdm_prop_list, tdm_prop)
- {
- free(tdm_prop);
- }
- }
- if(video->late_tdm_prop_list)
- {
- Tdm_Prop_Value *tdm_prop;
- EINA_LIST_FREE(video->late_tdm_prop_list, tdm_prop)
- {
- free(tdm_prop);
- }
- }
-
- if (video->input_buffer_list)
- NEVER_GET_HERE();
- if (video->pp_buffer_list)
- NEVER_GET_HERE();
- if (video->tdm_prop_list)
- NEVER_GET_HERE();
- if (video->late_tdm_prop_list)
- NEVER_GET_HERE();
-
- /* destroy converter second */
- if (video->pp)
- tdm_pp_destroy(video->pp);
-
- if (video->layer)
- {
- VIN("unset layer: destroy");
- _e_video_set_layer(video, EINA_FALSE);
- }
-
- video_list = eina_list_remove(video_list, video);
-
- free(video);
-
-#if 0
- if (e_devmgr_buffer_list_length() > 0)
- e_devmgr_buffer_list_print(NULL);
-#endif
-}
-
-static Eina_Bool
-_e_video_check_if_pp_needed(E_Video *video)
-{
- int i, count = 0;
- const tbm_format *formats;
- Eina_Bool found = EINA_FALSE;
- tdm_layer_capability capabilities = 0;
- tdm_layer *layer = e_devicemgr_tdm_video_layer_get(video->output);
-
- tdm_layer_get_capabilities(layer, &capabilities);
-
- /* don't need pp if a layer has TDM_LAYER_CAPABILITY_VIDEO capability*/
- if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
- return EINA_FALSE;
-
- /* check formats */
- tdm_layer_get_available_formats(layer, &formats, &count);
- for (i = 0; i < count; i++)
- if (formats[i] == video->tbmfmt)
- {
- found = EINA_TRUE;
- break;
- }
-
- if (!found)
- {
- video->pp_tbmfmt = TBM_FORMAT_ARGB8888;
- return EINA_TRUE;
- }
-
- /* check size */
- if (capabilities & TDM_LAYER_CAPABILITY_SCANOUT)
- goto need_pp;
-
- if (video->geo.input_r.w != video->geo.output_r.w || video->geo.input_r.h != video->geo.output_r.h)
- if (!(capabilities & TDM_LAYER_CAPABILITY_SCALE))
- goto need_pp;
-
- /* check rotate */
- if (video->geo.transform || e_comp->e_comp_screen->rotation > 0)
- if (!(capabilities & TDM_LAYER_CAPABILITY_TRANSFORM))
- goto need_pp;
-
- return EINA_FALSE;
-
-need_pp:
- video->pp_tbmfmt = video->tbmfmt;
- return EINA_TRUE;
-}
-
-static void
-_e_video_pp_buffer_cb_release(tbm_surface_h surface, void *user_data)
-{
- E_Devmgr_Buf *mbuf = (E_Devmgr_Buf*)user_data;
-
- mbuf->in_use = EINA_FALSE;
-}
-
-static void
-_e_video_pp_cb_done(tdm_pp *pp, tbm_surface_h sb, tbm_surface_h db, void *user_data)
-{
- E_Video *video = (E_Video*)user_data;
- E_Devmgr_Buf *input_buffer, *pp_buffer;
-
- input_buffer = _e_video_mbuf_find(video->input_buffer_list, sb);
- if (input_buffer)
- e_devmgr_buffer_unref(input_buffer);
-
- pp_buffer = _e_video_mbuf_find(video->pp_buffer_list, db);
- if (pp_buffer)
- {
- e_devmgr_buffer_set_use(pp_buffer, EINA_FALSE);
- if (!_e_video_is_visible(video)) return;
-
- _e_video_buffer_show(video, pp_buffer, 0);
-
- /* don't unref pp_buffer here because we will unref it when video destroyed */
-#ifdef DUMP_BUFFER
- static int i;
- e_devmgr_buffer_dump(pp_buffer, "out", i++, 0);
-#endif
- }
- else
- {
- VER("There is no pp_buffer");
- // there is no way to set in_use flag.
- // This will cause issue when server get available pp_buffer.
- }
-}
-
-static void
-_e_video_render(E_Video *video, const char *func)
-{
- E_Comp_Wl_Buffer *comp_buffer;
- E_Devmgr_Buf *pp_buffer = NULL;
- E_Devmgr_Buf *input_buffer = NULL;
- E_Client *topmost;
-
- EINA_SAFETY_ON_NULL_RETURN(video->ec);
-
- /* buffer can be NULL when camera/video's mode changed. Do nothing and
- * keep previous frame in this case.
- */
- if (!video->ec->pixmap)
- return;
-
- if (!_e_video_is_visible(video))
- {
- _e_video_hide(video);
- return;
- }
-
- comp_buffer = e_pixmap_resource_get(video->ec->pixmap);
- if (!comp_buffer) return;
-
- _e_video_format_info_get(video);
-
- /* not interested with other buffer type */
- if (!wayland_tbm_server_get_surface(NULL, comp_buffer->resource))
- return;
-
- topmost = find_topmost_parent_get(video->ec);
- EINA_SAFETY_ON_NULL_RETURN(topmost);
-
- if(e_devicemgr_viewport_is_changed(topmost))
- {
- VIN("need update viewport: apply topmost");
- e_devicemgr_viewport_apply(topmost);
- }
-
- if (!_e_video_geometry_cal(video))
- {
- if(!video->need_force_render && !_e_video_parent_is_viewable(video))
- {
- VIN("need force render");
- video->need_force_render = EINA_TRUE;
- }
- return;
- }
-
- if (!memcmp(&video->old_geo, &video->geo, sizeof video->geo) &&
- video->old_comp_buffer == comp_buffer)
- return;
-
- video->need_force_render = EINA_FALSE;
-
- DBG("====================================== (%s)", func);
- VDB("old: "GEO_FMT" buf(%p)", GEO_ARG(&video->old_geo), video->old_comp_buffer);
- VDB("new: "GEO_FMT" buf(%p) %c%c%c%c", GEO_ARG(&video->geo), comp_buffer, FOURCC_STR(video->tbmfmt));
-
- _e_video_input_buffer_valid(video, comp_buffer);
-
- if (!_e_video_check_if_pp_needed(video))
- {
- /* 1. non converting case */
- input_buffer = _e_video_input_buffer_get(video, comp_buffer, EINA_TRUE);
- EINA_SAFETY_ON_NULL_GOTO(input_buffer, render_fail);
-
- _e_video_buffer_show(video, input_buffer, video->geo.tdm_transform);
-
- video->old_geo = video->geo;
- video->old_comp_buffer = comp_buffer;
-
-#ifdef DUMP_BUFFER
- static int i;
- e_devmgr_buffer_dump(input_buffer, "render", i++, 0);
-#endif
- goto done;
- }
-
- /* 2. converting case */
- if (!video->pp)
- {
- video->pp = tdm_display_create_pp(e_devmgr_dpy->tdm, NULL);
- EINA_SAFETY_ON_NULL_GOTO(video->pp, render_fail);
-
- tdm_display_get_pp_available_size(e_devmgr_dpy->tdm, &video->pp_minw, &video->pp_minh,
- &video->pp_maxw, &video->pp_maxh, &video->pp_align);
- }
-
- if ((video->pp_minw > 0 && (video->geo.input_r.w < video->pp_minw || video->geo.tdm_output_r.w < video->pp_minw)) ||
- (video->pp_minh > 0 && (video->geo.input_r.h < video->pp_minh || video->geo.tdm_output_r.h < video->pp_minh)) ||
- (video->pp_maxw > 0 && (video->geo.input_r.w > video->pp_maxw || video->geo.tdm_output_r.w > video->pp_maxw)) ||
- (video->pp_maxh > 0 && (video->geo.input_r.h > video->pp_maxh || video->geo.tdm_output_r.h > video->pp_maxh)))
- {
- INF("size(%dx%d, %dx%d) is out of PP range",
- video->geo.input_r.w, video->geo.input_r.h, video->geo.tdm_output_r.w, video->geo.tdm_output_r.h);
- goto done;
- }
-
- input_buffer = _e_video_input_buffer_get(video, comp_buffer, EINA_FALSE);
- EINA_SAFETY_ON_NULL_GOTO(input_buffer, render_fail);
-
- pp_buffer = _e_video_pp_buffer_get(video, video->geo.tdm_output_r.w, video->geo.tdm_output_r.h);
- EINA_SAFETY_ON_NULL_GOTO(pp_buffer, render_fail);
-
- if (memcmp(&video->old_geo, &video->geo, sizeof video->geo))
- {
- tdm_info_pp info;
-
- CLEAR(info);
- info.src_config.size.h = input_buffer->width_from_pitch;
- info.src_config.size.v = input_buffer->height_from_size;
- info.src_config.pos.x = video->geo.input_r.x;
- info.src_config.pos.y = video->geo.input_r.y;
- info.src_config.pos.w = video->geo.input_r.w;
- info.src_config.pos.h = video->geo.input_r.h;
- info.src_config.format = video->tbmfmt;
- info.dst_config.size.h = pp_buffer->width_from_pitch;
- info.dst_config.size.v = pp_buffer->height_from_size;
- info.dst_config.pos.w = video->geo.tdm_output_r.w;
- info.dst_config.pos.h = video->geo.tdm_output_r.h;
- info.dst_config.format = video->pp_tbmfmt;
- info.transform = video->geo.tdm_transform;
-
- if (tdm_pp_set_info(video->pp, &info))
- goto render_fail;
-
- if (tdm_pp_set_done_handler(video->pp, _e_video_pp_cb_done, video))
- goto render_fail;
-
- CLEAR(video->pp_r);
- video->pp_r.w = info.dst_config.pos.w;
- video->pp_r.h = info.dst_config.pos.h;
- }
-
- pp_buffer->content_r = video->pp_r;
-
-#ifdef DUMP_BUFFER
- static int i;
- e_devmgr_buffer_dump(input_buffer, "in", i++, 0);
-#endif
-
- if (tdm_pp_attach(video->pp, input_buffer->tbm_surface, pp_buffer->tbm_surface))
- goto render_fail;
-
- e_devmgr_buffer_set_use(pp_buffer, EINA_TRUE);
-
- e_comp_wl_buffer_reference(&input_buffer->buffer_ref, comp_buffer);
-
- if (tdm_pp_commit(video->pp))
- {
- e_devmgr_buffer_set_use(pp_buffer, EINA_FALSE);
- goto render_fail;
- }
-
- video->old_geo = video->geo;
- video->old_comp_buffer = comp_buffer;
-
- goto done;
-
-render_fail:
- if (input_buffer)
- e_devmgr_buffer_unref(input_buffer);
-
-done:
- if (!video->cb_registered)
- {
- evas_object_event_callback_add(video->ec->frame, EVAS_CALLBACK_RESIZE,
- _e_video_cb_evas_resize, video);
- evas_object_event_callback_add(video->ec->frame, EVAS_CALLBACK_MOVE,
- _e_video_cb_evas_move, video);
- video->cb_registered = EINA_TRUE;
- }
- DBG("======================================.");
-}
-
-static Eina_Bool
-_e_video_cb_ec_buffer_change(void *data, int type, void *event)
-{
- E_Client *ec;
- E_Event_Client *ev = event;
- E_Video *video;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
-
- ec = ev->ec;
- if (e_object_is_del(E_OBJECT(ec)))
- return ECORE_CALLBACK_PASS_ON;
-
-#ifdef DUMP_BUFFER
- if (ec->comp_data->sub.data && ec->pixmap)
- {
- E_Comp_Wl_Buffer *comp_buffer = e_pixmap_resource_get(ec->pixmap);
- if (comp_buffer && wl_shm_buffer_get(comp_buffer->resource))
- {
- E_Devmgr_Buf *mbuf = e_devmgr_buffer_create(comp_buffer->resource);
- EINA_SAFETY_ON_NULL_RETURN_VAL(mbuf, ECORE_CALLBACK_PASS_ON);
- static int i;
- e_devmgr_buffer_dump(mbuf, "dump", i++, 0);
- e_devmgr_buffer_unref(mbuf);
- }
- }
-#endif
-
- /* not interested with non video_surface, */
- video = find_video_with_surface(ec->comp_data->surface);
- if (!video) return ECORE_CALLBACK_PASS_ON;
-
- if (!video->ec->comp_data->video_client)
- return ECORE_CALLBACK_PASS_ON;
-
- if (dconfig->conf->eom_enable == EINA_TRUE)
- {
- /* skip external client buffer if its top parent is not current for eom anymore */
- if (video->external_video && !e_devicemgr_eom_is_ec_external(ec))
- {
- VWR("skip external buffer");
- return ECORE_CALLBACK_PASS_ON;
- }
- }
-
- _e_video_render(video, __FUNCTION__);
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_video_cb_ec_remove(void *data, int type, void *event)
-{
- E_Event_Client *ev = event;
- E_Client *ec;
- E_Video *video;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
-
- ec = ev->ec;
- if (!ec->comp_data) return ECORE_CALLBACK_PASS_ON;
-
- video = find_video_with_surface(ec->comp_data->surface);
- if (!video) return ECORE_CALLBACK_PASS_ON;
-
- _e_video_destroy(video);
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_video_cb_ec_client_show(void *data, int type, void *event)
-{
- E_Event_Client *ev = event;
- E_Client *ec;
- E_Client *video_ec = NULL;
- E_Video *video = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
-
- ec = ev->ec;
- if (!ec->comp_data) return ECORE_CALLBACK_PASS_ON;
-
- video_ec = find_video_child_get(ec);
- if (!video_ec) return ECORE_CALLBACK_PASS_ON;
-
- video = find_video_with_surface(video_ec->comp_data->surface);
- if (!video) return ECORE_CALLBACK_PASS_ON;
-
- VIN("client(0x%08"PRIxPTR") show: find video child(0x%08"PRIxPTR")", (Ecore_Window)e_client_util_win_get(ec), (Ecore_Window)e_client_util_win_get(video_ec));
- if(video->old_comp_buffer)
- {
- VIN("video already rendering..");
- return ECORE_CALLBACK_PASS_ON;
- }
-
- if(ec == find_topmost_parent_get(video->ec))
- {
- VIN("video need rendering..");
- e_devicemgr_viewport_apply(ec);
- _e_video_render(video, __FUNCTION__);
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_video_cb_ec_visibility_change(void *data, int type, void *event)
-{
- E_Event_Remote_Surface_Provider *ev = event;
- E_Client *ec = ev->ec;
- E_Video *video;
- Eina_List *l;
-
- EINA_LIST_FOREACH(video_list, l, video)
- {
- E_Client *offscreen_parent = find_offscreen_parent_get(video->ec);
- if (!offscreen_parent) continue;
- if (offscreen_parent != ec) continue;
- switch (ec->visibility.obscured)
- {
- case E_VISIBILITY_FULLY_OBSCURED:
- _e_video_cb_evas_hide(video, NULL, NULL, NULL);
- break;
- case E_VISIBILITY_UNOBSCURED:
- _e_video_cb_evas_show(video, NULL, NULL, NULL);
- break;
- default:
- VER("Not implemented");
- return ECORE_CALLBACK_PASS_ON;
- }
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_e_video_cb_topmost_ec_visibility_change(void *data, int type, void *event)
-{
- E_Event_Client *ev = event;
- E_Client *ec = ev->ec;
- E_Video *video;
- Eina_List *l = NULL;
-
- EINA_LIST_FOREACH(video_list, l, video)
- {
- E_Client *topmost = find_topmost_parent_get(video->ec);
- if (!topmost) continue;
- if (topmost == video->ec) continue;
- if (topmost != ec) continue;
- if (video->follow_topmost_visibility)
- {
- switch (ec->visibility.obscured)
- {
- case E_VISIBILITY_FULLY_OBSCURED:
- VIN("follow_topmost_visibility: fully_obscured");
- _e_video_cb_evas_hide(video, NULL, NULL, NULL);
- break;
- case E_VISIBILITY_UNOBSCURED:
- VIN("follow_topmost_visibility: UNOBSCURED");
- _e_video_cb_evas_show(video, NULL, NULL, NULL);
- break;
- default:
- return ECORE_CALLBACK_PASS_ON;
- }
- }
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static void
-_e_devicemgr_video_object_destroy(struct wl_resource *resource)
-{
- E_Video *video = wl_resource_get_user_data(resource);
- EINA_SAFETY_ON_NULL_RETURN(video);
-
- VDT("Video from Client(%s):PID(%d) is being destroyed, details are: "
- "Buffer(%p), Video_Format(%c%c%c%c), "
- "Buffer_Size(%dx%d), Src Rect(%d,%d, %dx%d), Dest Rect(%d,%d, %dx%d),"
- " Transformed(%d)",
- e_client_util_name_get(video->ec) ?: "No Name" , video->ec->netwm.pid,
- video->current_fb, FOURCC_STR(video->tbmfmt),
- video->geo.input_w, video->geo.input_h, video->geo.input_r.x ,
- video->geo.input_r.y, video->geo.input_r.w, video->geo.input_r.h,
- video->geo.output_r.x ,video->geo.output_r.y, video->geo.output_r.w,
- video->geo.output_r.h, video->geo.transform);
-
- _e_video_destroy(video);
-}
-
-static void
-_e_devicemgr_video_object_cb_destroy(struct wl_client *client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-_e_devicemgr_video_object_cb_set_attribute(struct wl_client *client,
- struct wl_resource *resource,
- const char *name,
- int32_t value)
-{
- E_Video *video;
- int i, count = 0;
- const tdm_prop *props;
- tdm_layer *layer;
- Eina_Bool available = EINA_FALSE;
-
- video = wl_resource_get_user_data(resource);
- EINA_SAFETY_ON_NULL_RETURN(video);
-
- if(video->ec)
- VDT("Client(%s):PID(%d) RscID(%d) Attribute:%s, Value:%d",
- e_client_util_name_get(video->ec) ?: "No Name",
- video->ec->netwm.pid, wl_resource_get_id(video->surface),
- name,value);
-
- // check available property & count
- layer = e_devicemgr_tdm_video_layer_get(video->output);
- tdm_layer_get_available_properties(layer, &props, &count);
-
- for (i = 0; i < count; i++)
- {
- if (!strncmp(name, props[i].name, TDM_NAME_LEN))
- {
- available = EINA_TRUE;
- VDB("check property(%s) value(%d)", name, value);
- break;
- }
- }
-
- if(!available)
- {
- VIN("no available property");
- return;
- }
-
- if (!video->layer && video->allowed_attribute)
- {
- VIN("set layer: set_attribute");
- if (!_e_video_set_layer(video, EINA_TRUE))
- {
- VER("set layer failed");
- return;
- }
- }
-
- if (!_e_video_is_visible(video) || !video->layer)
- {
- /* if mute off, need to do it after buffer commit */
- if (!strncmp(props[i].name, "mute", TDM_NAME_LEN) && value == 0)
- {
- Tdm_Prop_Value *prop = NULL;
- const Eina_List *l = NULL;
-
- EINA_LIST_FOREACH(video->late_tdm_prop_list, l, prop)
- {
- if (!strncmp(name, prop->name, TDM_NAME_LEN))
- {
- prop->value.u32 = value;
- VDB("update property(%s) value(%d)", prop->name, value);
- return;
- }
- }
-
- prop = calloc(1, sizeof(Tdm_Prop_Value));
- if(!prop) return;
-
- prop->value.u32 = value;
- prop->id = props[i].id;
- memcpy(prop->name, props[i].name, sizeof(props[i].name));
- VIN("Add property(%s) value(%d)", prop->name, value);
- video->late_tdm_prop_list = eina_list_append(video->late_tdm_prop_list, prop);
- return;
- }
- }
-
- // check set video layer
- if(!video->layer)
- {
- VIN("no layer: save property value");
-
- Tdm_Prop_Value *prop = NULL;
- const Eina_List *l = NULL;
-
- EINA_LIST_FOREACH(video->tdm_prop_list, l, prop)
- {
- if (!strncmp(name, prop->name, TDM_NAME_LEN))
- {
- VDB("find prop data(%s) update value(%d -> %d)", prop->name, (unsigned int)prop->value.u32, (unsigned int)value);
- prop->value.u32 = value;
- return;
- }
- }
- EINA_LIST_FOREACH(video->late_tdm_prop_list, l, prop)
- {
- if (!strncmp(name, prop->name, TDM_NAME_LEN))
- {
- VDB("find prop data(%s) update value(%d -> %d)", prop->name, (unsigned int)prop->value.u32, (unsigned int)value);
- prop->value.u32 = value;
- return;
- }
- }
-
- prop = calloc(1, sizeof(Tdm_Prop_Value));
- if(!prop) return;
- prop->value.u32 = value;
- prop->id = props[i].id;
- memcpy(prop->name, props[i].name, sizeof(props[i].name));
- VIN("Add property(%s) value(%d)", prop->name, value);
- video->tdm_prop_list = eina_list_append(video->tdm_prop_list, prop);
- }
- // if set layer call property
- else
- {
- tdm_value v = {.u32 = value};
- VIN("set layer: call property(%s), value(%d)", name, value);
- tdm_layer_set_property(video->layer, props[i].id, v);
- }
-}
-
-static void
-_e_devicemgr_video_object_cb_follow_topmost_visibility(struct wl_client *client,
- struct wl_resource *resource)
-{
- E_Video *video;
-
- video = wl_resource_get_user_data(resource);
- EINA_SAFETY_ON_NULL_RETURN(video);
-
- if(!video->ec || video->follow_topmost_visibility)
- return;
-
- VIN("set follow_topmost_visibility");
-
- video->follow_topmost_visibility= EINA_TRUE;
-
-}
-
-static void
-_e_devicemgr_video_object_cb_unfollow_topmost_visibility(struct wl_client *client,
- struct wl_resource *resource)
-{
- E_Video *video;
-
- video = wl_resource_get_user_data(resource);
- EINA_SAFETY_ON_NULL_RETURN(video);
-
- if(!video->ec || !video->follow_topmost_visibility)
- return;
-
- VIN("set unfollow_topmost_visibility");
-
- video->follow_topmost_visibility= EINA_FALSE;
-
-}
-
-static void
-_e_devicemgr_video_object_cb_allowed_attribute(struct wl_client *client,
- struct wl_resource *resource)
-{
- E_Video *video;
-
- video = wl_resource_get_user_data(resource);
- EINA_SAFETY_ON_NULL_RETURN(video);
-
- if(!video->ec || video->allowed_attribute)
- return;
-
- VIN("set allowed_attribute");
-
- video->allowed_attribute= EINA_TRUE;
-
-}
-
-static void
-_e_devicemgr_video_object_cb_disallowed_attribute(struct wl_client *client,
- struct wl_resource *resource)
-{
- E_Video *video;
-
- video = wl_resource_get_user_data(resource);
- EINA_SAFETY_ON_NULL_RETURN(video);
-
- if(!video->ec || !video->allowed_attribute)
- return;
-
- VIN("set disallowed_attribute");
-
- video->allowed_attribute= EINA_FALSE;
-
-}
-
-static const struct tizen_video_object_interface _e_devicemgr_video_object_interface =
-{
- _e_devicemgr_video_object_cb_destroy,
- _e_devicemgr_video_object_cb_set_attribute,
- _e_devicemgr_video_object_cb_follow_topmost_visibility,
- _e_devicemgr_video_object_cb_unfollow_topmost_visibility,
- _e_devicemgr_video_object_cb_allowed_attribute,
- _e_devicemgr_video_object_cb_disallowed_attribute,
-};
-
-static void
-_e_devicemgr_video_cb_get_object(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t id,
- struct wl_resource *surface)
-{
- int version = wl_resource_get_version(resource);
- E_Video *video = wl_resource_get_user_data(resource);
- struct wl_resource *res;
-
- if (video)
- {
- wl_resource_post_error(resource,
- TIZEN_VIDEO_ERROR_OBJECT_EXISTS,
- "a video object for that surface already exists");
- return;
- }
-
- res = wl_resource_create(client, &tizen_video_object_interface, version, id);
- if (res == NULL)
- {
- wl_client_post_no_memory(client);
- return;
- }
-
- if (!(video = _e_video_create(res, surface)))
- {
- wl_resource_destroy(res);
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(res, &_e_devicemgr_video_object_interface,
- video, _e_devicemgr_video_object_destroy);
-}
-
-static void
-_e_devicemgr_video_cb_get_viewport(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t id,
- struct wl_resource *surface)
-{
- E_Client *ec;
-
- if (!(ec = wl_resource_get_user_data(surface))) return;
- if (!ec->comp_data) return;
-
- if (ec->comp_data && ec->comp_data->scaler.viewport)
- {
- wl_resource_post_error(resource,
- TIZEN_VIDEO_ERROR_VIEWPORT_EXISTS,
- "a viewport for that subsurface already exists");
- return;
- }
-
- if (!e_devicemgr_viewport_create(resource, id, surface))
- {
- ERR("Failed to create viewport for wl_surface@%d",
- wl_resource_get_id(surface));
- wl_client_post_no_memory(client);
- return;
- }
-}
-
-static const struct tizen_video_interface _e_devicemgr_video_interface =
-{
- _e_devicemgr_video_cb_get_object,
- _e_devicemgr_video_cb_get_viewport,
-};
-
-static void
-_e_devicemgr_video_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
-{
- struct wl_resource *res;
- const tbm_format *formats = NULL;
- int i, count = 0;
-
- if (!(res = wl_resource_create(client, &tizen_video_interface, MIN(version, 1), id)))
- {
- ERR("Could not create tizen_video_interface resource: %m");
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(res, &_e_devicemgr_video_interface, NULL, NULL);
-
- /* 1st, use pp information. */
- if (e_devmgr_dpy->pp_available)
- {
- tdm_display_get_pp_available_formats(e_devmgr_dpy->tdm, &formats, &count);
- for (i = 0; i < count; i++)
- tizen_video_send_format(res, formats[i]);
- }
- else
- {
- tdm_output *output = e_devicemgr_tdm_output_get(NULL);
- tdm_layer *layer;
-
- EINA_SAFETY_ON_NULL_RETURN(output);
-
- layer = e_devicemgr_tdm_video_layer_get(output);
- EINA_SAFETY_ON_NULL_RETURN(layer);
-
- tdm_layer_get_available_formats(layer, &formats, &count);
- for (i = 0; i < count; i++)
- tizen_video_send_format(res, formats[i]);
- }
-}
-
-static Eina_List *video_hdlrs;
-
-static void
-_e_devicemgr_mbuf_print(void *data, const char *log_path)
-{
- e_devmgr_buffer_list_print(log_path);
-}
-
-static void
-_e_devicemgr_video_dst_change(void *data, const char *log_path)
-{
- Eina_List *video_list, *l;
- E_Video *video;
- static int i = -1;
- int temp = 64;
- video_list = e_devicemgr_video_list_get();
-
- EINA_LIST_FOREACH(video_list, l, video)
- {
- E_Client *ec = video->ec;
- E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
-
- vp->changed = EINA_TRUE;
-
- if (ec->comp_data->sub.data)
- {
- ec->comp_data->sub.data->position.x -= (temp * i);
- ec->comp_data->sub.data->position.y -= (temp * i);
- ec->comp_data->sub.data->position.set = EINA_TRUE;
- }
-
- vp->surface.width += (temp * i) * 2;
- vp->surface.height += (temp * i) * 2;
-
- e_comp_wl_map_size_cal_from_buffer(ec);
- e_comp_wl_map_size_cal_from_viewport(ec);
- e_comp_wl_map_apply(ec);
- }
-
- i *= -1;
-}
-
-static void
-_e_devicemgr_video_to_primary(void *data, const char *log_path)
-{
- video_to_primary = !video_to_primary;
-}
-
-static void
-_e_devicemgr_video_punch(void *data, const char *log_path)
-{
- video_punch = !video_punch;
-}
-
-int
-e_devicemgr_video_init(void)
-{
- if (!e_comp_wl) return 0;
- if (!e_comp_wl->wl.disp) return 0;
- if (e_comp->wl_comp_data->video.global) return 1;
-
- e_info_server_hook_set("mbuf", _e_devicemgr_mbuf_print, NULL);
- e_info_server_hook_set("video-dst-change", _e_devicemgr_video_dst_change, NULL);
- e_info_server_hook_set("video-to-primary", _e_devicemgr_video_to_primary, NULL);
- e_info_server_hook_set("video-punch", _e_devicemgr_video_punch, NULL);
-
- _video_detail_log_dom = eina_log_domain_register("e-devicemgr-video", EINA_COLOR_BLUE);
- if (_video_detail_log_dom < 0)
- {
- ERR("Failed eina_log_domain_register()..!\n");
- return 0;
- }
-
- e_comp->wl_comp_data->video.global =
- wl_global_create(e_comp_wl->wl.disp, &tizen_video_interface, 1, NULL, _e_devicemgr_video_cb_bind);
-
- /* try to add tizen_video to wayland globals */
- if (!e_comp->wl_comp_data->video.global)
- {
- ERR("Could not add tizen_video to wayland globals");
- return 0;
- }
-
- E_LIST_HANDLER_APPEND(video_hdlrs, E_EVENT_CLIENT_BUFFER_CHANGE,
- _e_video_cb_ec_buffer_change, NULL);
- E_LIST_HANDLER_APPEND(video_hdlrs, E_EVENT_CLIENT_REMOVE,
- _e_video_cb_ec_remove, NULL);
- E_LIST_HANDLER_APPEND(video_hdlrs, E_EVENT_CLIENT_SHOW,
- _e_video_cb_ec_client_show, NULL);
- E_LIST_HANDLER_APPEND(video_hdlrs, E_EVENT_REMOTE_SURFACE_PROVIDER_VISIBILITY_CHANGE,
- _e_video_cb_ec_visibility_change, NULL);
- E_LIST_HANDLER_APPEND(video_hdlrs, E_EVENT_CLIENT_VISIBILITY_CHANGE,
- _e_video_cb_topmost_ec_visibility_change, NULL);
-
- return 1;
-}
-
-void
-e_devicemgr_video_fini(void)
-{
- E_FREE_LIST(video_hdlrs, ecore_event_handler_del);
-
- e_info_server_hook_set("mbuf", NULL, NULL);
- e_info_server_hook_set("video-dst-change", NULL, NULL);
- e_info_server_hook_set("video-to-primary", NULL, NULL);
- e_info_server_hook_set("video-punch", NULL, NULL);
-
- eina_log_domain_unregister(_video_detail_log_dom);
- _video_detail_log_dom = -1;
-}
-
-Eina_List*
-e_devicemgr_video_list_get(void)
-{
- return video_list;
-}
-
-E_Devmgr_Buf*
-e_devicemgr_video_fb_get(E_Video *video)
-{
- tdm_layer_capability capabilities = 0;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(video, NULL);
-
- if (!video->layer)
- return NULL;
-
- if (tdm_layer_get_capabilities(video->layer, &capabilities) != TDM_ERROR_NONE)
- return NULL;
-
- if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
- return NULL;
-
- return video->current_fb;
-}
-
-void
-e_devicemgr_video_pos_get(E_Video *video, int *x, int *y)
-{
- EINA_SAFETY_ON_NULL_RETURN(video);
-
- if (x) *x = video->geo.output_r.x;
- if (y) *y = video->geo.output_r.y;
-}
-
-Ecore_Drm_Output*
-e_devicemgr_video_drm_output_get(E_Video *video)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(video, NULL);
-
- return video->drm_output;
-}
-
-tdm_layer *
-e_devicemgr_video_layer_get(tdm_output *output)
-{
- E_Video *video;
- Eina_List *l;
-
- if (!output)
- return NULL;
-
- EINA_LIST_FOREACH(video_list, l, video)
- {
- if (video->output == output)
- return video->layer;
- }
-
- return NULL;
-}
-
+++ /dev/null
-#ifndef __E_DEVICEMGR_VIDEO_H__
-#define __E_DEVICEMGR_VIDEO_H__
-
-#define E_COMP_WL
-#include "e.h"
-#include "e_comp_wl.h"
-#include <wayland-server.h>
-#include <Ecore_Drm.h>
-#include "e_devicemgr_buffer.h"
-
-typedef struct _E_Video E_Video;
-
-int e_devicemgr_video_init(void);
-void e_devicemgr_video_fini(void);
-
-Eina_List* e_devicemgr_video_list_get(void);
-E_Devmgr_Buf* e_devicemgr_video_fb_get(E_Video *video);
-void e_devicemgr_video_pos_get(E_Video *video, int *x, int *y);
-Ecore_Drm_Output* e_devicemgr_video_drm_output_get(E_Video *video);
-tdm_layer* e_devicemgr_video_layer_get(tdm_output *output);
-
-#endif
+++ /dev/null
-#include "e_devicemgr_viewport.h"
-#include "e_devicemgr_buffer.h"
-
-#define PER(fmt,arg...) ERR("window(0x%08"PRIxPTR") ec(%p) epc(%p): "fmt, \
- viewport->window, viewport->ec, viewport->epc, ##arg)
-#define PWR(fmt,arg...) WRN("window(0x%08"PRIxPTR") ec(%p) epc(%p): "fmt, \
- viewport->window, viewport->ec, viewport->epc, ##arg)
-#define PIN(fmt,arg...) INF("window(0x%08"PRIxPTR") ec(%p) epc(%p): "fmt, \
- viewport->window, viewport->ec, viewport->epc, ##arg)
-#define PDB(fmt,arg...) DBG("window(0x%08"PRIxPTR") ec(%p) epc(%p): "fmt, \
- viewport->window, viewport->ec, viewport->epc, ##arg)
-
-#undef SWAP
-#define SWAP(a, b) ({double t; t = a; a = b; b = t;})
-
-typedef enum {
- DESTINATION_TYPE_NONE,
- DESTINATION_TYPE_RECT,
- DESTINATION_TYPE_RATIO,
- DESTINATION_TYPE_MODE,
-} E_Viewport_Destination_Type;
-
-typedef struct _E_Viewport {
- struct wl_resource *resource;
-
- E_Client *ec;
- E_Client *epc;
- Ecore_Window window;
-
- Ecore_Event_Handler *topmost_rotate_hdl;
-
- struct wl_listener surface_destroy_listener;
- struct wl_listener surface_apply_viewport_listener;
-
- Eina_Bool changed;
-
- unsigned int transform;
-
- Eina_Rectangle source;
- Eina_Rectangle cropped_source;
-
- E_Viewport_Destination_Type type;
- struct {
- Eina_Rectangle rect;
-
- struct {
- double x, y, w, h;
- } ratio;
-
- struct {
- struct wl_resource *resource;
-
- enum tizen_destination_mode_type type;
-
- double ratio_h;
- double ratio_v;
-
- double scale_h;
- double scale_v;
-
- int offset_x;
- int offset_y;
- int offset_w;
- int offset_h;
-
- double align_h;
- double align_v;
- } mode;
- } destination;
-
- Eina_Bool query_parent_size;
- Eina_Rectangle parent_size;
-
- Eina_Bool follow_parent_transform;
-
- E_Client_Hook *client_hook_del;
- E_Client_Hook *client_hook_move;
- E_Client_Hook *client_hook_resize;
-
- E_Comp_Wl_Hook *subsurf_hook_create;
-} E_Viewport;
-
-static E_Viewport* _e_devicemgr_viewport_get_viewport(struct wl_resource *resource);
-static void _e_devicemgr_viewport_cb_parent_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
-static void _e_devicemgr_viewport_parent_check(E_Viewport *viewport);
-
-static E_Client*
-_topmost_parent_get(E_Client *ec)
-{
- E_Client *parent = NULL;
-
- if (!ec->comp_data || !ec->comp_data->sub.data)
- return ec;
-
- parent = ec->comp_data->sub.data->parent;
- while (parent)
- {
- if (!parent->comp_data || !parent->comp_data->sub.data)
- return parent;
-
- parent = parent->comp_data->sub.data->parent;
- }
-
- return ec;
-}
-
-static void
-_destroy_viewport(E_Viewport *viewport)
-{
- E_Client *ec;
-
- if (!viewport) return;
-
- ec = viewport->ec;
-
- ecore_event_handler_del(viewport->topmost_rotate_hdl);
-
- if (viewport->epc && viewport->query_parent_size)
- {
- evas_object_event_callback_del_full(viewport->epc->frame, EVAS_CALLBACK_RESIZE,
- _e_devicemgr_viewport_cb_parent_resize, viewport);
- viewport->epc = NULL;
- }
-
- e_client_hook_del(viewport->client_hook_del);
- e_client_hook_del(viewport->client_hook_move);
- e_client_hook_del(viewport->client_hook_resize);
-
- e_comp_wl_hook_del(viewport->subsurf_hook_create);
-
- wl_list_remove(&viewport->surface_destroy_listener.link);
- wl_list_remove(&viewport->surface_apply_viewport_listener.link);
-
- wl_resource_set_user_data(viewport->resource, NULL);
-
- if (viewport->destination.mode.resource)
- wl_resource_set_user_data(viewport->destination.mode.resource, NULL);
-
- if (ec->comp_data && ec->comp_data->scaler.viewport)
- {
- ec->comp_data->scaler.viewport = NULL;
- ec->comp_data->scaler.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
- ec->comp_data->scaler.buffer_viewport.surface.width = -1;
- ec->comp_data->scaler.buffer_viewport.changed = 1;
- ec->comp_data->pending.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
- ec->comp_data->pending.buffer_viewport.surface.width = -1;
- ec->comp_data->pending.buffer_viewport.changed = 1;
- }
-
- PIN("tizen_viewport@%d destroy. viewport(%p)", wl_resource_get_id(viewport->resource), viewport);
-
- free(viewport);
-}
-
-static void
-_subsurface_cb_create(void *data, E_Client *ec)
-{
- E_Viewport *viewport = data;
-
- if (EINA_UNLIKELY(!ec)) return;
- if (viewport->ec != ec) return;
-
- _e_devicemgr_viewport_parent_check(viewport);
-}
-
-static void
-_client_cb_del(void *data, E_Client *ec)
-{
- E_Viewport *viewport = data;
-
- if (viewport->epc != ec) return;
-
- evas_object_event_callback_del(viewport->epc->frame, EVAS_CALLBACK_RESIZE,
- _e_devicemgr_viewport_cb_parent_resize);
- PIN("epc del");
- viewport->epc = NULL;
-}
-
-static void
-_client_cb_move(void *data, E_Client *ec)
-{
- E_Viewport *viewport = data;
- E_Client *topmost = _topmost_parent_get(ec);
-
- if (ec != topmost && ec != viewport->epc) return;
-
- PDB("move start: topmost(%p)", topmost);
- e_devicemgr_viewport_apply(topmost);
- PDB("move end");
-}
-
-static void
-_client_cb_resize(void *data, E_Client *ec)
-{
- E_Viewport *viewport = data;
- E_Client *topmost = _topmost_parent_get(ec);
-
- if (ec != topmost && ec != viewport->epc) return;
-
- PDB("resize start: topmost(%p)", topmost);
- e_devicemgr_viewport_apply(topmost);
- PDB("resize end");
-}
-
-static void
-_e_devicemgr_viewport_parent_check(E_Viewport *viewport)
-{
- E_Client *ec = viewport->ec;
- E_Client *new_parent;
-
- if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return;
-
- new_parent = (ec->comp_data->sub.data) ? ec->comp_data->sub.data->parent : NULL;
-
- if (viewport->epc == new_parent) return;
-
- if (viewport->epc)
- evas_object_event_callback_del(viewport->epc->frame, EVAS_CALLBACK_RESIZE,
- _e_devicemgr_viewport_cb_parent_resize);
-
- viewport->epc = new_parent;
-
- PIN("epc(%p)", viewport->epc);
-
- if (!viewport->epc) return;
-
- if (viewport->query_parent_size)
- evas_object_event_callback_add(viewport->epc->frame, EVAS_CALLBACK_RESIZE,
- _e_devicemgr_viewport_cb_parent_resize, viewport);
-}
-
-static void
-_e_devicemgr_viewport_set_changed(E_Viewport *viewport)
-{
- E_Client *ec;
- E_Client *subc;
- Eina_List *l;
- E_Viewport *sub_viewport;
-
- if (!viewport) return;
-
- viewport->changed = EINA_TRUE;
-
- ec = viewport->ec;
- EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
- {
- if (!subc || !subc->comp_data || e_object_is_del(E_OBJECT(subc)))
- continue;
-
- sub_viewport = _e_devicemgr_viewport_get_viewport(subc->comp_data->scaler.viewport);
- _e_devicemgr_viewport_set_changed(sub_viewport);
- }
-
- EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
- {
- if (!subc || !subc->comp_data || e_object_is_del(E_OBJECT(subc)))
- continue;
-
- sub_viewport = _e_devicemgr_viewport_get_viewport(subc->comp_data->scaler.viewport);
- _e_devicemgr_viewport_set_changed(sub_viewport);
- }
-}
-
-static void
-_e_devicemgr_destination_mode_destroy(struct wl_resource *resource)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
-
- if (!viewport) return;
-
- if (viewport->type == DESTINATION_TYPE_MODE)
- viewport->type = DESTINATION_TYPE_NONE;
-
- _e_devicemgr_viewport_set_changed(viewport);
-
- PIN("destination.mode destroy");
-}
-
-static void
-_e_devicemgr_destination_mode_cb_destroy(struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-_e_devicemgr_destination_mode_cb_follow_parent_transform(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
-
- if (!viewport) return;
-
- if (viewport->follow_parent_transform)
- return;
-
- PIN("follow_parent_transform");
-
- viewport->follow_parent_transform = EINA_TRUE;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_destination_mode_cb_unfollow_parent_transform(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
-
- if (!viewport) return;
-
- if (!viewport->follow_parent_transform)
- return;
-
- PIN("unfollow_parent_transform");
-
- viewport->follow_parent_transform = EINA_FALSE;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_destination_mode_cb_set(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t type)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
-
- if (!viewport) return;
-
- if (type > TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER)
- {
- PER("invalid param: type(%d)", type);
- return;
- }
-
- if (type != TIZEN_DESTINATION_MODE_TYPE_NONE)
- viewport->type = DESTINATION_TYPE_MODE;
-
- if (viewport->destination.mode.type == type)
- return;
-
- PIN("type(%d)", type);
-
- viewport->destination.mode.type = type;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_destination_mode_cb_set_ratio(struct wl_client *client,
- struct wl_resource *resource,
- wl_fixed_t horizontal,
- wl_fixed_t vertical)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
- double ratio_h, ratio_v;
-
- if (!viewport) return;
-
- ratio_h = wl_fixed_to_double(horizontal);
- ratio_v = wl_fixed_to_double(vertical);
-
- if (ratio_h == -1.0)
- {
- PDB("reset destinatino ratio");
- viewport->destination.mode.ratio_h = ratio_h;
- _e_devicemgr_viewport_set_changed(viewport);
- return;
- }
-
- if (ratio_h <= 0 || ratio_v <= 0)
- {
- PER("invalid param: ratio_h(%.2f) ratio_v(%.2f)", ratio_h, ratio_v);
- return;
- }
-
- if (viewport->destination.mode.ratio_h == ratio_h &&
- viewport->destination.mode.ratio_v == ratio_v)
- return;
-
- PIN("ratio_h(%.2f) ratio_v(%.2f)", ratio_h, ratio_v);
-
- viewport->destination.mode.ratio_h = ratio_h;
- viewport->destination.mode.ratio_v = ratio_v;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_destination_mode_cb_set_scale(struct wl_client *client,
- struct wl_resource *resource,
- wl_fixed_t horizontal,
- wl_fixed_t vertical)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
- double scale_h, scale_v;
-
- if (!viewport) return;
-
- scale_h = wl_fixed_to_double(horizontal);
- scale_v = wl_fixed_to_double(vertical);
-
- if (scale_h == -1.0)
- {
- PDB("reset destinatino scale");
- viewport->destination.mode.scale_h = scale_h;
- _e_devicemgr_viewport_set_changed(viewport);
- return;
- }
-
- if (scale_h <= 0 || scale_v <= 0)
- {
- PER("invalid param: scale_h(%.2f) scale_v(%.2f)", scale_h, scale_v);
- return;
- }
-
- if (viewport->destination.mode.scale_h == scale_h &&
- viewport->destination.mode.scale_v == scale_v)
- return;
-
- PIN("scale_h(%.2f) scale_v(%.2f)", scale_h, scale_v);
-
- viewport->destination.mode.scale_h = scale_h;
- viewport->destination.mode.scale_v = scale_v;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_destination_mode_cb_set_align(struct wl_client *client,
- struct wl_resource *resource,
- wl_fixed_t horizontal,
- wl_fixed_t vertical)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
- double align_h, align_v;
-
- if (!viewport) return;
-
- align_h = wl_fixed_to_double(horizontal);
- align_v = wl_fixed_to_double(vertical);
-
- if (align_h == -1.0)
- {
- PDB("reset destinatino align");
- viewport->destination.mode.align_h = align_h;
- _e_devicemgr_viewport_set_changed(viewport);
- return;
- }
-
- if (align_h < 0.0)
- align_h = 0.0;
- else if (align_h > 1.0)
- align_h = 1.0;
-
- if (align_v < 0.0)
- align_v = 0.0;
- else if (align_v > 1.0)
- align_v = 1.0;
-
- if (viewport->destination.mode.align_h == align_h &&
- viewport->destination.mode.align_v == align_v)
- return;
-
- PIN("align_h(%.2f) align_v(%.2f)", align_h, align_v);
-
- viewport->destination.mode.align_h = align_h;
- viewport->destination.mode.align_v = align_v;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_destination_mode_cb_set_offset(struct wl_client *client,
- struct wl_resource *resource,
- int32_t x,
- int32_t y,
- int32_t w,
- int32_t h)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
-
- if (!viewport) return;
-
- if (viewport->destination.mode.offset_x == x &&
- viewport->destination.mode.offset_y == y &&
- viewport->destination.mode.offset_w == w &&
- viewport->destination.mode.offset_h == h)
- return;
-
- PIN("offset_x(%d) offset_y(%d) offset_w(%d) offset_h(%d)", x, y, w, h);
-
- viewport->destination.mode.offset_x = x;
- viewport->destination.mode.offset_y = y;
- viewport->destination.mode.offset_w = w;
- viewport->destination.mode.offset_h = h;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static const struct tizen_destination_mode_interface _e_devicemgr_destination_mode_interface =
-{
- _e_devicemgr_destination_mode_cb_destroy,
- _e_devicemgr_destination_mode_cb_follow_parent_transform,
- _e_devicemgr_destination_mode_cb_unfollow_parent_transform,
- _e_devicemgr_destination_mode_cb_set,
- _e_devicemgr_destination_mode_cb_set_ratio,
- _e_devicemgr_destination_mode_cb_set_scale,
- _e_devicemgr_destination_mode_cb_set_align,
- _e_devicemgr_destination_mode_cb_set_offset,
-};
-
-static void
-_e_devicemgr_viewport_cb_parent_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
-{
- E_Viewport *viewport = data;
- Evas_Coord old_w, old_h;
-
- if (e_object_is_del(E_OBJECT(viewport->epc))) return;
-
- old_w = viewport->parent_size.w;
- old_h = viewport->parent_size.h;
-
- evas_object_geometry_get(viewport->epc->frame,
- &viewport->parent_size.x, &viewport->parent_size.y,
- &viewport->parent_size.w, &viewport->parent_size.h);
-
- if (old_w != viewport->parent_size.w || old_h != viewport->parent_size.h)
- tizen_viewport_send_parent_size(viewport->resource,
- viewport->parent_size.w,
- viewport->parent_size.h);
-}
-
-static void
-_e_devicemgr_viewport_destroy(struct wl_resource *resource)
-{
- E_Viewport *viewport = _e_devicemgr_viewport_get_viewport(resource);
-
- if (!viewport) return;
-
- _destroy_viewport(viewport);
-}
-
-static void
-_e_devicemgr_viewport_cb_destroy(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-_e_devicemgr_viewport_cb_set_transform(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource,
- uint32_t transform)
-{
- E_Viewport *viewport = _e_devicemgr_viewport_get_viewport(resource);
-
- if (!viewport) return;
-
- if (transform > WL_OUTPUT_TRANSFORM_FLIPPED_270)
- {
- PER("invalid param: transform(%d)", transform);
- return;
- }
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (viewport->transform == transform)
- return;
-
- PIN("transform(%d)", transform);
-
- viewport->transform = transform;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_viewport_cb_set_source(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource,
- uint32_t x,
- uint32_t y,
- uint32_t width,
- uint32_t height)
-{
- E_Viewport *viewport = _e_devicemgr_viewport_get_viewport(resource);
-
- if (!viewport) return;
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (viewport->source.x == x && viewport->source.y == y &&
- viewport->source.w == width && viewport->source.h == height)
- return;
-
- viewport->source.x = x;
- viewport->source.y = y;
- viewport->source.w = width;
- viewport->source.h = height;
- viewport->cropped_source = viewport->source;
- _e_devicemgr_viewport_set_changed(viewport);
-
- PIN("source(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(&viewport->source));
-}
-
-static void
-_e_devicemgr_viewport_cb_set_destination(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource,
- int32_t x,
- int32_t y,
- uint32_t width,
- uint32_t height)
-{
- E_Viewport *viewport = _e_devicemgr_viewport_get_viewport(resource);
-
- if (!viewport) return;
-
- if (width == 0 || height == 0)
- {
- PER("invalid param: destination.rect(%d,%d %dx%d)", x, y, width, height);
- return;
- }
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- viewport->type = DESTINATION_TYPE_RECT;
-
- if (viewport->destination.rect.x == x && viewport->destination.rect.y == y &&
- viewport->destination.rect.w == width && viewport->destination.rect.h == height)
- return;
-
- PIN("destination.rect(%d,%d %dx%d)", x, y, width, height);
-
- viewport->destination.rect.x = x;
- viewport->destination.rect.y = y;
- viewport->destination.rect.w = width;
- viewport->destination.rect.h = height;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_viewport_cb_set_destination_ratio(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource,
- wl_fixed_t x,
- wl_fixed_t y,
- wl_fixed_t width,
- wl_fixed_t height)
-{
- E_Viewport *viewport = _e_devicemgr_viewport_get_viewport(resource);
- double ratio_x, ratio_y, ratio_w, ratio_h;
-
- if (!viewport) return;
-
- if (viewport->type == DESTINATION_TYPE_MODE)
- {
- PER("couldn't set viewport destination ratio. tizen_viewport@%d has the mode",
- wl_resource_get_id(resource));
- return;
- }
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- ratio_x = (viewport->epc) ? wl_fixed_to_double(x) : 0;
- ratio_y = (viewport->epc) ? wl_fixed_to_double(y) : 0;
- ratio_w = wl_fixed_to_double(width);
- ratio_h = wl_fixed_to_double(height);
-
- if (ratio_x < 0 || ratio_x >= 1 || ratio_y < 0 || ratio_y >= 1 || ratio_w <= 0 || ratio_h <= 0)
- {
- PER("invalid param: destination.ratio(%.2f,%.2f %.2fx%.2f)", ratio_x, ratio_y, ratio_w, ratio_h);
- return;
- }
-
- viewport->type = DESTINATION_TYPE_RATIO;
-
- if (viewport->destination.ratio.x == ratio_x && viewport->destination.ratio.y == ratio_y &&
- viewport->destination.ratio.w == ratio_w && viewport->destination.ratio.h == ratio_h)
- return;
-
- PIN("destination.ratio(%.2f,%.2f %.2fx%.2f)", ratio_x, ratio_y, ratio_w, ratio_h);
-
- viewport->destination.ratio.x = ratio_x;
- viewport->destination.ratio.y = ratio_y;
- viewport->destination.ratio.w = ratio_w;
- viewport->destination.ratio.h = ratio_h;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-static void
-_e_devicemgr_viewport_cb_get_destination_mode(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t id)
-{
- int version = wl_resource_get_version(resource);
- E_Viewport *viewport = _e_devicemgr_viewport_get_viewport(resource);
- struct wl_resource *res;
-
- if (!viewport)
- {
- wl_resource_post_error(resource,
- WL_DISPLAY_ERROR_INVALID_OBJECT,
- "tizen_viewport@%d is invalid",
- wl_resource_get_id(resource));
- return;
- }
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (!(res = wl_resource_create(client, &tizen_destination_mode_interface, version, id)))
- {
- PER("Failed to create destination_mode resource");
- wl_resource_post_no_memory(resource);
- return;
- }
-
- memset(&viewport->destination.mode, 0, sizeof viewport->destination.mode);
-
- PIN("destination.mode created");
-
- viewport->destination.mode.resource = res;
- viewport->destination.mode.type = TIZEN_DESTINATION_MODE_TYPE_NONE;
- viewport->destination.mode.ratio_h = -1.0;
- viewport->destination.mode.scale_h = -1.0;
- viewport->destination.mode.align_h = -1.0;
-
- /* set resource implementation */
- wl_resource_set_implementation(res, &_e_devicemgr_destination_mode_interface,
- viewport, _e_devicemgr_destination_mode_destroy);
-
-}
-
-static void
-_e_devicemgr_viewport_cb_query_parent_size(struct wl_client *client,
- struct wl_resource *resource)
-{
- E_Viewport *viewport = _e_devicemgr_viewport_get_viewport(resource);
- Evas_Coord w = 0, h = 0;
-
- if (!viewport) return;
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (viewport->epc)
- {
- evas_object_geometry_get(viewport->epc->frame,
- &viewport->parent_size.x, &viewport->parent_size.y,
- &viewport->parent_size.w, &viewport->parent_size.h);
- w = viewport->parent_size.w;
- h = viewport->parent_size.h;
-
- if (!viewport->query_parent_size)
- {
- viewport->query_parent_size = EINA_TRUE;
- evas_object_event_callback_add(viewport->epc->frame, EVAS_CALLBACK_RESIZE,
- _e_devicemgr_viewport_cb_parent_resize, viewport);
- }
- }
- else
- {
- E_Zone *zone = e_comp_zone_xy_get(viewport->ec->x, viewport->ec->y);
- if (zone)
- {
- w = zone->w;
- h = zone->h;
- }
- else
- PWR("out of zone");
- }
-
- tizen_viewport_send_parent_size(resource, w, h);
-}
-
-static void
-_e_devicemgr_viewport_cb_follow_parent_transform(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
-
- if (!viewport) return;
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (viewport->follow_parent_transform)
- return;
-
- PIN("follow_parent_transform");
-
- viewport->follow_parent_transform = EINA_TRUE;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static void
-_e_devicemgr_viewport_cb_unfollow_parent_transform(struct wl_client *client EINA_UNUSED,
- struct wl_resource *resource)
-{
- E_Viewport *viewport = wl_resource_get_user_data(resource);
-
- if (!viewport) return;
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (!viewport->follow_parent_transform)
- return;
-
- PIN("unfollow_parent_transform");
-
- viewport->follow_parent_transform = EINA_FALSE;
- _e_devicemgr_viewport_set_changed(viewport);
-}
-
-static const struct tizen_viewport_interface _e_devicemgr_viewport_interface =
-{
- _e_devicemgr_viewport_cb_destroy,
- _e_devicemgr_viewport_cb_set_transform,
- _e_devicemgr_viewport_cb_set_source,
- _e_devicemgr_viewport_cb_set_destination,
- _e_devicemgr_viewport_cb_set_destination_ratio,
- _e_devicemgr_viewport_cb_get_destination_mode,
- _e_devicemgr_viewport_cb_query_parent_size,
- _e_devicemgr_viewport_cb_follow_parent_transform,
- _e_devicemgr_viewport_cb_unfollow_parent_transform,
-};
-
-static void
-_source_transform_coord(int width, int height, int trans, int scale, float ox, float oy, float *tx, float *ty)
-{
- switch (trans)
- {
- case WL_OUTPUT_TRANSFORM_NORMAL:
- default:
- *tx = ox, *ty = oy;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- *tx = width - ox, *ty = oy;
- break;
- case WL_OUTPUT_TRANSFORM_90:
- *tx = oy, *ty = width - ox;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- *tx = height - oy, *ty = width - ox;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- *tx = width - ox, *ty = height - oy;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- *tx = ox, *ty = height - oy;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- *tx = height - oy, *ty = ox;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- *tx = oy, *ty = ox;
- break;
- }
-
- *tx /= scale;
- *ty /= scale;
-}
-
-static void
-_source_transform_to_surface(int width, int height, int trans, int scale,
- Eina_Rectangle *orig, Eina_Rectangle *tran)
-{
- float x1, x2, y1, y2;
-
- _source_transform_coord(width, height, trans, scale, orig->x, orig->y, &x1, &y1);
- _source_transform_coord(width, height, trans, scale, orig->x + orig->w, orig->y + orig->h, &x2, &y2);
-
- tran->x = (x1 <= x2) ? x1 : x2;
- tran->w = (x1 <= x2) ? x2 - x1 : x1 - x2;
- tran->y = (y1 <= y2) ? y1 : y2;
- tran->h = (y1 <= y2) ? y2 - y1 : y1 - y2;
-}
-
-static void
-_destination_mode_calculate_letter_box(int pw, int ph, int sw, int sh,
- double rh, double rv,
- Eina_Rectangle *rect)
-{
- int fit_width;
- int fit_height;
- double fw, fh, ssw, ssh, max;
-
- ssw = sw;
- if (rh != -1.0)
- ssh = (double)sw * rv / rh;
- else
- ssh = sh;
-
- fw = ssw / pw;
- fh = ssh / ph;
- max = MAX(fw, fh);
-
- fit_width = ssw / max;
- fit_height = ssh / max;
-
- rect->x = (pw - fit_width) / 2;
- rect->y = (ph - fit_height) / 2;
- rect->w = fit_width;
- rect->h = fit_height;
-}
-
-static void
-_destination_mode_calculate_origin(int pw, int ph, int sw, int sh,
- double rh, double rv,
- Eina_Rectangle *rect)
-{
- rect->x = (pw - sw) / 2;
- rect->y = (ph - sh) / 2;
- rect->w = sw;
- rect->h = sh;
-}
-
-static void
-_destination_mode_calculate_full(int pw, int ph, int sw, int sh,
- double rh, double rv,
- Eina_Rectangle *rect)
-{
- rect->x = rect->y = 0;
- rect->w = pw;
- rect->h = ph;
-}
-
-static void
-_destination_mode_calculate_cropped_full(int pw, int ph, int sw, int sh,
- double rh, double rv,
- Eina_Rectangle *rect)
-{
- int fit_width;
- int fit_height;
- double fw, fh, ssw, ssh, min;
-
- ssw = sw;
- if (rh != -1.0)
- ssh = (double)sw * rv / rh;
- else
- ssh = sh;
-
- fw = ssw / pw;
- fh = ssh / ph;
- min = MIN(fw, fh);
-
- fit_width = ssw / min;
- fit_height = ssh / min;
-
- rect->x = (pw - fit_width) / 2;
- rect->y = (ph - fit_height) / 2;
- rect->w = fit_width;
- rect->h = fit_height;
-}
-
-static void
-_destination_mode_calculate_origin_or_letter(int pw, int ph, int sw, int sh,
- double rh, double rv,
- Eina_Rectangle *rect)
-{
- if (sw < pw && sh < ph)
- _destination_mode_calculate_origin(pw, ph, sw, sh, rh, rv, rect);
- else
- _destination_mode_calculate_letter_box(pw, ph, sw, sh, rh, rv, rect);
-}
-
-/* we have to consider the output transform. if epc is toplevel, and if
- * output transform is 3, and if vpp->buffer.transform is 3, then actual
- * epc's transform is 0.
- */
-static int
-_get_parent_transform(E_Viewport *viewport)
-{
- E_Client *epc = viewport->epc;
- E_Client *topmost;
- unsigned int ptran, pflip;
- int ptransform;
-
- if (!epc->comp_data || e_object_is_del(E_OBJECT(epc)))
- return 0;
-
- ptransform = e_comp_wl_output_buffer_transform_get(epc);
-
- topmost = _topmost_parent_get(epc);
-
- if (ptransform != 0 && epc == topmost)
- {
- E_Comp_Wl_Output *output = e_comp_wl_output_find(topmost);
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output, 0);
-
- ptran = ptransform & 0x3;
- pflip = ptransform & 0x4;
- ptransform = pflip + (4 + ptran - output->transform) % 4;
- }
-
- return ptransform;
-}
-
-static Eina_Bool
-_destination_mode_calculate_destination(E_Viewport *viewport, Eina_Rectangle *prect, Eina_Rectangle *rect)
-{
- E_Client *ec = viewport->ec;
- int sw = 0, sh = 0, transform;
- double rh = -1.0, rv = -1.0;
-
- if (viewport->source.w != -1)
- {
- sw = viewport->source.w;
- sh = viewport->source.h;
- }
- else
- e_devmgr_buffer_size_get(ec, &sw, &sh);
-
- transform = e_comp_wl_output_buffer_transform_get(ec);
-
- if (transform % 2)
- SWAP(sw, sh);
-
- PDB("parent(%dx%d) src(%dx%d)", prect->w, prect->h, sw, sh);
-
- /* ratio -> type -> scale -> offset -> align */
- if (viewport->destination.mode.ratio_h != -1.0)
- {
- if (transform % 2)
- {
- rh = viewport->destination.mode.ratio_v;
- rv = viewport->destination.mode.ratio_h;
- }
- else
- {
- rh = viewport->destination.mode.ratio_h;
- rv = viewport->destination.mode.ratio_v;
- }
- }
-
- PDB("%dx%d %dx%d %.2fx%.2f (%d,%d %dx%d)", prect->w, prect->h, sw, sh, rh, rv, EINA_RECTANGLE_ARGS(rect));
-
- switch(viewport->destination.mode.type)
- {
- case TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX:
- _destination_mode_calculate_letter_box(prect->w, prect->h, sw, sh, rh, rv, rect);
- break;
- case TIZEN_DESTINATION_MODE_TYPE_ORIGIN:
- _destination_mode_calculate_origin(prect->w, prect->h, sw, sh, rh, rv, rect);
- break;
- case TIZEN_DESTINATION_MODE_TYPE_FULL:
- _destination_mode_calculate_full(prect->w, prect->h, sw, sh, rh, rv, rect);
- break;
- case TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL:
- _destination_mode_calculate_cropped_full(prect->w, prect->h, sw, sh, rh, rv, rect);
- break;
- case TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER:
- _destination_mode_calculate_origin_or_letter(prect->w, prect->h, sw, sh, rh, rv, rect);
- break;
- case TIZEN_DESTINATION_MODE_TYPE_NONE:
- default:
- PER("no destination mode for tizen_viewport@%d", wl_resource_get_id(viewport->resource));
- return EINA_FALSE;
- }
-
- PDB("(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(rect));
-
- if (viewport->destination.mode.scale_h != -1.0)
- {
- int new_x, new_y, new_w, new_h;
- double h = viewport->destination.mode.scale_h;
- double v = viewport->destination.mode.scale_v;
-
- if (transform % 2)
- SWAP(h, v);
-
- new_w = rect->w * h;
- new_h = rect->h * v;
- new_x = rect->x + (rect->w - new_w) / 2;
- new_y = rect->y + (rect->h - new_h) / 2;
- rect->x = new_x;
- rect->y = new_y;
- rect->w = new_w;
- rect->h = new_h;
- }
-
- PDB("(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(rect));
-
- if (viewport->destination.mode.align_h != -1.0)
- {
- E_Client *epc = viewport->epc;
- double h = viewport->destination.mode.align_h;
- double v = viewport->destination.mode.align_v;
- int dx, dy;
-
- if (epc)
- {
- int ptransform;
-
- if (!epc->comp_data || e_object_is_del(E_OBJECT(epc)))
- return EINA_FALSE;
-
- ptransform = e_comp_wl_output_buffer_transform_get(epc);
-
- PDB("parent's transform(%d)", ptransform);
-
- switch (ptransform)
- {
- default:
- case WL_OUTPUT_TRANSFORM_NORMAL:
- break;
- case WL_OUTPUT_TRANSFORM_90:
- SWAP(h, v);
- v = 1.0 - v;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- h = 1.0 - h;
- v = 1.0 - v;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- SWAP(h, v);
- h = 1.0 - h;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- h = 1.0 - h;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- SWAP(h, v);
- h = 1.0 - h;
- v = 1.0 - v;
- break;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- v = 1.0 - v;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- SWAP(h, v);
- break;
- }
- }
-
- dx = (prect->w - rect->w) * (h - 0.5);
- dy = (prect->h - rect->h) * (v - 0.5);
-
- rect->x += dx;
- rect->y += dy;
- }
-
- PDB("(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(rect));
-
- if (viewport->destination.mode.offset_x != 0 ||
- viewport->destination.mode.offset_y != 0 ||
- viewport->destination.mode.offset_w != 0 ||
- viewport->destination.mode.offset_h != 0)
- {
- int x = viewport->destination.mode.offset_x;
- int y = viewport->destination.mode.offset_y;
- int w = viewport->destination.mode.offset_w;
- int h = viewport->destination.mode.offset_h;
-
- if (transform % 2)
- {
- SWAP(x, y);
- SWAP(w, h);
- }
-
- rect->x += x;
- rect->y += y;
- rect->w += w;
- rect->h += h;
- }
-
- PDB("mode destination(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(rect));
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_devicemgr_viewport_calculate_destination(E_Viewport *viewport, Eina_Rectangle *prect, Eina_Rectangle *rect)
-{
- switch (viewport->type)
- {
- case DESTINATION_TYPE_RECT:
- rect->x = viewport->destination.rect.x;
- rect->y = viewport->destination.rect.y;
- rect->w = viewport->destination.rect.w;
- rect->h = viewport->destination.rect.h;
- break;
- case DESTINATION_TYPE_RATIO:
- rect->x = viewport->destination.ratio.x * prect->w;
- rect->y = viewport->destination.ratio.y * prect->h;
- rect->w = viewport->destination.ratio.w * prect->w;
- rect->h = viewport->destination.ratio.h * prect->h;
- break;
- case DESTINATION_TYPE_MODE:
- case DESTINATION_TYPE_NONE:
- default:
- PER("wrong destination type: %d", viewport->type);
- return EINA_FALSE;
- }
-
- if (viewport->epc)
- {
- int ptransform = _get_parent_transform(viewport);
-
- if (ptransform > 0)
- {
- if (ptransform % 2)
- _source_transform_to_surface(prect->h, prect->w, ptransform, 1, rect, rect);
- else
- _source_transform_to_surface(prect->w, prect->h, ptransform, 1, rect, rect);
- }
- }
-
- PDB("destination(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(rect));
-
- return EINA_TRUE;
-}
-
-static void
-_e_devicemgr_viewport_crop_by_parent(E_Viewport *viewport, Eina_Rectangle *parent, Eina_Rectangle *dst)
-{
- E_Comp_Wl_Buffer_Viewport *vp = &viewport->ec->comp_data->scaler.buffer_viewport;
- Eina_Rectangle crop;
- double rx, ry, rw, rh;
- int bw, bh;
-
- PDB("dst(%d,%d %dx%d) parent(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(dst), EINA_RECTANGLE_ARGS(parent));
-
- crop = *dst;
-
- if (!eina_rectangle_intersection(&crop, parent))
- {
- *dst = crop;
- PDB("dst(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(dst));
- return;
- }
-
- if (crop.w == dst->w && crop.h == dst->h)
- {
- if (viewport->source.w == -1)
- {
- e_devmgr_buffer_size_get(viewport->ec, &bw, &bh);
-
- viewport->cropped_source.x = viewport->cropped_source.y = 0;
- viewport->cropped_source.w = bw;
- viewport->cropped_source.h = bh;
- }
- else
- viewport->cropped_source = viewport->source;
-
- PDB("src(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(&viewport->cropped_source));
-
- return;
- }
-
- PDB("dst(%d,%d %dx%d)", EINA_RECTANGLE_ARGS(dst));
-
- crop.x -= dst->x;
- crop.y -= dst->y;
-
- rx = (double)crop.x / dst->w;
- ry = (double)crop.y / dst->h;
- rw = (double)crop.w / dst->w;
- rh = (double)crop.h / dst->h;
-
- crop.x += dst->x;
- crop.y += dst->y;
- *dst = crop;
-
- PDB(" => (%d,%d %dx%d)", EINA_RECTANGLE_ARGS(dst));
-
- e_devmgr_buffer_size_get(viewport->ec, &bw, &bh);
-
- if (viewport->source.w == -1)
- {
- viewport->cropped_source.x = viewport->cropped_source.y = 0;
- viewport->cropped_source.w = bw;
- viewport->cropped_source.h = bh;
- }
- else
- viewport->cropped_source = viewport->source;
-
- PDB("src(%d,%d %dx%d) ratio(%.2f,%.2f,%.2f,%.2f)",
- EINA_RECTANGLE_ARGS(&viewport->cropped_source), rx, ry, rw, rh);
-
- viewport->cropped_source.x += viewport->cropped_source.w * rx;
- viewport->cropped_source.y += viewport->cropped_source.h * ry;
- viewport->cropped_source.w = viewport->cropped_source.w * rw;
- viewport->cropped_source.h = viewport->cropped_source.h * rh;
-
- _source_transform_to_surface(bw, bh,
- e_comp_wl_output_buffer_transform_get(viewport->ec), 1,
- &viewport->cropped_source, &viewport->cropped_source);
-
- vp->buffer.src_x = wl_fixed_from_int(viewport->cropped_source.x);
- vp->buffer.src_y = wl_fixed_from_int(viewport->cropped_source.y);
- vp->buffer.src_width = wl_fixed_from_int(viewport->cropped_source.w);
- vp->buffer.src_height = wl_fixed_from_int(viewport->cropped_source.h);
-
- PDB(" => (%d,%d %dx%d)", EINA_RECTANGLE_ARGS(&viewport->cropped_source));
-}
-
-static Eina_Bool
-_e_devicemgr_viewport_apply_transform(E_Viewport *viewport, int *rtransform)
-{
- E_Client *ec = viewport->ec;
- E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
- Eina_Bool changed = EINA_FALSE;
- unsigned int new_transform;
-
- new_transform = viewport->transform;
-
- if (viewport->follow_parent_transform && viewport->epc)
- {
- E_Client *epc = viewport->epc;
- unsigned int pwtran, ptran, pflip, ctran, cflip;
- int ptransform;
-
- if (!epc->comp_data || e_object_is_del(E_OBJECT(epc)))
- {
- *rtransform = vp->buffer.transform;
- return EINA_FALSE;
- }
-
- ptransform = _get_parent_transform(viewport);
- PDB("parent's transform(%d) rot.ang.curr(%d)", ptransform, epc->e.state.rot.ang.curr/90);
-
- pwtran = ((epc->e.state.rot.ang.curr + 360) % 360) / 90;
-
- ptran = ((pwtran & 0x3) + (ptransform & 0x3)) & 0x3;
- pflip = (ptransform & 0x4);
-
- ctran = (viewport->transform & 0x3);
- cflip = (viewport->transform & 0x4);
-
- new_transform = ((ptran + ctran) & 0x3) + ((pflip + cflip) & 0x4);
- }
-
- if (new_transform != vp->buffer.transform)
- {
- vp->buffer.transform = new_transform;
- vp->changed = changed = EINA_TRUE;
-
- ec->comp_data->pending.buffer_viewport = *vp;
- if (ec->comp_data->sub.data)
- ec->comp_data->sub.data->cached.buffer_viewport = *vp;
- }
-
- if (changed)
- PIN("apply transform: %d type(%d) follow(%d) changed(%d)",
- vp->buffer.transform, viewport->type,
- viewport->follow_parent_transform, changed);
-
- *rtransform = vp->buffer.transform;
-
- return changed;
-}
-
-static Eina_Bool
-_e_devicemgr_viewport_apply_destination(E_Viewport *viewport, Eina_Rectangle *rrect)
-{
- E_Client *ec = viewport->ec;
- E_Comp_Wl_Buffer_Viewport *vp;
- Eina_Rectangle dst = {0,}, prect;
- Eina_Bool changed = EINA_FALSE;
-
- vp = &ec->comp_data->scaler.buffer_viewport;
- if (!viewport->epc)
- {
- E_Zone *zone = e_comp_zone_xy_get(ec->x, ec->y);
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL(zone != NULL, EINA_FALSE);
-
- prect.x = prect.y = 0;
- prect.w = zone->w;
- prect.h = zone->h;
- }
- else
- {
- E_Client *epc = viewport->epc;
- E_Comp_Wl_Buffer_Viewport *vpp;
-
- if (!epc->comp_data || e_object_is_del(E_OBJECT(epc)))
- return EINA_FALSE;
-
- vpp = &epc->comp_data->scaler.buffer_viewport;
- prect.x = prect.y = 0;
- if (vpp->surface.width != -1)
- {
- prect.w = vpp->surface.width;
- prect.h = vpp->surface.height;
- }
- else
- e_devmgr_buffer_transform_scale_size_get(epc, &prect.w, &prect.h);
- }
-
- if (!(prect.w > 0 && prect.h > 0))
- {
- PWR("prect.w > 0 && prect.h > 0 is false");
- return EINA_FALSE;
- }
-
- switch (viewport->type)
- {
- case DESTINATION_TYPE_RECT:
- case DESTINATION_TYPE_RATIO:
- if (!_e_devicemgr_viewport_calculate_destination(viewport, &prect, &dst))
- return EINA_FALSE;
- break;
- case DESTINATION_TYPE_MODE:
- if (!_destination_mode_calculate_destination(viewport, &prect, &dst))
- return EINA_FALSE;
- break;
- case DESTINATION_TYPE_NONE:
- default:
- PER("no destination for tizen_viewport@%d", wl_resource_get_id(viewport->resource));
- return EINA_FALSE;
- }
-
- _e_devicemgr_viewport_crop_by_parent(viewport, &prect, &dst);
-
- /* The values of below x, y, w, h are specified in the transform 0 and in the parent */
- if (ec->comp_data->sub.data)
- {
- if (ec->comp_data->sub.data->position.x != dst.x ||
- ec->comp_data->sub.data->position.y != dst.y)
- {
- ec->comp_data->sub.data->position.x = dst.x;
- ec->comp_data->sub.data->position.y = dst.y;
- ec->comp_data->sub.data->position.set = EINA_TRUE;
- vp->changed = changed = EINA_TRUE;
- }
- }
- else
- {
- /* if toplevel surface, the x,y pos is decided by shell surface */
- dst.x = ec->x;
- dst.y = ec->y;
- }
-
- if (vp->surface.width != dst.w || vp->surface.height != dst.h)
- {
- vp->surface.width = dst.w;
- vp->surface.height = dst.h;
- vp->changed = changed = EINA_TRUE;
-
- ec->comp_data->pending.buffer_viewport = *vp;
- if (ec->comp_data->sub.data)
- ec->comp_data->sub.data->cached.buffer_viewport = *vp;
- }
-
- *rrect = dst;
-
- if (changed)
- PIN("apply destination: %d,%d %dx%d changed(%d)", EINA_RECTANGLE_ARGS(&dst), changed);
-
- return changed;
-}
-
-static Eina_Bool
-_e_devicemgr_viewport_apply_source(E_Viewport *viewport)
-{
- E_Client *ec = viewport->ec;
- E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
- Eina_Rectangle rect = {0,};
- int bw = 0, bh = 0;
- wl_fixed_t fx, fy, fw, fh;
- Eina_Bool changed = EINA_FALSE;
-
- if (viewport->cropped_source.w == -1)
- return EINA_FALSE;
-
- e_devmgr_buffer_size_get(ec, &bw, &bh);
-
- rect.w = bw;
- rect.h = bh;
-
- if (!eina_rectangle_intersection(&rect, &viewport->cropped_source))
- {
- PWR("source area is empty");
- return EINA_FALSE;
- }
-
- _source_transform_to_surface(bw, bh,
- e_comp_wl_output_buffer_transform_get(ec), 1,
- &rect, &rect);
-
- fx = wl_fixed_from_int(rect.x);
- fy = wl_fixed_from_int(rect.y);
- fw = wl_fixed_from_int(rect.w);
- fh = wl_fixed_from_int(rect.h);
-
- if (vp->buffer.src_x != fx || vp->buffer.src_y != fy ||
- vp->buffer.src_width != fw || vp->buffer.src_height != fh)
- {
- vp->buffer.src_x = wl_fixed_from_int(rect.x);
- vp->buffer.src_y = wl_fixed_from_int(rect.y);
- vp->buffer.src_width = wl_fixed_from_int(rect.w);
- vp->buffer.src_height = wl_fixed_from_int(rect.h);
- vp->changed = changed = EINA_TRUE;
-
- ec->comp_data->pending.buffer_viewport = *vp;
- if (ec->comp_data->sub.data)
- ec->comp_data->sub.data->cached.buffer_viewport = *vp;
- }
-
- if (changed)
- PDB("apply source: %d,%d %dx%d orig(%d,%d %dx%d) changed(%d)",
- EINA_RECTANGLE_ARGS(&rect), EINA_RECTANGLE_ARGS(&viewport->cropped_source), changed);
-
- return changed;
-}
-
-Eina_Bool
-e_devicemgr_viewport_apply(E_Client *ec)
-{
- E_Viewport *viewport;
- E_Client *subc;
- Eina_List *l;
-
- if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec)))
- return EINA_FALSE;
-
- viewport = _e_devicemgr_viewport_get_viewport(ec->comp_data->scaler.viewport);
-
- if (viewport)
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (viewport && ec->comp_data->buffer_ref.buffer)
- {
- E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
- Eina_Bool changed = EINA_FALSE, src_changed = EINA_FALSE;
- Eina_Rectangle rrect = {0,};
- int rtransform = 0;
-
- /* evas map follow screen coordinates. so all information including the
- * transform and destination also should follow screen coordinates.
- */
- changed |= _e_devicemgr_viewport_apply_transform(viewport, &rtransform);
- changed |= _e_devicemgr_viewport_apply_destination(viewport, &rrect);
- src_changed |= _e_devicemgr_viewport_apply_source(viewport);
-
- viewport->changed = EINA_FALSE;
-
- PDB("changed(%d) src_changed(%d)", changed, src_changed);
-
- if (changed || src_changed)
- {
- e_comp_wl_map_size_cal_from_buffer(viewport->ec);
- e_comp_wl_map_size_cal_from_viewport(viewport->ec);
- e_comp_wl_map_apply(viewport->ec);
-
- if (changed)
- {
- PIN("send destination_changed: transform(%d) x(%d) y(%d) w(%d) h(%d)",
- rtransform, rrect.x, rrect.y, rrect.w, rrect.h);
- tizen_viewport_send_destination_changed(viewport->resource, rtransform,
- rrect.x, rrect.y, rrect.w, rrect.h);
- }
-
- vp->changed = EINA_TRUE;
- }
- }
- else if (viewport)
- PDB("%p buffer", ec->comp_data->buffer_ref.buffer);
-
- EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
- e_devicemgr_viewport_apply(subc);
-
- EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
- e_devicemgr_viewport_apply(subc);
-
- return EINA_TRUE;
-}
-
-Eina_Bool
-e_devicemgr_viewport_is_changed(E_Client *ec)
-{
- E_Viewport *viewport;
- E_Client *subc;
- Eina_List *l;
-
- if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec)))
- return EINA_FALSE;
-
- viewport = _e_devicemgr_viewport_get_viewport(ec->comp_data->scaler.viewport);
- if(viewport && viewport->changed)
- return EINA_TRUE;
-
- EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
- if (e_devicemgr_viewport_is_changed(subc))
- return EINA_TRUE;
-
- EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
- if (e_devicemgr_viewport_is_changed(subc))
- return EINA_TRUE;
-
- return EINA_FALSE;
-}
-
-static void
-_e_devicemgr_viewport_cb_surface_destroy(struct wl_listener *listener, void *data)
-{
- E_Viewport *viewport = container_of(listener, E_Viewport, surface_destroy_listener);
-
- _destroy_viewport(viewport);
-}
-
-static void
-_e_devicemgr_viewport_cb_apply_viewport(struct wl_listener *listener, void *data)
-{
- E_Viewport *viewport = container_of(listener, E_Viewport, surface_apply_viewport_listener);
- E_Client *ec = viewport->ec;
- E_Client *topmost = _topmost_parent_get(ec);
- E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
-
- if (vp->changed)
- _e_devicemgr_viewport_set_changed(viewport);
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- if (!viewport->changed) return;
- if (!ec->comp_data->buffer_ref.buffer) return;
- if (viewport->epc && !viewport->epc->comp_data->buffer_ref.buffer) return;
-
- PDB("apply: topmost(%p)", topmost);
-
- if (!e_devicemgr_viewport_apply(topmost))
- {
- PER("failed to apply tizen_viewport");
- return;
- }
-}
-
-static Eina_Bool
-_e_devicemgr_viewport_cb_topmost_rotate(void *data, int type, void *event)
-{
- E_Viewport *viewport = data;
- E_Client *ec = viewport->ec;
- E_Client *topmost = _topmost_parent_get(ec);
- E_Event_Client *ev = event;
-
- if (topmost != ev->ec)
- return ECORE_CALLBACK_PASS_ON;
-
- PDB("rorate start: topmost(%p)", topmost);
- e_devicemgr_viewport_apply(topmost);
- PDB("rorate end");
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-Eina_Bool
-e_devicemgr_viewport_create(struct wl_resource *resource,
- uint32_t id,
- struct wl_resource *surface)
-{
- E_Client *ec = wl_resource_get_user_data(surface);
- int version = wl_resource_get_version(resource);
- struct wl_client *client;
- struct wl_resource *res;
- E_Viewport *viewport;
-
- if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec)) || !ec->comp_data->surface)
- {
- ERR("wrong resource %d", wl_resource_get_id(surface));
- return EINA_FALSE;
- }
-
- if (ec->comp_data->scaler.viewport)
- {
- ERR("wl_surface@%d already has a viewport",
- wl_resource_get_id(surface));
- return EINA_FALSE;
- }
-
- if (!(client = wl_resource_get_client(surface)))
- {
- ERR("Could not get client from wl_surface@%d",
- wl_resource_get_id(surface));
- return EINA_FALSE;
- }
-
- viewport = calloc(1, sizeof *viewport);
- if (!viewport)
- {
- ERR("failed to alloc a viewport");
- return EINA_FALSE;
- }
-
- res = wl_resource_create(client, &tizen_viewport_interface, version, id);
- if (!res)
- {
- ERR("Could not create tizen_viewport_interface resource");
- free(viewport);
- return EINA_FALSE;
- }
-
- viewport->resource = res;
- viewport->ec = ec;
- viewport->window = e_client_util_win_get(ec);
-
- _e_devicemgr_viewport_parent_check(viewport);
-
- viewport->client_hook_del = e_client_hook_add(E_CLIENT_HOOK_DEL, _client_cb_del, viewport);
- viewport->client_hook_move = e_client_hook_add(E_CLIENT_HOOK_MOVE_UPDATE, _client_cb_move, viewport);
- viewport->client_hook_resize = e_client_hook_add(E_CLIENT_HOOK_RESIZE_UPDATE, _client_cb_resize, viewport);
-
- viewport->subsurf_hook_create = e_comp_wl_hook_add(E_COMP_WL_HOOK_SUBSURFACE_CREATE, _subsurface_cb_create, viewport);
-
- viewport->topmost_rotate_hdl =
- ecore_event_handler_add(E_EVENT_CLIENT_ROTATION_CHANGE_END,
- _e_devicemgr_viewport_cb_topmost_rotate, viewport);
-
- viewport->source.w = -1;
- viewport->cropped_source.w = -1;
-
- viewport->surface_apply_viewport_listener.notify = _e_devicemgr_viewport_cb_apply_viewport;
- wl_signal_add(&ec->comp_data->apply_viewport_signal, &viewport->surface_apply_viewport_listener);
-
- /* Use scaler variable because tizen_viewport is the alternative of wl_viewport */
- ec->comp_data->scaler.viewport = res;
- wl_resource_set_implementation(res, &_e_devicemgr_viewport_interface,
- viewport, _e_devicemgr_viewport_destroy);
-
- viewport->surface_destroy_listener.notify = _e_devicemgr_viewport_cb_surface_destroy;
- wl_resource_add_destroy_listener(ec->comp_data->surface, &viewport->surface_destroy_listener);
-
- PIN("tizen_viewport@%d viewport(%p) created", id, viewport);
-
- return EINA_TRUE;
-}
-
-static E_Viewport*
-_e_devicemgr_viewport_get_viewport(struct wl_resource *resource)
-{
- if (!resource)
- return NULL;
-
- if (wl_resource_instance_of(resource, &tizen_viewport_interface, &_e_devicemgr_viewport_interface))
- return wl_resource_get_user_data(resource);
-
- return NULL;
-}
-
-static void
-_e_devicemgr_viewport_print(void *data, const char *log_path)
-{
- FILE *log_fl;
- Evas_Object *o;
- const char *dest_type_str[] = { "None", "Rect", "Ratio", "Mode" };
- const char *mode_str[] = { "None", "LetterBox", "Origin", "Full", "Cropped_Full", "Origin_or_Letter" };
- int first_line = 1;
- log_fl = fopen(log_path, "a");
- if (!log_fl)
- {
- ERR("failed: open file(%s)", log_path);
- return;
- }
-
- setvbuf(log_fl, NULL, _IOLBF, 512);
-
- // append clients.
- for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
- {
- E_Client *ec;
- E_Viewport *viewport;
- Ecore_Window win = 0;
- const char *name = NULL;
-
- ec = evas_object_data_get(o, "E_Client");
- if (!ec || e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) continue;
-
- viewport = _e_devicemgr_viewport_get_viewport(ec->comp_data->scaler.viewport);
- if (!viewport) continue;
-
- if (first_line)
- {
- fprintf(log_fl, "\n[ viewport information ]\n");
- first_line = 0;
- }
-
- win = e_client_util_win_get(ec);
- name = e_client_util_name_get(ec);
- if (!name)
- name = "NO NAME";
-
- fprintf(log_fl, "* WinID: 0x%08"PRIxPTR" '%s'", win, name);
- if (viewport->epc)
- {
- win = e_client_util_win_get(viewport->epc);
- fprintf(log_fl, " (parentID: 0x%08"PRIxPTR")\n", win);
- }
- else
- fprintf(log_fl, "\n");
- if (viewport->transform > 0)
- fprintf(log_fl, "\t transform: %d%s\n",
- (viewport->transform & 0x3) * 90 % 360,
- (viewport->transform & 0x4) ? "(flipped)" : "");
- if (viewport->follow_parent_transform)
- fprintf(log_fl, "\t follow: parent's transform\n");
- if (viewport->source.w != -1)
- fprintf(log_fl, "\t source: %dx%d+%d+%d\n",
- viewport->source.w, viewport->source.h,
- viewport->source.x, viewport->source.y);
- fprintf(log_fl, "\t type: %s\n", dest_type_str[viewport->type]);
- if (viewport->type == DESTINATION_TYPE_RECT)
- fprintf(log_fl, "\t dest_rect: %dx%d+%d+%d\n",
- viewport->destination.rect.w, viewport->destination.rect.h,
- viewport->destination.rect.x, viewport->destination.rect.y);
- else if (viewport->type == DESTINATION_TYPE_RATIO)
- fprintf(log_fl, "\t dest_ratio: %.2fx%.2f+%.2f+%.2f\n",
- viewport->destination.ratio.w, viewport->destination.ratio.h,
- viewport->destination.ratio.x, viewport->destination.ratio.y);
- else if (viewport->type == DESTINATION_TYPE_MODE)
- {
- fprintf(log_fl, "\t mode: %s\n",
- mode_str[viewport->destination.mode.type]);
- if (viewport->destination.mode.ratio_h != -1.0)
- fprintf(log_fl, "\t\t ratio: H(%.2f) V(%.2f)\n",
- viewport->destination.mode.ratio_h,
- viewport->destination.mode.ratio_v);
- if (viewport->destination.mode.scale_h != -1.0)
- fprintf(log_fl, "\t\t scale: H(%.2f) V(%.2f)\n",
- viewport->destination.mode.scale_h,
- viewport->destination.mode.scale_v);
- if (viewport->destination.mode.align_h != -1.0)
- fprintf(log_fl, "\t\t align: H(%.2f) V(%.2f)\n",
- viewport->destination.mode.align_h,
- viewport->destination.mode.align_v);
- if (viewport->destination.mode.offset_w != 0 ||
- viewport->destination.mode.offset_h != 0 ||
- viewport->destination.mode.offset_x != 0 ||
- viewport->destination.mode.offset_y != 0)
- fprintf(log_fl, "\t\t offset: W(%d) H(%d) (%d) Y(%d)\n",
- viewport->destination.mode.offset_w, viewport->destination.mode.offset_h,
- viewport->destination.mode.offset_x, viewport->destination.mode.offset_y);
- }
-
- fprintf(log_fl, "\n");
- }
-
- fflush(log_fl);
- fclose(log_fl);
-}
-
-
-int
-e_devicemgr_viewport_init(void)
-{
- if (!e_comp_wl) return 0;
- if (!e_comp_wl->wl.disp) return 0;
-
- e_info_server_hook_set("viewport", _e_devicemgr_viewport_print, NULL);
-
- return 1;
-}
-
-void
-e_devicemgr_viewport_fini(void)
-{
- e_info_server_hook_set("viewport", NULL, NULL);
-}
+++ /dev/null
-#ifndef __E_DEVICEMGR_VIEWPORT_H__
-#define __E_DEVICEMGR_VIEWPORT_H__
-
-#define E_COMP_WL
-#include "e.h"
-#include "e_comp_wl.h"
-#include "e_mod_main.h"
-#include "e_devicemgr_privates.h"
-#include <wayland-server.h>
-#include <wayland-tbm-server.h>
-
-int e_devicemgr_viewport_init(void);
-void e_devicemgr_viewport_fini(void);
-
-Eina_Bool e_devicemgr_viewport_create(struct wl_resource *resource,
- uint32_t id,
- struct wl_resource *surface);
-Eina_Bool e_devicemgr_viewport_apply(E_Client *ec);
-Eina_Bool e_devicemgr_viewport_is_changed(E_Client *ec);
-
-#endif
#include "eina_log.h"
#include "e_mod_main.h"
#include "e_devicemgr_input.h"
-#include "e_devicemgr_output.h"
-#include "e_devicemgr_scale.h"
#ifdef HAVE_WAYLAND_ONLY
-#include "e_devicemgr_dpms.h"
-#include "e_devicemgr_screenshooter.h"
-#include "e_devicemgr_video.h"
-#include "e_devicemgr_tdm.h"
#include "e_devicemgr_embedded_compositor.h"
#include "e_devicemgr_device.h"
-#include "e_devicemgr_viewport.h"
-#include "e_devicemgr_eom.h"
#endif
#include "e_devicemgr_privates.h"
return NULL;
}
- if (!e_devicemgr_output_init())
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_output_init()..!\n", __FUNCTION__);
- return NULL;
- }
-
if (!e_devicemgr_input_init())
{
SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_input_init()..!\n", __FUNCTION__);
return NULL;
}
- if (!e_devicemgr_scale_init())
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_scale_init()..!\n", __FUNCTION__);
- return NULL;
- }
-
#ifdef HAVE_WAYLAND_ONLY
- if (!e_devicemgr_dpms_init())
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_dpms_init()..!\n", __FUNCTION__);
- return NULL;
- }
-
- if (!e_devicemgr_tdm_init())
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_tdm_init()..!\n", __FUNCTION__);
- return NULL;
- }
-
- const char *engine_name = ecore_evas_engine_name_get(e_comp->ee);
- if (!engine_name)
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ ecore_evas_engine_name_get()..!\n", __FUNCTION__);
- return NULL;
- }
-
- if (!strncmp(engine_name, "drm", 3) || !strncmp(engine_name, "gl_drm", 6))
- if (!e_devicemgr_screenshooter_init())
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_screenshooter_init()..!\n", __FUNCTION__);
- return NULL;
- }
-
- if (!e_devicemgr_video_init())
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_video_init()..!\n", __FUNCTION__);
- return NULL;
- }
-
if (!e_devicemgr_embedded_compositor_init())
{
SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_embedded_compositor_init()..!\n", __FUNCTION__);
SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_device_init()..!\n", __FUNCTION__);
return NULL;
}
-
- if (!e_devicemgr_viewport_init())
- {
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_viewport_init()..!\n", __FUNCTION__);
- return NULL;
- }
- if (dconfig->conf->eom_enable == EINA_TRUE)
- if (!e_devicemgr_eom_init())
- SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ e_devicemgr_eom_init()..!\n", __FUNCTION__);
#endif
return dconfig;
{
E_Devicemgr_Config_Data *dconf = m->data;
#ifdef HAVE_WAYLAND_ONLY
- e_devicemgr_viewport_fini();
- e_devicemgr_dpms_fini();
- e_devicemgr_screenshooter_fini();
- e_devicemgr_video_fini();
- if (dconfig->conf->eom_enable == EINA_TRUE)
- e_devicemgr_eom_fini();
- e_devicemgr_tdm_fini();
e_devicemgr_embedded_compositor_fini();
e_devicemgr_device_fini();
#endif
- e_devicemgr_scale_fini();
e_devicemgr_input_fini();
- e_devicemgr_output_fini();
e_devicemgr_conf_fini(dconf);
E_FREE(dconf);