#define EOM_NUM_ATTR 3
#define EOM_CONNECT_CHECK_TIMEOUT 4.0
+#define EOM_DELAY_CONNECT_CHECK_TIMEOUT 1.0
#define EOMERR(f, output, x...) \
do \
Eina_List *eom_outputs;
Eina_List *clients;
Eina_List *handlers;
- Eina_List *hooks;
Eina_List *comp_object_intercept_hooks;
E_Output_Hook *output_connect_status_hook;
E_Output_Hook *output_mode_changes_hook;
Eina_Bool added;
E_EomClientPtr eom_client;
+ Eina_Bool wait_presentation;
+ /* If attribute has been set while external output is disconnected
+ * then show black screen and wait until EOM client start sending
+ * buffers. After expiring of the delay start mirroring */
+ Ecore_Timer *delay_timer;
};
struct _E_Eom_Comp_Object_Intercept_Hook_Data
E_Comp_Object_Intercept_Hook *hook = NULL;
int w, h;
- ec = e_output_presentation_ec_get(eom_output->output);
- EINA_SAFETY_ON_NULL_RETURN(ec);
-
cdata = ec->comp_data;
EINA_SAFETY_ON_NULL_RETURN(cdata);
EINA_SAFETY_ON_NULL_RETURN(cdata->shell.configure_send);
E_Comp_Wl_Buffer *wl_buffer = NULL;
tbm_surface_h tbm_buffer = NULL;
Eina_List *l;
- E_Output_Display_Mode display_mode;
+ E_Output_Display_Mode display_mode, display_mode_prev;
int width, height;
EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
eom_output = _e_eom_output_get_by_id(eom_client->output_id);
EINA_SAFETY_ON_NULL_RETURN_VAL(eom_output, ECORE_CALLBACK_PASS_ON);
+ if (eom_output->delay_timer)
+ {
+ ecore_timer_del(eom_output->delay_timer);
+ eom_output->delay_timer = NULL;
+ eom_output->wait_presentation = EINA_FALSE;
+ }
+
if (eom_trace_debug)
EOMINF("===============> EXT START", ec, eom_output->output);
if (eom_trace_debug)
EOMINF("buffer_changed callback", ec, eom_output->output);
+ display_mode_prev = e_output_display_mode_get(eom_output->output);
+
+ e_output_presentation_ec_set(eom_output->output, ec);
+
/* set the ec to the output for presentation. */
if (!e_output_presentation_update(eom_output->output, eom_client->ec))
{
- EOMERR("e_output_presentation_update fails.", eom_output->output);
+ EOMERR("e_output_presentation_update fail", eom_output->output);
return ECORE_CALLBACK_PASS_ON;
}
- EINA_LIST_FOREACH(g_eom->clients, l, eom_client_itr)
+ display_mode = e_output_display_mode_get(eom_output->output);
+ if (display_mode != display_mode_prev)
{
- if (eom_client_itr->output_id == eom_output->id)
+ EINA_LIST_FOREACH(g_eom->clients, l, eom_client_itr)
{
- display_mode = e_output_display_mode_get(eom_output->output);
- wl_eom_send_output_mode(eom_client->resource, eom_output->id, _e_eom_output_mode_get(display_mode));
+ if (eom_client_itr->output_id == eom_output->id)
+ wl_eom_send_output_mode(eom_client->resource, eom_output->id, _e_eom_output_mode_get(display_mode));
}
}
return ECORE_CALLBACK_PASS_ON;
}
+static Eina_Bool
+_e_eom_presentation_check(void *data)
+{
+ E_EomOutputPtr eom_output = NULL;
+ E_Output *primary_output;
+
+ if (!data) return ECORE_CALLBACK_CANCEL;
+
+ eom_output = (E_EomOutputPtr)data;
+
+ if (eom_output->wait_presentation)
+ {
+ if (eom_trace_debug)
+ EOMINF("_e_eom_presentation_check wait expired set to mirror", NULL, eom_output->output);
+ primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
+ e_output_mirror_set(eom_output->output, primary_output);
+ eom_output->wait_presentation = EINA_FALSE;
+ }
+
+ eom_output->delay_timer = NULL;
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
static void
_e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute)
{
/* Set the attribute to the eom_client */
if (eom_output->eom_client)
{
- // if eom_ouitput->eom_client == eom_client
if (eom_output->eom_client == eom_client)
{
/* Current client can set any flag it wants */
primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
if (!e_output_mirror_set(eom_output->output, primary_output))
{
- EOMERR("e_output_mirror_set fails", eom_output->output);
+ EOMERR("e_output_mirror_set fail", eom_output->output);
goto no_eom_output;
}
eom_client->current = EINA_TRUE;
eom_output->eom_client = eom_client;
- if (e_output_presentation_wait_set(eom_output->output, eom_client->ec))
- {
- EOMERR("e_output_presentation_wait_set fails\n", NULL);
- return;
- }
+ if (eom_output->delay_timer)
+ ecore_timer_del(eom_output->delay_timer);
+ eom_output->delay_timer = ecore_timer_add(EOM_DELAY_CONNECT_CHECK_TIMEOUT, _e_eom_presentation_check, eom_output);
+ eom_output->wait_presentation = EINA_TRUE;
+ EOMINF("e_eom_presentation_wait_set", NULL, eom_output->output);
/* Send changes to the caller-client */
wl_eom_send_output_attribute(eom_client->resource, eom_output->id,
E_EomClientPtr eom_client = NULL;
E_Client *ec = NULL;
- if (!(ec = wl_resource_get_user_data(surface)))
+ ec = e_xdg_shell_v6_xdg_surface_ec_get(surface);
+ if (!ec)
{
wl_resource_post_error(surface, WL_DISPLAY_ERROR_INVALID_OBJECT, "No Client For Shell Surface");
return;
EOMINF("set shell output id:%d resource:%p surface:%p", ec, eom_output->output, output_id, resource, surface);
- if (ec == e_output_presentation_ec_get(eom_output->output))
+ if (!eom_client->current)
{
wl_eom_send_output_set_window(resource, output_id, WL_EOM_ERROR_OUTPUT_OCCUPIED);
return;
primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
if (!e_output_mirror_set(eom_output->output, primary_output))
- EOMERR("e_output_mirror_set fails", eom_output->output);
+ EOMERR("e_output_mirror_set fail", eom_output->output);
}
end:
}
static Eina_Bool
-_e_eom_connect(E_Output *output)
+_e_eom_connect(E_EomOutputPtr eom_output)
{
- E_EomOutputPtr eom_output = NULL;
+ E_Output *primary_output = NULL;
E_Client *ec = NULL;
int w, h;
if (!g_eom) return EINA_TRUE;
- eom_output = _e_eom_output_find(output);
- if (!eom_output)
+ if (eom_output->eom_client)
{
- EOMERR("cannot find eom_output", NULL);
- return EINA_FALSE;
- }
+ EOMINF("Start Wait Presentation", NULL, eom_output->output);
+ /* the fallback timer for not setting the presentation. */
+ if (eom_output->delay_timer)
+ ecore_timer_del(eom_output->delay_timer);
+ eom_output->delay_timer = ecore_timer_add(EOM_DELAY_CONNECT_CHECK_TIMEOUT, _e_eom_presentation_check, eom_output);
+ eom_output->wait_presentation = EINA_TRUE;
- if (e_output_display_mode_get(eom_output->output) == E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION)
- {
EOMINF("Send Configure Event for Presentation", NULL, eom_output->output);
-
ec = e_output_presentation_ec_get(eom_output->output);
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
_e_eom_output_send_configure_event(eom_output, ec);
}
+ else
+ {
+ EOMINF("Start Mirroring", NULL, eom_output->output);
+
+ primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
+ if (!e_output_mirror_set(eom_output->output, primary_output))
+ {
+ EOMERR("e_output_mirror_set fail", eom_output->output);
+ return EINA_FALSE;
+ }
+ }
eom_output->connection = WL_EOM_STATUS_CONNECTION;
/* get the output size */
e_output_size_get(eom_output->output, &w, &h);
- EOMINF("Setup new eom_output: (%dx%d)", NULL, eom_output->output, w, h);
+ EOMINF("eom_output: (%dx%d) connected", NULL, eom_output->output, w, h);
return EINA_TRUE;
}
static Eina_Bool
-_e_eom_disconnect(E_Output *output)
+_e_eom_disconnect(E_EomOutputPtr eom_output)
{
- E_EomOutputPtr eom_output = NULL;
-
if (!g_eom) return EINA_TRUE;
- eom_output = _e_eom_output_find(output);
- if (!eom_output)
+ switch (e_output_display_mode_get(eom_output->output))
+ {
+ case E_OUTPUT_DISPLAY_MODE_NONE:
+ break;
+ case E_OUTPUT_DISPLAY_MODE_MIRROR:
+ /* unset mirror */
+ e_output_mirror_unset(eom_output->output);
+ break;
+ case E_OUTPUT_DISPLAY_MODE_PRESENTATION:
+ /* only change the display_mode */
+ e_output_presentation_unset(eom_output->output);
+ break;
+ default:
+ EOMERR("unknown display_mode:%d", eom_output->output, e_output_display_mode_get(eom_output->output));
+ break;
+ }
+
+ /* delete presentation_delay_timer */
+ if (eom_output->delay_timer)
{
- EOMERR("cannot find output", NULL);
- return EINA_FALSE;
+ ecore_timer_del(eom_output->delay_timer);
+ eom_output->delay_timer = NULL;
}
/* update eom_output disconnect */
/* If there were previously connected clients to the output - notify them */
_e_eom_output_info_broadcast(eom_output, EOM_OUTPUT_ATTRIBUTE_STATE_INACTIVE);
- EOMINF("Destory output.", NULL, eom_output->output);
+ EOMINF("eom_output: disconnected.", NULL, eom_output->output);
return EINA_TRUE;
}
static void
_e_eom_output_cb_output_connect_status_change(void *data, E_Output *output)
{
+ E_EomOutputPtr eom_output = NULL;
+
+ eom_output = _e_eom_output_find(output);
+ if (!eom_output)
+ {
+ EOMERR("cannot find eom_output", output);
+ return;
+ }
+
if (e_output_connected(output))
- _e_eom_connect(output);
+ _e_eom_connect(eom_output);
else
- _e_eom_disconnect(output);
+ _e_eom_disconnect(eom_output);
}
static void
EINA_SAFETY_ON_NULL_RETURN(ec);
_e_eom_output_send_configure_event(eom_output, ec);
+
+ if (eom_output->delay_timer)
+ ecore_timer_del(eom_output->delay_timer);
+ eom_output->delay_timer = ecore_timer_add(EOM_DELAY_CONNECT_CHECK_TIMEOUT, _e_eom_presentation_check, eom_output);
+ eom_output->wait_presentation = EINA_TRUE;
}
}
{
if (!_e_eom_output_create(output, EINA_TRUE))
{
- EOMERR("_e_eom_output_create fails.", output);
+ EOMERR("_e_eom_output_create fail", output);
return;
}
}
{
if (!_e_eom_output_destroy(output))
{
- EOMERR("_e_eom_output_destroy fails.", output);
+ EOMERR("_e_eom_output_destroy fail", output);
return;
}
}
if (!_e_eom_output_create(output, EINA_FALSE))
{
- EOMERR("_e_eom_output_create fails.", output);
+ EOMERR("_e_eom_output_create fail", output);
goto err;
}
}
if (!eom_output) return EINA_FALSE;
return EINA_TRUE;
-}
\ No newline at end of file
+}
{
E_Comp_Wl_Buffer *wl_buffer = NULL;
tbm_surface_h tsurface = NULL;
- E_Hwc_Window *hwc_window = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
{
if (!hwc->presentation_hwc_window)
{
+ /* There is the hwc_window of this ec which is already generated at the primary hwc */
+ if (ec->hwc_window) e_hwc_window_free(ec->hwc_window);
+
/* create the hwc_window on the external hwc. */
hwc->presentation_hwc_window = e_hwc_window_new(hwc, ec, E_HWC_WINDOW_STATE_DEVICE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->presentation_hwc_window, EINA_FALSE);
// TODO: deal with the video
}
tsurface = wayland_tbm_server_get_surface(e_comp->wl_comp_data->tbm.server, wl_buffer->resource);
EINA_SAFETY_ON_NULL_RETURN_VAL(tsurface, EINA_FALSE);
-
- hwc->presentation_tsurface = tsurface;
}
else
{
- hwc->presentation_tsurface = NULL;
-
if (hwc->presentation_hwc_window)
{
- e_hwc_window_free(hwc_window);
+ e_hwc_window_free(hwc->presentation_hwc_window);
hwc->presentation_hwc_window = NULL;
}
}
/* set the target_buffer if the output need to update */
#if 1
- if (display_mode == E_OUTPUT_DISPLAY_MODE_MIRROR)
- {
- if (!_e_hwc_windows_mirror_changes_update(hwc))
- return EINA_TRUE;
+ if (display_mode == E_OUTPUT_DISPLAY_MODE_MIRROR)
+ {
+ if (!_e_hwc_windows_mirror_changes_update(hwc))
+ return EINA_TRUE;
- if (!_e_hwc_windows_evaluate(hwc))
- return EINA_TRUE;
- }
- else if (display_mode == E_OUTPUT_DISPLAY_MODE_PRESENTATION)
- {
- if (!_e_hwc_windows_presentation_changes_update(hwc))
- return EINA_TRUE;
+ if (!_e_hwc_windows_evaluate(hwc))
+ return EINA_TRUE;
+ }
+ else if (display_mode == E_OUTPUT_DISPLAY_MODE_PRESENTATION)
+ {
+ if (!_e_hwc_windows_presentation_changes_update(hwc))
+ return EINA_TRUE;
- if (!_e_hwc_windows_evaluate(hwc))
- return EINA_TRUE;
+ if (!_e_hwc_windows_evaluate(hwc))
+ return EINA_TRUE;
- /* if the presentation window is client type. copy it on the target window. */
- if (!_e_hwc_windows_presentation_evaluation_check(hwc))
- return EINA_TRUE;
- }
- else
- {
- EHWSERR("Unknown display_mode : %d", hwc, display_mode);
- goto fail;
- }
+ /* if the presentation window is client type. copy it on the target window. */
+ if (!_e_hwc_windows_presentation_evaluation_check(hwc))
+ return EINA_TRUE;
+ }
+ else
+ {
+ EHWSERR("Unknown display_mode : %d", hwc, display_mode);
+ goto fail;
+ }
#else
if (!_e_hwc_windows_changes_update(hwc))
return EINA_TRUE;
#define DUMP_FPS 30
#define OUTPUT_DELAY_CONNECT_CHECK_TIMEOUT 3.0
-#define OUTPUT_DELAY_CHECK_TIMEOUT 1.0
typedef struct _E_Output_Capture E_Output_Capture;
typedef struct _E_Output_Layer E_Output_Layer;
return aligned_width;
}
-static Eina_Bool
-_e_output_presentation_check(void *data)
-{
- E_Output *output;
- E_Output *primary_output;
-
- if (!data) return ECORE_CALLBACK_CANCEL;
-
- output = (E_Output *)data;
-
- if (e_output_display_mode_get(output) == E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION)
- {
- primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
- e_output_mirror_set(output, primary_output);
- }
-
- output->delay_timer = NULL;
-
- return ECORE_CALLBACK_CANCEL;
-}
-
static inline void
_e_output_display_mode_set(E_Output *output, E_Output_Display_Mode display_mode)
{
}
}
-static Eina_Bool
-_e_output_external_connect_display_set(E_Output *output)
-{
- E_Output *primary_output = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
-
- if (e_output_display_mode_get(output) == E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION)
- {
- EOINF("Start Wait Presentation", output);
-
- /* the fallback timer for not setting the presentation. */
- if (output->delay_timer) ecore_timer_del(output->delay_timer);
- output->delay_timer = ecore_timer_add(OUTPUT_DELAY_CONNECT_CHECK_TIMEOUT, _e_output_presentation_check, output);
- }
- else
- {
- EOINF("Start Mirroring", output);
-
- primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
- if (!e_output_mirror_set(output, primary_output))
- {
- EOERR("e_output_mirror_set fails.", output);
- return EINA_FALSE;
- }
- }
-
- EOINF("_e_output_external_connect_display_set done: display_mode:%d", output, e_output_display_mode_get(output));
-
- return EINA_TRUE;
-}
-
-static void
-_e_output_external_disconnect_display_set(E_Output *output)
-{
- EINA_SAFETY_ON_NULL_RETURN(output);
-
- switch (e_output_display_mode_get(output))
- {
- case E_OUTPUT_DISPLAY_MODE_NONE:
- break;
- case E_OUTPUT_DISPLAY_MODE_MIRROR:
- /* unset mirror */
- e_output_mirror_unset(output);
- break;
- case E_OUTPUT_DISPLAY_MODE_PRESENTATION:
- /* only change the display_mode */
- _e_output_display_mode_set(output, E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION);
- break;
- case E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION:
- /* delete presentation_delay_timer */
- if (output->delay_timer)
- {
- ecore_timer_del(output->delay_timer);
- output->delay_timer = NULL;
- }
- break;
- default:
- EOERR("unknown display_mode:%d", output, output->display_mode);
- break;
- }
-
- EOINF("_e_output_external_disconnect_display_set done.", output);
-}
-
static void
_e_output_primary_update(E_Output *output)
{
_e_output_hook_call(E_OUTPUT_HOOK_CONNECT_STATUS_CHANGE, output);
- ret = _e_output_external_connect_display_set(output);
- if (ret == EINA_FALSE)
- {
- EOERR("fail to _e_output_external_connect_display_set.", output);
- return EINA_FALSE;
- }
-
EOINF("Connect the external output", output);
}
else
_e_output_hook_call(E_OUTPUT_HOOK_CONNECT_STATUS_CHANGE, output);
- _e_output_external_disconnect_display_set(output);
-
if (output->hwc)
{
e_hwc_del(output->hwc);
_e_output_hook_call(E_OUTPUT_HOOK_MODE_CHANGE, output);
EOINF("mode change output: (%dx%d)", output, w, h);
- if (e_output_display_mode_get(output) == E_OUTPUT_DISPLAY_MODE_PRESENTATION)
- {
- _e_output_display_mode_set(output, E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION);
- if (output->delay_timer) ecore_timer_del(output->delay_timer);
- output->delay_timer = ecore_timer_add(OUTPUT_DELAY_CONNECT_CHECK_TIMEOUT, _e_output_presentation_check, output);
- }
if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
{
}
EINTERN Eina_Bool
-e_output_presentation_wait_set(E_Output *output, E_Client *ec)
-{
- EINA_SAFETY_ON_FALSE_RETURN_VAL(output, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(ec, EINA_FALSE);
-
- _e_output_display_mode_set(output, E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION);
-
- /* the ec does not commit the buffer to the exernal output
- * Therefore, it needs the timer to prevent the eternal waiting.
- */
- if (output->delay_timer)
- {
- ecore_timer_del(output->delay_timer);
- output->delay_timer = ecore_timer_add(OUTPUT_DELAY_CHECK_TIMEOUT, _e_output_presentation_check, output);
- }
-
- EOINF("e_output_presentation_wait_set done: E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION", output);
-
- return EINA_TRUE;
-}
-
-EINTERN Eina_Bool
e_output_presentation_update(E_Output *output, E_Client *ec)
{
E_Hwc *hwc;
- E_Output_Display_Mode display_mode;
EINA_SAFETY_ON_FALSE_RETURN_VAL(output, EINA_FALSE);
EINA_SAFETY_ON_FALSE_RETURN_VAL(ec, EINA_FALSE);
hwc = output->hwc;
EINA_SAFETY_ON_FALSE_RETURN_VAL(hwc, EINA_FALSE);
- display_mode = e_output_display_mode_get(output);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(display_mode == E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION, EINA_FALSE);
-
- /* delete the delay timer on E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION */
- if (output->delay_timer) ecore_timer_del(output->delay_timer);
- output->delay_timer = NULL;
-
if (e_hwc_policy_get(hwc) == E_HWC_POLICY_PLANES)
{
if (!e_hwc_planes_presentation_update(hwc, ec))
}
}
- output->presentation_ec = ec;
_e_output_display_mode_set(output, E_OUTPUT_DISPLAY_MODE_PRESENTATION);
output->external_set = EINA_TRUE;
hwc = output->hwc;
EINA_SAFETY_ON_FALSE_RETURN(hwc);
- /* delete the delay timer on E_OUTPUT_DISPLAY_MODE_WAIT_PRESENTATION */
- if (output->delay_timer) ecore_timer_del(output->delay_timer);
- output->delay_timer = NULL;
-
output->external_set = EINA_FALSE;
_e_output_display_mode_set(output, E_OUTPUT_DISPLAY_MODE_NONE);
e_hwc_windows_presentation_update(hwc, NULL);
}
+EINTERN Eina_Bool
+e_output_presentation_ec_set(E_Output *output, E_Client *ec)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(output, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(output, EINA_FALSE);
+
+ output->presentation_ec = ec;
+
+ return EINA_TRUE;
+}
+
EINTERN E_Client *
e_output_presentation_ec_get(E_Output *output)
{