*/
tdm_error
tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target_buffer,
- tdm_hwc_region damage);
+ tdm_hwc_region damage, tdm_hwc_window **composited_wnds,
+ uint32_t num_wnds);
/**
* @brief Validate the output
* @since 2.0.0
*/
tdm_error (*output_hwc_set_client_target_buffer)(tdm_output *output, tbm_surface_h target_buffer,
- tdm_hwc_region damage);
+ tdm_hwc_region damage, tdm_hwc_window **composited_wnds,
+ uint32_t num_wnds);
/**
* @brief Validate the output
if (private_output->dpms_changed_timer)
tdm_event_loop_source_remove(private_output->dpms_changed_timer);
+ tdm_event_loop_source_remove(private_output->need_validate.event_source);
+ close(private_output->need_validate.event_fd);
+
private_output->stamp = 0;
free(private_output);
}
return TDM_ERROR_NONE;
}
+/* backend operates itself types */
+static tdm_private_output*
+_look_for_frontend_hwc_output(tdm_output *backend_output)
+{
+ tdm_private_output *frontend_output = NULL, *o = NULL;
+ tdm_private_display *dpy;
+
+ dpy = tdm_display_init(NULL);
+ TDM_RETURN_VAL_IF_FAIL(dpy != NULL, NULL);
+
+ LIST_FOR_EACH_ENTRY(o, &dpy->output_list, link) {
+ if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC))
+ continue;
+
+ if (o->output_backend == backend_output) {
+ frontend_output = o;
+ break;
+ }
+ }
+
+ tdm_display_deinit(dpy);
+
+ return frontend_output;
+}
+
EXTERN tdm_error
tdm_backend_trigger_need_validate_event(tdm_output *output)
{
uint64_t value;
int res;
- TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ private_output = _look_for_frontend_hwc_output(output);
+ TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER);
- private_output = (tdm_private_output*)output;
value = 1;
/* do not lock the global display lock here */
}
}
- private_hwc_window = calloc(1, sizeof(tdm_private_capture));
+ private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
if (!private_hwc_window) {
/* LCOV_EXCL_START */
TDM_ERR("failed: alloc memory");
EXTERN tdm_error
tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target_buffer,
- tdm_hwc_region damage)
+ tdm_hwc_region damage, tdm_hwc_window **composited_wnds,
+ uint32_t num_wnds)
{
tdm_func_output *func_output = NULL;
+ tdm_private_hwc_window **composited_wnds_frontend = NULL;
+ tdm_hwc_window **composited_wnds_backend = NULL;
+ int i;
OUTPUT_FUNC_ENTRY();
_tdm_target_window_dump_buffer((tdm_private_output *)output, target_buffer);
/* LCOV_EXCL_STOP */
- ret = func_output->output_hwc_set_client_target_buffer(private_output->output_backend, target_buffer, damage);
+ composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *));
+ if (!composited_wnds_backend) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_OUT_OF_MEMORY;
+ /* LCOV_EXCL_STOP */
+ }
+
+ composited_wnds_frontend = (tdm_private_hwc_window **)composited_wnds;
+
+ for (i = 0; i < num_wnds; i++)
+ composited_wnds_backend[i] = composited_wnds_frontend[i]->hwc_window_backend;
+
+ ret = func_output->output_hwc_set_client_target_buffer(private_output->output_backend, target_buffer,
+ damage, composited_wnds_backend, num_wnds);
+
+ free(composited_wnds_backend);
_pthread_mutex_unlock(&private_display->lock);
}
}
+static int
+_is_hwc_output_still_existed(tdm_private_output *private_output)
+{
+ tdm_private_display *dpy;
+ tdm_private_output *o = NULL;
+
+ dpy = tdm_display_init(NULL);
+ TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_OPERATION_FAILED);
+
+ LIST_FOR_EACH_ENTRY(o, &dpy->output_list, link) {
+ if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC))
+ continue;
+
+ if (o == private_output)
+ goto exist;
+ }
+
+ tdm_display_deinit(dpy);
+ return 0;
+
+exist:
+ tdm_display_deinit(dpy);
+ return 1;
+}
/* gets called on behalf of the ecore-main-loop thread */
INTERN tdm_error
{
TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ /* as we get 'private_output' within an event, an output this 'private_output'
+ * points to can be destroyed already */
+ if (!_is_hwc_output_still_existed(private_output))
+ return TDM_ERROR_NONE;
+
TDM_INFO("tdm-backend asks for revalidation for the output:%p.", private_output);
if (private_output->need_validate.hndl)
tdm_thread_cb_need_validate ev;
tdm_private_output *private_output;
tdm_error ret;
+ uint64_t value;
private_output = (tdm_private_output *)user_data;
+ if (read(private_output->need_validate.event_fd, &value, sizeof(value)) < 0) {
+ TDM_ERR("error while trying to read from a need_validate.event_fd fd.");
+ return TDM_ERROR_OPERATION_FAILED;
+ }
+
ev.base.type = TDM_THREAD_CB_NEED_VALIDATE;
ev.base.length = sizeof ev;
ev.o = private_output;
fd = eventfd(0, 0);
TDM_WARNING_IF_FAIL(fd >= 0);
- tdm_event_loop_add_fd_handler(private_display, fd, TDM_EVENT_LOOP_READABLE,
- _need_validate_handler, private_output, &ret);
+ private_output->need_validate.event_source = tdm_event_loop_add_fd_handler(private_display,
+ fd, TDM_EVENT_LOOP_READABLE, _need_validate_handler, private_output, &ret);
TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
private_output->need_validate.event_fd = fd;
/* look at the tdm_output_set_need_revalidate_handler() declaration for the details */
tdm_output_need_validate_handler hndl;
int event_fd;
+ tdm_event_loop_source *event_source;
} need_validate;
/* calling a output commit per a vblank */
/* tdm_error tdm_output_hwc_set_client_target_buffer(tdm_output *output,
- tbm_surface_h target_buffer, tdm_hwc_region damage); */
-TEST_F(TDMOutputHwc, SetClientTargetBufferFailNullOutput)
+ tbm_surface_h target_buffer, tdm_hwc_region damage,
+ tdm_hwc_window *composited_wnds, uint32_t num_wnds); */
+TEST_F(TDMOutputHwc, DISABLED_SetClientTargetBufferFailNullOutput)
{
tdm_hwc_region reg;
tbm_surface_h target_buff = CreateBufferForOutput(0);
- error = tdm_output_hwc_set_client_target_buffer(NULL, target_buff, reg);
+ error = tdm_output_hwc_set_client_target_buffer(NULL, target_buff, reg, NULL, 0 /* TODO: sergs_ut */);
tbm_surface_internal_destroy(target_buff);
ASSERT_NE(TDM_ERROR_NONE, error);
}
-TEST_F(TDMOutputHwcWithoutHwcCap, SetClientTargetBufferFailNoHwc)
+TEST_F(TDMOutputHwcWithoutHwcCap, DISABLED_SetClientTargetBufferFailNoHwc)
{
tdm_hwc_region damage;
for (int i = 0; i < output_count; i++) {
tbm_surface_h target_buff = CreateBufferForOutput(i);
ASSERT_NE(NULL, target_buff);
- error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage);
+ error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage,
+ NULL, 0 /* TODO: sergs_ut */);
tbm_surface_internal_destroy(target_buff);
ASSERT_NE(TDM_ERROR_NONE, error);
}
}
-TEST_F(TDMOutputHwc, SetClientTargetBufferSuccessfulSetBuff)
+TEST_F(TDMOutputHwc, DISABLED_SetClientTargetBufferSuccessfulSetBuff)
{
tdm_hwc_region damage;
tbm_surface_h target_buff = CreateBufferForOutput(i);
ASSERT_NE(NULL, target_buff);
if (IsHwcEnable(i)) {
- error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage);
+ error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage,
+ NULL, 0 /* TODO: sergs_ut_ut */);
tbm_surface_internal_destroy(target_buff);
ASSERT_EQ(TDM_ERROR_NONE, error);
} else {
- error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage);
+ error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage,
+ NULL, 0 /* TODO: sergs_ut */);
tbm_surface_internal_destroy(target_buff);
ASSERT_NE(TDM_ERROR_NONE, error);
}
}
}
-TEST_F(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff)
+TEST_F(TDMOutputHwc, DISABLED_SetClientTargetBufferSuccessfulResetBuff)
{
tdm_hwc_region damage;
for (int i = 0; i < output_count; i++) {
if (IsHwcEnable(i)) {
- error = tdm_output_hwc_set_client_target_buffer(outputs[i], NULL, damage);
+ error = tdm_output_hwc_set_client_target_buffer(outputs[i], NULL, damage,
+ NULL, 0 /* TODO: sergs_ut */);
ASSERT_EQ(TDM_ERROR_NONE, error);
} else {
- error = tdm_output_hwc_set_client_target_buffer(outputs[i], NULL, damage);
+ error = tdm_output_hwc_set_client_target_buffer(outputs[i], NULL, damage,
+ NULL, 0 /* TODO: sergs_ut */);
ASSERT_NE(TDM_ERROR_NONE, error);
}
}