hwc:window_commit
authorSooChan Lim <sc1.lim@samsung.com>
Sun, 11 Feb 2018 08:22:06 +0000 (17:22 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Sun, 11 Feb 2018 08:22:06 +0000 (17:22 +0900)
Change-Id: Icf4e5e4935fb014b0c44649030d2c33f7fa049d8

include/tdm.h
include/tdm_backend.h
include/tdm_types.h
src/tdm_hwc_window.c
src/tdm_layer.c
src/tdm_output.c
src/tdm_private.h
src/tdm_private_types.h

index d6bc82a..402d31d 100644 (file)
@@ -1059,6 +1059,18 @@ tdm_error
 tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags);
 
 /**
+ * @brief Commit changes for a window object
+ * @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_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data);
+
+/**
  * @brief Get the available property array  of a video hwc window object.
  * @param[in] hwc window A video hwc window object
  * @param[out] props The available property array
index 297c74a..62ac805 100644 (file)
@@ -595,6 +595,16 @@ typedef struct _tdm_func_output {
        tdm_error (*output_hwc_set_client_target_buffer)(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage);
 
        /**
+        * @brief Get the layer associated with the client target buffer
+        * @details TODO:
+        * @param[in] output A output object
+        * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value.
+        * @return A layer object.
+        * @since 2.0.0
+        */
+       tdm_layer *(*output_hwc_get_target_buffer_layer)(tdm_output *output, tdm_error *error);
+
+       /**
         * @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
@@ -896,6 +906,19 @@ typedef struct _tdm_func_window {
                                                                           tbm_surface_h buffer);
 
        /**
+        * @brief Get a layer associated with a window object
+        * @param[in] hwc_window A window object
+        * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value.
+        * @return A layer which is @b assigend to a window object
+        * @remark
+        * A backend module @b SHOULD implement this function. The backend should
+        * return the tdm_layer assoicated with a hwc_window which must be assigend
+        * hw overlay.\n
+        */
+       tdm_layer *(*hwc_window_get_layer)(tdm_hwc_window *hwc_window,
+                                                                          tdm_error *error);
+
+       /**
         * @brief Set a flags to a window object
         * @param[in] hwc_window A window object
         * @param[in] flags A hwc_window flags
index a20049f..8567149 100644 (file)
@@ -260,6 +260,13 @@ typedef void (*tdm_output_commit_handler)(tdm_output *output, unsigned int seque
                                                                                  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 layer commit handler
  */
 typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence,
@@ -267,6 +274,13 @@ typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence
                                                                                 void *user_data);
 
 /**
+ * @brief The hwc_window commit handler
+ */
+typedef void (*tdm_hwc_window_commit_handler)(tdm_hwc_window *hwc_window, 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 73f92c0..342b9db 100644 (file)
@@ -195,6 +195,10 @@ tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
                         info->transform);
 
        ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
+       if (ret == TDM_ERROR_NONE) {
+               if (memcmp(&private_hwc_window->info, info, sizeof(tdm_hwc_window_info)) != 0)
+                       private_hwc_window->info = *info;
+       }
 
        _pthread_mutex_unlock(&private_display->lock);
 
@@ -230,6 +234,8 @@ tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
        }
 
        ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
+       if (ret == TDM_ERROR_NONE)
+               private_hwc_window->buffer = buffer;
 
        _pthread_mutex_unlock(&private_display->lock);
 
@@ -383,6 +389,91 @@ tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags
        return ret;
 }
 
+static
+void _tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence,
+                                                                                unsigned int tv_sec, unsigned int tv_usec,
+                                                                                void *user_data)
+{
+       tdm_private_hwc_window_commit_handler *hwc_window_commit_handler = (tdm_private_hwc_window_commit_handler *)user_data;
+       tdm_hwc_window_commit_handler func = hwc_window_commit_handler->func;
+       tdm_hwc_window *hwc_window = (tdm_hwc_window *)hwc_window_commit_handler->private_hwc_window;
+       void *data = hwc_window_commit_handler->user_data;
+
+       func(hwc_window, sequence, tv_sec, tv_usec, data);
+
+       free(hwc_window_commit_handler);
+}
+
+tdm_error
+tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data)
+{
+       tdm_func_hwc_window *func_hwc_window = NULL;
+       tdm_private_hwc_window_commit_handler *hwc_window_commit_handler;
+       tdm_layer *layer = NULL;
+       tdm_private_layer *private_layer;
+
+       HWC_WINDOW_FUNC_ENTRY();
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       func_hwc_window = &private_display->func_hwc_window;
+
+       if (!func_hwc_window->hwc_window_get_layer) {
+               /* LCOV_EXCL_START */
+               _pthread_mutex_unlock(&private_display->lock);
+               TDM_ERR("not implemented!!");
+               return TDM_ERROR_NOT_IMPLEMENTED;
+               /* LCOV_EXCL_STOP */
+       }
+
+       layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_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 */
+       }
+
+       layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_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;
+
+       hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler));
+       if (!hwc_window_commit_handler) {
+               /* LCOV_EXCL_START */
+               TDM_ERR("failed: alloc memory");
+               return TDM_ERROR_OUT_OF_MEMORY;
+               /* LCOV_EXCL_STOP */
+       }
+
+       hwc_window_commit_handler->private_hwc_window = private_hwc_window;
+       hwc_window_commit_handler->func = func;
+       hwc_window_commit_handler->user_data = user_data;
+
+       ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, user_data);
+       if (ret != TDM_ERROR_NONE) {
+               /* LCOV_EXCL_START */
+               TDM_ERR("failed: commit layer(window)");
+               free(hwc_window_commit_handler);
+               /* LCOV_EXCL_STOP */
+               return ret;
+       }
+
+       _pthread_mutex_unlock(&private_display->lock);
+
+       return ret;
+}
+
 EXTERN tdm_error
 tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
                                                                        tdm_hwc_window_video_capability *video_capability)
index 8ef46a6..6787258 100644 (file)
@@ -406,17 +406,11 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer)
        }
 }
 
-EXTERN tdm_error
-tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
+INTERN tdm_error
+tdm_layer_set_buffer_internal(tdm_private_layer *private_layer, tbm_surface_h buffer)
 {
        tdm_func_layer *func_layer;
 
-       LAYER_FUNC_ENTRY();
-
-       TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       _pthread_mutex_lock(&private_display->lock);
-
        /* LCOV_EXCL_START */
        /* dump buffer */
        if (tdm_dump_enable && !(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO))
@@ -441,7 +435,6 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
 
        if (!func_layer->layer_set_buffer) {
                /* LCOV_EXCL_START */
-               _pthread_mutex_unlock(&private_display->lock);
                TDM_ERR("not implemented!!");
                return TDM_ERROR_NOT_IMPLEMENTED;
                /* LCOV_EXCL_START */
@@ -475,19 +468,31 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
                TDM_TRACE_ASYNC_BEGIN((intptr_t)private_layer, "[LAYER] %d", tbm_bo_export(bo));
        }
 
+       return TDM_ERROR_NONE;
+}
+
+EXTERN tdm_error
+tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
+{
+       LAYER_FUNC_ENTRY();
+
+       TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       ret = tdm_layer_set_buffer_internal(private_layer, buffer);
+
        _pthread_mutex_unlock(&private_display->lock);
 
        return ret;
 }
 
-EXTERN tdm_error
-tdm_layer_unset_buffer(tdm_layer *layer)
+INTERN tdm_error
+tdm_layer_unset_buffer_internal(tdm_private_layer *private_layer)
 {
        tdm_func_layer *func_layer;
        LAYER_FUNC_ENTRY();
 
-       _pthread_mutex_lock(&private_display->lock);
-
        func_layer = &private_display->func_layer;
 
        _tdm_layer_free_all_buffers(private_layer);
@@ -499,7 +504,6 @@ tdm_layer_unset_buffer(tdm_layer *layer)
 
        if (!func_layer->layer_unset_buffer) {
                /* LCOV_EXCL_START */
-               _pthread_mutex_unlock(&private_display->lock);
                TDM_ERR("not implemented!!");
                return TDM_ERROR_NOT_IMPLEMENTED;
                /* LCOV_EXCL_START */
@@ -508,6 +512,18 @@ tdm_layer_unset_buffer(tdm_layer *layer)
        ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
        TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
+       return ret;
+}
+
+EXTERN tdm_error
+tdm_layer_unset_buffer(tdm_layer *layer)
+{
+       LAYER_FUNC_ENTRY();
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       ret = tdm_layer_unset_buffer_internal(private_layer);
+
        _pthread_mutex_unlock(&private_display->lock);
 
        return ret;
@@ -934,12 +950,11 @@ commit_failed:
        return ret;
 }
 
-EXTERN tdm_error
-tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
+INTERN tdm_error
+tdm_layer_commit_internal(tdm_private_layer *private_layer, tdm_layer_commit_handler func, void *user_data)
 {
-       LAYER_FUNC_ENTRY();
-
-       _pthread_mutex_lock(&private_display->lock);
+       tdm_private_output *private_output = private_layer->private_output;
+       tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */
 
        if (private_output->commit_type == TDM_COMMIT_TYPE_NONE) {
                if (!private_output->commit_per_vblank)
@@ -949,22 +964,32 @@ tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_dat
        }
 
        if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) {
-               TDM_ERR("layer(%p)'s output(%d) dpms: %s", layer, private_output->pipe,
+               TDM_ERR("layer(%p)'s output(%d) dpms: %s", private_layer, private_output->pipe,
                                tdm_dpms_str(private_output->current_dpms_value));
-               _pthread_mutex_unlock(&private_display->lock);
                return TDM_ERROR_DPMS_OFF;
        }
 
        /* don't call this inside of _tdm_layer_commit */
        ret = tdm_layer_commit_pending_data(private_layer);
        if (ret != TDM_ERROR_NONE) {
-               TDM_ERR("layer(%p) committing pending data failed", layer);
-               _pthread_mutex_unlock(&private_display->lock);
+               TDM_ERR("layer(%p) committing pending data failed", private_layer);
                return ret;
        }
 
        ret = _tdm_layer_commit(private_layer, func, user_data);
 
+       return ret;
+}
+
+EXTERN tdm_error
+tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
+{
+       LAYER_FUNC_ENTRY();
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       ret = tdm_layer_commit_internal(private_layer, func, user_data);
+
        _pthread_mutex_unlock(&private_display->lock);
 
        return ret;
index 63fe459..1595cce 100644 (file)
@@ -1826,6 +1826,87 @@ tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target
        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_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;
+
+       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_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_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;
+
+       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 6cf2a6d..eea36d4 100644 (file)
@@ -136,6 +136,8 @@ void
 tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data);
 
 tdm_error
+tdm_layer_commit_internal(tdm_private_layer *private_layer, tdm_layer_commit_handler func, void *user_data);
+tdm_error
 tdm_layer_commit_pending_data(tdm_private_layer *private_layer);
 void
 tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer **committed_buffer);
index 8f7fb7d..7a1829d 100644 (file)
@@ -106,7 +106,9 @@ typedef struct _tdm_private_server tdm_private_server;
 typedef struct _tdm_private_thread tdm_private_thread;
 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_output_hwc_target_buffer_window_commit_handler tdm_private_output_hwc_target_buffer_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_change_handler tdm_private_change_handler;
 typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer;
 
@@ -251,11 +253,14 @@ struct _tdm_private_hwc_window {
        struct list_head link;
 
        int index;
-       uint32_t zpos;
 
        tdm_private_display *private_display;
        tdm_private_output *private_output;
 
+       uint32_t zpos;
+       tdm_hwc_window_info info;
+       tbm_surface_h buffer;
+
        tdm_hwc_window *hwc_window_backend;
 };
 
@@ -358,6 +363,12 @@ struct _tdm_private_output_commit_handler {
        pid_t owner_tid;
 };
 
+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_layer_commit_handler {
        struct list_head link;
 
@@ -368,6 +379,12 @@ struct _tdm_private_layer_commit_handler {
        tdm_private_layer_buffer *committed_buffer;   /* for layer_commit */
 };
 
+struct _tdm_private_hwc_window_commit_handler {
+       tdm_private_hwc_window *private_hwc_window;
+       tdm_hwc_window_commit_handler func;
+       void *user_data;
+};
+
 struct _tdm_private_change_handler {
        struct list_head link;