src/bin/e_comp_wl_data.h \
src/bin/e_comp_wl_input.h \
src/bin/e_comp_wl.h \
-src/bin/e_output_hwc.h \
-src/bin/e_output_hwc_planes.h \
-src/bin/e_output_hwc_windows.h \
+src/bin/e_hwc.h \
+src/bin/e_hwc_planes.h \
+src/bin/e_hwc_windows.h \
src/bin/e_hwc_window.h
if HAVE_WAYLAND_TBM
src/bin/e_comp_wl_data.c \
src/bin/e_comp_wl_input.c \
src/bin/e_comp_wl.c \
-src/bin/e_output_hwc.c \
-src/bin/e_output_hwc_planes.c \
-src/bin/e_output_hwc_windows.c \
+src/bin/e_hwc.c \
+src/bin/e_hwc_planes.c \
+src/bin/e_hwc_windows.c \
src/bin/e_hwc_window.c \
$(ENLIGHTENMENTHEADERS)
Eina_Bool saved_img : 1; // indicates that window has been saved as the image file even once
Eina_Bool skip_save_img: 1; // indicates that window doesn't want to save its image file
- E_Hwc_Window *hwc_window; // hwc window for the tdm_output_hwc.
+ E_Hwc_Window *hwc_window; // hwc window for the tdm_hwc.
};
#define e_client_focus_policy_click(ec) \
eout = e_output_find(ec->zone->output_id);
if (!eout) return EINA_FALSE;
- if (e_output_hwc_policy_get(eout->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(eout->hwc) == E_HWC_POLICY_PLANES)
{
- if (!e_output_hwc_mode_get(eout->output_hwc)) return EINA_FALSE;
+ if (!e_hwc_mode_get(eout->hwc)) return EINA_FALSE;
EINA_LIST_FOREACH_SAFE(eout->planes, l, ll, ep)
{
output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
EINA_SAFETY_ON_NULL_RETURN(output);
- e_output_hwc_deactive_set(output->output_hwc, set);
+ e_hwc_deactive_set(output->hwc, set);
}
/* get the deactive value to the only primary output */
output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
- return e_output_hwc_deactive_get(output->output_hwc);
+ return e_hwc_deactive_get(output->hwc);
}
/* set the multi_plane value to the only primary output */
output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
EINA_SAFETY_ON_NULL_RETURN(output);
- e_output_hwc_planes_multi_plane_set(output->output_hwc, EINA_TRUE);
+ e_hwc_planes_multi_plane_set(output->hwc, EINA_TRUE);
}
/* get the multi_plane value to the only primary output */
output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
- return e_output_hwc_planes_multi_plane_get(output->output_hwc);
+ return e_hwc_planes_multi_plane_get(output->hwc);
}
/* end the hwc policy at the primary output */
output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
EINA_SAFETY_ON_NULL_RETURN(output);
- e_output_hwc_planes_end(output->output_hwc, location);
+ e_hwc_planes_end(output->hwc, location);
}
if (!output) continue;
if (!output->config.enabled) continue;
- e_output_hwc_apply(output->output_hwc);
+ e_hwc_apply(output->hwc);
if (!e_output_commit(output))
ERR("fail to commit e_comp_screen->outputs.");
if (!output) continue;
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
err = tdm_output_get_conn_status(output->toutput, &conn_status);
if (err != TDM_ERROR_NONE) continue;
output = _get_e_output(toutput);
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
- if (e_output_hwc_policy_get(output->output_hwc) != E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(output->hwc) != E_HWC_POLICY_WINDOWS)
{
/* get the first suitable layer */
layer = _e_video_tdm_video_layer_get(toutput);
layer->video = video;
layer->e_client = video->ec;
- if (e_output_hwc_policy_get(video->e_output->output_hwc) != E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(video->e_output->hwc) != E_HWC_POLICY_WINDOWS)
{
layer->tdm_layer = _e_video_tdm_avaiable_video_layer_get(video->output);
if (!layer->tdm_layer)
* Try to create a video hwc window.
* In this moment the video resource will be held.
*/
- hwc_window = e_hwc_window_new(video->e_output->output_hwc, video->ec, E_HWC_WINDOW_STATE_VIDEO);
+ hwc_window = e_hwc_window_new(video->e_output->hwc, video->ec, E_HWC_WINDOW_STATE_VIDEO);
if (!hwc_window)
{
VER("hwc_opt: cannot create new video hwc window for ec(%p)", video->ec);
output = _get_e_output(toutput);
EINA_SAFETY_ON_NULL_RETURN(output);
- if (e_output_hwc_policy_get(output->output_hwc) != E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(output->hwc) != E_HWC_POLICY_WINDOWS)
{
/* get the first suitable layer */
layer = _e_video_tdm_video_layer_get(output);
const tdm_prop *props;
int i, count = 0;
- if (e_output_hwc_policy_get(video->e_output->output_hwc) != E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(video->e_output->hwc) != E_HWC_POLICY_WINDOWS)
{
layer = _e_video_tdm_video_layer_get(video->output);
tdm_layer_get_available_properties(layer, &props, &count);
}
// TODO: this function has to be removed.....
-// Use. e_output_hwc_policy_get();
+// Use. e_hwc_policy_get();
static Eina_Bool
_is_video_hwc_windows(E_Video *video)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(video, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(video->e_output, EINA_FALSE);
- if (e_output_hwc_policy_get(video->e_output->output_hwc) == E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(video->e_output->hwc) == E_HWC_POLICY_WINDOWS)
return EINA_TRUE;
return EINA_FALSE;
video->layer = NULL;
video->old_comp_buffer = NULL;
- if (e_output_hwc_policy_get(video->e_output->output_hwc) != E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(video->e_output->hwc) != E_HWC_POLICY_WINDOWS)
{
e_plane_video_set(video->e_plane, EINA_FALSE, NULL);
video->e_plane = NULL;
return EINA_FALSE;
}
- if (e_output_hwc_policy_get(video->e_output->output_hwc) != E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(video->e_output->hwc) != E_HWC_POLICY_WINDOWS)
{
ret = tdm_layer_get_zpos(video->layer->tdm_layer, &zpos);
if (ret == TDM_ERROR_NONE)
tdm_layer_capability capabilities = 0;
tdm_error error;
- if (e_output_hwc_policy_get(video->e_output->output_hwc) != E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(video->e_output->hwc) != E_HWC_POLICY_WINDOWS)
{
tdm_layer *layer = _e_video_tdm_video_layer_get(video->output);
--- /dev/null
+#include "e.h"
+#include "services/e_service_quickpanel.h"
+
+static void
+_e_hwc_cb_ee_resize(Ecore_Evas *ee EINA_UNUSED)
+{
+ e_comp_canvas_update();
+}
+
+static void *
+_e_hwc_tbm_surface_queue_alloc(void *data, int w, int h)
+{
+ E_Hwc *hwc = (E_Hwc *)data;
+ E_Output *output = hwc->output;
+ E_Comp_Screen *e_comp_screen = output->e_comp_screen;
+ tdm_output *toutput = output->toutput;
+ tbm_surface_queue_h tqueue = NULL;
+ tdm_error error;
+ int scr_w, scr_h, queue_w, queue_h;
+
+ e_output_size_get(output, &scr_w, &scr_h);
+
+ if (output->tdm_hwc)
+ {
+ tqueue = tdm_output_hwc_get_target_buffer_queue(toutput, &error);
+ if (error != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_output_hwc_get_target_buffer_queue");
+ return (void *)NULL;
+ }
+ }
+ else
+ {
+ tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
+ if (!tqueue)
+ {
+ ERR("fail to tdm_output_hwc_get_target_buffer_queue");
+ return (void *)NULL;
+ }
+ }
+
+ queue_w = tbm_surface_queue_get_width(tqueue);
+ if (scr_w != queue_w)
+ WRN("!!!!!!WARNING::: the queue width(%d) is diffrent from output width(%d)!!!!!!", queue_w, scr_w);
+ queue_h = tbm_surface_queue_get_height(tqueue);
+ if (scr_h != queue_h)
+ WRN("!!!!!!WARNING::: the queue height(%d) is diffrent from output height(%d)!!!!!!", queue_h, scr_h);
+
+ hwc->target_buffer_queue = tqueue;
+
+ // TODO: change the e_comp_screen->tqueue into hwc->target_buffer_queue
+ e_comp_screen->tqueue = tqueue;
+
+ return (void *)tqueue;
+}
+
+static void
+_e_hwc_tbm_surface_queue_free(void *data, void *tqueue)
+{
+ E_Hwc *hwc = (E_Hwc *)data;
+
+ tbm_surface_queue_destroy(tqueue);
+ hwc->target_buffer_queue = NULL;
+}
+
+static void
+_e_hwc_ee_deinit(E_Hwc *hwc)
+{
+ // TODO:
+ E_Output *output = hwc->output;
+ E_Output *primary_output = NULL;
+
+ primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
+ if (primary_output != output)
+ {
+ if (hwc->ee)
+ ecore_evas_free(hwc->ee);
+ hwc->ee = NULL;
+ }
+ else
+ {
+ /* ecore_evas_free execute when e_comp free */
+ hwc->ee = NULL;
+ }
+}
+
+// TODO: Currently E20 has only one e_output for the primary output.
+// We need to change the ee and other logic for multiple E_Output.
+static Eina_Bool
+_e_hwc_ee_init(E_Hwc* hwc)
+{
+ E_Output *output = hwc->output;
+ E_Output *primary_output = NULL;
+ Ecore_Evas *ee = NULL;
+ int w = 0, h = 0, scr_w = 1, scr_h = 1;
+ int screen_rotation;
+ char buf[1024];
+
+ INF("E_HWC: ecore evase engine init.");
+
+ // TODO: fix me. change the screen_rotation into output_rotation.
+ screen_rotation = output->e_comp_screen->rotation;
+
+ /* set env for use tbm_surface_queue*/
+ setenv("USE_EVAS_SOFTWARE_TBM_ENGINE", "1", 1);
+ //setenv("USE_EVAS_GL_TBM_ENGINE", "1", 1);
+
+ /* set gl available if we have ecore_evas support */
+ if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM) ||
+ ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_TBM))
+ e_comp_gl_set(EINA_TRUE);
+
+ /* get the size of the primary output */
+ e_output_size_get(output, &scr_w, &scr_h);
+
+ /* if output is disconnected, set the default width, height */
+ if (scr_w == 0 || scr_h == 0)
+ {
+ scr_w = 2;
+ scr_h = 1;
+
+ if (!e_output_fake_config_set(output, scr_w, scr_h))
+ {
+ e_error_message_show(_("Fail to set the fake output config!\n"));
+ _e_hwc_ee_deinit(hwc);
+ return EINA_FALSE;
+ }
+ }
+
+ INF("GL available:%d config engine:%d screen size:%dx%d",
+ e_comp_gl_get(), e_comp_config_get()->engine, scr_w, scr_h);
+
+ if ((e_comp_gl_get()) &&
+ (e_comp_config_get()->engine == E_COMP_ENGINE_GL))
+ {
+ e_main_ts_begin("\tEE_GL_DRM New");
+ ee = ecore_evas_tbm_allocfunc_new("gl_tbm", scr_w, scr_h, _e_hwc_tbm_surface_queue_alloc, _e_hwc_tbm_surface_queue_free, (void *)hwc);
+ snprintf(buf, sizeof(buf), "\tEE_GL_DRM New Done %p %dx%d", ee, scr_w, scr_h);
+ e_main_ts_end(buf);
+
+ if (!ee)
+ e_comp_gl_set(EINA_FALSE);
+ else
+ {
+ Evas_GL *evasgl = NULL;
+ Evas_GL_API *glapi = NULL;
+
+ e_main_ts_begin("\tEvas_GL New");
+ evasgl = evas_gl_new(ecore_evas_get(ee));
+ if (evasgl)
+ {
+ glapi = evas_gl_api_get(evasgl);
+ if (!((glapi) && (glapi->evasglBindWaylandDisplay)))
+ {
+ e_comp_gl_set(EINA_FALSE);
+ ecore_evas_free(ee);
+ ee = NULL;
+ e_main_ts_end("\tEvas_GL New Failed 1");
+ }
+ else
+ {
+ e_main_ts_end("\tEvas_GL New Done");
+ }
+ }
+ else
+ {
+ e_comp_gl_set(EINA_FALSE);
+ ecore_evas_free(ee);
+ ee = NULL;
+ e_main_ts_end("\tEvas_GL New Failed 2");
+ }
+ evas_gl_free(evasgl);
+ }
+ }
+
+ /* fallback to framebuffer drm (non-accel) */
+ if (!ee)
+ {
+ e_main_ts_begin("\tEE_DRM New");
+ ee = ecore_evas_tbm_allocfunc_new("software_tbm", scr_w, scr_h, _e_hwc_tbm_surface_queue_alloc, _e_hwc_tbm_surface_queue_free, (void *)hwc);
+ snprintf(buf, sizeof(buf), "\tEE_DRM New Done %p %dx%d", ee, scr_w, scr_h);
+ e_main_ts_end(buf);
+ }
+
+ if (!ee)
+ {
+ e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
+ _e_hwc_ee_deinit(hwc);
+ return EINA_FALSE;
+ }
+
+ hwc->ee = ee;
+
+ primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
+ if (primary_output == output)
+ {
+ e_comp->ee = ee;
+ ecore_evas_data_set(e_comp->ee, "comp", e_comp);
+
+ ecore_evas_callback_resize_set(e_comp->ee, _e_hwc_cb_ee_resize);
+
+ if (screen_rotation)
+ {
+ /* SHOULD called with resize option after ecore_evas_resize */
+ ecore_evas_rotation_with_resize_set(e_comp->ee, screen_rotation);
+ ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
+
+ snprintf(buf, sizeof(buf), "\tEE Rotate and Resize %d, %dx%d", screen_rotation, w, h);
+ e_main_ts(buf);
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+EINTERN E_Hwc *
+e_hwc_new(E_Output *output)
+{
+ E_Hwc *hwc = NULL;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
+
+ hwc = E_NEW(E_Hwc, 1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
+
+ hwc->output = output;
+
+ if (!_e_hwc_ee_init(hwc))
+ {
+ ERR("hwc_opt: _e_hwc_ee_init failed");
+ goto fail;
+ }
+
+ /*
+ * E20 has two hwc policy options.
+ * 1. One is the E_HWC_POLICY_PLANES.
+ * - E20 decides the hwc policy with the E_Planes associated with the tdm_layers.
+ * - E20 manages how to set the surface(buffer) of the ec to the E_Plane.
+ * 2. Another is the E_HWC_POLICY_WIDNOWS.
+ * - The tdm-backend decides the hwc policy with the E_Hwc_Windows associated with the tdm_hwc_window.
+ * - E20 asks to verify the compsition types of the E_Hwc_Window of the ec.
+ */
+ if (!output->tdm_hwc)
+ {
+ hwc->hwc_policy = E_HWC_POLICY_PLANES;
+ if (!e_hwc_planes_init())
+ {
+ ERR("hwc_opt: e_hwc_windows_init failed");
+ goto fail;
+ }
+
+ INF("Output uses the HWC PLANES Policy.");
+ }
+ else
+ {
+ hwc->hwc_policy = E_HWC_POLICY_WINDOWS;
+
+ if (!e_hwc_windows_init(hwc))
+ {
+ ERR("hwc_opt: e_hwc_windows_init failed");
+ goto fail;
+ }
+
+ if (!e_hwc_window_init(hwc))
+ {
+ ERR("hwc_opt: E_Hwc_Window init failed");
+ goto fail;
+ }
+
+ /* turn on sw compositor at the start */
+ ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
+
+ INF("Output uses the HWC WINDOWS Policy.");
+ }
+
+ return hwc;
+
+fail:
+ E_FREE(hwc);
+
+ return NULL;
+}
+
+EINTERN void
+e_hwc_del(E_Hwc *hwc)
+{
+ if (!hwc) return;
+
+ _e_hwc_ee_deinit(hwc);
+
+ if (hwc->hwc_policy == E_HWC_POLICY_PLANES)
+ e_hwc_planes_deinit();
+ else
+ {
+ e_hwc_window_deinit(hwc);
+ e_hwc_windows_deinit();
+ }
+
+ E_FREE(hwc);
+}
+
+EINTERN void
+e_hwc_apply(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+ EINA_SAFETY_ON_NULL_RETURN(hwc->output);
+ if (e_hwc_policy_get(hwc) == E_HWC_POLICY_NONE ||
+ e_hwc_policy_get(hwc) == E_HWC_POLICY_WINDOWS) return;
+
+ if (e_hwc_deactive_get(hwc))
+ {
+ if (hwc->hwc_mode != E_HWC_MODE_NONE)
+ e_hwc_planes_end(hwc, "deactive set.");
+ return;
+ }
+
+ if (!e_hwc_planes_usable(hwc))
+ {
+ e_hwc_planes_end(hwc, __FUNCTION__);
+ return;
+ }
+
+ if (hwc->hwc_mode == E_HWC_MODE_NONE)
+ e_hwc_planes_begin(hwc);
+ else
+ e_hwc_planes_changed(hwc);
+}
+
+EINTERN E_Hwc_Mode
+e_hwc_mode_get(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, E_HWC_MODE_NONE);
+
+ return hwc->hwc_mode;
+}
+
+EINTERN E_Hwc_Policy
+e_hwc_policy_get(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, E_HWC_MODE_NONE);
+
+ return hwc->hwc_policy;
+}
+
+EINTERN void
+e_hwc_deactive_set(E_Hwc *hwc, Eina_Bool set)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+ e_hwc_planes_end(hwc, __FUNCTION__);
+ hwc->hwc_deactive = set;
+
+ ELOGF("HWC", "e_hwc_deactive_set : %d", NULL, NULL, set);
+}
+
+EINTERN Eina_Bool
+e_hwc_deactive_get(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+ return hwc->hwc_deactive;
+}
--- /dev/null
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Hwc E_Hwc;
+
+typedef enum _E_Hwc_Mode
+{
+ E_HWC_MODE_NONE = 0,
+ E_HWC_MODE_HYBRID,
+ E_HWC_MODE_FULL
+} E_Hwc_Mode;
+
+typedef enum _E_Hwc_Policy
+{
+ E_HWC_POLICY_NONE = 0,
+ E_HWC_POLICY_PLANES, // hwc_planes policy that controls the hwc policy at e20 with e_planes
+ E_HWC_POLICY_WINDOWS, // hwc_windows policy that controls the hwc policy at tdm-backend with e_hwc_windows
+} E_Hwc_Policy;
+
+#else
+#ifndef E_HWC_H
+#define E_HWC_H
+
+struct _E_Hwc
+{
+ E_Output *output;
+
+ E_Hwc_Policy hwc_policy;
+ E_Hwc_Mode hwc_mode;
+ Eina_Bool hwc_deactive : 1; // deactive hwc policy
+
+ Ecore_Evas *ee;
+
+ /* variables for hwc_planes polic */
+ Eina_Bool hwc_use_multi_plane;
+
+ /* variables for hwc_windows policy */
+ Eina_Bool hwc_wins;
+ Eina_List *hwc_windows;
+ E_Hwc_Window_Target *target_hwc_window;
+ tbm_surface_queue_h target_buffer_queue;
+ Eina_Bool wait_commit;
+ int num_visible_windows;
+
+ /* variables for pp at hwc_windows policy */
+ tdm_pp *tpp;
+ Eina_List *pp_hwc_window_list;
+ Eina_List *pending_pp_hwc_window_list;
+ Eina_List *pending_pp_commit_data_list;
+ tbm_surface_queue_h pp_tqueue;
+ tbm_surface_h pp_tsurface;
+ Eina_Bool pp_set_info;
+ Eina_Bool pp_set;
+ Eina_Bool pp_commit;
+ Eina_Bool pp_output_commit;
+ E_Hwc_Window_Commit_Data *pp_output_commit_data;
+ Eina_Rectangle pp_rect;
+};
+
+EINTERN E_Hwc *e_hwc_new(E_Output *output);
+EINTERN void e_hwc_del(E_Hwc *hwc);
+EINTERN void e_hwc_apply(E_Hwc *hwc);
+EINTERN E_Hwc_Policy e_hwc_policy_get(E_Hwc *hwc);
+EINTERN E_Hwc_Mode e_hwc_mode_get(E_Hwc *hwc);
+EINTERN void e_hwc_deactive_set(E_Hwc *hwc, Eina_Bool set);
+EINTERN Eina_Bool e_hwc_deactive_get(E_Hwc *hwc);
+
+#endif
+#endif
--- /dev/null
+#include "e.h"
+#include "services/e_service_quickpanel.h"
+
+EINTERN Eina_Bool
+e_hwc_planes_init(void)
+{
+ return EINA_TRUE;
+}
+
+EINTERN void
+e_hwc_planes_deinit(void)
+{
+ // TODO:
+ ;;;
+}
+
+static Eina_Bool
+_e_hwc_planes_ec_check(E_Client *ec)
+{
+ E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
+ E_Output *eout;
+ int minw = 0, minh = 0;
+
+ if ((!cdata) ||
+ (!cdata->buffer_ref.buffer) ||
+ (cdata->width_from_buffer != cdata->width_from_viewport) ||
+ (cdata->height_from_buffer != cdata->height_from_viewport) ||
+ cdata->never_hwc)
+ {
+ return EINA_FALSE;
+ }
+
+ if (e_client_transform_core_enable_get(ec)) return EINA_FALSE;
+
+ switch (cdata->buffer_ref.buffer->type)
+ {
+ case E_COMP_WL_BUFFER_TYPE_NATIVE:
+ case E_COMP_WL_BUFFER_TYPE_TBM:
+ break;
+ case E_COMP_WL_BUFFER_TYPE_SHM:
+ if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
+ break;
+ default:
+ return EINA_FALSE;
+ }
+
+ eout = e_output_find(ec->zone->output_id);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(eout, EINA_FALSE);
+
+ tdm_output_get_available_size(eout->toutput, &minw, &minh, NULL, NULL, NULL);
+
+ if ((minw > 0) && (minw > cdata->buffer_ref.buffer->w))
+ return EINA_FALSE;
+ if ((minh > 0) && (minh > cdata->buffer_ref.buffer->h))
+ return EINA_FALSE;
+
+ /* If a client doesn't watch the ignore_output_transform events, we can't show
+ * a client buffer to HW overlay directly when the buffer transform is not same
+ * with output transform. If a client watch the ignore_output_transform events,
+ * we can control client's buffer transform. In this case, we don't need to
+ * check client's buffer transform here.
+ */
+ if (!e_comp_screen_rotation_ignore_output_transform_watch(ec))
+ {
+ int transform = e_comp_wl_output_buffer_transform_get(ec);
+
+ if ((eout->config.rotation / 90) != transform)
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_e_hwc_planes_prepare_init(E_Hwc *hwc)
+{
+ const Eina_List *ep_l = NULL, *l ;
+ E_Plane *ep = NULL;
+ E_Output *eout = hwc->output;
+
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+ ep_l = e_output_planes_get(eout);
+ EINA_LIST_FOREACH(ep_l, l, ep)
+ {
+ if (!hwc->hwc_use_multi_plane &&
+ !e_plane_is_cursor(ep) &&
+ !e_plane_is_fb_target(ep))
+ continue;
+
+ e_plane_ec_prepare_set(ep, NULL);
+ }
+}
+
+static int
+_e_hwc_planes_prepare_cursor(E_Output *eout, int n_cur, Eina_List *hwc_clist)
+{
+ // policy for cursor layer
+ const Eina_List *ep_l = NULL, *l ;
+ Eina_List *cur_ly = NULL;
+ E_Plane *ep = NULL;
+ int n_skip = 0;
+ int n_curly = 0;
+ int nouse = 0;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_clist, EINA_FALSE);
+
+ // list up cursor only layers
+ ep_l = e_output_planes_get(eout);
+ EINA_LIST_FOREACH(ep_l, l, ep)
+ {
+ if (e_plane_is_cursor(ep))
+ {
+ cur_ly = eina_list_append(cur_ly, ep);
+ continue;
+ }
+ }
+
+ if (!cur_ly) return 0;
+ n_curly = eina_list_count(cur_ly);
+
+ if (n_cur > 0 && n_curly > 0)
+ {
+ if (n_cur >= n_curly) nouse = 0;
+ else nouse = n_curly - n_cur;
+
+ //assign cursor on cursor only layers
+ EINA_LIST_REVERSE_FOREACH(cur_ly, l, ep)
+ {
+ E_Client *ec = NULL;
+ if (nouse > 0)
+ {
+ nouse--;
+ continue;
+ }
+ if (hwc_clist) ec = eina_list_data_get(hwc_clist);
+ if (ec && e_plane_ec_prepare_set(ep, ec))
+ {
+ n_skip += 1;
+ hwc_clist = eina_list_next(hwc_clist);
+ }
+ }
+ }
+
+ eina_list_free(cur_ly);
+
+ return n_skip;
+}
+
+static Eina_Bool
+_e_hwc_planes_prepare_plane(E_Hwc *hwc, int n_vis, int n_skip, Eina_List *hwc_clist)
+{
+ const Eina_List *ep_l = NULL, *l ;
+ Eina_List *hwc_ly = NULL;
+ E_Plane *ep = NULL, *ep_fb = NULL;
+ int n_ly = 0, n_ec = 0;
+ E_Client *ec = NULL;
+ Eina_Bool ret = EINA_FALSE;
+ int nouse = 0;
+ E_Output *eout = hwc->output;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_clist, EINA_FALSE);
+
+ n_ec = eina_list_count(hwc_clist);
+ if (n_skip > 0)
+ {
+ int i;
+ for (i = 0; i < n_skip; i++)
+ hwc_clist = eina_list_next(hwc_clist);
+
+ n_ec -= n_skip;
+ n_vis -= n_skip;
+ }
+
+ if (n_ec <= 0) return EINA_FALSE;
+
+ // list up available_hw layers E_Client can be set
+ // if e_comp->hwc_use_multi_plane FALSE, than use only fb target plane
+ ep_l = e_output_planes_get(eout);
+ EINA_LIST_FOREACH(ep_l, l, ep)
+ {
+ if (!ep_fb)
+ {
+ if (e_plane_is_fb_target(ep))
+ {
+ ep_fb = ep;
+ hwc_ly = eina_list_append(hwc_ly, ep);
+ }
+ continue;
+ }
+ if (!hwc->hwc_use_multi_plane) continue;
+ if (e_plane_is_cursor(ep)) continue;
+ if (ep->zpos > ep_fb->zpos)
+ hwc_ly = eina_list_append(hwc_ly, ep);
+ }
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_ly, EINA_FALSE);
+
+ // finally, assign client on available_hw layers
+ n_ly = eina_list_count(hwc_ly);
+ if ((n_ec == n_vis) &&
+ (n_ec <= n_ly)) // fully hwc
+ {
+ nouse = n_ly - n_ec;
+ }
+ else if ((n_ly < n_vis) || // e_comp->evas on fb target plane
+ (n_ec < n_vis))
+ {
+ if (n_ec <= n_ly) nouse = n_ly - n_ec - 1;
+ else nouse = 0;
+ }
+
+ EINA_LIST_REVERSE_FOREACH(hwc_ly, l, ep)
+ {
+ ec = NULL;
+ if (nouse > 0)
+ {
+ nouse--;
+ continue;
+ }
+ if (hwc_clist) ec = eina_list_data_get(hwc_clist);
+ if (ec && e_plane_ec_prepare_set(ep, ec))
+ {
+ ret = EINA_TRUE;
+
+ hwc_clist = eina_list_next(hwc_clist);
+ n_ec--; n_vis--;
+ }
+ if (e_plane_is_fb_target(ep))
+ {
+ if (n_ec > 0 || n_vis > 0) e_plane_ec_prepare_set(ep, NULL);
+ break;
+ }
+ }
+
+ eina_list_free(hwc_ly);
+
+ return ret;
+}
+
+static void
+_e_hwc_planes_cancel(E_Hwc *hwc)
+{
+ Eina_List *l ;
+ E_Plane *ep;
+ E_Output *eout = hwc->output;
+
+ EINA_LIST_FOREACH(eout->planes, l, ep)
+ {
+ if (!hwc->hwc_use_multi_plane &&
+ !e_plane_is_cursor(ep) &&
+ !e_plane_is_fb_target(ep))
+ continue;
+
+ e_plane_ec_prepare_set(ep, NULL);
+ e_plane_ec_set(ep, NULL);
+ }
+}
+
+static Eina_Bool
+_e_hwc_planes_reserved_clean(E_Hwc *hwc)
+{
+ Eina_List *l;
+ E_Plane *ep;
+ E_Output *eout = hwc->output;
+
+ EINA_LIST_FOREACH(eout->planes, l, ep)
+ {
+ if (!hwc->hwc_use_multi_plane &&
+ !e_plane_is_cursor(ep) &&
+ !e_plane_is_fb_target(ep))
+ continue;
+
+ if (e_plane_is_reserved(ep))
+ e_plane_reserved_set(ep, 0);
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_e_hwc_planes_unset(E_Plane *ep)
+{
+ if (e_plane_is_reserved(ep))
+ e_plane_reserved_set(ep, 0);
+
+ e_plane_ec_prepare_set(ep, NULL);
+ e_plane_ec_set(ep, NULL);
+
+ ELOGF("HWC-PLNS", "unset plane %d to NULL", NULL, NULL, ep->zpos);
+}
+
+static Eina_Bool
+_e_hwc_planes_change_ec(E_Plane *ep, E_Client *new_ec)
+{
+ if (!e_plane_ec_set(ep, new_ec))
+ {
+ ELOGF("HWC-PLNS", "failed to set new_ec(%s) on %d",
+ NULL, new_ec,
+ new_ec ? (new_ec->icccm.name ? new_ec->icccm.name : "no name") : "NULL",
+ ep->zpos);
+ return EINA_FALSE;
+ }
+
+ if (new_ec)
+ ELOGF("HWC-PLNS", "new_ec(%s) is set on %d",
+ new_ec->pixmap, new_ec,
+ e_client_util_name_get(new_ec) ? new_ec->icccm.name : "no name", ep->zpos);
+ else
+ ELOGF("HWC-PLNS", "NULL is set on %d", NULL, NULL, ep->zpos);
+
+ return EINA_TRUE;
+}
+
+EINTERN void
+e_hwc_planes_changed(E_Hwc *hwc)
+{
+ Eina_Bool ret = EINA_FALSE;
+ E_Plane *ep = NULL;
+ const Eina_List *ep_l = NULL, *p_l;
+ Eina_Bool assign_success = EINA_TRUE;
+ int mode = E_HWC_MODE_NONE;
+ E_Output *eout = hwc->output;
+
+ ep_l = e_output_planes_get(eout);
+ /* check the planes from top to down */
+ EINA_LIST_REVERSE_FOREACH(ep_l, p_l, ep)
+ {
+ if (!assign_success)
+ {
+ //unset planes from 'assign_success' became EINA_FALSE to the fb target
+ _e_hwc_planes_unset(ep);
+ continue;
+ }
+
+ if (e_plane_is_reserved(ep) &&
+ ep->prepare_ec == NULL)
+ {
+ e_plane_reserved_set(ep, 0);
+ ELOGF("HWC-PLNS", "unset reserved mem on %d", NULL, NULL, ep->zpos);
+ }
+
+ if (ep->ec != ep->prepare_ec)
+ {
+ assign_success = _e_hwc_planes_change_ec(ep, ep->prepare_ec);
+ ret = EINA_TRUE;
+ }
+
+ if (ep->ec) mode = E_HWC_MODE_HYBRID;
+
+ if (e_plane_is_fb_target(ep))
+ {
+ if (ep->ec) mode = E_HWC_MODE_FULL;
+ break;
+ }
+ }
+
+ if (hwc->hwc_mode != mode)
+ {
+ ELOGF("HWC-PLNS", "mode changed (from %d to %d) due to surface changes",
+ NULL, NULL,
+ hwc->hwc_mode, mode);
+
+ if (mode == E_HWC_MODE_FULL)
+ {
+ // fb target is occupied by a client surface, means compositor disabled
+ ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
+ }
+ else if (hwc->hwc_mode == E_HWC_MODE_FULL)
+ {
+ // fb target is occupied by a client surface, means compositor disabled
+ ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
+ }
+
+ hwc->hwc_mode = mode;
+ }
+
+ if (ret)
+ {
+ if (hwc->hwc_mode == E_HWC_MODE_NONE)
+ ELOGF("HWC-PLNS", " End... due to surface changes", NULL, NULL);
+ else
+ ELOGF("HWC-PLNS", " hwc surface changed", NULL, NULL);
+ }
+}
+
+static Eina_Bool
+_e_hwc_planes_prepare(E_Hwc *hwc, E_Zone *zone)
+{
+ Eina_List *vl;
+ Eina_Bool ret = EINA_FALSE;
+ E_Client *ec;
+ int n_vis = 0, n_ec = 0, n_cur = 0, n_skip = 0;
+ Eina_List *hwc_ok_clist = NULL, *vis_clist = NULL;
+ E_Output *output = hwc->output;
+
+ vis_clist = e_comp_vis_ec_list_get(zone);
+ if (!vis_clist) return EINA_FALSE;
+
+ // check clients not able to use hwc
+ EINA_LIST_FOREACH(vis_clist, vl, ec)
+ {
+ // if there is a ec which is lower than quickpanel and quickpanel is opened.
+ if (E_POLICY_QUICKPANEL_LAYER >= evas_object_layer_get(ec->frame))
+ {
+ // check whether quickpanel is open than break
+ if (e_qp_visible_get()) goto done;
+ }
+
+ // if ec->frame is not for client buffer (e.g. launchscreen)
+ if (e_comp_object_content_type_get(ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
+ goto done;
+
+ // if there is UI subfrace, it means need to composite
+ if (e_client_normal_client_has(ec))
+ goto done;
+
+ // if ec has invalid buffer or scaled( transformed ) or forced composite(never_hwc)
+ if (!_e_hwc_planes_ec_check(ec))
+ {
+ if (!n_ec) goto done;
+ break;
+ }
+
+ // listup as many as possible from the top most visible order
+ n_ec++;
+ if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role)) n_cur++;
+ hwc_ok_clist = eina_list_append(hwc_ok_clist, ec);
+ }
+
+ n_vis = eina_list_count(vis_clist);
+ if ((n_vis < 1) || (n_ec < 1))
+ goto done;
+
+ _e_hwc_planes_prepare_init(hwc);
+
+ if (n_cur >= 1)
+ n_skip = _e_hwc_planes_prepare_cursor(output, n_cur, hwc_ok_clist);
+
+ if (n_skip > 0) ret = EINA_TRUE;
+
+ ret |= _e_hwc_planes_prepare_plane(hwc, n_vis, n_skip, hwc_ok_clist);
+
+done:
+ eina_list_free(hwc_ok_clist);
+ eina_list_free(vis_clist);
+
+ return ret;
+}
+
+EINTERN Eina_Bool
+e_hwc_planes_usable(E_Hwc *hwc)
+{
+ E_Output *eout = hwc->output;
+ E_Comp_Wl_Buffer *buffer = NULL;
+ E_Zone *zone = NULL;
+ int bw = 0, bh = 0;
+ Eina_Bool all_null = EINA_TRUE;
+ E_Plane *ep = NULL;
+ const Eina_List *ep_l = NULL, *p_l;
+
+ zone = e_comp_zone_find(e_output_output_id_get(eout));
+ EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
+
+ // check whether to use hwc and prepare the core assignment policy
+ if (!_e_hwc_planes_prepare(hwc, zone)) return EINA_FALSE;
+
+ // extra policy can replace core policy
+ e_comp_hook_call(E_COMP_HOOK_PREPARE_PLANE, NULL);
+
+ // It is not hwc_usable if cursor is shown when the hw cursor is not supported by libtdm.
+ if (!e_pointer_is_hidden(e_comp->pointer) &&
+ (eout->cursor_available.max_w == -1 || eout->cursor_available.max_h == -1))
+ return EINA_FALSE;
+
+ // check the hwc is avaliable.
+ ep_l = e_output_planes_get(eout);
+ EINA_LIST_FOREACH(ep_l, p_l, ep)
+ {
+ if (!ep->prepare_ec) continue;
+
+ // It is not hwc_usable if attached buffer is not valid.
+ buffer = e_pixmap_resource_get(ep->prepare_ec->pixmap);
+ if (!buffer) return EINA_FALSE;
+
+ if (e_plane_is_fb_target(ep))
+ {
+ // It is not hwc_usable if the geometry of the prepare_ec at the ep_fb is not proper.
+ e_pixmap_size_get(ep->prepare_ec->pixmap, &bw, &bh);
+
+ // if client and zone's geometry is not match with, or
+ // if plane with reserved_memory(esp. fb target) has assigned smaller buffer,
+ // won't support hwc properly, than let's composite
+ if (ep->reserved_memory &&
+ ((bw != zone->w) || (bh != zone->h) ||
+ (ep->prepare_ec->x != zone->x) || (ep->prepare_ec->y != zone->y) ||
+ (ep->prepare_ec->w != zone->w) || (ep->prepare_ec->h != zone->h)))
+ {
+ DBG("Cannot use HWC if geometry is not 1 on 1 match with reserved_memory");
+ return EINA_FALSE;
+ }
+ }
+
+ all_null = EINA_FALSE;
+ break;
+ }
+
+ // It is not hwc_usable if the all prepare_ec in every plane are null
+ if (all_null) return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_hwc_planes_can_hwcompose(E_Output *eout)
+{
+ const Eina_List *ep_l = NULL, *l;
+ E_Plane *ep = NULL, *ep_fb = NULL;
+
+ ep_l = e_output_planes_get(eout);
+ /* check the planes from down to top */
+ EINA_LIST_FOREACH(ep_l, l, ep)
+ {
+ if (e_plane_is_fb_target(ep))
+ {
+ /* can hwcompose if fb_target has a ec. */
+ if (ep->prepare_ec != NULL) return EINA_TRUE;
+ else ep_fb = ep;
+ }
+ else
+ {
+ /* can hwcompose if ep has a ec and zpos is higher than ep_fb */
+ if (ep->prepare_ec != NULL &&
+ ep_fb &&
+ ep->zpos > ep_fb->zpos)
+ return EINA_TRUE;
+ }
+ }
+
+ return EINA_FALSE;
+}
+
+EINTERN void
+e_hwc_planes_begin(E_Hwc *hwc)
+{
+ const Eina_List *ep_l = NULL, *l;
+ E_Output *eout = hwc->output;
+ E_Plane *ep = NULL;
+ E_Hwc_Mode mode = E_HWC_MODE_NONE;
+ Eina_Bool set = EINA_FALSE;
+
+ if (e_comp->nocomp_override > 0) return;
+
+ if (_e_hwc_planes_can_hwcompose(eout))
+ {
+ ep_l = e_output_planes_get(eout);
+
+ /* set the prepare_ec to the e_plane */
+ /* check the planes from top to down */
+ EINA_LIST_REVERSE_FOREACH(ep_l, l , ep)
+ {
+ if (!ep->prepare_ec) continue;
+
+ set = e_plane_ec_set(ep, ep->prepare_ec);
+ if (!set) break;
+
+ if (e_plane_is_fb_target(ep))
+ {
+ ELOGF("HWC-PLNS", "is set on fb_target( %d)", ep->prepare_ec->pixmap, ep->prepare_ec, ep->zpos);
+ mode = E_HWC_MODE_FULL;
+
+ // fb target is occupied by a client surface, means compositor disabled
+ ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
+ }
+ else
+ {
+ ELOGF("HWC-PLNS", "is set on %d", ep->prepare_ec->pixmap, ep->prepare_ec, ep->zpos);
+ mode = E_HWC_MODE_HYBRID;
+ }
+ }
+
+ if (mode == E_HWC_MODE_NONE)
+ ELOGF("HWC-PLNS", " Begin is not available yet ...", NULL, NULL);
+ else
+ ELOGF("HWC-PLNS", " Begin ...", NULL, NULL);
+ }
+
+ hwc->hwc_mode = mode;
+}
+
+static E_Hwc_Mode
+_e_hwc_mode_get(E_Hwc *hwc)
+{
+ const Eina_List *ll = NULL, *l;
+ E_Output *output = hwc->output;
+ E_Plane *plane = NULL;
+
+ /* check the planes from down to top */
+ EINA_LIST_FOREACH_SAFE(output->planes, l, ll, plane)
+ {
+ if (!plane->ec) continue;
+ if (e_plane_is_fb_target(plane)) return E_HWC_MODE_FULL;
+
+ return E_HWC_MODE_HYBRID;
+ }
+
+ return E_HWC_MODE_NONE;
+}
+
+EINTERN void
+e_hwc_planes_multi_plane_set(E_Hwc *hwc, Eina_Bool set)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+ e_hwc_planes_end(hwc, __FUNCTION__);
+ hwc->hwc_use_multi_plane = set;
+
+ ELOGF("HWC-PLNS", "e_hwc_planes_multi_plane_set : %d", NULL, NULL, set);
+}
+
+EINTERN Eina_Bool
+e_hwc_planes_multi_plane_get(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+ return hwc->hwc_use_multi_plane;
+}
+
+EINTERN void
+e_hwc_planes_end(E_Hwc *hwc, const char *location)
+{
+ E_Hwc_Mode new_mode = E_HWC_MODE_NONE;
+
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+ /* clean the reserved planes(clean the candidate ecs) */
+ _e_hwc_planes_reserved_clean(hwc);
+
+ if (!hwc->hwc_mode) return;
+
+ /* set null to the e_planes */
+ _e_hwc_planes_cancel(hwc);
+
+ /* check the current mode */
+ new_mode = _e_hwc_mode_get(hwc);
+
+ if (hwc->hwc_mode == E_HWC_MODE_FULL &&
+ new_mode != E_HWC_MODE_FULL)
+ ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
+
+ hwc->hwc_mode = new_mode;
+
+ ELOGF("HWC-PLNS", " End... at %s.", NULL, NULL, location);
+}
--- /dev/null
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_HWC_PLANES_H
+#define E_HWC_PLANES_H
+
+/* used by e_hwc */
+EINTERN Eina_Bool e_hwc_planes_init(void);
+EINTERN void e_hwc_planes_deinit(void);
+
+EINTERN Eina_Bool e_hwc_planes_usable(E_Hwc *hwc);
+EINTERN void e_hwc_planes_begin(E_Hwc *hwc);
+EINTERN void e_hwc_planes_end(E_Hwc *hwc, const char *location);
+EINTERN void e_hwc_planes_changed(E_Hwc *hwc);
+
+EINTERN void e_hwc_planes_multi_plane_set(E_Hwc *hwc, Eina_Bool set);
+EINTERN Eina_Bool e_hwc_planes_multi_plane_get(E_Hwc *hwc);
+
+#endif
+#endif
}
static E_Hwc_Window_Target *
-_e_hwc_window_target_new(E_Output_Hwc *output_hwc)
+_e_hwc_window_target_new(E_Hwc *hwc)
{
const char *name = NULL;
E_Hwc_Window_Target *target_hwc_window = NULL;
((E_Hwc_Window *)target_hwc_window)->is_target = EINA_TRUE;
((E_Hwc_Window *)target_hwc_window)->state = E_HWC_WINDOW_STATE_DEVICE;
- ((E_Hwc_Window *)target_hwc_window)->output_hwc = output_hwc;
+ ((E_Hwc_Window *)target_hwc_window)->hwc = hwc;
target_hwc_window->ee = e_comp->ee;
target_hwc_window->evas = ecore_evas_get(target_hwc_window->ee);
_e_hwc_window_target_window_get(E_Hwc_Window *hwc_window)
{
E_Hwc_Window_Target *target_hwc_window;
- E_Output_Hwc *output_hwc;
+ E_Hwc *hwc;
- output_hwc = hwc_window->output_hwc;
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, NULL);
+ hwc = hwc_window->hwc;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
- target_hwc_window = output_hwc->target_hwc_window;
+ target_hwc_window = hwc->target_hwc_window;
EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, NULL);
return target_hwc_window;
/* If an e_client belongs to the e_output managed by hwc_plane policy,
* there's no need to deal with hwc_windows. */
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
return;
- hwc_window = e_hwc_window_new(output->output_hwc, ec, E_HWC_WINDOW_STATE_NONE);
+ hwc_window = e_hwc_window_new(output->hwc, ec, E_HWC_WINDOW_STATE_NONE);
EINA_SAFETY_ON_NULL_RETURN(hwc_window);
/* set the hwc window to the e client */
/* If an e_client belongs to the e_output managed by hwc_plane policy,
* there's no need to deal with hwc_windows. */
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
return;
if (!ec->hwc_window) return;
/* If an e_client belongs to the e_output managed by hwc_plane policy,
* there's no need to deal with hwc_windows. */
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
return ECORE_CALLBACK_PASS_ON;
if (ec->hwc_window)
{
/* we manage the video window in the video module */
if (e_hwc_window_is_video(ec->hwc_window)) goto end;
- if (ec->hwc_window->output_hwc == output->output_hwc) goto end;
+ if (ec->hwc_window->hwc == output->hwc) goto end;
e_hwc_window_free(ec->hwc_window);
ec->hwc_window = NULL;
}
- hwc_window = e_hwc_window_new(output->output_hwc, ec, E_HWC_WINDOW_STATE_NONE);
+ hwc_window = e_hwc_window_new(output->hwc, ec, E_HWC_WINDOW_STATE_NONE);
EINA_SAFETY_ON_NULL_GOTO(hwc_window, end);
/* set the hwc window to the e client */
static Eina_Bool
_e_hwc_window_cursor_surface_refresh(E_Hwc_Window *hwc_window, E_Pointer *pointer)
{
- E_Output_Hwc *output_hwc = NULL;
+ E_Hwc *hwc = NULL;
E_Output *output = NULL;
int w, h, tw, th;
int tsurface_w, tsurface_h;
ec = hwc_window->ec;
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
- output_hwc = hwc_window->output_hwc;
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
+ hwc = hwc_window->hwc;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
- output = output_hwc->output;
+ output = hwc->output;
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
buffer = ec->comp_data->buffer_ref.buffer;
static Eina_Bool
_e_hwc_window_info_set(E_Hwc_Window *hwc_window, tbm_surface_h tsurface)
{
- E_Output_Hwc *output_hwc = hwc_window->output_hwc;
- E_Output *output = output_hwc->output;
+ E_Hwc *hwc = hwc_window->hwc;
+ E_Output *output = hwc->output;
E_Client *ec = hwc_window->ec;
tbm_surface_info_s surf_info;
int size_w, size_h, src_x, src_y, src_w, src_h;
{
E_Client *ec;
int transform;
- E_Output_Hwc *output_hwc = hwc_window->output_hwc;
- E_Output *output = output_hwc->output;
+ E_Hwc *hwc = hwc_window->hwc;
+ E_Output *output = hwc->output;
/* do not check the transformation of the video window */
if (e_hwc_window_is_video(hwc_window)) return EINA_TRUE;
#endif
EINTERN Eina_Bool
-e_hwc_window_init(E_Output_Hwc *output_hwc)
+e_hwc_window_init(E_Hwc *hwc)
{
E_Hwc_Window_Target *target_hwc_window;
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
- if (e_output_hwc_policy_get(output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(hwc) == E_HWC_POLICY_PLANES)
return EINA_FALSE;
client_hook_new = e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT,
return EINA_FALSE;
}
- target_hwc_window = _e_hwc_window_target_new(output_hwc);
+ target_hwc_window = _e_hwc_window_target_new(hwc);
EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
- /* set the target_window to the output_hwc */
- output_hwc->target_hwc_window = target_hwc_window;
+ /* set the target_window to the hwc */
+ hwc->target_hwc_window = target_hwc_window;
- output_hwc->hwc_windows = eina_list_append(output_hwc->hwc_windows, target_hwc_window);
+ hwc->hwc_windows = eina_list_append(hwc->hwc_windows, target_hwc_window);
return EINA_TRUE;
}
// TODO:
EINTERN void
-e_hwc_window_deinit(E_Output_Hwc *output_hwc)
+e_hwc_window_deinit(E_Hwc *hwc)
{
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
// TODO:
}
EINTERN E_Hwc_Window *
-e_hwc_window_new(E_Output_Hwc *output_hwc, E_Client *ec, E_Hwc_Window_State state)
+e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state)
{
E_Hwc_Window *hwc_window = NULL;
tdm_output *toutput;
tdm_error error;
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc->output, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->output, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
- toutput = output_hwc->output->toutput;
+ toutput = hwc->output->toutput;
EINA_SAFETY_ON_NULL_RETURN_VAL(toutput, EINA_FALSE);
hwc_window = E_NEW(E_Hwc_Window, 1);
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, NULL);
- hwc_window->output_hwc = output_hwc;
+ hwc_window->hwc = hwc;
hwc_window->ec = ec;
hwc_window->state = state;
hwc_window->need_change_buffer_transform = EINA_TRUE;
if (state == E_HWC_WINDOW_STATE_VIDEO)
hwc_window->is_video = EINA_TRUE;
- output_hwc->hwc_windows = eina_list_append(output_hwc->hwc_windows, hwc_window);
+ hwc->hwc_windows = eina_list_append(hwc->hwc_windows, hwc_window);
ELOGF("HWC-WINS", "ehw:%p is created on eout:%p, zone_id:%d",
hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
- hwc_window, output_hwc->output, ec->zone->id);
+ hwc_window, hwc->output, ec->zone->id);
return hwc_window;
}
EINTERN void
e_hwc_window_free(E_Hwc_Window *hwc_window)
{
- E_Output_Hwc *output_hwc = NULL;
+ E_Hwc *hwc = NULL;
E_Output *output = NULL;
tdm_output *toutput = NULL;
EINA_SAFETY_ON_NULL_RETURN(hwc_window);
- EINA_SAFETY_ON_NULL_RETURN(hwc_window->output_hwc);
+ EINA_SAFETY_ON_NULL_RETURN(hwc_window->hwc);
- output_hwc = hwc_window->output_hwc;
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
+ hwc = hwc_window->hwc;
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
- output = output_hwc->output;
- EINA_SAFETY_ON_NULL_RETURN(output_hwc->output);
+ output = hwc->output;
+ EINA_SAFETY_ON_NULL_RETURN(hwc->output);
toutput = output->toutput;
EINA_SAFETY_ON_NULL_RETURN(toutput);
{
ELOGF("HWC-WINS", "ehw:%p is destroyed on eout:%p. displaying surface.",
hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
- hwc_window, output_hwc->output);
+ hwc_window, hwc->output);
/* mark as deleted and delete when commit_data will be released */
hwc_window->is_deleted = EINA_TRUE;
else
ELOGF("HWC-WINS", "ehw:%p is destroyed on eout:%p",
hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
- hwc_window, output_hwc->output);
+ hwc_window, hwc->output);
if (hwc_window->thwc_window)
tdm_output_hwc_destroy_window(toutput, hwc_window->thwc_window);
- output_hwc->hwc_windows = eina_list_remove(output_hwc->hwc_windows, hwc_window);
+ hwc->hwc_windows = eina_list_remove(hwc->hwc_windows, hwc_window);
free(hwc_window);
}
e_hwc_window_target_buffer_fetch(E_Hwc_Window_Target *target_hwc_window)
{
E_Output *output;
- E_Output_Hwc *output_hwc;
+ E_Hwc *hwc;
E_Hwc_Window *hwc_window, *hw;
tbm_surface_h tsurface;
tdm_hwc_region fb_damage;
hwc_window->tsurface = tsurface;
- output_hwc = hwc_window->output_hwc;
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
+ hwc = hwc_window->hwc;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
- output = output_hwc->output;
+ output = hwc->output;
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
/* the damage isn't supported by hwc extension yet */
Eina_List *ee_rendered_hw_list = NULL, *new_list = NULL;
E_Hwc_Window *hw1, *hw2;
const Eina_List *l, *ll;
- E_Output_Hwc *output_hwc;
+ E_Hwc *hwc;
tbm_surface_h target_tsurface;
- output_hwc = target_window->hwc_window.output_hwc;
+ hwc = target_window->hwc_window.hwc;
target_tsurface = target_window->hwc_window.tsurface;
tbm_surface_internal_get_user_data(target_tsurface, ee_rendered_hw_list_key, (void**)&ee_rendered_hw_list);
/* refresh list of composited e_thwc_windows according to existed ones */
EINA_LIST_FOREACH(ee_rendered_hw_list, l, hw1)
- EINA_LIST_FOREACH(output_hwc->hwc_windows, ll, hw2)
+ EINA_LIST_FOREACH(hwc->hwc_windows, ll, hw2)
if (hw1 == hw2) new_list = eina_list_append(new_list, hw1);
return new_list;
E_Client *ec = NULL;
int transform;
E_Output *output = NULL;
- E_Output_Hwc *output_hwc = NULL;
+ E_Hwc *hwc = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
* on the fb_target and a hw overlay owned by it gets free? */
wayland_tbm_server_client_queue_deactivate(cqueue);
- output_hwc = hwc_window->output_hwc;
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
+ hwc = hwc_window->hwc;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
- output = output_hwc->output;
+ output = hwc->output;
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
transform = e_comp_wl_output_buffer_transform_get(ec);
struct _E_Hwc_Window
{
E_Client *ec;
- E_Output_Hwc *output_hwc;
+ E_Hwc *hwc;
tdm_hwc_window *thwc_window;
int zpos;
Eina_Bool is_target;
tbm_surface_h tsurface;
};
-EINTERN Eina_Bool e_hwc_window_init(E_Output_Hwc *output_hwc);
-EINTERN void e_hwc_window_deinit(E_Output_Hwc *output_hwc); // TODO:
+EINTERN Eina_Bool e_hwc_window_init(E_Hwc *hwc);
+EINTERN void e_hwc_window_deinit(E_Hwc *hwc); // TODO:
-EINTERN E_Hwc_Window *e_hwc_window_new(E_Output_Hwc *output_hwc, E_Client *ec, E_Hwc_Window_State state);
+EINTERN E_Hwc_Window *e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state);
EINTERN void e_hwc_window_free(E_Hwc_Window *hwc_window);
EINTERN Eina_Bool e_hwc_window_zpos_set(E_Hwc_Window *hwc_window, int zpos);
--- /dev/null
+#include "e.h"
+#include "services/e_service_quickpanel.h"
+
+#define DBG_EVALUATE 1
+
+#define ZPOS_NONE -999
+
+static Eina_Bool _e_hwc_windows_pp_output_data_commit(E_Hwc *hwc, E_Hwc_Window_Commit_Data *data);
+static Eina_Bool _e_hwc_windows_pp_window_commit(E_Hwc *hwc, E_Hwc_Window *hwc_window);
+
+// if ec has invalid buffer or scaled( transformed ) or forced composite(never_hwc)
+static Eina_Bool
+_e_hwc_windows_device_state_check(E_Client *ec)
+{
+ E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
+ E_Output *eout;
+ int minw = 0, minh = 0;
+ int transform;
+
+ if ((!cdata) || (!cdata->buffer_ref.buffer))
+ {
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(null cdata or buffer)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ return EINA_FALSE;
+ }
+
+ if ((cdata->width_from_buffer != cdata->width_from_viewport) ||
+ (cdata->height_from_buffer != cdata->height_from_viewport))
+ {
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(size_from_viewport)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ return EINA_FALSE;
+ }
+
+ if (cdata->never_hwc)
+ {
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(never_hwc)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ return EINA_FALSE;
+ }
+
+ if (e_client_transform_core_enable_get(ec))
+ {
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(transfrom_core)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ return EINA_FALSE;
+ }
+
+ switch (cdata->buffer_ref.buffer->type)
+ {
+ case E_COMP_WL_BUFFER_TYPE_NATIVE:
+ break;
+ case E_COMP_WL_BUFFER_TYPE_TBM:
+ if (cdata->buffer_ref.buffer->resource)
+ break;
+ case E_COMP_WL_BUFFER_TYPE_SHM:
+ if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
+ break;
+ default:
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(buffer_type)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ return EINA_FALSE;
+ }
+
+ eout = e_output_find(ec->zone->output_id);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(eout, EINA_FALSE);
+
+ tdm_output_get_available_size(eout->toutput, &minw, &minh, NULL, NULL, NULL);
+
+ if ((minw > 0) && (minw > cdata->buffer_ref.buffer->w))
+ {
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(minw:%d > buffer->w:%d)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title, minw, cdata->buffer_ref.buffer->w);
+ return EINA_FALSE;
+ }
+
+ if ((minh > 0) && (minh > cdata->buffer_ref.buffer->h))
+ {
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(minh:%d > buffer->h:%d)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title, minh, cdata->buffer_ref.buffer->h);
+ return EINA_FALSE;
+ }
+
+ transform = e_comp_wl_output_buffer_transform_get(ec);
+
+ /* If a client doesn't watch the ignore_output_transform events, we can't show
+ * a client buffer to HW overlay directly when the buffer transform is not same
+ * with output transform. If a client watch the ignore_output_transform events,
+ * we can control client's buffer transform. In this case, we don't need to
+ * check client's buffer transform here.
+ */
+ if (!e_comp_screen_rotation_ignore_output_transform_watch(ec))
+ {
+ if ((eout->config.rotation / 90) != transform)
+ {
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(no igrore_transfrom)",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ return EINA_FALSE;
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+static E_Hwc_Mode
+_e_hwc_windows_hwc_mode_get(E_Hwc *hwc)
+{
+ Eina_List *l;
+ E_Hwc_Window *hwc_window;
+ E_Hwc_Mode hwc_mode = E_HWC_MODE_NONE;
+ int num_visible = 0;
+ int num_visible_client = 0;
+
+ EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
+ {
+ if (e_hwc_window_is_target(hwc_window)) continue;
+
+ if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) continue;
+ if (hwc_window->state == E_HWC_WINDOW_STATE_VIDEO) continue;
+
+ if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT)
+ num_visible_client++;
+
+ num_visible++;
+ }
+
+ if (!num_visible)
+ hwc_mode = E_HWC_MODE_NONE;
+ else if (num_visible_client > 0)
+ hwc_mode = E_HWC_MODE_HYBRID;
+ else
+ hwc_mode = E_HWC_MODE_FULL;
+
+ return hwc_mode;
+}
+
+static int
+_e_hwc_windows_sort_cb(const void *d1, const void *d2)
+{
+ E_Hwc_Window *hwc_window_1 = (E_Hwc_Window *)d1;
+ E_Hwc_Window *hwc_window_2 = (E_Hwc_Window *)d2;
+
+ if (!hwc_window_1) return(-1);
+ if (!hwc_window_2) return(1);
+
+ return (hwc_window_2->zpos - hwc_window_1->zpos);
+}
+
+static unsigned int
+_e_hwc_windows_aligned_width_get(tbm_surface_h tsurface)
+{
+ unsigned int aligned_width = 0;
+ tbm_surface_info_s surf_info;
+
+ tbm_surface_get_info(tsurface, &surf_info);
+
+ switch (surf_info.format)
+ {
+ case TBM_FORMAT_YUV420:
+ case TBM_FORMAT_YVU420:
+ case TBM_FORMAT_YUV422:
+ case TBM_FORMAT_YVU422:
+ case TBM_FORMAT_NV12:
+ case TBM_FORMAT_NV21:
+ aligned_width = surf_info.planes[0].stride;
+ break;
+ case TBM_FORMAT_YUYV:
+ case TBM_FORMAT_UYVY:
+ aligned_width = surf_info.planes[0].stride >> 1;
+ break;
+ case TBM_FORMAT_ARGB8888:
+ case TBM_FORMAT_XRGB8888:
+ aligned_width = surf_info.planes[0].stride >> 2;
+ break;
+ default:
+ ERR("not supported format: %x", surf_info.format);
+ }
+
+ return aligned_width;
+}
+
+static void
+_e_hwc_windows_commit_handler(tdm_output *toutput, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data)
+{
+ const Eina_List *l;
+ E_Hwc_Window *hwc_window;
+ E_Hwc *hwc = (E_Hwc *)user_data;
+
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+ if (hwc->pp_tsurface && !hwc->output->zoom_set)
+ {
+ tbm_surface_internal_unref(hwc->pp_tsurface);
+ hwc->pp_tsurface = NULL;
+ }
+
+ ELOGF("HWC-WINS", "!!!!!!!! Output Commit Handler !!!!!!!!", NULL, NULL);
+
+ EINA_LIST_FOREACH(e_hwc_windows_get(hwc), l, hwc_window)
+ {
+ if (e_hwc_window_is_video(hwc_window))
+ {
+ ELOGF("HWC-WINS", "!!!!!!!! Output Commit Handler (VIDEO)!!!!!!!!", NULL, NULL);
+ e_comp_wl_video_hwc_window_commit_data_release(hwc_window, sequence, tv_sec, tv_usec);
+ }
+ if (!e_hwc_window_commit_data_release(hwc_window)) continue;
+ }
+
+ /* 'wait_commit' is mechanism to make 'fetch and commit' no more than one time per a frame;
+ * a 'page flip' happened so it's time to allow to make 'fetch and commit' for the e_output */
+ hwc->wait_commit = EINA_FALSE;
+}
+
+static Eina_Bool
+_e_hwc_windows_prepare_commit(E_Output *output, E_Hwc_Window *hwc_window)
+{
+ if (!e_hwc_window_commit_data_aquire(hwc_window))
+ return EINA_FALSE;
+
+ /* send frame event enlightenment dosen't send frame evnet in nocomp */
+ if (hwc_window->ec)
+ e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_hwc_windows_offscreen_commit(E_Output *output, E_Hwc_Window *hwc_window)
+{
+ if (!e_hwc_window_commit_data_aquire(hwc_window))
+ return EINA_FALSE;
+
+ /* send frame event enlightenment doesn't send frame event in nocomp */
+ if (hwc_window->ec)
+ e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
+
+ e_hwc_window_commit_data_release(hwc_window);
+
+ return EINA_TRUE;
+}
+
+static E_Hwc_Window *
+_e_hwc_windows_pp_window_get(E_Hwc *hwc, tbm_surface_h tsurface)
+{
+ Eina_List *l;
+ E_Hwc_Window *hwc_window = NULL;
+
+ EINA_LIST_FOREACH(hwc->pp_hwc_window_list, l, hwc_window)
+ {
+ if (!hwc_window) continue;
+ if (!hwc_window->commit_data) continue;
+
+ if (hwc_window->commit_data->tsurface == tsurface)
+ return hwc_window;
+ }
+
+ return NULL;
+}
+
+static void
+_e_hwc_windows_pp_pending_data_remove(E_Hwc *hwc)
+{
+ E_Hwc_Window_Commit_Data *data = NULL;
+ Eina_List *l = NULL, *ll = NULL;
+
+ if (eina_list_count(hwc->pending_pp_commit_data_list) != 0)
+ {
+ EINA_LIST_FOREACH_SAFE(hwc->pending_pp_commit_data_list, l, ll, data)
+ {
+ if (!data) continue;
+ hwc->pending_pp_commit_data_list = eina_list_remove_list(hwc->pending_pp_commit_data_list, l);
+ tbm_surface_queue_release(hwc->pp_tqueue, data->tsurface);
+ tbm_surface_internal_unref(data->tsurface);
+ E_FREE(data);
+ }
+ }
+ eina_list_free(hwc->pending_pp_commit_data_list);
+ hwc->pending_pp_commit_data_list = NULL;
+
+ if (eina_list_count(hwc->pending_pp_hwc_window_list) != 0)
+ {
+ E_Hwc_Window *hwc_window;
+ EINA_LIST_FOREACH_SAFE(hwc->pending_pp_hwc_window_list, l, ll, hwc_window)
+ {
+ if (!hwc_window) continue;
+ hwc->pending_pp_hwc_window_list = eina_list_remove_list(hwc->pending_pp_hwc_window_list, l);
+
+ if (hwc_window->ec) e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
+ e_hwc_window_commit_data_release(hwc_window);
+ }
+ }
+ eina_list_free(hwc->pending_pp_hwc_window_list);
+ hwc->pending_pp_hwc_window_list = NULL;
+}
+
+static void
+_e_hwc_windows_pp_output_commit_handler(tdm_output *toutput, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data)
+{
+ E_Hwc *hwc;
+ E_Hwc_Window_Commit_Data *data = NULL;
+ E_Output *output = NULL;
+ const Eina_List *l;
+ E_Hwc_Window *window;
+
+ EINA_SAFETY_ON_NULL_RETURN(user_data);
+
+ hwc = user_data;
+
+ hwc->pp_output_commit = EINA_FALSE;
+
+ EINA_LIST_FOREACH(e_hwc_windows_get(hwc), l, window)
+ {
+ if (window->commit_data && !window->commit_data->tsurface)
+ e_hwc_window_commit_data_release(window);
+ }
+
+ /* layer already resetted */
+ if (hwc->pp_output_commit_data)
+ {
+ data = hwc->pp_output_commit_data;
+ hwc->pp_output_commit_data = NULL;
+
+ /* if pp_set is false, do not deal with pending list */
+ if (!hwc->pp_set)
+ {
+ if (hwc->pp_tsurface)
+ tbm_surface_internal_unref(hwc->pp_tsurface);
+
+ hwc->pp_tsurface = data->tsurface;
+ hwc->wait_commit = EINA_FALSE;
+
+ E_FREE(data);
+
+ return;
+ }
+
+ if (hwc->pp_tqueue && hwc->pp_tsurface)
+ {
+ /* release and unref the current pp surface on the plane */
+ tbm_surface_queue_release(hwc->pp_tqueue, hwc->pp_tsurface);
+ tbm_surface_internal_unref(hwc->pp_tsurface);
+ }
+
+ /* set the new pp surface to the plane */
+ hwc->pp_tsurface = data->tsurface;
+
+ E_FREE(data);
+ }
+
+ ELOGF("HWC-WINS", "PP Output Commit Handler Hwc(%p)", NULL, NULL, hwc);
+
+ output = hwc->output;
+ if (e_output_dpms_get(output))
+ {
+ _e_hwc_windows_pp_pending_data_remove(hwc);
+ return;
+ }
+
+ /* deal with the pending layer commit */
+ if (eina_list_count(hwc->pending_pp_commit_data_list) != 0)
+ {
+ data = eina_list_nth(hwc->pending_pp_commit_data_list, 0);
+ if (data)
+ {
+ hwc->pending_pp_commit_data_list = eina_list_remove(hwc->pending_pp_commit_data_list, data);
+
+ ELOGF("HWC-WINS", "PP Output Commit Handler start pending commit data(%p) tsurface(%p)", NULL, NULL, data, data->tsurface);
+
+ if (!_e_hwc_windows_pp_output_data_commit(hwc, data))
+ {
+ ERR("fail to _e_hwc_windows_pp_output_data_commit");
+ return;
+ }
+ }
+ }
+
+ /* deal with the pending pp commit */
+ if (eina_list_count(hwc->pending_pp_hwc_window_list) != 0)
+ {
+ E_Hwc_Window *hwc_window;
+
+ hwc_window = eina_list_nth(hwc->pending_pp_hwc_window_list, 0);
+ if (hwc_window)
+ {
+ if (!tbm_surface_queue_can_dequeue(hwc->pp_tqueue, 0))
+ return;
+
+ hwc->pending_pp_hwc_window_list = eina_list_remove(hwc->pending_pp_hwc_window_list, hwc_window);
+
+ if (data)
+ ELOGF("HWC-WINS", "PP Layer Commit Handler start pending pp data(%p) tsurface(%p)", NULL, NULL, data, data->tsurface);
+ else
+ ELOGF("HWC-WINS", "PP Layer Commit Handler start pending pp data(%p) tsurface(%p)", NULL, NULL, NULL, NULL);
+
+ if (!_e_hwc_windows_pp_window_commit(hwc, hwc_window))
+ {
+ ERR("fail _e_hwc_windows_pp_data_commit");
+ e_hwc_window_commit_data_release(hwc_window);
+ return;
+ }
+ }
+ }
+}
+
+static Eina_Bool
+_e_hwc_windows_pp_output_data_commit(E_Hwc *hwc, E_Hwc_Window_Commit_Data *data)
+{
+ E_Output *output = NULL;
+ tdm_layer *toutput = NULL;
+ tdm_error terror;
+ tdm_hwc_region fb_damage;
+
+ /* the damage isn't supported by hwc extension yet */
+ memset(&fb_damage, 0, sizeof(fb_damage));
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
+
+ output = hwc->output;
+ toutput = output->toutput;
+
+ if (e_output_dpms_get(output))
+ {
+ _e_hwc_windows_pp_pending_data_remove(hwc);
+ goto fail;
+ }
+
+ /* no need to pass composited_wnds list because smooth transition isn't
+ * used is this case */
+ terror = tdm_output_hwc_set_client_target_buffer(toutput, data->tsurface, fb_damage);
+ if (terror != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_output_hwc_set_client_target_buffer");
+ goto fail;
+ }
+
+ terror = tdm_output_commit(toutput, 0, _e_hwc_windows_pp_output_commit_handler, hwc);
+
+ if (terror != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_output_commit hwc:%p", hwc);
+ goto fail;
+ }
+
+ hwc->pp_output_commit = EINA_TRUE;
+ hwc->pp_output_commit_data = data;
+
+ return EINA_TRUE;
+
+fail:
+ tbm_surface_internal_unref(data->tsurface);
+ tbm_surface_queue_release(hwc->pp_tqueue, data->tsurface);
+ E_FREE(data);
+
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_e_hwc_windows_pp_output_commit(E_Hwc *hwc, tbm_surface_h tsurface)
+{
+ tbm_surface_h pp_tsurface = NULL;
+ tbm_error_e tbm_err;
+ E_Hwc_Window_Commit_Data *data = NULL;
+
+ ELOGF("HWC-WINS", "PP Layer Commit hwc(%p) pp_tsurface(%p)", NULL, NULL, hwc, tsurface);
+
+ tbm_err = tbm_surface_queue_enqueue(hwc->pp_tqueue, tsurface);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ ERR("fail tbm_surface_queue_enqueue");
+ goto fail;
+ }
+
+ tbm_err = tbm_surface_queue_acquire(hwc->pp_tqueue, &pp_tsurface);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ ERR("fail tbm_surface_queue_acquire");
+ goto fail;
+ }
+
+ data = E_NEW(E_Hwc_Window_Commit_Data, 1);
+ if (!data) goto fail;
+ data->tsurface = pp_tsurface;
+ tbm_surface_internal_ref(data->tsurface);
+
+ if (hwc->pp_output_commit)
+ {
+ hwc->pending_pp_commit_data_list = eina_list_append(hwc->pending_pp_commit_data_list, data);
+ return EINA_TRUE;
+ }
+
+ if (!_e_hwc_windows_pp_output_data_commit(hwc, data))
+ {
+ ERR("fail to _e_hwc_windows_pp_output_data_commit");
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+
+fail:
+ tbm_surface_queue_release(hwc->pp_tqueue, tsurface);
+ if (pp_tsurface && pp_tsurface != tsurface)
+ tbm_surface_queue_release(hwc->pp_tqueue, pp_tsurface);
+
+ return EINA_FALSE;
+}
+
+static void
+_e_hwc_windows_pp_commit_handler(tdm_pp *pp, tbm_surface_h tsurface_src, tbm_surface_h tsurface_dst, void *user_data)
+{
+ E_Output *output = NULL;
+ E_Hwc *hwc = NULL;
+ E_Hwc_Window *hwc_window = NULL;
+
+ hwc = (E_Hwc *)user_data;
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+ hwc_window = _e_hwc_windows_pp_window_get(hwc, tsurface_src);
+ EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+
+ hwc->pp_hwc_window_list = eina_list_remove(hwc->pp_hwc_window_list, hwc_window);
+
+ if (hwc_window->ec) e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
+ e_hwc_window_commit_data_release(hwc_window);
+
+ if (eina_list_count(hwc->pending_pp_hwc_window_list) == 0)
+ {
+ hwc->wait_commit = EINA_FALSE;
+ hwc->pp_commit = EINA_FALSE;
+ }
+
+ ELOGF("HWC-WINS", "PP Commit Handler hwc(%p) tsurface src(%p) dst(%p)",
+ NULL, NULL, hwc, tsurface_src, tsurface_dst);
+
+ /* if pp_set is false, skip the commit */
+ if (!hwc->pp_set)
+ {
+ if (hwc->tpp)
+ {
+ tdm_pp_destroy(hwc->tpp);
+ hwc->tpp = NULL;
+ }
+ goto done;
+ }
+
+ output = hwc->output;
+ if (e_output_dpms_get(output))
+ {
+ _e_hwc_windows_pp_pending_data_remove(hwc);
+ tbm_surface_queue_release(hwc->pp_tqueue, tsurface_dst);
+
+ goto done;
+ }
+
+ if (!_e_hwc_windows_pp_output_commit(hwc, tsurface_dst))
+ ERR("fail to _e_hwc_windows_pp_output_commit");
+
+done:
+ tbm_surface_internal_unref(tsurface_src);
+ tbm_surface_internal_unref(tsurface_dst);
+}
+
+static Eina_Bool
+_e_hwc_pp_windows_info_set(E_Hwc *hwc, E_Hwc_Window *hwc_window,
+ tbm_surface_h dst_tsurface)
+{
+ tdm_info_pp pp_info;
+ tdm_error ret = TDM_ERROR_NONE;
+ unsigned int aligned_width_src = 0, aligned_width_dst = 0;
+ tbm_surface_info_s surf_info_src, surf_info_dst;
+ tbm_surface_h src_tsurface = hwc_window->commit_data->tsurface;
+
+ /* when the pp_set_info is true, change the pp set_info */
+ if (!hwc->pp_set_info) return EINA_TRUE;
+ hwc->pp_set_info = EINA_FALSE;
+
+ tbm_surface_get_info(src_tsurface, &surf_info_src);
+
+ aligned_width_src = _e_hwc_windows_aligned_width_get(src_tsurface);
+ if (aligned_width_src == 0) return EINA_FALSE;
+
+ tbm_surface_get_info(dst_tsurface, &surf_info_dst);
+
+ aligned_width_dst = _e_hwc_windows_aligned_width_get(dst_tsurface);
+ if (aligned_width_dst == 0) return EINA_FALSE;
+
+ pp_info.src_config.size.h = aligned_width_src;
+ pp_info.src_config.size.v = surf_info_src.height;
+ pp_info.src_config.format = surf_info_src.format;
+
+ pp_info.dst_config.size.h = aligned_width_dst;
+ pp_info.dst_config.size.v = surf_info_dst.height;
+ pp_info.dst_config.format = surf_info_dst.format;
+
+ pp_info.transform = TDM_TRANSFORM_NORMAL;
+ pp_info.sync = 0;
+ pp_info.flags = 0;
+
+ pp_info.src_config.pos.x = hwc->pp_rect.x;
+ pp_info.src_config.pos.y = hwc->pp_rect.y;
+ pp_info.src_config.pos.w = hwc->pp_rect.w;
+ pp_info.src_config.pos.h = hwc->pp_rect.h;
+ pp_info.dst_config.pos.x = 0;
+ pp_info.dst_config.pos.y = 0;
+ pp_info.dst_config.pos.w = surf_info_dst.width;
+ pp_info.dst_config.pos.h = surf_info_dst.height;
+
+ ret = tdm_pp_set_info(hwc->tpp, &pp_info);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
+
+ ELOGF("HWC-WINS", "PP Info Hwc(%p) src_rect(%d,%d),(%d,%d), dst_rect(%d,%d),(%d,%d)",
+ NULL, NULL, hwc,
+ pp_info.src_config.pos.x, pp_info.src_config.pos.y, pp_info.src_config.pos.w, pp_info.src_config.pos.h,
+ pp_info.dst_config.pos.x, pp_info.dst_config.pos.y, pp_info.dst_config.pos.w, pp_info.dst_config.pos.h);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_hwc_windows_pp_window_commit(E_Hwc *hwc, E_Hwc_Window *hwc_window)
+{
+ E_Output *output = NULL;
+ tbm_surface_h pp_tsurface = NULL;
+ tbm_error_e tbm_err = TBM_ERROR_NONE;
+ tdm_error terror = TDM_ERROR_NONE;
+ E_Hwc_Window_Commit_Data *commit_data = hwc_window->commit_data;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(commit_data, EINA_FALSE);
+
+ tbm_surface_h tsurface = commit_data->tsurface;
+
+ ELOGF("HWC-WINS", "PP Commit Hwc(%p) tsurface(%p) tqueue(%p) wl_buffer(%p) data(%p)",
+ NULL, NULL, hwc, commit_data->tsurface, hwc->pp_tqueue,
+ commit_data->buffer_ref.buffer ? commit_data->buffer_ref.buffer->resource : NULL, commit_data);
+
+ output = hwc->output;
+ if (e_output_dpms_get(output))
+ {
+ _e_hwc_windows_pp_pending_data_remove(hwc);
+ return EINA_FALSE;
+ }
+
+ tbm_err = tbm_surface_queue_dequeue(hwc->pp_tqueue, &pp_tsurface);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ ERR("fail tbm_surface_queue_dequeue");
+ return EINA_FALSE;
+ }
+
+ if (!_e_hwc_pp_windows_info_set(hwc, hwc_window, pp_tsurface))
+ {
+ ERR("fail _e_hwc_windows_info_set");
+ goto pp_fail;
+ }
+
+ terror = tdm_pp_set_done_handler(hwc->tpp, _e_hwc_windows_pp_commit_handler, hwc);
+ EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, pp_fail);
+
+ tbm_surface_internal_ref(pp_tsurface);
+ tbm_surface_internal_ref(commit_data->tsurface);
+ terror = tdm_pp_attach(hwc->tpp, commit_data->tsurface, pp_tsurface);
+ EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, attach_fail);
+
+ hwc->pp_hwc_window_list = eina_list_append(hwc->pp_hwc_window_list, hwc_window);
+
+ terror = tdm_pp_commit(hwc->tpp);
+ EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, commit_fail);
+
+ hwc->wait_commit = EINA_TRUE;
+ hwc->pp_commit = EINA_TRUE;
+
+ return EINA_TRUE;
+
+commit_fail:
+ hwc->pp_hwc_window_list = eina_list_remove(hwc->pp_hwc_window_list, hwc_window);
+attach_fail:
+ tbm_surface_internal_unref(pp_tsurface);
+ tbm_surface_internal_unref(tsurface);
+pp_fail:
+ tbm_surface_queue_release(hwc->pp_tqueue, pp_tsurface);
+
+ ERR("failed _e_hwc_windows_pp_data_commit");
+
+ return EINA_FALSE;
+}
+
+static E_Hwc_Window *
+_e_hwc_windows_pp_get_hwc_window_for_zoom(E_Hwc *hwc)
+{
+ const Eina_List *hwc_windows, *l;
+ E_Hwc_Window *hwc_window = NULL;
+ E_Hwc_Window *hwc_window_for_zoom = NULL;
+ int num = 0;
+ int w, h;
+
+ e_output_size_get(hwc->output, &w, &h);
+
+ hwc_windows = e_hwc_windows_get(hwc);
+ EINA_LIST_FOREACH(hwc_windows, l, hwc_window)
+ {
+ if (!e_hwc_window_is_on_hw_overlay(hwc_window)) continue;
+
+ hwc_window_for_zoom = hwc_window;
+ num++;
+ }
+
+ if (num != 1) return NULL;
+ if (!hwc_window_for_zoom->tsurface) return NULL;
+ if (tbm_surface_get_width(hwc_window_for_zoom->tsurface) != w ||
+ tbm_surface_get_height(hwc_window_for_zoom->tsurface) != h)
+ return NULL;
+
+ return hwc_window_for_zoom;
+}
+
+static Eina_Bool
+_e_hwc_windows_pp_commit(E_Hwc *hwc)
+{
+ E_Hwc_Window_Commit_Data *commit_data = NULL;
+ E_Hwc_Window *hwc_window = NULL;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->pp_tqueue, EINA_FALSE);
+
+ hwc_window = _e_hwc_windows_pp_get_hwc_window_for_zoom(hwc);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
+
+ commit_data = hwc_window->commit_data;
+ if (!commit_data) return EINA_TRUE;
+ if (!commit_data->tsurface) return EINA_TRUE;
+
+ if (!tbm_surface_queue_can_dequeue(hwc->pp_tqueue, 0))
+ {
+ ELOGF("HWC-WINS", "PP Commit Can Dequeue failed Hwc(%p) tsurface(%p) tqueue(%p) wl_buffer(%p) data(%p)",
+ NULL, NULL, hwc, commit_data->tsurface, hwc->pp_tqueue,
+ commit_data->buffer_ref.buffer ? commit_data->buffer_ref.buffer->resource : NULL, commit_data);
+ hwc->pending_pp_hwc_window_list = eina_list_append(hwc->pending_pp_hwc_window_list, hwc_window);
+
+ hwc->wait_commit = EINA_TRUE;
+
+ return EINA_TRUE;
+ }
+
+ if (eina_list_count(hwc->pending_pp_hwc_window_list) != 0)
+ {
+ ELOGF("HWC-WINS", "PP Commit Pending pp data remained Hwc(%p) tsurface(%p) tqueue(%p) wl_buffer(%p) data(%p)",
+ NULL, NULL, hwc, commit_data->tsurface, hwc->pp_tqueue,
+ commit_data->buffer_ref.buffer ? commit_data->buffer_ref.buffer->resource : NULL, commit_data);
+ hwc->pending_pp_hwc_window_list = eina_list_append(hwc->pending_pp_hwc_window_list, hwc_window);
+
+ hwc->wait_commit = EINA_TRUE;
+
+ return EINA_TRUE;
+ }
+
+ if (!_e_hwc_windows_pp_window_commit(hwc, hwc_window))
+ {
+ ERR("fail _e_hwc_windows_pp_data_commit");
+ e_hwc_window_commit_data_release(hwc_window);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_e_hwc_windows_status_print(E_Hwc *hwc, Eina_Bool with_target)
+{
+ const Eina_List *l;
+ Eina_List *sort_wnds;
+ E_Hwc_Window *hwc_window;
+
+ sort_wnds = eina_list_clone(hwc->hwc_windows);
+ sort_wnds = eina_list_sort(sort_wnds, eina_list_count(sort_wnds), _e_hwc_windows_sort_cb);
+
+ EINA_LIST_FOREACH(sort_wnds, l, hwc_window)
+ {
+ if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) continue;
+
+ if (e_hwc_window_is_target(hwc_window))
+ {
+ if (!with_target) continue;
+
+ ELOGF("HWC-WINS", " ehw:%p ts:%p -- {%25s}, state:%s",
+ NULL, NULL, hwc_window, hwc_window->tsurface, "@TARGET WINDOW@",
+ e_hwc_window_state_string_get(hwc_window->state));
+ continue;
+ }
+
+ ELOGF("HWC-WINS", " ehw:%p ts:%p -- {%25s}, state:%s, zpos:%d, deleted:%s",
+ hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
+ hwc_window, hwc_window->tsurface, hwc_window->ec ? hwc_window->ec->icccm.title : "UNKNOWN",
+ e_hwc_window_state_string_get(hwc_window->state),
+ hwc_window->zpos, hwc_window->is_deleted ? "yes" : "no");
+ }
+
+ eina_list_free(sort_wnds);
+}
+
+static void
+_e_hwc_windows_ouput_commit_dump(E_Hwc *hwc)
+{
+ const Eina_List *l;
+ Eina_List *sort_wnds;
+ E_Hwc_Window *hwc_window;
+ char fname[PATH_MAX];
+ Ecore_Window ec_win;
+ int i = 0;
+
+ sort_wnds = eina_list_clone(hwc->hwc_windows);
+ sort_wnds = eina_list_sort(sort_wnds, eina_list_count(sort_wnds), _e_hwc_windows_sort_cb);
+
+ EINA_LIST_FOREACH(sort_wnds, l, hwc_window)
+ {
+ if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) continue;
+
+ ec_win = e_client_util_win_get(hwc_window->ec);
+
+ if (e_hwc_window_is_target(hwc_window))
+ snprintf(fname, sizeof(fname), "(%d)_output_commit_0x%08x_%s", i++, ec_win, e_hwc_window_state_string_get(hwc_window->state));
+ else
+ snprintf(fname, sizeof(fname), "(%d)_output_commit_0x%08x_%s_%d", i++, ec_win, e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
+
+ tbm_surface_internal_dump_buffer(hwc_window->tsurface, fname);
+ }
+
+ eina_list_free(sort_wnds);
+}
+
+static E_Hwc_Window *
+_e_hwc_windows_window_find_by_twin(E_Hwc *hwc, tdm_hwc_window *hwc_win)
+{
+ Eina_List *l;
+ E_Hwc_Window *hwc_window;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_win, NULL);
+
+ EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
+ {
+ if (hwc_window->thwc_window == hwc_win) return hwc_window;
+ }
+
+ return NULL;
+}
+
+static Eina_Bool
+_e_hwc_windows_compsitions_update(E_Hwc *hwc)
+{
+ const Eina_List *l;
+ E_Hwc_Window *hwc_window;
+
+ EINA_LIST_FOREACH(e_hwc_windows_get(hwc), l, hwc_window)
+ {
+ if (e_hwc_window_is_target(hwc_window)) continue;
+
+ if (!e_hwc_window_compsition_update(hwc_window))
+ {
+ ERR("HWC-WINS: cannot update E_Hwc_Window(%p)", hwc_window);
+ return EINA_FALSE;
+ }
+ }
+
+#if DBG_EVALUATE
+ ELOGF("HWC-WINS", " Request HWC Validation to TDM HWC:", NULL, NULL);
+ _e_hwc_windows_status_print(hwc, EINA_FALSE);
+#endif
+
+ return EINA_TRUE;
+}
+
+static E_Hwc_Window_State
+_e_hwc_windows_window_state_get(tdm_hwc_window_composition composition_type)
+{
+ E_Hwc_Window_State state = E_HWC_WINDOW_STATE_NONE;
+
+ switch (composition_type)
+ {
+ case TDM_COMPOSITION_NONE:
+ state = E_HWC_WINDOW_STATE_NONE;
+ break;
+ case TDM_COMPOSITION_CLIENT:
+ state = E_HWC_WINDOW_STATE_CLIENT;
+ break;
+ case TDM_COMPOSITION_DEVICE:
+ state = E_HWC_WINDOW_STATE_DEVICE;
+ break;
+ case TDM_COMPOSITION_DEVICE_CANDIDATE:
+ state = E_HWC_WINDOW_STATE_DEVICE_CANDIDATE;
+ break;
+ case TDM_COMPOSITION_CURSOR:
+ state = E_HWC_WINDOW_STATE_CURSOR;
+ break;
+ case TDM_COMPOSITION_VIDEO:
+ state = E_HWC_WINDOW_STATE_VIDEO;
+ break;
+ default:
+ state = E_HWC_WINDOW_STATE_NONE;
+ ERR("HWC-WINS: unknown state of hwc_window.");
+ }
+
+ return state;
+}
+
+static Eina_Bool
+_e_hwc_windows_accept(E_Hwc *hwc, uint32_t num_changes)
+{
+ E_Output *output = hwc->output;
+ E_Hwc_Window *hwc_window;
+ E_Hwc_Window_State state;
+ tdm_error terror;
+ tdm_output *toutput = output->toutput;
+ tdm_hwc_window **changed_hwc_window = NULL;
+ tdm_hwc_window_composition *composition_types = NULL;
+ Eina_Bool accept_changes = EINA_TRUE;
+ int i;
+
+ changed_hwc_window = E_NEW(tdm_hwc_window *, num_changes);
+ EINA_SAFETY_ON_NULL_GOTO(changed_hwc_window, fail);
+
+ composition_types = E_NEW(tdm_hwc_window_composition, num_changes);
+ EINA_SAFETY_ON_NULL_GOTO(composition_types, fail);
+
+ terror = tdm_output_hwc_get_changed_composition_types(toutput,
+ &num_changes, changed_hwc_window,
+ composition_types);
+ if (terror != TDM_ERROR_NONE)
+ {
+ ERR("HWC-WINS: failed to get changed composition types");
+ goto fail;
+ }
+
+ ELOGF("HWC-WINS", " Accept Changes NUM : %d", NULL, NULL, num_changes);
+
+ for (i = 0; i < num_changes; ++i)
+ {
+ hwc_window = _e_hwc_windows_window_find_by_twin(hwc, changed_hwc_window[i]);
+ if (!hwc_window)
+ {
+ ERR("HWC-WINS: cannot find the E_Hwc_Window by hwc hwc_window");
+ goto fail;
+ }
+
+ /* accept_changes failed at DEVICE to CLIENT transition */
+ if (hwc_window->prev_state == E_HWC_WINDOW_STATE_DEVICE &&
+ composition_types[i] == TDM_COMPOSITION_CLIENT)
+ {
+ if (!e_hwc_window_is_on_target_window(hwc_window))
+ {
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT;
+ accept_changes = EINA_FALSE;
+
+ ELOGF("HWC-WINS", " E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT is set.(Accept_Changes)",
+ hwc_window->ec ? ec->pixmap : NULL, hwc_window->ec);
+ }
+ }
+
+ /* update the state with the changed compsition */
+ state = _e_hwc_windows_window_state_get(composition_types[i]);
+ e_hwc_window_state_set(hwc_window, state);
+ }
+
+#if DBG_EVALUATE
+ ELOGF("HWC-WINS", " Modified after HWC Validation:", NULL, NULL);
+ _e_hwc_windows_status_print(hwc, EINA_FALSE);
+#endif
+
+ /* re-validate when there is a DEVICE_TO_CLIENT transition */
+ if (!accept_changes) goto fail;
+
+ /* accept changes */
+ terror = tdm_output_hwc_accept_changes(toutput);
+ if (terror != TDM_ERROR_NONE)
+ {
+ ERR("HWC-WINS: failed to accept changes required by the hwc extension");
+ goto fail;
+ }
+
+ free(changed_hwc_window);
+ free(composition_types);
+
+ return EINA_TRUE;
+
+fail:
+ if (changed_hwc_window) free(changed_hwc_window);
+ if (composition_types) free(composition_types);
+
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_e_hwc_windows_validate(E_Hwc *hwc, Eina_List *visible_windows_list, uint32_t *num_changes)
+{
+ E_Output *output = hwc->output;
+ tdm_error terror;
+ tdm_output *toutput = output->toutput;
+ tdm_hwc_window **thwc_windows = NULL;
+ int i, n_thw;
+ E_Hwc_Window *hwc_window;
+ const Eina_List *l;
+
+ n_thw = eina_list_count(visible_windows_list);
+ if (n_thw)
+ {
+ thwc_windows = E_NEW(tdm_hwc_window *, n_thw);
+ EINA_SAFETY_ON_NULL_GOTO(thwc_windows, error);
+
+ i = 0;
+ EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
+ thwc_windows[i++] = hwc_window->thwc_window;
+ }
+
+ /* make hwc extension choose which clients will own hw overlays */
+ terror = tdm_output_hwc_validate(toutput, thwc_windows, n_thw, num_changes);
+ if (terror != TDM_ERROR_NONE) goto error;
+
+ E_FREE(thwc_windows);
+
+ return EINA_TRUE;
+
+error:
+ ERR("HWC-WINS: failed to validate the output(%p)", toutput);
+ E_FREE(thwc_windows);
+
+ return EINA_FALSE;
+}
+
+static void
+_e_hwc_windows_activation_states_update(E_Hwc *hwc)
+{
+ E_Hwc_Window *hwc_window;
+ const Eina_List *l;
+
+ /* mark the active/deactive on hwc_window */
+ EINA_LIST_FOREACH(e_hwc_windows_get(hwc), l, hwc_window)
+ {
+ if (hwc_window->is_deleted) continue;
+ if (e_hwc_window_is_target(hwc_window)) continue;
+
+ if (e_hwc_window_is_on_hw_overlay(hwc_window))
+ /* notify the hwc_window that it will be displayed on hw layer */
+ e_hwc_window_activate(hwc_window);
+ else
+ /* notify the hwc_window that it will be composite on the target buffer */
+ e_hwc_window_deactivate(hwc_window);
+ }
+}
+
+static Eina_Bool
+_e_hwc_windows_target_window_render(E_Output *output, E_Hwc_Window_Target *target_hwc_window)
+{
+ if (target_hwc_window->hwc_window.state == E_HWC_WINDOW_STATE_NONE) return EINA_TRUE;
+
+ if (e_comp_canvas_norender_get() > 0)
+ {
+ ELOGF("HWC-WINS", " NoRender get. Do not ecore_evas_manual_render.", NULL, NULL);
+ return EINA_TRUE;
+ }
+
+ /* render the ecore_evas and
+ update_ee is to be true at post_render_cb when the render is successful. */
+ TRACE_DS_BEGIN(MANUAL RENDER);
+
+ if (e_hwc_window_target_surface_queue_can_dequeue(target_hwc_window))
+ {
+ ELOGF("HWC-WINS", "###### Render target window(ecore_evas_manual_render))", NULL, NULL);
+ ecore_evas_manual_render(target_hwc_window->ee);
+ }
+
+ TRACE_DS_END();
+
+ return EINA_TRUE;
+}
+
+static Eina_List *
+_e_hwc_windows_visible_windows_list_get(E_Hwc *hwc)
+{
+ Eina_List *windows_list = NULL;
+ Eina_List *l;
+ E_Hwc_Window *hwc_window;
+ E_Client *ec;
+ Evas_Object *o;
+ int scr_w, scr_h;
+ int zpos = 0;
+ E_Comp_Wl_Client_Data *cdata = NULL;
+
+ for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
+ {
+ ec = evas_object_data_get(o, "E_Client");
+ if (!ec) continue;
+ if (!ec->hwc_window) continue;
+
+ hwc_window = ec->hwc_window;
+
+ if (e_object_is_del(E_OBJECT(ec)))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} ec is destroying. Set E_HWC_WINDOW_STATE_NONE.",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ continue;
+ }
+
+ // check clients to skip composite
+ if (e_client_util_ignored_get(ec))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} ec is ignored. Set E_HWC_WINDOW_STATE_NONE.",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ continue;
+ }
+
+ // check clients to skip composite
+ if (!evas_object_visible_get(ec->frame))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} ec->frame is not visible. Set E_HWC_WINDOW_STATE_NONE.",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ continue;
+ }
+
+ // check geometry if located out of screen such as quick panel
+ ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &scr_w, &scr_h);
+ if (!E_INTERSECTS(0, 0, scr_w, scr_h, ec->client.x, ec->client.y, ec->client.w, ec->client.h))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ continue;
+ }
+
+ if (evas_object_data_get(ec->frame, "comp_skip"))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ continue;
+ }
+
+ /* skip all small clients except the video clients */
+ if ((ec->w == 1 || ec->h == 1) && !e_hwc_window_is_video(hwc_window))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ continue;
+ }
+
+ /* skip the cdata is null */
+ cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
+ if (!cdata)
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} cdata is NULL. Set E_HWC_WINDOW_STATE_NONE.",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ continue;
+ }
+
+ /* skip the cdata->buffer_ref.buffer is null */
+ if (!cdata->buffer_ref.buffer)
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} cdata->buffer_ref.buffer is NULL. Set E_HWC_WINDOW_STATE_NONE.",
+ ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
+ continue;
+ }
+
+ if (e_hwc_window_is_video(hwc_window))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_VIDEO);
+ continue;
+ }
+
+ windows_list = eina_list_append(windows_list, hwc_window);
+ }
+
+ /* assign zpos */
+ EINA_LIST_REVERSE_FOREACH(windows_list, l, hwc_window)
+ e_hwc_window_zpos_set(hwc_window, zpos++);
+
+ hwc->num_visible_windows = eina_list_count(windows_list);
+
+#if DBG_EVALUATE
+ ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, hwc->num_visible_windows);
+#endif
+ return windows_list;
+}
+
+static Eina_Bool
+_e_hwc_windows_full_gl_composite_check(E_Hwc *hwc, Eina_List *visible_windows_list)
+{
+ Eina_List *l;
+ E_Client *ec;
+ E_Hwc_Window *hwc_window = NULL;
+
+ /* make the full_gl_composite when the zoom is enabled */
+ if (hwc->output->zoom_set) goto full_gl_composite;
+
+ /* full composite is forced to be set */
+ if (e_hwc_deactive_get(hwc)) goto full_gl_composite;
+
+ /* hwc_window manager required full GLES composition */
+ if (e_comp->nocomp_override > 0)
+ {
+ ELOGF("HWC-WINS", " HWC_MODE_HYBRID due to nocomp_override > 0.", NULL, NULL);
+ goto full_gl_composite;
+ }
+
+ EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
+ {
+ ec = hwc_window->ec;
+
+ // if there is a ec which is lower than quickpanel and quickpanel is opened.
+ if (E_POLICY_QUICKPANEL_LAYER >= evas_object_layer_get(ec->frame))
+ {
+ // check whether quickpanel is open than break
+ if (e_qp_visible_get())
+ {
+ ELOGF("HWC-WINS", " HWC_MODE_NONE due to quickpanel is opened.{%25s}.",
+ ec->pixmap, ec, ec->icccm.title);
+ goto full_gl_composite;
+ }
+ }
+
+ // if ec->frame is not for client buffer (e.g. launchscreen)
+ if (e_comp_object_content_type_get(ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
+ {
+ ELOGF("HWC-WINS", " HWC_MODE_NONE due to E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE{%25s}.",
+ ec->pixmap, ec, ec->icccm.title);
+ goto full_gl_composite;
+ }
+
+ // if there is UI subfrace, it means need to composite
+ if (e_client_normal_client_has(ec))
+ {
+ ELOGF("HWC-WINS", " HWC_MODE_NONE due to UI subfrace{%25s}.",
+ ec->pixmap, ec, ec->icccm.title);
+ goto full_gl_composite;
+ }
+ }
+
+ return EINA_FALSE;
+
+full_gl_composite:
+ EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
+ {
+ /* The video window is not composited by gl compositor */
+ if (e_hwc_window_is_video(hwc_window)) continue;
+
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT);
+
+ ELOGF("HWC-WINS", " ehw:%p -- {%25s} is NOT hwc_acceptable.",
+ hwc_window->ec->pixmap, hwc_window->ec, hwc_window, hwc_window->ec->icccm.title);
+ }
+ return EINA_TRUE;
+}
+
+/* filter visible clients by the hwc_window manager
+ *
+ * returns list of clients which are acceptable to be composited by hw,
+ * it's a caller responsibility to free it
+ *
+ * for optimized hwc the returned list contains ALL clients
+ */
+static void
+_e_hwc_windows_hwc_acceptable_check(Eina_List *visible_windows_list)
+{
+ Eina_List *l;
+ E_Hwc_Window *hwc_window = NULL;
+
+ EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
+ {
+ /* The video window is not composited by gl compositor */
+ if (e_hwc_window_is_video(hwc_window)) continue;
+
+ // check clients are able to use hwc
+ if (_e_hwc_windows_device_state_check(hwc_window->ec))
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_DEVICE);
+ else
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT);
+ }
+}
+
+static Eina_Bool
+_e_hwc_windows_composition_evaulate(E_Hwc *hwc, Eina_List *visible_windows_list)
+{
+ Eina_Bool ret = EINA_FALSE;
+ uint32_t num_changes;
+
+ /* evaluate the transition */
+ if (!_e_hwc_windows_compsitions_update(hwc))
+ {
+ ERR("HWC-WINS: _e_hwc_windows_compsitions_update failed.");
+ ret = EINA_FALSE;
+ goto done;
+ }
+
+ /* validate the updated hwc_windows by asking tdm_hwc_output */
+ if (!_e_hwc_windows_validate(hwc, visible_windows_list, &num_changes))
+ {
+ ERR("HWC-WINS: _e_hwc_windows_validate failed.");
+ ret = EINA_FALSE;
+ goto done;
+ }
+
+ if (num_changes > 0)
+ {
+ if (_e_hwc_windows_accept(hwc, num_changes))
+ ret = EINA_TRUE;
+ else
+ ret = EINA_FALSE;
+ }
+ else
+ ret = EINA_TRUE;
+
+done:
+
+ return ret;
+}
+
+static Eina_List *
+_e_hwc_windows_states_evaluate(E_Hwc *hwc)
+{
+ Eina_List *visible_windows_list = NULL;
+
+ /* get the visible ecs */
+ visible_windows_list = _e_hwc_windows_visible_windows_list_get(hwc);
+
+ /* check the gles composite with all hwc_windows. */
+ if (!_e_hwc_windows_full_gl_composite_check(hwc, visible_windows_list))
+ {
+ /* by demand of hwc_window manager to prevent some e_clients to be shown by hw directly */
+ _e_hwc_windows_hwc_acceptable_check(visible_windows_list);
+ }
+
+ return visible_windows_list;
+}
+
+/* evaluate the hwc_windows */
+static Eina_Bool
+_e_hwc_windows_evaluate(E_Hwc *hwc, Eina_List *visible_windows_list)
+{
+ E_Hwc_Mode hwc_mode = E_HWC_MODE_NONE;
+ E_Hwc_Window *target_window = (E_Hwc_Window *)hwc->target_hwc_window;
+
+ ELOGF("HWC-WINS", "====================== Output HWC Apply (evaluate) ======================", NULL, NULL);
+
+ /* evaulate the compositions with the states*/
+ if (_e_hwc_windows_composition_evaulate(hwc, visible_windows_list))
+ ELOGF("HWC-WINS", " Succeed the compsition_evaulation.", NULL, NULL);
+ else
+ ELOGF("HWC-WINS", " Need the comopsition re-evaulation.", NULL, NULL);
+
+ /* update the activate/decativate state */
+ _e_hwc_windows_activation_states_update(hwc);
+
+ /* decide the E_HWC_MODE */
+ hwc_mode = _e_hwc_windows_hwc_mode_get(hwc);
+ if (hwc->hwc_mode != hwc_mode)
+ {
+ if (hwc_mode == E_HWC_MODE_HYBRID || hwc_mode == E_HWC_MODE_NONE)
+ ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
+ else
+ ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
+
+ hwc->hwc_mode = hwc_mode;
+ }
+
+#if DBG_EVALUATE
+ if (hwc_mode == E_HWC_MODE_NONE)
+ ELOGF("HWC-WINS", " HWC_MODE is NONE composition.", NULL, NULL);
+ else if (hwc_mode == E_HWC_MODE_HYBRID)
+ ELOGF("HWC-WINS", " HWC_MODE is HYBRID composition.", NULL, NULL);
+ else
+ ELOGF("HWC-WINS", " HWC_MODE is FULL HW composition.", NULL, NULL);
+#endif
+
+ /* set the state of the target_window */
+ if (hwc_mode == E_HWC_MODE_HYBRID || hwc_mode == E_HWC_MODE_NONE)
+ e_hwc_window_state_set(target_window, E_HWC_WINDOW_STATE_DEVICE);
+ else
+ e_hwc_window_state_set(target_window, E_HWC_WINDOW_STATE_NONE);
+
+ /* target state is DEVICE and no surface, then return false */
+ if (e_hwc_window_state_get(target_window) == E_HWC_WINDOW_STATE_DEVICE &&
+ target_window->tsurface == NULL)
+ {
+ ELOGF("HWC-WINS", "Need target_window buffer.", NULL, NULL);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_e_hwc_windows_prev_states_update(E_Hwc *hwc)
+{
+ E_Hwc_Window *hwc_window = NULL;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
+ e_hwc_window_prev_state_update(hwc_window);
+}
+
+/* check if there is a need to update the output */
+static Eina_Bool
+_e_hwc_windows_update_changes(E_Hwc *hwc)
+{
+ const Eina_List *l;
+ E_Hwc_Window *hwc_window;
+ Eina_Bool update_changes = EINA_FALSE;
+
+ /* fetch the target buffer */
+ if (e_hwc_window_target_buffer_fetch(hwc->target_hwc_window)) // try aquire
+ update_changes = EINA_TRUE;
+
+ /* fetch the windows buffers */
+ EINA_LIST_FOREACH(e_hwc_windows_get(hwc), l, hwc_window)
+ {
+ if (e_hwc_window_is_target(hwc_window)) continue;
+
+ if (!e_hwc_window_buffer_fetch(hwc_window))
+ continue;
+
+ if (!e_hwc_window_buffer_update(hwc_window))
+ {
+ ERR("HWC-WINS: cannot update E_Hwc_Window(%p)", hwc_window);
+ continue;
+ }
+
+ update_changes = EINA_TRUE;
+ }
+
+ return update_changes;
+}
+
+EINTERN Eina_Bool
+e_hwc_windows_init(E_Hwc *hwc)
+{
+ return EINA_TRUE;
+}
+
+EINTERN void
+e_hwc_windows_deinit(void)
+{
+ // TDOO:
+ ;;;
+}
+
+EINTERN const Eina_List *
+e_hwc_windows_get(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
+
+ return hwc->hwc_windows;
+}
+
+EINTERN Eina_Bool
+e_hwc_windows_render(E_Hwc *hwc)
+{
+ E_Output *output = hwc->output;
+ E_Hwc_Window_Target *target_hwc_window;
+
+ target_hwc_window = hwc->target_hwc_window;
+ if (!target_hwc_window)
+ {
+ ERR("fail to get target hwc_window for output(%p).", output);
+ return EINA_FALSE;
+ }
+
+ if (!_e_hwc_windows_target_window_render(output, target_hwc_window))
+ ERR("fail to render output(%p).", output);
+
+ return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_hwc_windows_commit(E_Hwc *hwc)
+{
+ E_Hwc_Window *hwc_window = NULL;
+ Eina_List *l;
+ E_Output *output = NULL;
+ tdm_error error = TDM_ERROR_NONE;
+ Eina_List *visible_windows_list = NULL;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+ output = hwc->output;
+
+ if (hwc->wait_commit)
+ {
+ ELOGF("HWC-WINS", "!!!!!!!! Didn't get Output Commit Handler Yet !!!!!!!!", NULL, NULL);
+ return EINA_TRUE;
+ }
+
+ if (e_comp_canvas_norender_get() > 0)
+ {
+ ELOGF("HWC-WINS", " Block Display... NoRender get.", NULL, NULL);
+ return EINA_TRUE;
+ }
+
+ if (output->dpms == E_OUTPUT_DPMS_OFF)
+ {
+ EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
+ _e_hwc_windows_offscreen_commit(output, hwc_window);
+
+ return EINA_TRUE;
+ }
+
+ /* evaulate the current states */
+ visible_windows_list = _e_hwc_windows_states_evaluate(hwc);
+
+ if (_e_hwc_windows_update_changes(hwc))
+ {
+ if (!_e_hwc_windows_evaluate(hwc, visible_windows_list))
+ {
+ ELOGF("HWC-WINS", "Evaluation is not completed. No Commit at this time.", NULL, NULL);
+ /* update the previous states. */
+ _e_hwc_windows_prev_states_update(hwc);
+ goto fail;
+ }
+
+ EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
+ _e_hwc_windows_prepare_commit(output, hwc_window);
+
+ if (output->zoom_set)
+ {
+ e_output_zoom_rotating_check(output);
+ ELOGF("HWC-WINS", "###### PP Commit", NULL, NULL);
+ if (!_e_hwc_windows_pp_commit(hwc))
+ {
+ ERR("_e_hwc_windows_pp_commit failed.");
+ goto fail;
+ }
+ }
+ else
+ {
+ ELOGF("HWC-WINS", "!!!!!!!! Output Commit !!!!!!!!", NULL, NULL);
+ ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, hwc->num_visible_windows);
+ _e_hwc_windows_status_print(hwc, EINA_TRUE);
+ _e_hwc_windows_ouput_commit_dump(hwc);
+
+ error = tdm_output_commit(output->toutput, 0, _e_hwc_windows_commit_handler, hwc);
+ if (error != TDM_ERROR_NONE)
+ {
+ ERR("tdm_output_commit failed.");
+ _e_hwc_windows_commit_handler(output->toutput, 0, 0, 0, hwc);
+ goto fail;
+ }
+
+ hwc->wait_commit = EINA_TRUE;
+ }
+
+
+ /* update the previous states. */
+ _e_hwc_windows_prev_states_update(hwc);
+ }
+
+ if (visible_windows_list)
+ eina_list_free(visible_windows_list);
+
+ return EINA_TRUE;
+
+fail:
+
+ if (visible_windows_list)
+ eina_list_free(visible_windows_list);
+
+ return EINA_FALSE;
+}
+
+EINTERN Eina_Bool
+e_hwc_windows_pp_commit_possible_check(E_Hwc *hwc)
+{
+ if (!hwc->pp_set) return EINA_FALSE;
+
+ if (hwc->pp_tqueue)
+ {
+ if (!tbm_surface_queue_can_dequeue(hwc->pp_tqueue, 0))
+ return EINA_FALSE;
+ }
+
+ if (hwc->pending_pp_hwc_window_list)
+ {
+ if (eina_list_count(hwc->pending_pp_hwc_window_list) != 0)
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_hwc_windows_zoom_set(E_Hwc *hwc, Eina_Rectangle *rect)
+{
+ E_Comp_Screen *e_comp_screen = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+ int w, h;
+ Eina_List *l;
+ E_Hwc_Window *hwc_window;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+ if ((hwc->pp_rect.x == rect->x) &&
+ (hwc->pp_rect.y == rect->y) &&
+ (hwc->pp_rect.w == rect->w) &&
+ (hwc->pp_rect.h == rect->h))
+ return EINA_TRUE;
+
+ e_comp_screen = e_comp->e_comp_screen;
+ e_output_size_get(hwc->output, &w, &h);
+
+ if (!hwc->tpp)
+ {
+ hwc->tpp = tdm_display_create_pp(e_comp_screen->tdisplay, &ret);
+ if (ret != TDM_ERROR_NONE)
+ {
+ ERR("fail tdm pp create");
+ goto fail;
+ }
+ }
+
+ if (!hwc->pp_tqueue)
+ {
+ //TODO: Does e20 get the buffer flags from the tdm backend?
+ hwc->pp_tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
+ if (!hwc->pp_tqueue)
+ {
+ ERR("fail tbm_surface_queue_create");
+ goto fail;
+ }
+ }
+
+ hwc->pp_rect.x = rect->x;
+ hwc->pp_rect.y = rect->y;
+ hwc->pp_rect.w = rect->w;
+ hwc->pp_rect.h = rect->h;
+
+ hwc->pp_set = EINA_TRUE;
+ hwc->target_hwc_window->skip_surface_set = EINA_TRUE;
+ hwc->pp_set_info = EINA_TRUE;
+
+ EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
+ {
+ if (e_hwc_window_state_get(hwc_window) ==E_HWC_WINDOW_STATE_NONE) continue;
+ if (e_hwc_window_is_target(hwc_window)) continue;
+ if (e_hwc_window_is_video(hwc_window)) continue;
+
+ hwc_window->update_exist = EINA_TRUE;
+ }
+
+ /* to wake up main loop */
+ uint64_t value = 1;
+ if (write(hwc->target_hwc_window->event_fd, &value, sizeof(value)) < 0)
+ ERR("failed to wake up main loop:%m");
+
+ return EINA_TRUE;
+
+fail:
+ if (hwc->tpp)
+ {
+ tdm_pp_destroy(hwc->tpp);
+ hwc->tpp = NULL;
+ }
+
+ return EINA_FALSE;
+}
+
+EINTERN void
+e_hwc_windows_zoom_unset(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+ hwc->pp_set_info = EINA_FALSE;
+ hwc->target_hwc_window->skip_surface_set = EINA_FALSE;
+ hwc->pp_set = EINA_FALSE;
+
+ hwc->pp_rect.x = 0;
+ hwc->pp_rect.y = 0;
+ hwc->pp_rect.w = 0;
+ hwc->pp_rect.h = 0;
+
+ _e_hwc_windows_pp_pending_data_remove(hwc);
+
+ if (hwc->pp_tsurface)
+ tbm_surface_queue_release(hwc->pp_tqueue, hwc->pp_tsurface);
+
+ if (hwc->pp_tqueue)
+ {
+ tbm_surface_queue_destroy(hwc->pp_tqueue);
+ hwc->pp_tqueue = NULL;
+ }
+
+ if (!hwc->pp_commit)
+ {
+ if (hwc->tpp)
+ {
+ tdm_pp_destroy(hwc->tpp);
+ hwc->tpp = NULL;
+ }
+ }
+
+ if (hwc->pp_output_commit_data)
+ hwc->wait_commit = EINA_TRUE;
+
+ /* to wake up main loop */
+ uint64_t value = 1;
+ if (write(hwc->target_hwc_window->event_fd, &value, sizeof(value)) < 0)
+ ERR("failed to wake up main loop:%m");
+}
+
--- /dev/null
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_HWC_WINDOWS_H
+#define E_HWC_WINDOWS_H
+
+EINTERN Eina_Bool e_hwc_windows_init(E_Hwc *hwc);
+EINTERN void e_hwc_windows_deinit(void);
+
+EINTERN const Eina_List *e_hwc_windows_get(E_Hwc *hwc);
+EINTERN Eina_Bool e_hwc_windows_render(E_Hwc *hwc);
+EINTERN Eina_Bool e_hwc_windows_commit(E_Hwc *hwc);
+
+EINTERN Eina_Bool e_hwc_windows_pp_commit_possible_check(E_Hwc *hwc);
+EINTERN Eina_Bool e_hwc_windows_zoom_set(E_Hwc *hwc, Eina_Rectangle *rect);
+EINTERN void e_hwc_windows_zoom_unset(E_Hwc *hwc);
+
+#endif
+#endif
#include "e_plane.h"
#include "e_plane_renderer.h"
#include "e_output.h"
-#include "e_output_hwc.h"
-#include "e_output_hwc_planes.h"
-#include "e_output_hwc_windows.h"
+#include "e_hwc.h"
+#include "e_hwc_planes.h"
+#include "e_hwc_windows.h"
#include "e_hwc_window.h"
#include "e_comp_wl.h"
#include "e_comp_wl_data.h"
eout = e_output_find(ec->zone->output_id);
if (!eout) return;
- if (e_output_hwc_policy_get(eout->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(eout->hwc) == E_HWC_POLICY_PLANES)
{
EINA_LIST_FOREACH(eout->planes, l, ep)
{
if (!primary_output)
return 0;
- if (e_output_hwc_policy_get(primary_output->output_hwc) == E_OUTPUT_HWC_POLICY_WINDOWS)
+ if (e_hwc_policy_get(primary_output->hwc) == E_HWC_POLICY_WINDOWS)
return 1;
return 0;
DBG("zoom_rect rotate(x:%d,y:%d) (w:%d,h:%d)",
output->zoom_conf.rect.x, output->zoom_conf.rect.y, output->zoom_conf.rect.w, output->zoom_conf.rect.h);
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
EINA_LIST_FOREACH(output->planes, l, ep)
{
}
else
{
- e_output_hwc_windows_zoom_set(output->output_hwc, &output->zoom_conf.rect);
+ e_hwc_windows_zoom_set(output->hwc, &output->zoom_conf.rect);
if (!_e_output_zoom_touch_set(output))
ERR("fail _e_output_zoom_touch_set");
/* update the ecore_evas */
- if (e_output_hwc_windows_pp_commit_possible_check(output->output_hwc))
+ if (e_hwc_windows_pp_commit_possible_check(output->hwc))
_e_output_render_update(output);
}
}
if (!output) return;
- if (output->output_hwc) e_output_hwc_del(output->output_hwc);
+ if (output->hwc) e_hwc_del(output->hwc);
e_plane_shutdown();
EINTERN Eina_Bool
e_output_setup(E_Output *output)
{
- E_Output_Hwc *output_hwc = NULL;
+ E_Hwc *hwc = NULL;
Eina_List *l, *ll;
E_Plane *plane = NULL;
if (e_comp->hwc)
{
- output_hwc = e_output_hwc_new(output);
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
- output->output_hwc = output_hwc;
+ hwc = e_hwc_new(output);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+ output->hwc = hwc;
}
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
E_Output *primary_output = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
EINA_LIST_REVERSE_FOREACH(output->planes, l, plane)
{
}
else
{
- if (!e_output_hwc_windows_render(output->output_hwc))
+ if (!e_hwc_windows_render(output->hwc))
{
- ERR("fail to e_output_hwc_windows_render.");
+ ERR("fail to e_hwc_windows_render.");
return EINA_FALSE;
}
}
output_primary = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
EINA_SAFETY_ON_NULL_RETURN_VAL(output_primary, EINA_FALSE);
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
if (output == output_primary)
{
}
else
{
- if (!e_output_hwc_windows_commit(output->output_hwc))
+ if (!e_hwc_windows_commit(output->hwc))
{
return EINA_FALSE;
}
if (!output || !output->planes) continue;
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
fprintf(stderr, "HWC in %s .. \n", output->id);
fprintf(stderr, "HWC \tzPos \t on_plane \t\t\t\t on_prepare \t \n");
_e_output_zoom_coordinate_cal(output);
_e_output_zoom_touch_rect_get(output);
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
ep = e_output_fb_target_get(output);
EINA_SAFETY_ON_NULL_RETURN_VAL(ep, EINA_FALSE);
output->zoom_conf.unset_skip = EINA_TRUE;
}
- e_output_hwc_planes_multi_plane_set(output->output_hwc, EINA_FALSE);
+ e_hwc_planes_multi_plane_set(output->hwc, EINA_FALSE);
if (!e_plane_zoom_set(ep, &output->zoom_conf.rect))
{
ERR("e_plane_zoom_set failed.");
output->zoom_conf.unset_skip = EINA_FALSE;
- e_output_hwc_planes_multi_plane_set(output->output_hwc, EINA_TRUE);
+ e_hwc_planes_multi_plane_set(output->hwc, EINA_TRUE);
return EINA_FALSE;
}
}
else
{
- if (!e_output_hwc_windows_zoom_set(output->output_hwc, &output->zoom_conf.rect))
+ if (!e_hwc_windows_zoom_set(output->hwc, &output->zoom_conf.rect))
{
- ERR("e_output_hwc_windows_zoom_set failed.");
+ ERR("e_hwc_windows_zoom_set failed.");
return EINA_FALSE;
}
/* update the ecore_evas */
- if (e_output_hwc_windows_pp_commit_possible_check(output->output_hwc))
+ if (e_hwc_windows_pp_commit_possible_check(output->hwc))
_e_output_render_update(output);
}
if (!_e_output_zoom_touch_unset(output))
ERR("fail _e_output_zoom_touch_unset");
- if (e_output_hwc_policy_get(output->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
ep = e_output_fb_target_get(output);
if (ep) e_plane_zoom_unset(ep);
- e_output_hwc_planes_multi_plane_set(output->output_hwc, EINA_TRUE);
+ e_hwc_planes_multi_plane_set(output->hwc, EINA_TRUE);
}
else
{
- e_output_hwc_windows_zoom_unset(output->output_hwc);
+ e_hwc_windows_zoom_unset(output->hwc);
}
output->zoom_conf.zoomx = 0;
_e_output_external_rect_get(output_primary, p_w, p_h, w, h, &output->zoom_conf.rect);
- e_output_hwc_planes_multi_plane_set(output_primary->output_hwc, EINA_FALSE);
- e_output_hwc_deactive_set(output_primary->output_hwc, EINA_TRUE);
+ e_hwc_planes_multi_plane_set(output_primary->hwc, EINA_FALSE);
+ e_hwc_deactive_set(output_primary->hwc, EINA_TRUE);
ep->output_primary = output_primary;
if (!e_plane_external_set(ep, &output->zoom_conf.rect, state))
{
ERR("e_plane_mirror_set failed.");
- e_output_hwc_planes_multi_plane_set(output_primary->output_hwc, EINA_TRUE);
- e_output_hwc_deactive_set(output_primary->output_hwc, EINA_FALSE);
+ e_hwc_planes_multi_plane_set(output_primary->hwc, EINA_TRUE);
+ e_hwc_deactive_set(output_primary->hwc, EINA_FALSE);
return EINA_FALSE;
}
output->zoom_conf.rect.w = 0;
output->zoom_conf.rect.h = 0;
- e_output_hwc_planes_multi_plane_set(output_primary->output_hwc, EINA_TRUE);
+ e_hwc_planes_multi_plane_set(output_primary->hwc, EINA_TRUE);
/* update the ecore_evas */
_e_output_render_update(output_primary);
if (ret == EINA_FALSE)
{
ERR("fail to e_eom_connect.");
- e_output_hwc_del(output->output_hwc);
- output->output_hwc = NULL;
+ e_hwc_del(output->hwc);
+ output->hwc = NULL;
return EINA_FALSE;
}
}
return EINA_FALSE;
}
- if (output->output_hwc)
+ if (output->hwc)
{
- e_output_hwc_del(output->output_hwc);
- output->output_hwc = NULL;
+ e_hwc_del(output->hwc);
+ output->hwc = NULL;
}
if (!e_output_dpms_set(output, E_OUTPUT_DPMS_OFF))
} stream_capture;
/* output hwc */
- E_Output_Hwc *output_hwc;
+ E_Hwc *hwc;
Eina_Bool tdm_hwc;
/* external */
+++ /dev/null
-#include "e.h"
-#include "services/e_service_quickpanel.h"
-
-static void
-_e_output_hwc_cb_ee_resize(Ecore_Evas *ee EINA_UNUSED)
-{
- e_comp_canvas_update();
-}
-
-static void *
-_e_output_hwc_tbm_surface_queue_alloc(void *data, int w, int h)
-{
- E_Output_Hwc *output_hwc = (E_Output_Hwc *)data;
- E_Output *output = output_hwc->output;
- E_Comp_Screen *e_comp_screen = output->e_comp_screen;
- tdm_output *toutput = output->toutput;
- tbm_surface_queue_h tqueue = NULL;
- tdm_error error;
- int scr_w, scr_h, queue_w, queue_h;
-
- e_output_size_get(output, &scr_w, &scr_h);
-
- if (output->tdm_hwc)
- {
- tqueue = tdm_output_hwc_get_target_buffer_queue(toutput, &error);
- if (error != TDM_ERROR_NONE)
- {
- ERR("fail to tdm_output_hwc_get_target_buffer_queue");
- return (void *)NULL;
- }
- }
- else
- {
- tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
- if (!tqueue)
- {
- ERR("fail to tdm_output_hwc_get_target_buffer_queue");
- return (void *)NULL;
- }
- }
-
- queue_w = tbm_surface_queue_get_width(tqueue);
- if (scr_w != queue_w)
- WRN("!!!!!!WARNING::: the queue width(%d) is diffrent from output width(%d)!!!!!!", queue_w, scr_w);
- queue_h = tbm_surface_queue_get_height(tqueue);
- if (scr_h != queue_h)
- WRN("!!!!!!WARNING::: the queue height(%d) is diffrent from output height(%d)!!!!!!", queue_h, scr_h);
-
- output_hwc->target_buffer_queue = tqueue;
-
- // TODO: change the e_comp_screen->tqueue into output_hwc->target_buffer_queue
- e_comp_screen->tqueue = tqueue;
-
- return (void *)tqueue;
-}
-
-static void
-_e_output_hwc_tbm_surface_queue_free(void *data, void *tqueue)
-{
- E_Output_Hwc *output_hwc = (E_Output_Hwc *)data;
-
- tbm_surface_queue_destroy(tqueue);
- output_hwc->target_buffer_queue = NULL;
-}
-
-static void
-_e_output_hwc_ee_deinit(E_Output_Hwc *output_hwc)
-{
- // TODO:
- E_Output *output = output_hwc->output;
- E_Output *primary_output = NULL;
-
- primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
- if (primary_output != output)
- {
- if (output_hwc->ee)
- ecore_evas_free(output_hwc->ee);
- output_hwc->ee = NULL;
- }
- else
- {
- /* ecore_evas_free execute when e_comp free */
- output_hwc->ee = NULL;
- }
-}
-
-// TODO: Currently E20 has only one e_output for the primary output.
-// We need to change the ee and other logic for multiple E_Output.
-static Eina_Bool
-_e_output_hwc_ee_init(E_Output_Hwc* output_hwc)
-{
- E_Output *output = output_hwc->output;
- E_Output *primary_output = NULL;
- Ecore_Evas *ee = NULL;
- int w = 0, h = 0, scr_w = 1, scr_h = 1;
- int screen_rotation;
- char buf[1024];
-
- INF("E_OUTPUT_HWC: ecore evase engine init.");
-
- // TODO: fix me. change the screen_rotation into output_rotation.
- screen_rotation = output->e_comp_screen->rotation;
-
- /* set env for use tbm_surface_queue*/
- setenv("USE_EVAS_SOFTWARE_TBM_ENGINE", "1", 1);
- //setenv("USE_EVAS_GL_TBM_ENGINE", "1", 1);
-
- /* set gl available if we have ecore_evas support */
- if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM) ||
- ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_TBM))
- e_comp_gl_set(EINA_TRUE);
-
- /* get the size of the primary output */
- e_output_size_get(output, &scr_w, &scr_h);
-
- /* if output is disconnected, set the default width, height */
- if (scr_w == 0 || scr_h == 0)
- {
- scr_w = 2;
- scr_h = 1;
-
- if (!e_output_fake_config_set(output, scr_w, scr_h))
- {
- e_error_message_show(_("Fail to set the fake output config!\n"));
- _e_output_hwc_ee_deinit(output_hwc);
- return EINA_FALSE;
- }
- }
-
- INF("GL available:%d config engine:%d screen size:%dx%d",
- e_comp_gl_get(), e_comp_config_get()->engine, scr_w, scr_h);
-
- if ((e_comp_gl_get()) &&
- (e_comp_config_get()->engine == E_COMP_ENGINE_GL))
- {
- e_main_ts_begin("\tEE_GL_DRM New");
- ee = ecore_evas_tbm_allocfunc_new("gl_tbm", scr_w, scr_h, _e_output_hwc_tbm_surface_queue_alloc, _e_output_hwc_tbm_surface_queue_free, (void *)output_hwc);
- snprintf(buf, sizeof(buf), "\tEE_GL_DRM New Done %p %dx%d", ee, scr_w, scr_h);
- e_main_ts_end(buf);
-
- if (!ee)
- e_comp_gl_set(EINA_FALSE);
- else
- {
- Evas_GL *evasgl = NULL;
- Evas_GL_API *glapi = NULL;
-
- e_main_ts_begin("\tEvas_GL New");
- evasgl = evas_gl_new(ecore_evas_get(ee));
- if (evasgl)
- {
- glapi = evas_gl_api_get(evasgl);
- if (!((glapi) && (glapi->evasglBindWaylandDisplay)))
- {
- e_comp_gl_set(EINA_FALSE);
- ecore_evas_free(ee);
- ee = NULL;
- e_main_ts_end("\tEvas_GL New Failed 1");
- }
- else
- {
- e_main_ts_end("\tEvas_GL New Done");
- }
- }
- else
- {
- e_comp_gl_set(EINA_FALSE);
- ecore_evas_free(ee);
- ee = NULL;
- e_main_ts_end("\tEvas_GL New Failed 2");
- }
- evas_gl_free(evasgl);
- }
- }
-
- /* fallback to framebuffer drm (non-accel) */
- if (!ee)
- {
- e_main_ts_begin("\tEE_DRM New");
- ee = ecore_evas_tbm_allocfunc_new("software_tbm", scr_w, scr_h, _e_output_hwc_tbm_surface_queue_alloc, _e_output_hwc_tbm_surface_queue_free, (void *)output_hwc);
- snprintf(buf, sizeof(buf), "\tEE_DRM New Done %p %dx%d", ee, scr_w, scr_h);
- e_main_ts_end(buf);
- }
-
- if (!ee)
- {
- e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
- _e_output_hwc_ee_deinit(output_hwc);
- return EINA_FALSE;
- }
-
- output_hwc->ee = ee;
-
- primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
- if (primary_output == output)
- {
- e_comp->ee = ee;
- ecore_evas_data_set(e_comp->ee, "comp", e_comp);
-
- ecore_evas_callback_resize_set(e_comp->ee, _e_output_hwc_cb_ee_resize);
-
- if (screen_rotation)
- {
- /* SHOULD called with resize option after ecore_evas_resize */
- ecore_evas_rotation_with_resize_set(e_comp->ee, screen_rotation);
- ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
-
- snprintf(buf, sizeof(buf), "\tEE Rotate and Resize %d, %dx%d", screen_rotation, w, h);
- e_main_ts(buf);
- }
- }
-
- return EINA_TRUE;
-}
-
-EINTERN E_Output_Hwc *
-e_output_hwc_new(E_Output *output)
-{
- E_Output_Hwc *output_hwc = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
-
- output_hwc = E_NEW(E_Output_Hwc, 1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, NULL);
-
- output_hwc->output = output;
-
- if (!_e_output_hwc_ee_init(output_hwc))
- {
- ERR("hwc_opt: _e_output_hwc_ee_init failed");
- goto fail;
- }
-
- /*
- * E20 has two hwc policy options.
- * 1. One is the E_OUTPUT_HWC_POLICY_PLANES.
- * - E20 decides the hwc policy with the E_Planes associated with the tdm_layers.
- * - E20 manages how to set the surface(buffer) of the ec to the E_Plane.
- * 2. Another is the E_OUTPUT_HWC_POLICY_WIDNOWS.
- * - The tdm-backend decides the hwc policy with the E_Hwc_Windows associated with the tdm_hwc_window.
- * - E20 asks to verify the compsition types of the E_Hwc_Window of the ec.
- */
- if (!output->tdm_hwc)
- {
- output_hwc->hwc_policy = E_OUTPUT_HWC_POLICY_PLANES;
- if (!e_output_hwc_planes_init())
- {
- ERR("hwc_opt: e_output_hwc_windows_init failed");
- goto fail;
- }
-
- INF("Output uses the HWC PLANES Policy.");
- }
- else
- {
- output_hwc->hwc_policy = E_OUTPUT_HWC_POLICY_WINDOWS;
-
- if (!e_output_hwc_windows_init(output_hwc))
- {
- ERR("hwc_opt: e_output_hwc_windows_init failed");
- goto fail;
- }
-
- if (!e_hwc_window_init(output_hwc))
- {
- ERR("hwc_opt: E_Hwc_Window init failed");
- goto fail;
- }
-
- /* turn on sw compositor at the start */
- ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
-
- INF("Output uses the HWC WINDOWS Policy.");
- }
-
- return output_hwc;
-
-fail:
- E_FREE(output_hwc);
-
- return NULL;
-}
-
-EINTERN void
-e_output_hwc_del(E_Output_Hwc *output_hwc)
-{
- if (!output_hwc) return;
-
- _e_output_hwc_ee_deinit(output_hwc);
-
- if (output_hwc->hwc_policy == E_OUTPUT_HWC_POLICY_PLANES)
- e_output_hwc_planes_deinit();
- else
- {
- e_hwc_window_deinit(output_hwc);
- e_output_hwc_windows_deinit();
- }
-
- E_FREE(output_hwc);
-}
-
-EINTERN void
-e_output_hwc_apply(E_Output_Hwc *output_hwc)
-{
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
- EINA_SAFETY_ON_NULL_RETURN(output_hwc->output);
- if (e_output_hwc_policy_get(output_hwc) == E_OUTPUT_HWC_POLICY_NONE ||
- e_output_hwc_policy_get(output_hwc) == E_OUTPUT_HWC_POLICY_WINDOWS) return;
-
- if (e_output_hwc_deactive_get(output_hwc))
- {
- if (output_hwc->hwc_mode != E_OUTPUT_HWC_MODE_NONE)
- e_output_hwc_planes_end(output_hwc, "deactive set.");
- return;
- }
-
- if (!e_output_hwc_planes_usable(output_hwc))
- {
- e_output_hwc_planes_end(output_hwc, __FUNCTION__);
- return;
- }
-
- if (output_hwc->hwc_mode == E_OUTPUT_HWC_MODE_NONE)
- e_output_hwc_planes_begin(output_hwc);
- else
- e_output_hwc_planes_changed(output_hwc);
-}
-
-EINTERN E_Output_Hwc_Mode
-e_output_hwc_mode_get(E_Output_Hwc *output_hwc)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, E_OUTPUT_HWC_MODE_NONE);
-
- return output_hwc->hwc_mode;
-}
-
-EINTERN E_Output_Hwc_Policy
-e_output_hwc_policy_get(E_Output_Hwc *output_hwc)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, E_OUTPUT_HWC_MODE_NONE);
-
- return output_hwc->hwc_policy;
-}
-
-EINTERN void
-e_output_hwc_deactive_set(E_Output_Hwc *output_hwc, Eina_Bool set)
-{
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
-
- e_output_hwc_planes_end(output_hwc, __FUNCTION__);
- output_hwc->hwc_deactive = set;
-
- ELOGF("HWC", "e_output_hwc_deactive_set : %d", NULL, NULL, set);
-}
-
-EINTERN Eina_Bool
-e_output_hwc_deactive_get(E_Output_Hwc *output_hwc)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
-
- return output_hwc->hwc_deactive;
-}
+++ /dev/null
-#ifdef E_TYPEDEFS
-
-typedef struct _E_Output_Hwc E_Output_Hwc;
-
-typedef enum _E_Output_Hwc_Mode
-{
- E_OUTPUT_HWC_MODE_NONE = 0,
- E_OUTPUT_HWC_MODE_HYBRID,
- E_OUTPUT_HWC_MODE_FULL
-} E_Output_Hwc_Mode;
-
-typedef enum _E_Output_Hwc_Policy
-{
- E_OUTPUT_HWC_POLICY_NONE = 0,
- E_OUTPUT_HWC_POLICY_PLANES, // hwc_planes policy that controls the hwc policy at e20 with e_planes
- E_OUTPUT_HWC_POLICY_WINDOWS, // hwc_windows policy that controls the hwc policy at tdm-backend with e_hwc_windows
-} E_Output_Hwc_Policy;
-
-#else
-#ifndef E_OUTPUT_HWC_H
-#define E_OUTPUT_HWC_H
-
-struct _E_Output_Hwc
-{
- E_Output *output;
-
- E_Output_Hwc_Policy hwc_policy;
- E_Output_Hwc_Mode hwc_mode;
- Eina_Bool hwc_deactive : 1; // deactive hwc policy
-
- Ecore_Evas *ee;
-
- /* variables for hwc_planes polic */
- Eina_Bool hwc_use_multi_plane;
-
- /* variables for hwc_windows policy */
- Eina_Bool hwc_wins;
- Eina_List *hwc_windows;
- E_Hwc_Window_Target *target_hwc_window;
- tbm_surface_queue_h target_buffer_queue;
- Eina_Bool wait_commit;
- int num_visible_windows;
-
- /* variables for pp at hwc_windows policy */
- tdm_pp *tpp;
- Eina_List *pp_hwc_window_list;
- Eina_List *pending_pp_hwc_window_list;
- Eina_List *pending_pp_commit_data_list;
- tbm_surface_queue_h pp_tqueue;
- tbm_surface_h pp_tsurface;
- Eina_Bool pp_set_info;
- Eina_Bool pp_set;
- Eina_Bool pp_commit;
- Eina_Bool pp_output_commit;
- E_Hwc_Window_Commit_Data *pp_output_commit_data;
- Eina_Rectangle pp_rect;
-};
-
-EINTERN E_Output_Hwc *e_output_hwc_new(E_Output *output);
-EINTERN void e_output_hwc_del(E_Output_Hwc *output_hwc);
-EINTERN void e_output_hwc_apply(E_Output_Hwc *output_hwc);
-EINTERN E_Output_Hwc_Policy e_output_hwc_policy_get(E_Output_Hwc *output_hwc);
-EINTERN E_Output_Hwc_Mode e_output_hwc_mode_get(E_Output_Hwc *output_hwc);
-EINTERN void e_output_hwc_deactive_set(E_Output_Hwc *output_hwc, Eina_Bool set);
-EINTERN Eina_Bool e_output_hwc_deactive_get(E_Output_Hwc *output_hwc);
-
-#endif
-#endif
+++ /dev/null
-#include "e.h"
-#include "services/e_service_quickpanel.h"
-
-EINTERN Eina_Bool
-e_output_hwc_planes_init(void)
-{
- return EINA_TRUE;
-}
-
-EINTERN void
-e_output_hwc_planes_deinit(void)
-{
- // TODO:
- ;;;
-}
-
-static Eina_Bool
-_e_output_hwc_planes_ec_check(E_Client *ec)
-{
- E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
- E_Output *eout;
- int minw = 0, minh = 0;
-
- if ((!cdata) ||
- (!cdata->buffer_ref.buffer) ||
- (cdata->width_from_buffer != cdata->width_from_viewport) ||
- (cdata->height_from_buffer != cdata->height_from_viewport) ||
- cdata->never_hwc)
- {
- return EINA_FALSE;
- }
-
- if (e_client_transform_core_enable_get(ec)) return EINA_FALSE;
-
- switch (cdata->buffer_ref.buffer->type)
- {
- case E_COMP_WL_BUFFER_TYPE_NATIVE:
- case E_COMP_WL_BUFFER_TYPE_TBM:
- break;
- case E_COMP_WL_BUFFER_TYPE_SHM:
- if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
- break;
- default:
- return EINA_FALSE;
- }
-
- eout = e_output_find(ec->zone->output_id);
- EINA_SAFETY_ON_NULL_RETURN_VAL(eout, EINA_FALSE);
-
- tdm_output_get_available_size(eout->toutput, &minw, &minh, NULL, NULL, NULL);
-
- if ((minw > 0) && (minw > cdata->buffer_ref.buffer->w))
- return EINA_FALSE;
- if ((minh > 0) && (minh > cdata->buffer_ref.buffer->h))
- return EINA_FALSE;
-
- /* If a client doesn't watch the ignore_output_transform events, we can't show
- * a client buffer to HW overlay directly when the buffer transform is not same
- * with output transform. If a client watch the ignore_output_transform events,
- * we can control client's buffer transform. In this case, we don't need to
- * check client's buffer transform here.
- */
- if (!e_comp_screen_rotation_ignore_output_transform_watch(ec))
- {
- int transform = e_comp_wl_output_buffer_transform_get(ec);
-
- if ((eout->config.rotation / 90) != transform)
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-static void
-_e_output_hwc_planes_prepare_init(E_Output_Hwc *output_hwc)
-{
- const Eina_List *ep_l = NULL, *l ;
- E_Plane *ep = NULL;
- E_Output *eout = output_hwc->output;
-
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
-
- ep_l = e_output_planes_get(eout);
- EINA_LIST_FOREACH(ep_l, l, ep)
- {
- if (!output_hwc->hwc_use_multi_plane &&
- !e_plane_is_cursor(ep) &&
- !e_plane_is_fb_target(ep))
- continue;
-
- e_plane_ec_prepare_set(ep, NULL);
- }
-}
-
-static int
-_e_output_hwc_planes_prepare_cursor(E_Output *eout, int n_cur, Eina_List *hwc_clist)
-{
- // policy for cursor layer
- const Eina_List *ep_l = NULL, *l ;
- Eina_List *cur_ly = NULL;
- E_Plane *ep = NULL;
- int n_skip = 0;
- int n_curly = 0;
- int nouse = 0;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_clist, EINA_FALSE);
-
- // list up cursor only layers
- ep_l = e_output_planes_get(eout);
- EINA_LIST_FOREACH(ep_l, l, ep)
- {
- if (e_plane_is_cursor(ep))
- {
- cur_ly = eina_list_append(cur_ly, ep);
- continue;
- }
- }
-
- if (!cur_ly) return 0;
- n_curly = eina_list_count(cur_ly);
-
- if (n_cur > 0 && n_curly > 0)
- {
- if (n_cur >= n_curly) nouse = 0;
- else nouse = n_curly - n_cur;
-
- //assign cursor on cursor only layers
- EINA_LIST_REVERSE_FOREACH(cur_ly, l, ep)
- {
- E_Client *ec = NULL;
- if (nouse > 0)
- {
- nouse--;
- continue;
- }
- if (hwc_clist) ec = eina_list_data_get(hwc_clist);
- if (ec && e_plane_ec_prepare_set(ep, ec))
- {
- n_skip += 1;
- hwc_clist = eina_list_next(hwc_clist);
- }
- }
- }
-
- eina_list_free(cur_ly);
-
- return n_skip;
-}
-
-static Eina_Bool
-_e_output_hwc_planes_prepare_plane(E_Output_Hwc *output_hwc, int n_vis, int n_skip, Eina_List *hwc_clist)
-{
- const Eina_List *ep_l = NULL, *l ;
- Eina_List *hwc_ly = NULL;
- E_Plane *ep = NULL, *ep_fb = NULL;
- int n_ly = 0, n_ec = 0;
- E_Client *ec = NULL;
- Eina_Bool ret = EINA_FALSE;
- int nouse = 0;
- E_Output *eout = output_hwc->output;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_clist, EINA_FALSE);
-
- n_ec = eina_list_count(hwc_clist);
- if (n_skip > 0)
- {
- int i;
- for (i = 0; i < n_skip; i++)
- hwc_clist = eina_list_next(hwc_clist);
-
- n_ec -= n_skip;
- n_vis -= n_skip;
- }
-
- if (n_ec <= 0) return EINA_FALSE;
-
- // list up available_hw layers E_Client can be set
- // if e_comp->hwc_use_multi_plane FALSE, than use only fb target plane
- ep_l = e_output_planes_get(eout);
- EINA_LIST_FOREACH(ep_l, l, ep)
- {
- if (!ep_fb)
- {
- if (e_plane_is_fb_target(ep))
- {
- ep_fb = ep;
- hwc_ly = eina_list_append(hwc_ly, ep);
- }
- continue;
- }
- if (!output_hwc->hwc_use_multi_plane) continue;
- if (e_plane_is_cursor(ep)) continue;
- if (ep->zpos > ep_fb->zpos)
- hwc_ly = eina_list_append(hwc_ly, ep);
- }
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_ly, EINA_FALSE);
-
- // finally, assign client on available_hw layers
- n_ly = eina_list_count(hwc_ly);
- if ((n_ec == n_vis) &&
- (n_ec <= n_ly)) // fully hwc
- {
- nouse = n_ly - n_ec;
- }
- else if ((n_ly < n_vis) || // e_comp->evas on fb target plane
- (n_ec < n_vis))
- {
- if (n_ec <= n_ly) nouse = n_ly - n_ec - 1;
- else nouse = 0;
- }
-
- EINA_LIST_REVERSE_FOREACH(hwc_ly, l, ep)
- {
- ec = NULL;
- if (nouse > 0)
- {
- nouse--;
- continue;
- }
- if (hwc_clist) ec = eina_list_data_get(hwc_clist);
- if (ec && e_plane_ec_prepare_set(ep, ec))
- {
- ret = EINA_TRUE;
-
- hwc_clist = eina_list_next(hwc_clist);
- n_ec--; n_vis--;
- }
- if (e_plane_is_fb_target(ep))
- {
- if (n_ec > 0 || n_vis > 0) e_plane_ec_prepare_set(ep, NULL);
- break;
- }
- }
-
- eina_list_free(hwc_ly);
-
- return ret;
-}
-
-static void
-_e_output_hwc_planes_cancel(E_Output_Hwc *output_hwc)
-{
- Eina_List *l ;
- E_Plane *ep;
- E_Output *eout = output_hwc->output;
-
- EINA_LIST_FOREACH(eout->planes, l, ep)
- {
- if (!output_hwc->hwc_use_multi_plane &&
- !e_plane_is_cursor(ep) &&
- !e_plane_is_fb_target(ep))
- continue;
-
- e_plane_ec_prepare_set(ep, NULL);
- e_plane_ec_set(ep, NULL);
- }
-}
-
-static Eina_Bool
-_e_output_hwc_planes_reserved_clean(E_Output_Hwc *output_hwc)
-{
- Eina_List *l;
- E_Plane *ep;
- E_Output *eout = output_hwc->output;
-
- EINA_LIST_FOREACH(eout->planes, l, ep)
- {
- if (!output_hwc->hwc_use_multi_plane &&
- !e_plane_is_cursor(ep) &&
- !e_plane_is_fb_target(ep))
- continue;
-
- if (e_plane_is_reserved(ep))
- e_plane_reserved_set(ep, 0);
- }
-
- return EINA_TRUE;
-}
-
-static void
-_e_output_hwc_planes_unset(E_Plane *ep)
-{
- if (e_plane_is_reserved(ep))
- e_plane_reserved_set(ep, 0);
-
- e_plane_ec_prepare_set(ep, NULL);
- e_plane_ec_set(ep, NULL);
-
- ELOGF("HWC-PLNS", "unset plane %d to NULL", NULL, NULL, ep->zpos);
-}
-
-static Eina_Bool
-_e_output_hwc_planes_change_ec(E_Plane *ep, E_Client *new_ec)
-{
- if (!e_plane_ec_set(ep, new_ec))
- {
- ELOGF("HWC-PLNS", "failed to set new_ec(%s) on %d",
- NULL, new_ec,
- new_ec ? (new_ec->icccm.name ? new_ec->icccm.name : "no name") : "NULL",
- ep->zpos);
- return EINA_FALSE;
- }
-
- if (new_ec)
- ELOGF("HWC-PLNS", "new_ec(%s) is set on %d",
- new_ec->pixmap, new_ec,
- e_client_util_name_get(new_ec) ? new_ec->icccm.name : "no name", ep->zpos);
- else
- ELOGF("HWC-PLNS", "NULL is set on %d", NULL, NULL, ep->zpos);
-
- return EINA_TRUE;
-}
-
-EINTERN void
-e_output_hwc_planes_changed(E_Output_Hwc *output_hwc)
-{
- Eina_Bool ret = EINA_FALSE;
- E_Plane *ep = NULL;
- const Eina_List *ep_l = NULL, *p_l;
- Eina_Bool assign_success = EINA_TRUE;
- int mode = E_OUTPUT_HWC_MODE_NONE;
- E_Output *eout = output_hwc->output;
-
- ep_l = e_output_planes_get(eout);
- /* check the planes from top to down */
- EINA_LIST_REVERSE_FOREACH(ep_l, p_l, ep)
- {
- if (!assign_success)
- {
- //unset planes from 'assign_success' became EINA_FALSE to the fb target
- _e_output_hwc_planes_unset(ep);
- continue;
- }
-
- if (e_plane_is_reserved(ep) &&
- ep->prepare_ec == NULL)
- {
- e_plane_reserved_set(ep, 0);
- ELOGF("HWC-PLNS", "unset reserved mem on %d", NULL, NULL, ep->zpos);
- }
-
- if (ep->ec != ep->prepare_ec)
- {
- assign_success = _e_output_hwc_planes_change_ec(ep, ep->prepare_ec);
- ret = EINA_TRUE;
- }
-
- if (ep->ec) mode = E_OUTPUT_HWC_MODE_HYBRID;
-
- if (e_plane_is_fb_target(ep))
- {
- if (ep->ec) mode = E_OUTPUT_HWC_MODE_FULL;
- break;
- }
- }
-
- if (output_hwc->hwc_mode != mode)
- {
- ELOGF("HWC-PLNS", "mode changed (from %d to %d) due to surface changes",
- NULL, NULL,
- output_hwc->hwc_mode, mode);
-
- if (mode == E_OUTPUT_HWC_MODE_FULL)
- {
- // fb target is occupied by a client surface, means compositor disabled
- ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
- }
- else if (output_hwc->hwc_mode == E_OUTPUT_HWC_MODE_FULL)
- {
- // fb target is occupied by a client surface, means compositor disabled
- ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
- }
-
- output_hwc->hwc_mode = mode;
- }
-
- if (ret)
- {
- if (output_hwc->hwc_mode == E_OUTPUT_HWC_MODE_NONE)
- ELOGF("HWC-PLNS", " End... due to surface changes", NULL, NULL);
- else
- ELOGF("HWC-PLNS", " hwc surface changed", NULL, NULL);
- }
-}
-
-static Eina_Bool
-_e_output_hwc_planes_prepare(E_Output_Hwc *output_hwc, E_Zone *zone)
-{
- Eina_List *vl;
- Eina_Bool ret = EINA_FALSE;
- E_Client *ec;
- int n_vis = 0, n_ec = 0, n_cur = 0, n_skip = 0;
- Eina_List *hwc_ok_clist = NULL, *vis_clist = NULL;
- E_Output *output = output_hwc->output;
-
- vis_clist = e_comp_vis_ec_list_get(zone);
- if (!vis_clist) return EINA_FALSE;
-
- // check clients not able to use hwc
- EINA_LIST_FOREACH(vis_clist, vl, ec)
- {
- // if there is a ec which is lower than quickpanel and quickpanel is opened.
- if (E_POLICY_QUICKPANEL_LAYER >= evas_object_layer_get(ec->frame))
- {
- // check whether quickpanel is open than break
- if (e_qp_visible_get()) goto done;
- }
-
- // if ec->frame is not for client buffer (e.g. launchscreen)
- if (e_comp_object_content_type_get(ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
- goto done;
-
- // if there is UI subfrace, it means need to composite
- if (e_client_normal_client_has(ec))
- goto done;
-
- // if ec has invalid buffer or scaled( transformed ) or forced composite(never_hwc)
- if (!_e_output_hwc_planes_ec_check(ec))
- {
- if (!n_ec) goto done;
- break;
- }
-
- // listup as many as possible from the top most visible order
- n_ec++;
- if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role)) n_cur++;
- hwc_ok_clist = eina_list_append(hwc_ok_clist, ec);
- }
-
- n_vis = eina_list_count(vis_clist);
- if ((n_vis < 1) || (n_ec < 1))
- goto done;
-
- _e_output_hwc_planes_prepare_init(output_hwc);
-
- if (n_cur >= 1)
- n_skip = _e_output_hwc_planes_prepare_cursor(output, n_cur, hwc_ok_clist);
-
- if (n_skip > 0) ret = EINA_TRUE;
-
- ret |= _e_output_hwc_planes_prepare_plane(output_hwc, n_vis, n_skip, hwc_ok_clist);
-
-done:
- eina_list_free(hwc_ok_clist);
- eina_list_free(vis_clist);
-
- return ret;
-}
-
-EINTERN Eina_Bool
-e_output_hwc_planes_usable(E_Output_Hwc *output_hwc)
-{
- E_Output *eout = output_hwc->output;
- E_Comp_Wl_Buffer *buffer = NULL;
- E_Zone *zone = NULL;
- int bw = 0, bh = 0;
- Eina_Bool all_null = EINA_TRUE;
- E_Plane *ep = NULL;
- const Eina_List *ep_l = NULL, *p_l;
-
- zone = e_comp_zone_find(e_output_output_id_get(eout));
- EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
-
- // check whether to use hwc and prepare the core assignment policy
- if (!_e_output_hwc_planes_prepare(output_hwc, zone)) return EINA_FALSE;
-
- // extra policy can replace core policy
- e_comp_hook_call(E_COMP_HOOK_PREPARE_PLANE, NULL);
-
- // It is not hwc_usable if cursor is shown when the hw cursor is not supported by libtdm.
- if (!e_pointer_is_hidden(e_comp->pointer) &&
- (eout->cursor_available.max_w == -1 || eout->cursor_available.max_h == -1))
- return EINA_FALSE;
-
- // check the hwc is avaliable.
- ep_l = e_output_planes_get(eout);
- EINA_LIST_FOREACH(ep_l, p_l, ep)
- {
- if (!ep->prepare_ec) continue;
-
- // It is not hwc_usable if attached buffer is not valid.
- buffer = e_pixmap_resource_get(ep->prepare_ec->pixmap);
- if (!buffer) return EINA_FALSE;
-
- if (e_plane_is_fb_target(ep))
- {
- // It is not hwc_usable if the geometry of the prepare_ec at the ep_fb is not proper.
- e_pixmap_size_get(ep->prepare_ec->pixmap, &bw, &bh);
-
- // if client and zone's geometry is not match with, or
- // if plane with reserved_memory(esp. fb target) has assigned smaller buffer,
- // won't support hwc properly, than let's composite
- if (ep->reserved_memory &&
- ((bw != zone->w) || (bh != zone->h) ||
- (ep->prepare_ec->x != zone->x) || (ep->prepare_ec->y != zone->y) ||
- (ep->prepare_ec->w != zone->w) || (ep->prepare_ec->h != zone->h)))
- {
- DBG("Cannot use HWC if geometry is not 1 on 1 match with reserved_memory");
- return EINA_FALSE;
- }
- }
-
- all_null = EINA_FALSE;
- break;
- }
-
- // It is not hwc_usable if the all prepare_ec in every plane are null
- if (all_null) return EINA_FALSE;
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_output_hwc_planes_can_hwcompose(E_Output *eout)
-{
- const Eina_List *ep_l = NULL, *l;
- E_Plane *ep = NULL, *ep_fb = NULL;
-
- ep_l = e_output_planes_get(eout);
- /* check the planes from down to top */
- EINA_LIST_FOREACH(ep_l, l, ep)
- {
- if (e_plane_is_fb_target(ep))
- {
- /* can hwcompose if fb_target has a ec. */
- if (ep->prepare_ec != NULL) return EINA_TRUE;
- else ep_fb = ep;
- }
- else
- {
- /* can hwcompose if ep has a ec and zpos is higher than ep_fb */
- if (ep->prepare_ec != NULL &&
- ep_fb &&
- ep->zpos > ep_fb->zpos)
- return EINA_TRUE;
- }
- }
-
- return EINA_FALSE;
-}
-
-EINTERN void
-e_output_hwc_planes_begin(E_Output_Hwc *output_hwc)
-{
- const Eina_List *ep_l = NULL, *l;
- E_Output *eout = output_hwc->output;
- E_Plane *ep = NULL;
- E_Output_Hwc_Mode mode = E_OUTPUT_HWC_MODE_NONE;
- Eina_Bool set = EINA_FALSE;
-
- if (e_comp->nocomp_override > 0) return;
-
- if (_e_output_hwc_planes_can_hwcompose(eout))
- {
- ep_l = e_output_planes_get(eout);
-
- /* set the prepare_ec to the e_plane */
- /* check the planes from top to down */
- EINA_LIST_REVERSE_FOREACH(ep_l, l , ep)
- {
- if (!ep->prepare_ec) continue;
-
- set = e_plane_ec_set(ep, ep->prepare_ec);
- if (!set) break;
-
- if (e_plane_is_fb_target(ep))
- {
- ELOGF("HWC-PLNS", "is set on fb_target( %d)", ep->prepare_ec->pixmap, ep->prepare_ec, ep->zpos);
- mode = E_OUTPUT_HWC_MODE_FULL;
-
- // fb target is occupied by a client surface, means compositor disabled
- ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
- }
- else
- {
- ELOGF("HWC-PLNS", "is set on %d", ep->prepare_ec->pixmap, ep->prepare_ec, ep->zpos);
- mode = E_OUTPUT_HWC_MODE_HYBRID;
- }
- }
-
- if (mode == E_OUTPUT_HWC_MODE_NONE)
- ELOGF("HWC-PLNS", " Begin is not available yet ...", NULL, NULL);
- else
- ELOGF("HWC-PLNS", " Begin ...", NULL, NULL);
- }
-
- output_hwc->hwc_mode = mode;
-}
-
-static E_Output_Hwc_Mode
-_e_output_hwc_mode_get(E_Output_Hwc *output_hwc)
-{
- const Eina_List *ll = NULL, *l;
- E_Output *output = output_hwc->output;
- E_Plane *plane = NULL;
-
- /* check the planes from down to top */
- EINA_LIST_FOREACH_SAFE(output->planes, l, ll, plane)
- {
- if (!plane->ec) continue;
- if (e_plane_is_fb_target(plane)) return E_OUTPUT_HWC_MODE_FULL;
-
- return E_OUTPUT_HWC_MODE_HYBRID;
- }
-
- return E_OUTPUT_HWC_MODE_NONE;
-}
-
-EINTERN void
-e_output_hwc_planes_multi_plane_set(E_Output_Hwc *output_hwc, Eina_Bool set)
-{
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
-
- e_output_hwc_planes_end(output_hwc, __FUNCTION__);
- output_hwc->hwc_use_multi_plane = set;
-
- ELOGF("HWC-PLNS", "e_output_hwc_planes_multi_plane_set : %d", NULL, NULL, set);
-}
-
-EINTERN Eina_Bool
-e_output_hwc_planes_multi_plane_get(E_Output_Hwc *output_hwc)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
-
- return output_hwc->hwc_use_multi_plane;
-}
-
-EINTERN void
-e_output_hwc_planes_end(E_Output_Hwc *output_hwc, const char *location)
-{
- E_Output_Hwc_Mode new_mode = E_OUTPUT_HWC_MODE_NONE;
-
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
-
- /* clean the reserved planes(clean the candidate ecs) */
- _e_output_hwc_planes_reserved_clean(output_hwc);
-
- if (!output_hwc->hwc_mode) return;
-
- /* set null to the e_planes */
- _e_output_hwc_planes_cancel(output_hwc);
-
- /* check the current mode */
- new_mode = _e_output_hwc_mode_get(output_hwc);
-
- if (output_hwc->hwc_mode == E_OUTPUT_HWC_MODE_FULL &&
- new_mode != E_OUTPUT_HWC_MODE_FULL)
- ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
-
- output_hwc->hwc_mode = new_mode;
-
- ELOGF("HWC-PLNS", " End... at %s.", NULL, NULL, location);
-}
+++ /dev/null
-#ifdef E_TYPEDEFS
-#else
-#ifndef E_OUTPUT_HWC_PLANES_H
-#define E_OUTPUT_HWC_PLANES_H
-
-/* used by e_output_hwc */
-EINTERN Eina_Bool e_output_hwc_planes_init(void);
-EINTERN void e_output_hwc_planes_deinit(void);
-
-EINTERN Eina_Bool e_output_hwc_planes_usable(E_Output_Hwc *output_hwc);
-EINTERN void e_output_hwc_planes_begin(E_Output_Hwc *output_hwc);
-EINTERN void e_output_hwc_planes_end(E_Output_Hwc *output_hwc, const char *location);
-EINTERN void e_output_hwc_planes_changed(E_Output_Hwc *output_hwc);
-
-EINTERN void e_output_hwc_planes_multi_plane_set(E_Output_Hwc *output_hwc, Eina_Bool set);
-EINTERN Eina_Bool e_output_hwc_planes_multi_plane_get(E_Output_Hwc *output_hwc);
-
-#endif
-#endif
+++ /dev/null
-#include "e.h"
-#include "services/e_service_quickpanel.h"
-
-#define DBG_EVALUATE 1
-
-#define ZPOS_NONE -999
-
-static Eina_Bool _e_output_hwc_windows_pp_output_data_commit(E_Output_Hwc *output_hwc, E_Hwc_Window_Commit_Data *data);
-static Eina_Bool _e_output_hwc_windows_pp_window_commit(E_Output_Hwc *output_hwc, E_Hwc_Window *hwc_window);
-
-// if ec has invalid buffer or scaled( transformed ) or forced composite(never_hwc)
-static Eina_Bool
-_e_output_hwc_windows_device_state_check(E_Client *ec)
-{
- E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
- E_Output *eout;
- int minw = 0, minh = 0;
- int transform;
-
- if ((!cdata) || (!cdata->buffer_ref.buffer))
- {
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(null cdata or buffer)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- return EINA_FALSE;
- }
-
- if ((cdata->width_from_buffer != cdata->width_from_viewport) ||
- (cdata->height_from_buffer != cdata->height_from_viewport))
- {
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(size_from_viewport)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- return EINA_FALSE;
- }
-
- if (cdata->never_hwc)
- {
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(never_hwc)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- return EINA_FALSE;
- }
-
- if (e_client_transform_core_enable_get(ec))
- {
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(transfrom_core)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- return EINA_FALSE;
- }
-
- switch (cdata->buffer_ref.buffer->type)
- {
- case E_COMP_WL_BUFFER_TYPE_NATIVE:
- break;
- case E_COMP_WL_BUFFER_TYPE_TBM:
- if (cdata->buffer_ref.buffer->resource)
- break;
- case E_COMP_WL_BUFFER_TYPE_SHM:
- if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
- break;
- default:
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(buffer_type)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- return EINA_FALSE;
- }
-
- eout = e_output_find(ec->zone->output_id);
- EINA_SAFETY_ON_NULL_RETURN_VAL(eout, EINA_FALSE);
-
- tdm_output_get_available_size(eout->toutput, &minw, &minh, NULL, NULL, NULL);
-
- if ((minw > 0) && (minw > cdata->buffer_ref.buffer->w))
- {
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(minw:%d > buffer->w:%d)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title, minw, cdata->buffer_ref.buffer->w);
- return EINA_FALSE;
- }
-
- if ((minh > 0) && (minh > cdata->buffer_ref.buffer->h))
- {
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(minh:%d > buffer->h:%d)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title, minh, cdata->buffer_ref.buffer->h);
- return EINA_FALSE;
- }
-
- transform = e_comp_wl_output_buffer_transform_get(ec);
-
- /* If a client doesn't watch the ignore_output_transform events, we can't show
- * a client buffer to HW overlay directly when the buffer transform is not same
- * with output transform. If a client watch the ignore_output_transform events,
- * we can control client's buffer transform. In this case, we don't need to
- * check client's buffer transform here.
- */
- if (!e_comp_screen_rotation_ignore_output_transform_watch(ec))
- {
- if ((eout->config.rotation / 90) != transform)
- {
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(no igrore_transfrom)",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- return EINA_FALSE;
- }
- }
-
- return EINA_TRUE;
-}
-
-static E_Output_Hwc_Mode
-_e_output_hwc_windows_hwc_mode_get(E_Output_Hwc *output_hwc)
-{
- Eina_List *l;
- E_Hwc_Window *hwc_window;
- E_Output_Hwc_Mode hwc_mode = E_OUTPUT_HWC_MODE_NONE;
- int num_visible = 0;
- int num_visible_client = 0;
-
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- {
- if (e_hwc_window_is_target(hwc_window)) continue;
-
- if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) continue;
- if (hwc_window->state == E_HWC_WINDOW_STATE_VIDEO) continue;
-
- if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT)
- num_visible_client++;
-
- num_visible++;
- }
-
- if (!num_visible)
- hwc_mode = E_OUTPUT_HWC_MODE_NONE;
- else if (num_visible_client > 0)
- hwc_mode = E_OUTPUT_HWC_MODE_HYBRID;
- else
- hwc_mode = E_OUTPUT_HWC_MODE_FULL;
-
- return hwc_mode;
-}
-
-static int
-_e_output_hwc_windows_sort_cb(const void *d1, const void *d2)
-{
- E_Hwc_Window *hwc_window_1 = (E_Hwc_Window *)d1;
- E_Hwc_Window *hwc_window_2 = (E_Hwc_Window *)d2;
-
- if (!hwc_window_1) return(-1);
- if (!hwc_window_2) return(1);
-
- return (hwc_window_2->zpos - hwc_window_1->zpos);
-}
-
-static unsigned int
-_e_output_hwc_windows_aligned_width_get(tbm_surface_h tsurface)
-{
- unsigned int aligned_width = 0;
- tbm_surface_info_s surf_info;
-
- tbm_surface_get_info(tsurface, &surf_info);
-
- switch (surf_info.format)
- {
- case TBM_FORMAT_YUV420:
- case TBM_FORMAT_YVU420:
- case TBM_FORMAT_YUV422:
- case TBM_FORMAT_YVU422:
- case TBM_FORMAT_NV12:
- case TBM_FORMAT_NV21:
- aligned_width = surf_info.planes[0].stride;
- break;
- case TBM_FORMAT_YUYV:
- case TBM_FORMAT_UYVY:
- aligned_width = surf_info.planes[0].stride >> 1;
- break;
- case TBM_FORMAT_ARGB8888:
- case TBM_FORMAT_XRGB8888:
- aligned_width = surf_info.planes[0].stride >> 2;
- break;
- default:
- ERR("not supported format: %x", surf_info.format);
- }
-
- return aligned_width;
-}
-
-static void
-_e_output_hwc_windows_commit_handler(tdm_output *toutput, unsigned int sequence,
- unsigned int tv_sec, unsigned int tv_usec,
- void *user_data)
-{
- const Eina_List *l;
- E_Hwc_Window *hwc_window;
- E_Output_Hwc *output_hwc = (E_Output_Hwc *)user_data;
-
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
-
- if (output_hwc->pp_tsurface && !output_hwc->output->zoom_set)
- {
- tbm_surface_internal_unref(output_hwc->pp_tsurface);
- output_hwc->pp_tsurface = NULL;
- }
-
- ELOGF("HWC-WINS", "!!!!!!!! Output Commit Handler !!!!!!!!", NULL, NULL);
-
- EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
- {
- if (e_hwc_window_is_video(hwc_window))
- {
- ELOGF("HWC-WINS", "!!!!!!!! Output Commit Handler (VIDEO)!!!!!!!!", NULL, NULL);
- e_comp_wl_video_hwc_window_commit_data_release(hwc_window, sequence, tv_sec, tv_usec);
- }
- if (!e_hwc_window_commit_data_release(hwc_window)) continue;
- }
-
- /* 'wait_commit' is mechanism to make 'fetch and commit' no more than one time per a frame;
- * a 'page flip' happened so it's time to allow to make 'fetch and commit' for the e_output */
- output_hwc->wait_commit = EINA_FALSE;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_prepare_commit(E_Output *output, E_Hwc_Window *hwc_window)
-{
- if (!e_hwc_window_commit_data_aquire(hwc_window))
- return EINA_FALSE;
-
- /* send frame event enlightenment dosen't send frame evnet in nocomp */
- if (hwc_window->ec)
- e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_offscreen_commit(E_Output *output, E_Hwc_Window *hwc_window)
-{
- if (!e_hwc_window_commit_data_aquire(hwc_window))
- return EINA_FALSE;
-
- /* send frame event enlightenment doesn't send frame event in nocomp */
- if (hwc_window->ec)
- e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
-
- e_hwc_window_commit_data_release(hwc_window);
-
- return EINA_TRUE;
-}
-
-static E_Hwc_Window *
-_e_output_hwc_windows_pp_window_get(E_Output_Hwc *output_hwc, tbm_surface_h tsurface)
-{
- Eina_List *l;
- E_Hwc_Window *hwc_window = NULL;
-
- EINA_LIST_FOREACH(output_hwc->pp_hwc_window_list, l, hwc_window)
- {
- if (!hwc_window) continue;
- if (!hwc_window->commit_data) continue;
-
- if (hwc_window->commit_data->tsurface == tsurface)
- return hwc_window;
- }
-
- return NULL;
-}
-
-static void
-_e_output_hwc_windows_pp_pending_data_remove(E_Output_Hwc *output_hwc)
-{
- E_Hwc_Window_Commit_Data *data = NULL;
- Eina_List *l = NULL, *ll = NULL;
-
- if (eina_list_count(output_hwc->pending_pp_commit_data_list) != 0)
- {
- EINA_LIST_FOREACH_SAFE(output_hwc->pending_pp_commit_data_list, l, ll, data)
- {
- if (!data) continue;
- output_hwc->pending_pp_commit_data_list = eina_list_remove_list(output_hwc->pending_pp_commit_data_list, l);
- tbm_surface_queue_release(output_hwc->pp_tqueue, data->tsurface);
- tbm_surface_internal_unref(data->tsurface);
- E_FREE(data);
- }
- }
- eina_list_free(output_hwc->pending_pp_commit_data_list);
- output_hwc->pending_pp_commit_data_list = NULL;
-
- if (eina_list_count(output_hwc->pending_pp_hwc_window_list) != 0)
- {
- E_Hwc_Window *hwc_window;
- EINA_LIST_FOREACH_SAFE(output_hwc->pending_pp_hwc_window_list, l, ll, hwc_window)
- {
- if (!hwc_window) continue;
- output_hwc->pending_pp_hwc_window_list = eina_list_remove_list(output_hwc->pending_pp_hwc_window_list, l);
-
- if (hwc_window->ec) e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
- e_hwc_window_commit_data_release(hwc_window);
- }
- }
- eina_list_free(output_hwc->pending_pp_hwc_window_list);
- output_hwc->pending_pp_hwc_window_list = NULL;
-}
-
-static void
-_e_output_hwc_windows_pp_output_commit_handler(tdm_output *toutput, unsigned int sequence,
- unsigned int tv_sec, unsigned int tv_usec,
- void *user_data)
-{
- E_Output_Hwc *output_hwc;
- E_Hwc_Window_Commit_Data *data = NULL;
- E_Output *output = NULL;
- const Eina_List *l;
- E_Hwc_Window *window;
-
- EINA_SAFETY_ON_NULL_RETURN(user_data);
-
- output_hwc = user_data;
-
- output_hwc->pp_output_commit = EINA_FALSE;
-
- EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, window)
- {
- if (window->commit_data && !window->commit_data->tsurface)
- e_hwc_window_commit_data_release(window);
- }
-
- /* layer already resetted */
- if (output_hwc->pp_output_commit_data)
- {
- data = output_hwc->pp_output_commit_data;
- output_hwc->pp_output_commit_data = NULL;
-
- /* if pp_set is false, do not deal with pending list */
- if (!output_hwc->pp_set)
- {
- if (output_hwc->pp_tsurface)
- tbm_surface_internal_unref(output_hwc->pp_tsurface);
-
- output_hwc->pp_tsurface = data->tsurface;
- output_hwc->wait_commit = EINA_FALSE;
-
- E_FREE(data);
-
- return;
- }
-
- if (output_hwc->pp_tqueue && output_hwc->pp_tsurface)
- {
- /* release and unref the current pp surface on the plane */
- tbm_surface_queue_release(output_hwc->pp_tqueue, output_hwc->pp_tsurface);
- tbm_surface_internal_unref(output_hwc->pp_tsurface);
- }
-
- /* set the new pp surface to the plane */
- output_hwc->pp_tsurface = data->tsurface;
-
- E_FREE(data);
- }
-
- ELOGF("HWC-WINS", "PP Output Commit Handler Output_Hwc(%p)", NULL, NULL, output_hwc);
-
- output = output_hwc->output;
- if (e_output_dpms_get(output))
- {
- _e_output_hwc_windows_pp_pending_data_remove(output_hwc);
- return;
- }
-
- /* deal with the pending layer commit */
- if (eina_list_count(output_hwc->pending_pp_commit_data_list) != 0)
- {
- data = eina_list_nth(output_hwc->pending_pp_commit_data_list, 0);
- if (data)
- {
- output_hwc->pending_pp_commit_data_list = eina_list_remove(output_hwc->pending_pp_commit_data_list, data);
-
- ELOGF("HWC-WINS", "PP Output Commit Handler start pending commit data(%p) tsurface(%p)", NULL, NULL, data, data->tsurface);
-
- if (!_e_output_hwc_windows_pp_output_data_commit(output_hwc, data))
- {
- ERR("fail to _e_output_hwc_windows_pp_output_data_commit");
- return;
- }
- }
- }
-
- /* deal with the pending pp commit */
- if (eina_list_count(output_hwc->pending_pp_hwc_window_list) != 0)
- {
- E_Hwc_Window *hwc_window;
-
- hwc_window = eina_list_nth(output_hwc->pending_pp_hwc_window_list, 0);
- if (hwc_window)
- {
- if (!tbm_surface_queue_can_dequeue(output_hwc->pp_tqueue, 0))
- return;
-
- output_hwc->pending_pp_hwc_window_list = eina_list_remove(output_hwc->pending_pp_hwc_window_list, hwc_window);
-
- if (data)
- ELOGF("HWC-WINS", "PP Layer Commit Handler start pending pp data(%p) tsurface(%p)", NULL, NULL, data, data->tsurface);
- else
- ELOGF("HWC-WINS", "PP Layer Commit Handler start pending pp data(%p) tsurface(%p)", NULL, NULL, NULL, NULL);
-
- if (!_e_output_hwc_windows_pp_window_commit(output_hwc, hwc_window))
- {
- ERR("fail _e_output_hwc_windows_pp_data_commit");
- e_hwc_window_commit_data_release(hwc_window);
- return;
- }
- }
- }
-}
-
-static Eina_Bool
-_e_output_hwc_windows_pp_output_data_commit(E_Output_Hwc *output_hwc, E_Hwc_Window_Commit_Data *data)
-{
- E_Output *output = NULL;
- tdm_layer *toutput = NULL;
- tdm_error terror;
- tdm_hwc_region fb_damage;
-
- /* the damage isn't supported by hwc extension yet */
- memset(&fb_damage, 0, sizeof(fb_damage));
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
-
- output = output_hwc->output;
- toutput = output->toutput;
-
- if (e_output_dpms_get(output))
- {
- _e_output_hwc_windows_pp_pending_data_remove(output_hwc);
- goto fail;
- }
-
- /* no need to pass composited_wnds list because smooth transition isn't
- * used is this case */
- terror = tdm_output_hwc_set_client_target_buffer(toutput, data->tsurface, fb_damage);
- if (terror != TDM_ERROR_NONE)
- {
- ERR("fail to tdm_output_hwc_set_client_target_buffer");
- goto fail;
- }
-
- terror = tdm_output_commit(toutput, 0, _e_output_hwc_windows_pp_output_commit_handler, output_hwc);
-
- if (terror != TDM_ERROR_NONE)
- {
- ERR("fail to tdm_output_commit output_hwc:%p", output_hwc);
- goto fail;
- }
-
- output_hwc->pp_output_commit = EINA_TRUE;
- output_hwc->pp_output_commit_data = data;
-
- return EINA_TRUE;
-
-fail:
- tbm_surface_internal_unref(data->tsurface);
- tbm_surface_queue_release(output_hwc->pp_tqueue, data->tsurface);
- E_FREE(data);
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_pp_output_commit(E_Output_Hwc *output_hwc, tbm_surface_h tsurface)
-{
- tbm_surface_h pp_tsurface = NULL;
- tbm_error_e tbm_err;
- E_Hwc_Window_Commit_Data *data = NULL;
-
- ELOGF("HWC-WINS", "PP Layer Commit output_hwc(%p) pp_tsurface(%p)", NULL, NULL, output_hwc, tsurface);
-
- tbm_err = tbm_surface_queue_enqueue(output_hwc->pp_tqueue, tsurface);
- if (tbm_err != TBM_ERROR_NONE)
- {
- ERR("fail tbm_surface_queue_enqueue");
- goto fail;
- }
-
- tbm_err = tbm_surface_queue_acquire(output_hwc->pp_tqueue, &pp_tsurface);
- if (tbm_err != TBM_ERROR_NONE)
- {
- ERR("fail tbm_surface_queue_acquire");
- goto fail;
- }
-
- data = E_NEW(E_Hwc_Window_Commit_Data, 1);
- if (!data) goto fail;
- data->tsurface = pp_tsurface;
- tbm_surface_internal_ref(data->tsurface);
-
- if (output_hwc->pp_output_commit)
- {
- output_hwc->pending_pp_commit_data_list = eina_list_append(output_hwc->pending_pp_commit_data_list, data);
- return EINA_TRUE;
- }
-
- if (!_e_output_hwc_windows_pp_output_data_commit(output_hwc, data))
- {
- ERR("fail to _e_output_hwc_windows_pp_output_data_commit");
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-
-fail:
- tbm_surface_queue_release(output_hwc->pp_tqueue, tsurface);
- if (pp_tsurface && pp_tsurface != tsurface)
- tbm_surface_queue_release(output_hwc->pp_tqueue, pp_tsurface);
-
- return EINA_FALSE;
-}
-
-static void
-_e_output_hwc_windows_pp_commit_handler(tdm_pp *pp, tbm_surface_h tsurface_src, tbm_surface_h tsurface_dst, void *user_data)
-{
- E_Output *output = NULL;
- E_Output_Hwc *output_hwc = NULL;
- E_Hwc_Window *hwc_window = NULL;
-
- output_hwc = (E_Output_Hwc *)user_data;
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
- hwc_window = _e_output_hwc_windows_pp_window_get(output_hwc, tsurface_src);
- EINA_SAFETY_ON_NULL_RETURN(hwc_window);
-
- output_hwc->pp_hwc_window_list = eina_list_remove(output_hwc->pp_hwc_window_list, hwc_window);
-
- if (hwc_window->ec) e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
- e_hwc_window_commit_data_release(hwc_window);
-
- if (eina_list_count(output_hwc->pending_pp_hwc_window_list) == 0)
- {
- output_hwc->wait_commit = EINA_FALSE;
- output_hwc->pp_commit = EINA_FALSE;
- }
-
- ELOGF("HWC-WINS", "PP Commit Handler output_hwc(%p) tsurface src(%p) dst(%p)",
- NULL, NULL, output_hwc, tsurface_src, tsurface_dst);
-
- /* if pp_set is false, skip the commit */
- if (!output_hwc->pp_set)
- {
- if (output_hwc->tpp)
- {
- tdm_pp_destroy(output_hwc->tpp);
- output_hwc->tpp = NULL;
- }
- goto done;
- }
-
- output = output_hwc->output;
- if (e_output_dpms_get(output))
- {
- _e_output_hwc_windows_pp_pending_data_remove(output_hwc);
- tbm_surface_queue_release(output_hwc->pp_tqueue, tsurface_dst);
-
- goto done;
- }
-
- if (!_e_output_hwc_windows_pp_output_commit(output_hwc, tsurface_dst))
- ERR("fail to _e_output_hwc_windows_pp_output_commit");
-
-done:
- tbm_surface_internal_unref(tsurface_src);
- tbm_surface_internal_unref(tsurface_dst);
-}
-
-static Eina_Bool
-_e_output_hwc_pp_windows_info_set(E_Output_Hwc *output_hwc, E_Hwc_Window *hwc_window,
- tbm_surface_h dst_tsurface)
-{
- tdm_info_pp pp_info;
- tdm_error ret = TDM_ERROR_NONE;
- unsigned int aligned_width_src = 0, aligned_width_dst = 0;
- tbm_surface_info_s surf_info_src, surf_info_dst;
- tbm_surface_h src_tsurface = hwc_window->commit_data->tsurface;
-
- /* when the pp_set_info is true, change the pp set_info */
- if (!output_hwc->pp_set_info) return EINA_TRUE;
- output_hwc->pp_set_info = EINA_FALSE;
-
- tbm_surface_get_info(src_tsurface, &surf_info_src);
-
- aligned_width_src = _e_output_hwc_windows_aligned_width_get(src_tsurface);
- if (aligned_width_src == 0) return EINA_FALSE;
-
- tbm_surface_get_info(dst_tsurface, &surf_info_dst);
-
- aligned_width_dst = _e_output_hwc_windows_aligned_width_get(dst_tsurface);
- if (aligned_width_dst == 0) return EINA_FALSE;
-
- pp_info.src_config.size.h = aligned_width_src;
- pp_info.src_config.size.v = surf_info_src.height;
- pp_info.src_config.format = surf_info_src.format;
-
- pp_info.dst_config.size.h = aligned_width_dst;
- pp_info.dst_config.size.v = surf_info_dst.height;
- pp_info.dst_config.format = surf_info_dst.format;
-
- pp_info.transform = TDM_TRANSFORM_NORMAL;
- pp_info.sync = 0;
- pp_info.flags = 0;
-
- pp_info.src_config.pos.x = output_hwc->pp_rect.x;
- pp_info.src_config.pos.y = output_hwc->pp_rect.y;
- pp_info.src_config.pos.w = output_hwc->pp_rect.w;
- pp_info.src_config.pos.h = output_hwc->pp_rect.h;
- pp_info.dst_config.pos.x = 0;
- pp_info.dst_config.pos.y = 0;
- pp_info.dst_config.pos.w = surf_info_dst.width;
- pp_info.dst_config.pos.h = surf_info_dst.height;
-
- ret = tdm_pp_set_info(output_hwc->tpp, &pp_info);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
-
- ELOGF("HWC-WINS", "PP Info Output_Hwc(%p) src_rect(%d,%d),(%d,%d), dst_rect(%d,%d),(%d,%d)",
- NULL, NULL, output_hwc,
- pp_info.src_config.pos.x, pp_info.src_config.pos.y, pp_info.src_config.pos.w, pp_info.src_config.pos.h,
- pp_info.dst_config.pos.x, pp_info.dst_config.pos.y, pp_info.dst_config.pos.w, pp_info.dst_config.pos.h);
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_pp_window_commit(E_Output_Hwc *output_hwc, E_Hwc_Window *hwc_window)
-{
- E_Output *output = NULL;
- tbm_surface_h pp_tsurface = NULL;
- tbm_error_e tbm_err = TBM_ERROR_NONE;
- tdm_error terror = TDM_ERROR_NONE;
- E_Hwc_Window_Commit_Data *commit_data = hwc_window->commit_data;
- EINA_SAFETY_ON_FALSE_RETURN_VAL(commit_data, EINA_FALSE);
-
- tbm_surface_h tsurface = commit_data->tsurface;
-
- ELOGF("HWC-WINS", "PP Commit Output_Hwc(%p) tsurface(%p) tqueue(%p) wl_buffer(%p) data(%p)",
- NULL, NULL, output_hwc, commit_data->tsurface, output_hwc->pp_tqueue,
- commit_data->buffer_ref.buffer ? commit_data->buffer_ref.buffer->resource : NULL, commit_data);
-
- output = output_hwc->output;
- if (e_output_dpms_get(output))
- {
- _e_output_hwc_windows_pp_pending_data_remove(output_hwc);
- return EINA_FALSE;
- }
-
- tbm_err = tbm_surface_queue_dequeue(output_hwc->pp_tqueue, &pp_tsurface);
- if (tbm_err != TBM_ERROR_NONE)
- {
- ERR("fail tbm_surface_queue_dequeue");
- return EINA_FALSE;
- }
-
- if (!_e_output_hwc_pp_windows_info_set(output_hwc, hwc_window, pp_tsurface))
- {
- ERR("fail _e_output_hwc_windows_info_set");
- goto pp_fail;
- }
-
- terror = tdm_pp_set_done_handler(output_hwc->tpp, _e_output_hwc_windows_pp_commit_handler, output_hwc);
- EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, pp_fail);
-
- tbm_surface_internal_ref(pp_tsurface);
- tbm_surface_internal_ref(commit_data->tsurface);
- terror = tdm_pp_attach(output_hwc->tpp, commit_data->tsurface, pp_tsurface);
- EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, attach_fail);
-
- output_hwc->pp_hwc_window_list = eina_list_append(output_hwc->pp_hwc_window_list, hwc_window);
-
- terror = tdm_pp_commit(output_hwc->tpp);
- EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, commit_fail);
-
- output_hwc->wait_commit = EINA_TRUE;
- output_hwc->pp_commit = EINA_TRUE;
-
- return EINA_TRUE;
-
-commit_fail:
- output_hwc->pp_hwc_window_list = eina_list_remove(output_hwc->pp_hwc_window_list, hwc_window);
-attach_fail:
- tbm_surface_internal_unref(pp_tsurface);
- tbm_surface_internal_unref(tsurface);
-pp_fail:
- tbm_surface_queue_release(output_hwc->pp_tqueue, pp_tsurface);
-
- ERR("failed _e_output_hwc_windows_pp_data_commit");
-
- return EINA_FALSE;
-}
-
-static E_Hwc_Window *
-_e_output_hwc_windows_pp_get_hwc_window_for_zoom(E_Output_Hwc *output_hwc)
-{
- const Eina_List *hwc_windows, *l;
- E_Hwc_Window *hwc_window = NULL;
- E_Hwc_Window *hwc_window_for_zoom = NULL;
- int num = 0;
- int w, h;
-
- e_output_size_get(output_hwc->output, &w, &h);
-
- hwc_windows = e_output_hwc_windows_get(output_hwc);
- EINA_LIST_FOREACH(hwc_windows, l, hwc_window)
- {
- if (!e_hwc_window_is_on_hw_overlay(hwc_window)) continue;
-
- hwc_window_for_zoom = hwc_window;
- num++;
- }
-
- if (num != 1) return NULL;
- if (!hwc_window_for_zoom->tsurface) return NULL;
- if (tbm_surface_get_width(hwc_window_for_zoom->tsurface) != w ||
- tbm_surface_get_height(hwc_window_for_zoom->tsurface) != h)
- return NULL;
-
- return hwc_window_for_zoom;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_pp_commit(E_Output_Hwc *output_hwc)
-{
- E_Hwc_Window_Commit_Data *commit_data = NULL;
- E_Hwc_Window *hwc_window = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc->pp_tqueue, EINA_FALSE);
-
- hwc_window = _e_output_hwc_windows_pp_get_hwc_window_for_zoom(output_hwc);
- EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
-
- commit_data = hwc_window->commit_data;
- if (!commit_data) return EINA_TRUE;
- if (!commit_data->tsurface) return EINA_TRUE;
-
- if (!tbm_surface_queue_can_dequeue(output_hwc->pp_tqueue, 0))
- {
- ELOGF("HWC-WINS", "PP Commit Can Dequeue failed Output_Hwc(%p) tsurface(%p) tqueue(%p) wl_buffer(%p) data(%p)",
- NULL, NULL, output_hwc, commit_data->tsurface, output_hwc->pp_tqueue,
- commit_data->buffer_ref.buffer ? commit_data->buffer_ref.buffer->resource : NULL, commit_data);
- output_hwc->pending_pp_hwc_window_list = eina_list_append(output_hwc->pending_pp_hwc_window_list, hwc_window);
-
- output_hwc->wait_commit = EINA_TRUE;
-
- return EINA_TRUE;
- }
-
- if (eina_list_count(output_hwc->pending_pp_hwc_window_list) != 0)
- {
- ELOGF("HWC-WINS", "PP Commit Pending pp data remained Output_Hwc(%p) tsurface(%p) tqueue(%p) wl_buffer(%p) data(%p)",
- NULL, NULL, output_hwc, commit_data->tsurface, output_hwc->pp_tqueue,
- commit_data->buffer_ref.buffer ? commit_data->buffer_ref.buffer->resource : NULL, commit_data);
- output_hwc->pending_pp_hwc_window_list = eina_list_append(output_hwc->pending_pp_hwc_window_list, hwc_window);
-
- output_hwc->wait_commit = EINA_TRUE;
-
- return EINA_TRUE;
- }
-
- if (!_e_output_hwc_windows_pp_window_commit(output_hwc, hwc_window))
- {
- ERR("fail _e_output_hwc_windows_pp_data_commit");
- e_hwc_window_commit_data_release(hwc_window);
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-static void
-_e_output_hwc_windows_status_print(E_Output_Hwc *output_hwc, Eina_Bool with_target)
-{
- const Eina_List *l;
- Eina_List *sort_wnds;
- E_Hwc_Window *hwc_window;
-
- sort_wnds = eina_list_clone(output_hwc->hwc_windows);
- sort_wnds = eina_list_sort(sort_wnds, eina_list_count(sort_wnds), _e_output_hwc_windows_sort_cb);
-
- EINA_LIST_FOREACH(sort_wnds, l, hwc_window)
- {
- if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) continue;
-
- if (e_hwc_window_is_target(hwc_window))
- {
- if (!with_target) continue;
-
- ELOGF("HWC-WINS", " ehw:%p ts:%p -- {%25s}, state:%s",
- NULL, NULL, hwc_window, hwc_window->tsurface, "@TARGET WINDOW@",
- e_hwc_window_state_string_get(hwc_window->state));
- continue;
- }
-
- ELOGF("HWC-WINS", " ehw:%p ts:%p -- {%25s}, state:%s, zpos:%d, deleted:%s",
- hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
- hwc_window, hwc_window->tsurface, hwc_window->ec ? hwc_window->ec->icccm.title : "UNKNOWN",
- e_hwc_window_state_string_get(hwc_window->state),
- hwc_window->zpos, hwc_window->is_deleted ? "yes" : "no");
- }
-
- eina_list_free(sort_wnds);
-}
-
-static void
-_e_output_hwc_windows_ouput_commit_dump(E_Output_Hwc *output_hwc)
-{
- const Eina_List *l;
- Eina_List *sort_wnds;
- E_Hwc_Window *hwc_window;
- char fname[PATH_MAX];
- Ecore_Window ec_win;
- int i = 0;
-
- sort_wnds = eina_list_clone(output_hwc->hwc_windows);
- sort_wnds = eina_list_sort(sort_wnds, eina_list_count(sort_wnds), _e_output_hwc_windows_sort_cb);
-
- EINA_LIST_FOREACH(sort_wnds, l, hwc_window)
- {
- if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) continue;
-
- ec_win = e_client_util_win_get(hwc_window->ec);
-
- if (e_hwc_window_is_target(hwc_window))
- snprintf(fname, sizeof(fname), "(%d)_output_commit_0x%08x_%s", i++, ec_win, e_hwc_window_state_string_get(hwc_window->state));
- else
- snprintf(fname, sizeof(fname), "(%d)_output_commit_0x%08x_%s_%d", i++, ec_win, e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
-
- tbm_surface_internal_dump_buffer(hwc_window->tsurface, fname);
- }
-
- eina_list_free(sort_wnds);
-}
-
-static E_Hwc_Window *
-_e_output_hwc_windows_window_find_by_twin(E_Output_Hwc *output_hwc, tdm_hwc_window *hwc_win)
-{
- Eina_List *l;
- E_Hwc_Window *hwc_window;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_win, NULL);
-
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- {
- if (hwc_window->thwc_window == hwc_win) return hwc_window;
- }
-
- return NULL;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_compsitions_update(E_Output_Hwc *output_hwc)
-{
- const Eina_List *l;
- E_Hwc_Window *hwc_window;
-
- EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
- {
- if (e_hwc_window_is_target(hwc_window)) continue;
-
- if (!e_hwc_window_compsition_update(hwc_window))
- {
- ERR("HWC-WINS: cannot update E_Hwc_Window(%p)", hwc_window);
- return EINA_FALSE;
- }
- }
-
-#if DBG_EVALUATE
- ELOGF("HWC-WINS", " Request HWC Validation to TDM HWC:", NULL, NULL);
- _e_output_hwc_windows_status_print(output_hwc, EINA_FALSE);
-#endif
-
- return EINA_TRUE;
-}
-
-static E_Hwc_Window_State
-_e_output_hwc_windows_window_state_get(tdm_hwc_window_composition composition_type)
-{
- E_Hwc_Window_State state = E_HWC_WINDOW_STATE_NONE;
-
- switch (composition_type)
- {
- case TDM_COMPOSITION_NONE:
- state = E_HWC_WINDOW_STATE_NONE;
- break;
- case TDM_COMPOSITION_CLIENT:
- state = E_HWC_WINDOW_STATE_CLIENT;
- break;
- case TDM_COMPOSITION_DEVICE:
- state = E_HWC_WINDOW_STATE_DEVICE;
- break;
- case TDM_COMPOSITION_DEVICE_CANDIDATE:
- state = E_HWC_WINDOW_STATE_DEVICE_CANDIDATE;
- break;
- case TDM_COMPOSITION_CURSOR:
- state = E_HWC_WINDOW_STATE_CURSOR;
- break;
- case TDM_COMPOSITION_VIDEO:
- state = E_HWC_WINDOW_STATE_VIDEO;
- break;
- default:
- state = E_HWC_WINDOW_STATE_NONE;
- ERR("HWC-WINS: unknown state of hwc_window.");
- }
-
- return state;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_accept(E_Output_Hwc *output_hwc, uint32_t num_changes)
-{
- E_Output *output = output_hwc->output;
- E_Hwc_Window *hwc_window;
- E_Hwc_Window_State state;
- tdm_error terror;
- tdm_output *toutput = output->toutput;
- tdm_hwc_window **changed_hwc_window = NULL;
- tdm_hwc_window_composition *composition_types = NULL;
- Eina_Bool accept_changes = EINA_TRUE;
- int i;
-
- changed_hwc_window = E_NEW(tdm_hwc_window *, num_changes);
- EINA_SAFETY_ON_NULL_GOTO(changed_hwc_window, fail);
-
- composition_types = E_NEW(tdm_hwc_window_composition, num_changes);
- EINA_SAFETY_ON_NULL_GOTO(composition_types, fail);
-
- terror = tdm_output_hwc_get_changed_composition_types(toutput,
- &num_changes, changed_hwc_window,
- composition_types);
- if (terror != TDM_ERROR_NONE)
- {
- ERR("HWC-WINS: failed to get changed composition types");
- goto fail;
- }
-
- ELOGF("HWC-WINS", " Accept Changes NUM : %d", NULL, NULL, num_changes);
-
- for (i = 0; i < num_changes; ++i)
- {
- hwc_window = _e_output_hwc_windows_window_find_by_twin(output_hwc, changed_hwc_window[i]);
- if (!hwc_window)
- {
- ERR("HWC-WINS: cannot find the E_Hwc_Window by hwc hwc_window");
- goto fail;
- }
-
- /* accept_changes failed at DEVICE to CLIENT transition */
- if (hwc_window->prev_state == E_HWC_WINDOW_STATE_DEVICE &&
- composition_types[i] == TDM_COMPOSITION_CLIENT)
- {
- if (!e_hwc_window_is_on_target_window(hwc_window))
- {
- hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT;
- accept_changes = EINA_FALSE;
-
- ELOGF("HWC-WINS", " E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT is set.(Accept_Changes)",
- hwc_window->ec ? ec->pixmap : NULL, hwc_window->ec);
- }
- }
-
- /* update the state with the changed compsition */
- state = _e_output_hwc_windows_window_state_get(composition_types[i]);
- e_hwc_window_state_set(hwc_window, state);
- }
-
-#if DBG_EVALUATE
- ELOGF("HWC-WINS", " Modified after HWC Validation:", NULL, NULL);
- _e_output_hwc_windows_status_print(output_hwc, EINA_FALSE);
-#endif
-
- /* re-validate when there is a DEVICE_TO_CLIENT transition */
- if (!accept_changes) goto fail;
-
- /* accept changes */
- terror = tdm_output_hwc_accept_changes(toutput);
- if (terror != TDM_ERROR_NONE)
- {
- ERR("HWC-WINS: failed to accept changes required by the hwc extension");
- goto fail;
- }
-
- free(changed_hwc_window);
- free(composition_types);
-
- return EINA_TRUE;
-
-fail:
- if (changed_hwc_window) free(changed_hwc_window);
- if (composition_types) free(composition_types);
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_validate(E_Output_Hwc *output_hwc, Eina_List *visible_windows_list, uint32_t *num_changes)
-{
- E_Output *output = output_hwc->output;
- tdm_error terror;
- tdm_output *toutput = output->toutput;
- tdm_hwc_window **thwc_windows = NULL;
- int i, n_thw;
- E_Hwc_Window *hwc_window;
- const Eina_List *l;
-
- n_thw = eina_list_count(visible_windows_list);
- if (n_thw)
- {
- thwc_windows = E_NEW(tdm_hwc_window *, n_thw);
- EINA_SAFETY_ON_NULL_GOTO(thwc_windows, error);
-
- i = 0;
- EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
- thwc_windows[i++] = hwc_window->thwc_window;
- }
-
- /* make hwc extension choose which clients will own hw overlays */
- terror = tdm_output_hwc_validate(toutput, thwc_windows, n_thw, num_changes);
- if (terror != TDM_ERROR_NONE) goto error;
-
- E_FREE(thwc_windows);
-
- return EINA_TRUE;
-
-error:
- ERR("HWC-WINS: failed to validate the output(%p)", toutput);
- E_FREE(thwc_windows);
-
- return EINA_FALSE;
-}
-
-static void
-_e_output_hwc_windows_activation_states_update(E_Output_Hwc *output_hwc)
-{
- E_Hwc_Window *hwc_window;
- const Eina_List *l;
-
- /* mark the active/deactive on hwc_window */
- EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
- {
- if (hwc_window->is_deleted) continue;
- if (e_hwc_window_is_target(hwc_window)) continue;
-
- if (e_hwc_window_is_on_hw_overlay(hwc_window))
- /* notify the hwc_window that it will be displayed on hw layer */
- e_hwc_window_activate(hwc_window);
- else
- /* notify the hwc_window that it will be composite on the target buffer */
- e_hwc_window_deactivate(hwc_window);
- }
-}
-
-static Eina_Bool
-_e_output_hwc_windows_target_window_render(E_Output *output, E_Hwc_Window_Target *target_hwc_window)
-{
- if (target_hwc_window->hwc_window.state == E_HWC_WINDOW_STATE_NONE) return EINA_TRUE;
-
- if (e_comp_canvas_norender_get() > 0)
- {
- ELOGF("HWC-WINS", " NoRender get. Do not ecore_evas_manual_render.", NULL, NULL);
- return EINA_TRUE;
- }
-
- /* render the ecore_evas and
- update_ee is to be true at post_render_cb when the render is successful. */
- TRACE_DS_BEGIN(MANUAL RENDER);
-
- if (e_hwc_window_target_surface_queue_can_dequeue(target_hwc_window))
- {
- ELOGF("HWC-WINS", "###### Render target window(ecore_evas_manual_render))", NULL, NULL);
- ecore_evas_manual_render(target_hwc_window->ee);
- }
-
- TRACE_DS_END();
-
- return EINA_TRUE;
-}
-
-static Eina_List *
-_e_output_hwc_windows_visible_windows_list_get(E_Output_Hwc *output_hwc)
-{
- Eina_List *windows_list = NULL;
- Eina_List *l;
- E_Hwc_Window *hwc_window;
- E_Client *ec;
- Evas_Object *o;
- int scr_w, scr_h;
- int zpos = 0;
- E_Comp_Wl_Client_Data *cdata = NULL;
-
- for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
- {
- ec = evas_object_data_get(o, "E_Client");
- if (!ec) continue;
- if (!ec->hwc_window) continue;
-
- hwc_window = ec->hwc_window;
-
- if (e_object_is_del(E_OBJECT(ec)))
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} ec is destroying. Set E_HWC_WINDOW_STATE_NONE.",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- continue;
- }
-
- // check clients to skip composite
- if (e_client_util_ignored_get(ec))
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} ec is ignored. Set E_HWC_WINDOW_STATE_NONE.",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- continue;
- }
-
- // check clients to skip composite
- if (!evas_object_visible_get(ec->frame))
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} ec->frame is not visible. Set E_HWC_WINDOW_STATE_NONE.",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- continue;
- }
-
- // check geometry if located out of screen such as quick panel
- ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &scr_w, &scr_h);
- if (!E_INTERSECTS(0, 0, scr_w, scr_h, ec->client.x, ec->client.y, ec->client.w, ec->client.h))
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- continue;
- }
-
- if (evas_object_data_get(ec->frame, "comp_skip"))
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- continue;
- }
-
- /* skip all small clients except the video clients */
- if ((ec->w == 1 || ec->h == 1) && !e_hwc_window_is_video(hwc_window))
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- continue;
- }
-
- /* skip the cdata is null */
- cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
- if (!cdata)
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} cdata is NULL. Set E_HWC_WINDOW_STATE_NONE.",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- continue;
- }
-
- /* skip the cdata->buffer_ref.buffer is null */
- if (!cdata->buffer_ref.buffer)
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} cdata->buffer_ref.buffer is NULL. Set E_HWC_WINDOW_STATE_NONE.",
- ec->pixmap, ec, ec->hwc_window, ec->icccm.title);
- continue;
- }
-
- if (e_hwc_window_is_video(hwc_window))
- {
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_VIDEO);
- continue;
- }
-
- windows_list = eina_list_append(windows_list, hwc_window);
- }
-
- /* assign zpos */
- EINA_LIST_REVERSE_FOREACH(windows_list, l, hwc_window)
- e_hwc_window_zpos_set(hwc_window, zpos++);
-
- output_hwc->num_visible_windows = eina_list_count(windows_list);
-
-#if DBG_EVALUATE
- ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, output_hwc->num_visible_windows);
-#endif
- return windows_list;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_full_gl_composite_check(E_Output_Hwc *output_hwc, Eina_List *visible_windows_list)
-{
- Eina_List *l;
- E_Client *ec;
- E_Hwc_Window *hwc_window = NULL;
-
- /* make the full_gl_composite when the zoom is enabled */
- if (output_hwc->output->zoom_set) goto full_gl_composite;
-
- /* full composite is forced to be set */
- if (e_output_hwc_deactive_get(output_hwc)) goto full_gl_composite;
-
- /* hwc_window manager required full GLES composition */
- if (e_comp->nocomp_override > 0)
- {
- ELOGF("HWC-WINS", " HWC_MODE_HYBRID due to nocomp_override > 0.", NULL, NULL);
- goto full_gl_composite;
- }
-
- EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
- {
- ec = hwc_window->ec;
-
- // if there is a ec which is lower than quickpanel and quickpanel is opened.
- if (E_POLICY_QUICKPANEL_LAYER >= evas_object_layer_get(ec->frame))
- {
- // check whether quickpanel is open than break
- if (e_qp_visible_get())
- {
- ELOGF("HWC-WINS", " HWC_MODE_NONE due to quickpanel is opened.{%25s}.",
- ec->pixmap, ec, ec->icccm.title);
- goto full_gl_composite;
- }
- }
-
- // if ec->frame is not for client buffer (e.g. launchscreen)
- if (e_comp_object_content_type_get(ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
- {
- ELOGF("HWC-WINS", " HWC_MODE_NONE due to E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE{%25s}.",
- ec->pixmap, ec, ec->icccm.title);
- goto full_gl_composite;
- }
-
- // if there is UI subfrace, it means need to composite
- if (e_client_normal_client_has(ec))
- {
- ELOGF("HWC-WINS", " HWC_MODE_NONE due to UI subfrace{%25s}.",
- ec->pixmap, ec, ec->icccm.title);
- goto full_gl_composite;
- }
- }
-
- return EINA_FALSE;
-
-full_gl_composite:
- EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
- {
- /* The video window is not composited by gl compositor */
- if (e_hwc_window_is_video(hwc_window)) continue;
-
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT);
-
- ELOGF("HWC-WINS", " ehw:%p -- {%25s} is NOT hwc_acceptable.",
- hwc_window->ec->pixmap, hwc_window->ec, hwc_window, hwc_window->ec->icccm.title);
- }
- return EINA_TRUE;
-}
-
-/* filter visible clients by the hwc_window manager
- *
- * returns list of clients which are acceptable to be composited by hw,
- * it's a caller responsibility to free it
- *
- * for optimized hwc the returned list contains ALL clients
- */
-static void
-_e_output_hwc_windows_hwc_acceptable_check(Eina_List *visible_windows_list)
-{
- Eina_List *l;
- E_Hwc_Window *hwc_window = NULL;
-
- EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
- {
- /* The video window is not composited by gl compositor */
- if (e_hwc_window_is_video(hwc_window)) continue;
-
- // check clients are able to use hwc
- if (_e_output_hwc_windows_device_state_check(hwc_window->ec))
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_DEVICE);
- else
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT);
- }
-}
-
-static Eina_Bool
-_e_output_hwc_windows_composition_evaulate(E_Output_Hwc *output_hwc, Eina_List *visible_windows_list)
-{
- Eina_Bool ret = EINA_FALSE;
- uint32_t num_changes;
-
- /* evaluate the transition */
- if (!_e_output_hwc_windows_compsitions_update(output_hwc))
- {
- ERR("HWC-WINS: _e_output_hwc_windows_compsitions_update failed.");
- ret = EINA_FALSE;
- goto done;
- }
-
- /* validate the updated hwc_windows by asking tdm_hwc_output */
- if (!_e_output_hwc_windows_validate(output_hwc, visible_windows_list, &num_changes))
- {
- ERR("HWC-WINS: _e_output_hwc_windows_validate failed.");
- ret = EINA_FALSE;
- goto done;
- }
-
- if (num_changes > 0)
- {
- if (_e_output_hwc_windows_accept(output_hwc, num_changes))
- ret = EINA_TRUE;
- else
- ret = EINA_FALSE;
- }
- else
- ret = EINA_TRUE;
-
-done:
-
- return ret;
-}
-
-static Eina_List *
-_e_output_hwc_windows_states_evaluate(E_Output_Hwc *output_hwc)
-{
- Eina_List *visible_windows_list = NULL;
-
- /* get the visible ecs */
- visible_windows_list = _e_output_hwc_windows_visible_windows_list_get(output_hwc);
-
- /* check the gles composite with all hwc_windows. */
- if (!_e_output_hwc_windows_full_gl_composite_check(output_hwc, visible_windows_list))
- {
- /* by demand of hwc_window manager to prevent some e_clients to be shown by hw directly */
- _e_output_hwc_windows_hwc_acceptable_check(visible_windows_list);
- }
-
- return visible_windows_list;
-}
-
-/* evaluate the hwc_windows */
-static Eina_Bool
-_e_output_hwc_windows_evaluate(E_Output_Hwc *output_hwc, Eina_List *visible_windows_list)
-{
- E_Output_Hwc_Mode hwc_mode = E_OUTPUT_HWC_MODE_NONE;
- E_Hwc_Window *target_window = (E_Hwc_Window *)output_hwc->target_hwc_window;
-
- ELOGF("HWC-WINS", "====================== Output HWC Apply (evaluate) ======================", NULL, NULL);
-
- /* evaulate the compositions with the states*/
- if (_e_output_hwc_windows_composition_evaulate(output_hwc, visible_windows_list))
- ELOGF("HWC-WINS", " Succeed the compsition_evaulation.", NULL, NULL);
- else
- ELOGF("HWC-WINS", " Need the comopsition re-evaulation.", NULL, NULL);
-
- /* update the activate/decativate state */
- _e_output_hwc_windows_activation_states_update(output_hwc);
-
- /* decide the E_OUTPUT_HWC_MODE */
- hwc_mode = _e_output_hwc_windows_hwc_mode_get(output_hwc);
- if (output_hwc->hwc_mode != hwc_mode)
- {
- if (hwc_mode == E_OUTPUT_HWC_MODE_HYBRID || hwc_mode == E_OUTPUT_HWC_MODE_NONE)
- ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
- else
- ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
-
- output_hwc->hwc_mode = hwc_mode;
- }
-
-#if DBG_EVALUATE
- if (hwc_mode == E_OUTPUT_HWC_MODE_NONE)
- ELOGF("HWC-WINS", " HWC_MODE is NONE composition.", NULL, NULL);
- else if (hwc_mode == E_OUTPUT_HWC_MODE_HYBRID)
- ELOGF("HWC-WINS", " HWC_MODE is HYBRID composition.", NULL, NULL);
- else
- ELOGF("HWC-WINS", " HWC_MODE is FULL HW composition.", NULL, NULL);
-#endif
-
- /* set the state of the target_window */
- if (hwc_mode == E_OUTPUT_HWC_MODE_HYBRID || hwc_mode == E_OUTPUT_HWC_MODE_NONE)
- e_hwc_window_state_set(target_window, E_HWC_WINDOW_STATE_DEVICE);
- else
- e_hwc_window_state_set(target_window, E_HWC_WINDOW_STATE_NONE);
-
- /* target state is DEVICE and no surface, then return false */
- if (e_hwc_window_state_get(target_window) == E_HWC_WINDOW_STATE_DEVICE &&
- target_window->tsurface == NULL)
- {
- ELOGF("HWC-WINS", "Need target_window buffer.", NULL, NULL);
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-static void
-_e_output_hwc_windows_prev_states_update(E_Output_Hwc *output_hwc)
-{
- E_Hwc_Window *hwc_window = NULL;
- Eina_List *l;
-
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- e_hwc_window_prev_state_update(hwc_window);
-}
-
-/* check if there is a need to update the output */
-static Eina_Bool
-_e_output_hwc_windows_update_changes(E_Output_Hwc *output_hwc)
-{
- const Eina_List *l;
- E_Hwc_Window *hwc_window;
- Eina_Bool update_changes = EINA_FALSE;
-
- /* fetch the target buffer */
- if (e_hwc_window_target_buffer_fetch(output_hwc->target_hwc_window)) // try aquire
- update_changes = EINA_TRUE;
-
- /* fetch the windows buffers */
- EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
- {
- if (e_hwc_window_is_target(hwc_window)) continue;
-
- if (!e_hwc_window_buffer_fetch(hwc_window))
- continue;
-
- if (!e_hwc_window_buffer_update(hwc_window))
- {
- ERR("HWC-WINS: cannot update E_Hwc_Window(%p)", hwc_window);
- continue;
- }
-
- update_changes = EINA_TRUE;
- }
-
- return update_changes;
-}
-
-EINTERN Eina_Bool
-e_output_hwc_windows_init(E_Output_Hwc *output_hwc)
-{
- return EINA_TRUE;
-}
-
-EINTERN void
-e_output_hwc_windows_deinit(void)
-{
- // TDOO:
- ;;;
-}
-
-EINTERN const Eina_List *
-e_output_hwc_windows_get(E_Output_Hwc *output_hwc)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, NULL);
-
- return output_hwc->hwc_windows;
-}
-
-EINTERN Eina_Bool
-e_output_hwc_windows_render(E_Output_Hwc *output_hwc)
-{
- E_Output *output = output_hwc->output;
- E_Hwc_Window_Target *target_hwc_window;
-
- target_hwc_window = output_hwc->target_hwc_window;
- if (!target_hwc_window)
- {
- ERR("fail to get target hwc_window for output(%p).", output);
- return EINA_FALSE;
- }
-
- if (!_e_output_hwc_windows_target_window_render(output, target_hwc_window))
- ERR("fail to render output(%p).", output);
-
- return EINA_TRUE;
-}
-
-EINTERN Eina_Bool
-e_output_hwc_windows_commit(E_Output_Hwc *output_hwc)
-{
- E_Hwc_Window *hwc_window = NULL;
- Eina_List *l;
- E_Output *output = NULL;
- tdm_error error = TDM_ERROR_NONE;
- Eina_List *visible_windows_list = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
-
- output = output_hwc->output;
-
- if (output_hwc->wait_commit)
- {
- ELOGF("HWC-WINS", "!!!!!!!! Didn't get Output Commit Handler Yet !!!!!!!!", NULL, NULL);
- return EINA_TRUE;
- }
-
- if (e_comp_canvas_norender_get() > 0)
- {
- ELOGF("HWC-WINS", " Block Display... NoRender get.", NULL, NULL);
- return EINA_TRUE;
- }
-
- if (output->dpms == E_OUTPUT_DPMS_OFF)
- {
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- _e_output_hwc_windows_offscreen_commit(output, hwc_window);
-
- return EINA_TRUE;
- }
-
- /* evaulate the current states */
- visible_windows_list = _e_output_hwc_windows_states_evaluate(output_hwc);
-
- if (_e_output_hwc_windows_update_changes(output_hwc))
- {
- if (!_e_output_hwc_windows_evaluate(output_hwc, visible_windows_list))
- {
- ELOGF("HWC-WINS", "Evaluation is not completed. No Commit at this time.", NULL, NULL);
- /* update the previous states. */
- _e_output_hwc_windows_prev_states_update(output_hwc);
- goto fail;
- }
-
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- _e_output_hwc_windows_prepare_commit(output, hwc_window);
-
- if (output->zoom_set)
- {
- e_output_zoom_rotating_check(output);
- ELOGF("HWC-WINS", "###### PP Commit", NULL, NULL);
- if (!_e_output_hwc_windows_pp_commit(output_hwc))
- {
- ERR("_e_output_hwc_windows_pp_commit failed.");
- goto fail;
- }
- }
- else
- {
- ELOGF("HWC-WINS", "!!!!!!!! Output Commit !!!!!!!!", NULL, NULL);
- ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, output_hwc->num_visible_windows);
- _e_output_hwc_windows_status_print(output_hwc, EINA_TRUE);
- _e_output_hwc_windows_ouput_commit_dump(output_hwc);
-
- error = tdm_output_commit(output->toutput, 0, _e_output_hwc_windows_commit_handler, output_hwc);
- if (error != TDM_ERROR_NONE)
- {
- ERR("tdm_output_commit failed.");
- _e_output_hwc_windows_commit_handler(output->toutput, 0, 0, 0, output_hwc);
- goto fail;
- }
-
- output_hwc->wait_commit = EINA_TRUE;
- }
-
-
- /* update the previous states. */
- _e_output_hwc_windows_prev_states_update(output_hwc);
- }
-
- if (visible_windows_list)
- eina_list_free(visible_windows_list);
-
- return EINA_TRUE;
-
-fail:
-
- if (visible_windows_list)
- eina_list_free(visible_windows_list);
-
- return EINA_FALSE;
-}
-
-EINTERN Eina_Bool
-e_output_hwc_windows_pp_commit_possible_check(E_Output_Hwc *output_hwc)
-{
- if (!output_hwc->pp_set) return EINA_FALSE;
-
- if (output_hwc->pp_tqueue)
- {
- if (!tbm_surface_queue_can_dequeue(output_hwc->pp_tqueue, 0))
- return EINA_FALSE;
- }
-
- if (output_hwc->pending_pp_hwc_window_list)
- {
- if (eina_list_count(output_hwc->pending_pp_hwc_window_list) != 0)
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-EINTERN Eina_Bool
-e_output_hwc_windows_zoom_set(E_Output_Hwc *output_hwc, Eina_Rectangle *rect)
-{
- E_Comp_Screen *e_comp_screen = NULL;
- tdm_error ret = TDM_ERROR_NONE;
- int w, h;
- Eina_List *l;
- E_Hwc_Window *hwc_window;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
-
- if ((output_hwc->pp_rect.x == rect->x) &&
- (output_hwc->pp_rect.y == rect->y) &&
- (output_hwc->pp_rect.w == rect->w) &&
- (output_hwc->pp_rect.h == rect->h))
- return EINA_TRUE;
-
- e_comp_screen = e_comp->e_comp_screen;
- e_output_size_get(output_hwc->output, &w, &h);
-
- if (!output_hwc->tpp)
- {
- output_hwc->tpp = tdm_display_create_pp(e_comp_screen->tdisplay, &ret);
- if (ret != TDM_ERROR_NONE)
- {
- ERR("fail tdm pp create");
- goto fail;
- }
- }
-
- if (!output_hwc->pp_tqueue)
- {
- //TODO: Does e20 get the buffer flags from the tdm backend?
- output_hwc->pp_tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
- if (!output_hwc->pp_tqueue)
- {
- ERR("fail tbm_surface_queue_create");
- goto fail;
- }
- }
-
- output_hwc->pp_rect.x = rect->x;
- output_hwc->pp_rect.y = rect->y;
- output_hwc->pp_rect.w = rect->w;
- output_hwc->pp_rect.h = rect->h;
-
- output_hwc->pp_set = EINA_TRUE;
- output_hwc->target_hwc_window->skip_surface_set = EINA_TRUE;
- output_hwc->pp_set_info = EINA_TRUE;
-
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- {
- if (e_hwc_window_state_get(hwc_window) ==E_HWC_WINDOW_STATE_NONE) continue;
- if (e_hwc_window_is_target(hwc_window)) continue;
- if (e_hwc_window_is_video(hwc_window)) continue;
-
- hwc_window->update_exist = EINA_TRUE;
- }
-
- /* to wake up main loop */
- uint64_t value = 1;
- if (write(output_hwc->target_hwc_window->event_fd, &value, sizeof(value)) < 0)
- ERR("failed to wake up main loop:%m");
-
- return EINA_TRUE;
-
-fail:
- if (output_hwc->tpp)
- {
- tdm_pp_destroy(output_hwc->tpp);
- output_hwc->tpp = NULL;
- }
-
- return EINA_FALSE;
-}
-
-EINTERN void
-e_output_hwc_windows_zoom_unset(E_Output_Hwc *output_hwc)
-{
- EINA_SAFETY_ON_NULL_RETURN(output_hwc);
-
- output_hwc->pp_set_info = EINA_FALSE;
- output_hwc->target_hwc_window->skip_surface_set = EINA_FALSE;
- output_hwc->pp_set = EINA_FALSE;
-
- output_hwc->pp_rect.x = 0;
- output_hwc->pp_rect.y = 0;
- output_hwc->pp_rect.w = 0;
- output_hwc->pp_rect.h = 0;
-
- _e_output_hwc_windows_pp_pending_data_remove(output_hwc);
-
- if (output_hwc->pp_tsurface)
- tbm_surface_queue_release(output_hwc->pp_tqueue, output_hwc->pp_tsurface);
-
- if (output_hwc->pp_tqueue)
- {
- tbm_surface_queue_destroy(output_hwc->pp_tqueue);
- output_hwc->pp_tqueue = NULL;
- }
-
- if (!output_hwc->pp_commit)
- {
- if (output_hwc->tpp)
- {
- tdm_pp_destroy(output_hwc->tpp);
- output_hwc->tpp = NULL;
- }
- }
-
- if (output_hwc->pp_output_commit_data)
- output_hwc->wait_commit = EINA_TRUE;
-
- /* to wake up main loop */
- uint64_t value = 1;
- if (write(output_hwc->target_hwc_window->event_fd, &value, sizeof(value)) < 0)
- ERR("failed to wake up main loop:%m");
-}
-
+++ /dev/null
-#ifdef E_TYPEDEFS
-#else
-#ifndef E_OUTPUT_HWC_WINDOWS_H
-#define E_OUTPUT_HWC_WINDOWS_H
-
-EINTERN Eina_Bool e_output_hwc_windows_init(E_Output_Hwc *output_hwc);
-EINTERN void e_output_hwc_windows_deinit(void);
-
-EINTERN const Eina_List *e_output_hwc_windows_get(E_Output_Hwc *output_hwc);
-EINTERN Eina_Bool e_output_hwc_windows_render(E_Output_Hwc *output_hwc);
-EINTERN Eina_Bool e_output_hwc_windows_commit(E_Output_Hwc *output_hwc);
-
-EINTERN Eina_Bool e_output_hwc_windows_pp_commit_possible_check(E_Output_Hwc *output_hwc);
-EINTERN Eina_Bool e_output_hwc_windows_zoom_set(E_Output_Hwc *output_hwc, Eina_Rectangle *rect);
-EINTERN void e_output_hwc_windows_zoom_unset(E_Output_Hwc *output_hwc);
-
-#endif
-#endif
if (plane->ext_state == E_OUTPUT_EXT_MIRROR)
{
- if (e_output_hwc_policy_get(plane->output_primary->output_hwc) == E_OUTPUT_HWC_POLICY_PLANES)
+ if (e_hwc_policy_get(plane->output_primary->hwc) == E_HWC_POLICY_PLANES)
{
plane_primary_output_fb = e_output_fb_target_get(plane->output_primary);
EINA_SAFETY_ON_NULL_RETURN_VAL(plane_primary_output_fb, NULL);
}
else
{
- tsurface = plane->output_primary->output_hwc->target_hwc_window->hwc_window.tsurface;
+ tsurface = plane->output_primary->hwc->target_hwc_window->hwc_window.tsurface;
EINA_SAFETY_ON_NULL_RETURN_VAL(tsurface, NULL);
}
}