add mirror set/unset 42/211842/1
authorSooChan Lim <sc1.lim@samsung.com>
Mon, 22 Jul 2019 05:28:00 +0000 (14:28 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 9 Aug 2019 08:26:59 +0000 (17:26 +0900)
vc4 can the capability of the mirror

Change-Id: Iaeca4e8d8549fa39555afd1b272305dc543f3105

src/tdm_vc4.c
src/tdm_vc4.h
src/tdm_vc4_display.c
src/tdm_vc4_hwc.c
src/tdm_vc4_types.h

index eb100d4..c3798bb 100644 (file)
@@ -288,6 +288,8 @@ tdm_vc4_init(tdm_display *dpy, tdm_error *error)
        vc4_func_output.output_get_dpms = vc4_output_get_dpms;
        vc4_func_output.output_set_mode = vc4_output_set_mode;
        vc4_func_output.output_get_mode = vc4_output_get_mode;
+       vc4_func_output.output_set_mirror = vc4_output_set_mirror;
+       vc4_func_output.output_unset_mirror = vc4_output_unset_mirror;
 #ifdef HAVE_UDEV
        vc4_func_output.output_set_status_handler = vc4_output_set_status_handler;
 #endif
index 8f1b863..dffb04e 100644 (file)
@@ -50,6 +50,8 @@ tdm_error     vc4_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value);
 tdm_error      vc4_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value);
 tdm_error      vc4_output_set_mode(tdm_output *output, const tdm_output_mode *mode);
 tdm_error      vc4_output_get_mode(tdm_output *output, const tdm_output_mode **mode);
+tdm_error      vc4_output_set_mirror(tdm_output *output, tdm_output *src_output, tdm_transform transform);
+tdm_error      vc4_output_unset_mirror(tdm_output *output);
 tdm_error      vc4_output_set_status_handler(tdm_output *output, tdm_output_status_handler func, void *user_data);
 tdm_hwc    *vc4_output_get_hwc(tdm_output *output, tdm_error *error);
 
@@ -94,5 +96,7 @@ void          tdm_vc4_display_destroy_output_list(tdm_vc4_data *vc4_data);
 tdm_error      tdm_vc4_display_create_layer_list(tdm_vc4_data *vc4_data);
 
 tdm_vc4_layer_data * vc4_output_data_get_layer_data(tdm_vc4_output_data *output_data, int layer_zops);
+tdm_error            vc4_output_data_prepare_mirror_commit(tdm_vc4_output_data *output_data, tbm_surface_h surface);
+
 void                 tdm_vc4_data_destroy_buffer_list(tdm_vc4_data *vc4_data);
 #endif /* _TDM_VC4_H_ */
index c7ae1e7..12f235f 100644 (file)
@@ -72,7 +72,7 @@ check_hw_restriction(unsigned int crtc_w, unsigned int crtc_h, unsigned int buf_
 
        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);
 
@@ -216,6 +216,7 @@ _tdm_vc4_display_set_crtc(tdm_vc4_data *vc4_data, tdm_vc4_output_data *output_da
                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)) {
@@ -240,6 +241,7 @@ _tdm_vc4_display_set_crtc(tdm_vc4_data *vc4_data, tdm_vc4_output_data *output_da
        } 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");
@@ -409,6 +411,7 @@ _tdm_vc4_display_cb_event(int fd, unsigned int sequence,
        tdm_vc4_output_data *output_data;
        tdm_vc4_hwc_data *hwc_data;
 
+
        if (!event_data) {
                TDM_ERR("no event data");
                return;
@@ -416,6 +419,10 @@ _tdm_vc4_display_cb_event(int fd, unsigned int sequence,
 
        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)
@@ -1266,8 +1273,10 @@ vc4_output_get_capability(tdm_output *output, tdm_caps_output *caps)
                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);
@@ -1551,7 +1560,7 @@ _vc4_layer_make_atomic_request(tdm_vc4_layer_data *layer_data, drmModeAtomicReqP
        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);
@@ -1688,6 +1697,9 @@ _vc4_output_atomic_commit(tdm_output *output, int sync, void *user_data)
        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);
@@ -1874,6 +1886,12 @@ vc4_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
        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;
 }
 
@@ -1890,6 +1908,53 @@ vc4_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
        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)
 {
@@ -2350,3 +2415,67 @@ vc4_output_data_get_layer_data(tdm_vc4_output_data *output_data, int layer_zpos)
 
        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
index 0d47db9..14de29c 100644 (file)
@@ -583,13 +583,29 @@ tdm_error
 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);
 
@@ -638,16 +654,27 @@ tdm_error
 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;
 }
 
@@ -668,6 +695,12 @@ vc4_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
        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;
 }
 
index ed71a75..dc290be 100644 (file)
@@ -201,6 +201,11 @@ struct _tdm_vc4_output_data {
                uint32_t crtc_mode_id;
                uint32_t crtc_active;
        } atomic_props_ids;
+
+       /* mirroring output_data, only one support */
+       tdm_vc4_output_data *mirror_dst_output_data;
+       tdm_transform        mirror_dst_transform;
+       tdm_vc4_output_data *mirror_src_output_data;
 };
 
 struct _tdm_vc4_layer_data {