hwc: add tdm_output_hwc_commit_client_target_buffer 95/169895/5
authorSooChan Lim <sc1.lim@samsung.com>
Mon, 12 Feb 2018 02:17:05 +0000 (11:17 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 12 Feb 2018 07:29:47 +0000 (07:29 +0000)
Change-Id: I48164e6e2ea918567355c7bf69a751e0dfdee472

include/tdm.h
include/tdm_types.h
src/tdm_output.c
src/tdm_private_types.h

index 7437d86..f90fbe8 100644 (file)
@@ -645,6 +645,18 @@ tdm_error
 tdm_output_hwc_unset_client_target_buffer(tdm_output *output);
 
 /**
+ * @brief Commit changes for a target_window
+ * @details After all change of a window object are applied, a user commit handler
+ * will be called.
+ * @param[in] hwc_window A window object
+ * @param[in] func A user commit handler
+ * @param[in] user_data The user data
+ * @return #TDM_ERROR_NONE if success. Otherwise, error value.
+ */
+tdm_error
+tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_target_buffer_commit_handler func, void *user_data);
+
+/**
  * @brief Validate the output
  * @details Instructs the device to inspect all of the layer state and
  * determine if there are any composition type changes necessary before
index f08d347..d2013b7 100644 (file)
@@ -274,6 +274,13 @@ typedef void (*tdm_hwc_window_commit_handler)(tdm_hwc_window *hwc_window, unsign
                                                                                 void *user_data);
 
 /**
+ * @brief The output target_buffer commit handler
+ */
+typedef void (*tdm_output_hwc_target_buffer_commit_handler)(tdm_output *output, unsigned int sequence,
+                                                                                unsigned int tv_sec, unsigned int tv_usec,
+                                                                                void *user_data);
+
+/**
  * @brief The done handler of a pp object
  */
 typedef void (*tdm_pp_done_handler)(tdm_pp *pp, tbm_surface_h src,
index e5edf93..74745bd 100644 (file)
@@ -1858,6 +1858,143 @@ tdm_output_hwc_unset_client_target_buffer(tdm_output *output)
        return ret;
 }
 
+static void
+_tdm_output_hwc_layer_commit_handler(tdm_layer *layer, unsigned int sequence,
+                                                                                unsigned int tv_sec, unsigned int tv_usec,
+                                                                                void *user_data)
+{
+       tdm_private_output_hwc_target_buffer_commit_handler *output_hwc_target_buffer_commit_handler = (tdm_private_output_hwc_target_buffer_commit_handler *)user_data;
+       tdm_output_hwc_target_buffer_commit_handler func = output_hwc_target_buffer_commit_handler->func;
+       tdm_output *output = (tdm_output *)output_hwc_target_buffer_commit_handler->private_output;
+       void *data = output_hwc_target_buffer_commit_handler->user_data;
+
+       func(output, sequence, tv_sec, tv_usec, data);
+
+       free(output_hwc_target_buffer_commit_handler);
+}
+
+tdm_error
+tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_target_buffer_commit_handler func, void *user_data)
+{
+       tdm_func_output *func_output;
+       tdm_private_output_hwc_target_buffer_commit_handler *output_hwc_target_buffer_commit_handler;
+       tdm_layer *layer = NULL;
+       tdm_private_layer *private_layer;
+       const tdm_output_mode *mode;
+       tbm_surface_h buffer;
+
+       OUTPUT_FUNC_ENTRY();
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) {
+               TDM_ERR("output(%p) not support HWC", private_output);
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       func_output = &private_display->func_output;
+
+       if (!func_output->output_hwc_get_client_target_buffer_layer) {
+               /* LCOV_EXCL_START */
+               _pthread_mutex_unlock(&private_display->lock);
+               TDM_ERR("not implemented!!");
+               return TDM_ERROR_NOT_IMPLEMENTED;
+               /* LCOV_EXCL_STOP */
+       }
+
+       layer = func_output->output_hwc_get_client_target_buffer_layer(private_output->output_backend,
+                                                                                                                  &ret);
+       if (!layer) {
+               /* LCOV_EXCL_START */
+               _pthread_mutex_unlock(&private_display->lock);
+               TDM_ERR("no assigned layer!!");
+               return TDM_ERROR_INVALID_PARAMETER;
+               /* LCOV_EXCL_STOP */
+       }
+
+       private_layer = (tdm_private_layer*)layer;
+
+       if (!func_output->output_hwc_get_client_target_buffer) {
+               /* LCOV_EXCL_START */
+               _pthread_mutex_unlock(&private_display->lock);
+               TDM_ERR("not implemented!!");
+               return TDM_ERROR_NOT_IMPLEMENTED;
+               /* LCOV_EXCL_STOP */
+       }
+
+       buffer = func_output->output_hwc_get_client_target_buffer(private_output->output_backend,
+                                                                                                          &ret);
+       if (!buffer) {
+               /* LCOV_EXCL_START */
+               _pthread_mutex_unlock(&private_display->lock);
+               TDM_ERR("no assigned buffer!!");
+               return TDM_ERROR_INVALID_PARAMETER;
+               /* LCOV_EXCL_STOP */
+       }
+
+       if (buffer)
+               ret = tdm_layer_set_buffer_internal(private_layer, buffer);
+       else
+               ret = tdm_layer_unset_buffer_internal(private_layer);
+       if (ret != TDM_ERROR_NONE) {
+               /* LCOV_EXCL_START */
+               TDM_ERR("failed: layer set info(window)");
+               /* LCOV_EXCL_STOP */
+               return ret;
+       }
+
+       /* set layer_info only one time */
+       /* TODO: if the mode changes, set again the target_buffer_info. */
+       if (&private_output->target_buffer_info == NULL) {
+               mode = private_output->current_mode;
+               private_output->target_buffer_info.src_config.size.h = mode->hdisplay;
+               private_output->target_buffer_info.src_config.size.v = mode->vdisplay;
+               private_output->target_buffer_info.src_config.pos.x = 0;
+               private_output->target_buffer_info.src_config.pos.y = 0;
+               private_output->target_buffer_info.src_config.pos.w = mode->hdisplay;
+               private_output->target_buffer_info.src_config.pos.h = mode->vdisplay;
+               private_output->target_buffer_info.dst_pos.x = 0;
+               private_output->target_buffer_info.dst_pos.y = 0;
+               private_output->target_buffer_info.dst_pos.w = mode->hdisplay;
+               private_output->target_buffer_info.dst_pos.h = mode->vdisplay;
+               private_output->target_buffer_info.transform = TDM_TRANSFORM_NORMAL;
+       }
+
+       ret = tdm_layer_set_info_internal(private_layer, &private_output->target_buffer_info);
+       if (ret != TDM_ERROR_NONE) {
+               /* LCOV_EXCL_START */
+               TDM_ERR("failed: layer set info(window)");
+               /* LCOV_EXCL_STOP */
+               return ret;
+       }
+
+       output_hwc_target_buffer_commit_handler = calloc(1, sizeof(tdm_private_output_hwc_target_buffer_commit_handler));
+       if (!output_hwc_target_buffer_commit_handler) {
+               /* LCOV_EXCL_START */
+               TDM_ERR("failed: alloc memory");
+               return TDM_ERROR_OUT_OF_MEMORY;
+               /* LCOV_EXCL_STOP */
+       }
+
+       output_hwc_target_buffer_commit_handler->private_output = private_output;
+       output_hwc_target_buffer_commit_handler->func = func;
+       output_hwc_target_buffer_commit_handler->user_data = user_data;
+
+       ret = tdm_layer_commit_internal(private_layer, _tdm_output_hwc_layer_commit_handler, user_data);
+       if (ret != TDM_ERROR_NONE) {
+               /* LCOV_EXCL_START */
+               TDM_ERR("failed: commit layer(target buffer)");
+               free(output_hwc_target_buffer_commit_handler);
+               /* LCOV_EXCL_STOP */
+               return ret;
+       }
+
+       _pthread_mutex_unlock(&private_display->lock);
+
+       return ret;
+}
+
 tdm_error
 tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format **formats,
                                                                int *count)
index 642e962..021be9c 100644 (file)
@@ -108,6 +108,8 @@ typedef struct _tdm_private_vblank_handler tdm_private_vblank_handler;
 typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler;
 typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler;
 typedef struct _tdm_private_hwc_window_commit_handler tdm_private_hwc_window_commit_handler;
+typedef struct _tdm_private_output_hwc_target_buffer_window_commit_handler tdm_private_output_hwc_target_buffer_commit_handler;
+
 typedef struct _tdm_private_change_handler tdm_private_change_handler;
 typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer;
 
@@ -205,6 +207,8 @@ struct _tdm_private_output {
                tdm_event_loop_source *event_source;
        } need_validate;
 
+       tdm_info_layer target_buffer_info; /* layer_info for the target_buffer */
+
        /* calling a output commit per a vblank */
        int commit_per_vblank;
        tdm_commit_type commit_type;
@@ -375,6 +379,12 @@ struct _tdm_private_hwc_window_commit_handler {
        void *user_data;
 };
 
+struct _tdm_private_output_hwc_target_buffer_window_commit_handler {
+       tdm_private_output *private_output;
+       tdm_output_hwc_target_buffer_commit_handler func;
+       void *user_data;
+};
+
 struct _tdm_private_change_handler {
        struct list_head link;