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
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
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
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,
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,
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);
}
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);
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)
}
}
-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))
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 */
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);
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 */
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;
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)
}
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;
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)
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);
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;
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;
};
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;
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;