if (src_x != *new_src_x || src_w != *new_src_w || dst_x != *new_dst_x ||
dst_w != *new_dst_w)
- TDM_DBG("=> buf_w(%d) src(%d,%d) dst(%d,%d), virt(%d) start(%d) end(%d)",
+ TDM_INFO("=> buf_w(%d) src(%d,%d) dst(%d,%d), virt(%d) start(%d) end(%d)",
buf_w, *new_src_x, *new_src_w, *new_dst_x, *new_dst_w, virtual_screen, start,
end);
TDM_DBG("drmModeSetCrtc drm_fd(%d) crtc_id(%u) fb_id(%u) mode(%u,%u)",
vc4_data->drm_fd, output_data->crtc_id, fb_id,
mode->hdisplay, mode->vdisplay);
+
if (drmModeSetCrtc(vc4_data->drm_fd, output_data->crtc_id,
fb_id, 0, 0,
&output_data->connector_id, 1, mode)) {
} else {
TDM_DBG("drmModeSetCrtc unset drm_fd(%d) crtc_id(%u)",
vc4_data->drm_fd, output_data->crtc_id);
+
if (drmModeSetCrtc(vc4_data->drm_fd, output_data->crtc_id,
0, 0, 0, NULL, 0, NULL)) {
TDM_ERR("unset crtc failed: %m");
tdm_vc4_output_data *output_data;
tdm_vc4_hwc_data *hwc_data;
+
if (!event_data) {
TDM_ERR("no event data");
return;
output_data = event_data->output_data;
+
+ TDM_DBG("==== Atomic Commit Handler pipe, %u, crtc_id, %u connector_id, %u",
+ output_data->pipe, output_data->crtc_id, output_data->connector_id);
+
switch (event_data->type) {
case TDM_DRM_EVENT_TYPE_PAGEFLIP:
if (output_data->commit_func)
drmModeFreeProperty(prop);
}
- if (output_data->hwc_enable)
+ if (output_data->hwc_enable) {
caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC;
+ caps->capabilities |= TDM_OUTPUT_CAPABILITY_MIRROR;
+ }
drmModeFreeObjectProperties(props);
drmModeFreeCrtc(crtc);
layer_data->info_changed = 0;
if (!layer_data->display_buffer) {
- TDM_DBG("MakeAtomicRequest: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
+ TDM_INFO("MakeAtomicRequest: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
vc4_data->drm_fd, layer_data->plane_id, output_data->crtc_id);
ret = _vc4_layer_add_atomic_properties(layer_data, request, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
event_data->output_data = output_data;
event_data->user_data = user_data;
+ TDM_DBG("==== Atomic Commit pipe, %u, crtc_id, %u connector_id, %u",
+ output_data->pipe, output_data->crtc_id, output_data->connector_id);
+
if (drmModeAtomicCommit(output_data->vc4_data->drm_fd, request, flags, event_data) < 0) {
TDM_ERR("drmModeAtomicCommit failed.");
drmModeAtomicFree(request);
TDM_INFO("Set the output mode: %s, %d, %d, %d, %d, %d",
mode->name, mode->hdisplay, mode->vdisplay, mode->vrefresh, mode->flags, mode->type);
+ ret = _tdm_vc4_display_set_crtc(output_data->vc4_data, output_data, 1);
+ if (ret != TDM_ERROR_NONE) {
+ TDM_ERR("fail to set crtc.");
+ return TDM_ERROR_OPERATION_FAILED;
+ }
+
return TDM_ERROR_NONE;
}
return TDM_ERROR_NONE;
}
+tdm_error
+vc4_output_set_mirror(tdm_output *output, tdm_output *src_output, tdm_transform transform)
+{
+ tdm_vc4_output_data *output_data = (tdm_vc4_output_data *)output;
+ tdm_vc4_output_data *src_output_data = (tdm_vc4_output_data *)src_output;
+
+ RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(src_output_data, TDM_ERROR_INVALID_PARAMETER);
+
+ if (!output_data->hwc_enable) {
+ TDM_ERR("Output Mirroring is not Implemented.");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ }
+
+ output_data->mirror_src_output_data = src_output_data;
+ src_output_data->mirror_dst_output_data = output_data;
+ src_output_data->mirror_dst_transform = transform;
+
+ TDM_INFO("Set the mirror. transform(%d)", transform);
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+vc4_output_unset_mirror(tdm_output *output)
+{
+ tdm_vc4_output_data *output_data = (tdm_vc4_output_data *)output;
+ tdm_vc4_output_data *src_output_data;
+
+ RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+ if (!output_data->hwc_enable) {
+ TDM_ERR("Output Mirroring is not Implemented.");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ }
+
+ src_output_data = output_data->mirror_src_output_data;
+
+ src_output_data->mirror_dst_transform = TDM_TRANSFORM_NORMAL;
+ src_output_data->mirror_dst_output_data = NULL;
+ output_data->mirror_src_output_data = NULL;
+
+ TDM_INFO("Unet the mirror.");
+
+ return TDM_ERROR_NONE;
+}
+
tdm_hwc *
vc4_output_get_hwc(tdm_output *output, tdm_error *error)
{
return NULL;
}
+
+static void
+_vc4_output_data_center_rect_get(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *fit)
+{
+ float rh;
+
+ if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !fit)
+ return;
+
+ rh = (float) src_h / src_w;
+
+ fit->x = 0;
+ fit->y = 0;
+ fit->w = dst_w;
+ fit->h = dst_w * rh;
+
+ //TDM_ERR("=###### (%d, %d, %d, %d) (%f)", fit->x, fit->y, fit->w, fit->h, rh);
+}
+
+tdm_error
+vc4_output_data_prepare_mirror_commit(tdm_vc4_output_data *output_data, tbm_surface_h surface)
+{
+ tdm_vc4_layer_data *layer_data = NULL;
+ tdm_info_layer info;
+ tbm_surface_info_s surf_info;
+ tdm_error ret;
+ tdm_pos dst_pos;
+
+ RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(surface, TDM_ERROR_INVALID_PARAMETER);
+
+ RETURN_VAL_IF_FAIL(output_data->current_mode, TDM_ERROR_OPERATION_FAILED);
+
+ layer_data = vc4_output_data_get_layer_data(output_data, 0);
+ RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED);
+
+ memset(&dst_pos, 0, sizeof(tdm_pos));
+
+ tbm_surface_get_info(surface, &surf_info);
+ // TODO: NEED to fix the calculation of the dst_pos
+ _vc4_output_data_center_rect_get(surf_info.width, surf_info.height,
+ output_data->current_mode->hdisplay, output_data->current_mode->hdisplay,
+ &dst_pos);
+
+ info.src_config.size.h = surf_info.width;
+ info.src_config.size.v = surf_info.height;
+ info.src_config.pos.x = 0;
+ info.src_config.pos.y = 0;
+ info.src_config.pos.w = surf_info.width;
+ info.src_config.pos.h = surf_info.height;
+ info.dst_pos.x = dst_pos.x;
+ info.dst_pos.y = dst_pos.y;
+ info.dst_pos.w = dst_pos.w;
+ info.dst_pos.h = dst_pos.h;
+ info.transform = TDM_TRANSFORM_NORMAL;
+
+ ret = vc4_layer_set_info((tdm_layer *)layer_data, &info);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+ ret = vc4_layer_set_buffer(layer_data, surface);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+ return TDM_ERROR_NONE;
+}
\ No newline at end of file
vc4_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
{
tdm_vc4_hwc_data *hwc_data = hwc;
+ tdm_vc4_output_data *output_data;
+ tdm_vc4_hwc_window_data **composited_list = NULL;
+ int i;
RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
+ output_data = hwc_data->output_data;
+ RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
TDM_INFO(" ==============Validate=================================");
- _vc4_hwc_apply_policy(hwc_data, composited_wnds, num_wnds);
+ /* mirror is set. all clients should be the client type. */
+ if (output_data->mirror_dst_output_data) {
+ composited_list = (tdm_vc4_hwc_window_data **)composited_wnds;
+ for (i = 0; i < num_wnds; i++) {
+ composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
+ }
+ hwc_data->need_target_window = 1;
+ hwc_data->target_hwc_window->lzpos = ZPOS_0;
+ } else {
+ _vc4_hwc_apply_policy(hwc_data, composited_wnds, num_wnds);
+ }
*num_types = _vc4_hwc_get_changed_number(hwc_data);
vc4_hwc_accept_validation(tdm_hwc *hwc)
{
tdm_vc4_hwc_data *hwc_data = hwc;
+ tdm_vc4_output_data *output_data;
tdm_error ret = TDM_ERROR_NONE;
RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ output_data = hwc_data->output_data;
+
TDM_DBG(" ==============Accept Changes Done=================================");
ret = _vc4_hwc_prepare_commit(hwc_data);
RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ /* prepare_mirror_commit for mirroring */
+ if (output_data->mirror_dst_output_data) {
+ ret = vc4_output_data_prepare_mirror_commit(output_data->mirror_dst_output_data,
+ hwc_data->target_hwc_window->surface);
+ if (ret != TDM_ERROR_NONE)
+ TDM_ERR("fail to prepare mirror_commit.");
+ }
+
return TDM_ERROR_NONE;
}
ret = vc4_output_commit(output_data, sync, user_data);
RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ /* commit for mirroring */
+ if (output_data->mirror_dst_output_data) {
+ ret = vc4_output_commit(output_data->mirror_dst_output_data, sync, NULL);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ }
+
return TDM_ERROR_NONE;
}