From a8855a952419b40a6779b1c2716bee1873d7731a Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 5 Sep 2018 20:58:54 +0900 Subject: [PATCH] virtual: define functions and structure for supporting virtual output Change-Id: I71b298a2917645261c838dce51b9ae1854b341c3 Signed-off-by: Junkyeong Kim --- include/tdm.h | 72 ++++++++++++++++++++++++++ include/tdm_backend.h | 135 +++++++++++++++++++++++++++++++++++++++++++++++- include/tdm_types.h | 30 +++++++++++ src/tdm_macro.h | 4 ++ src/tdm_private.h | 38 ++++++++++++++ src/tdm_private_types.h | 97 ++++++++++++++++++++++++++++++++++ 6 files changed, 375 insertions(+), 1 deletion(-) diff --git a/include/tdm.h b/include/tdm.h index 11e6173..169fd7c 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -207,6 +207,30 @@ tdm_output * tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error); /** + * @brief Add a output create handler + * @param[in] output A output object + * @param[in] func A output create handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_display_add_output_create_handler(tdm_display *dpy, + tdm_output_create_handler func, + void *user_data); + +/** + * @brief Remove a output create handler + * @param[in] output A output object + * @param[in] func A output create handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +void +tdm_display_remove_output_create_handler(tdm_display *dpy, + tdm_output_create_handler func, + void *user_data); + +/** * @brief Find a output object which has the given name. * @param[in] dpy A display object * @param[in] name The name of a output object @@ -239,6 +263,30 @@ tdm_module_get_info(tdm_module *module, const char **name, const char **vendor, int *major, int *minor); /** + * @brief Add a output destroy handler + * @param[in] output A output object + * @param[in] func A output destroy handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_add_destroy_handler(tdm_output *output, + tdm_output_destroy_handler func, + void *user_data); + +/** + * @brief Remove a output destroy handler + * @param[in] output A output object + * @param[in] func A output destroy handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +void +tdm_output_remove_destroy_handler(tdm_output *output, + tdm_output_destroy_handler func, + void *user_data); + +/** * @brief Get a backend module object of the given output. * @param[in] output A output object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. @@ -305,6 +353,30 @@ tdm_output_remove_change_handler(tdm_output *output, void *user_data); /** + * @brief Add a output mode change handler + * @param[in] output A output object + * @param[in] func A output mode change handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_add_mode_change_request_handler(tdm_output *output, + tdm_output_mode_change_request_handler func, + void *user_data); + +/** + * @brief Remove a output mode change handler + * @param[in] output A output object + * @param[in] func A output mode change handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_remove_mode_change_request_handler(tdm_output *output, + tdm_output_mode_change_request_handler func, + void *user_data); + +/** * @brief Get the connection type of a output object. * @param[in] output A output object * @param[out] type The connection type. diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 033f803..675d9c4 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -335,7 +335,18 @@ typedef struct _tdm_func_display { */ tdm_pp *(*display_create_pp)(tdm_backend_data *bdata, tdm_error *error); - void (*reserved1)(void); + /** + * @brief Create a virtual output object of a backend module + * @param[in] bdata The backend module data + * @param[in] name The output name + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A tdm_voutput object + * @see voutput_destroy() function + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_voutput *(*voutput_create)(tdm_backend_data *bdata, const char *name, tdm_error *error); + void (*reserved2)(void); void (*reserved3)(void); void (*reserved4)(void); @@ -548,12 +559,102 @@ typedef struct _tdm_func_output { */ tdm_hwc *(*output_get_hwc)(tdm_output *output, tdm_error *error); + void (*reserved3)(void); + void (*reserved4)(void); void (*reserved5)(void); void (*reserved6)(void); void (*reserved7)(void); void (*reserved8)(void); } tdm_func_output; +typedef struct _tdm_func_voutput { + /** + * @brief Destroy a virtual output object of a backend module + * @param[in] voutput The voutput object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see voutput_create() function + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_error (*voutput_destroy)(tdm_voutput *voutput); + + /** + * @brief Set available modes of a virtual output object + * @param[in] voutput A voutput object + * @param[in] modes Modes of voutput + * @param[in] count A count of modes + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_error (*voutput_set_available_mode)(tdm_voutput *voutput, const tdm_output_mode *modes, int count); + + /** + * @brief Set physical size(mm) of a virtual output object + * @param[in] voutput A voutput object + * @param[in] mmwidth Width of voutput + * @param[in] mmheight Height of voutput + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_error (*voutput_set_physical_size)(tdm_voutput *voutput, unsigned int mmwidth, unsigned int mmheight); + + /** + * @brief Set connect status of a virtual output object + * @param[in] voutput A voutput object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_error (*voutput_connect)(tdm_voutput *voutput); + + /** + * @brief Set disconnect status of a virtual output object + * @param[in] voutput A voutput object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_error (*voutput_disconnect)(tdm_voutput *voutput); + + /** + * @brief Get output object from virtual output object + * @param[in] voutput A voutput object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A tdm_output object + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_output *(*voutput_get_output)(tdm_voutput *voutput, tdm_error *error); + + /** + * @brief Set a user commit function + * @param[in] voutput A voutput object + * @param[in] func A user voutput commit function + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + * If virtual output's output_commit is executed, call this voutput commit func. + */ + tdm_error (*voutput_set_commit_func)(tdm_voutput *voutput, tdm_voutput_commit_handler commit_func); + + /** + * @brief Notify commit done to backend + * @param[in] voutput A voutput object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @remark + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ + tdm_error (*voutput_commit_done)(tdm_voutput *voutput); + + void (*reserved1)(void); + void (*reserved2)(void); + void (*reserved3)(void); + void (*reserved4)(void); + void (*reserved5)(void); + void (*reserved6)(void); +} tdm_func_voutput; /** * @brief The layer functions for a backend module. */ @@ -1187,6 +1288,18 @@ tdm_backend_register_func_output(tdm_display *dpy, tdm_func_output *func_output); /** + * @brief Register the backend voutput functions to a display + * @param[in] dpy A display object + * @param[in] func_voutput voutput functions + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see tdm_backend_register_func_display, tdm_backend_register_func_output + * @remarks + * A backend module doesn't need to implement this function if doesn't support virtual output. + */ +tdm_error +tdm_backend_register_func_voutput(tdm_display *dpy, tdm_func_voutput *func_voutput); + +/** * @brief Register the backend layer functions to a display * @param[in] dpy A display object * @param[in] func_layer layer functions @@ -1252,6 +1365,26 @@ tdm_backend_register_func_capture(tdm_display *dpy, tdm_func_capture *func_capture); /** + * @brief Register the backend output to a display + * @param[in] dpy A display object + * @param[in] output A backend output object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see tdm_backend_unregister_output + */ +tdm_error +tdm_backend_register_output(tdm_display *dpy, tdm_output *output); + +/** + * @brief Unregister the backend output to a display + * @param[in] dpy A display object + * @param[in] output A backend output object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see tdm_backend_register_output + */ +void +tdm_backend_unregister_output(tdm_display *dpy, tdm_output *output); + +/** * @brief Increase the ref_count of a TDM buffer * @details * TDM has its own buffer release mechanism to let an frontend user know when a TDM buffer diff --git a/include/tdm_types.h b/include/tdm_types.h index b87fc18..24423d3 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -238,6 +238,11 @@ typedef void tdm_module; typedef void tdm_output; /** + * @brief The tdm voutput object + */ +typedef void tdm_voutput; + +/** * @brief The tdm layer object */ typedef void tdm_layer; @@ -270,6 +275,20 @@ typedef void tdm_pp; typedef void tdm_vblank; /** + * @brief The output create handler + * @details This handler will be called when the output object is + * createed in runtime. + */ +typedef void (*tdm_output_create_handler)(tdm_display *dpy, tdm_output *output, void *user_data); + +/** + * @brief The output destroy handler + * @details This handler will be called when the output object is + * destroied in runtime. + */ +typedef void (*tdm_output_destroy_handler)(tdm_output *output, void *user_data); + +/** * @brief The output change handler * @details This handler will be called when the status of a output object is * changed in runtime. @@ -296,6 +315,12 @@ typedef void (*tdm_output_commit_handler)(tdm_output *output, unsigned int seque void *user_data); /** + * @brief The output mode change request handler + */ +typedef void (*tdm_output_mode_change_request_handler)(tdm_output *output, + unsigned int index, void *user_data); + +/** * @brief The layer commit handler */ typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence, @@ -327,6 +352,11 @@ typedef void (*tdm_hwc_commit_handler)(tdm_hwc *hwc, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data); +typedef void (*tdm_voutput_commit_handler)(tdm_voutput *voutput, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data); + +typedef void (*tdm_voutput_commit_func)(tdm_voutput *voutput, tbm_surface_h buffer); #ifdef __cplusplus } #endif diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 5b8f861..bd7e257 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -86,6 +86,7 @@ extern "C" { /* common backend names *****************************************************/ #define TDM_DEFAULT_MODULE "libtdm-default.so" #define TDM_DUMMY_MODULE "libtdm-dummy.so" +#define TDM_VIRTUAL_MODULE "libtdm-virtual.so" /* dump directory ***********************************************************/ #define TDM_DUMP_DIR "/tmp" @@ -245,6 +246,8 @@ TDM_TYPE_NAME_FN(value_type) static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_NONE, "none" }, { TDM_THREAD_CB_EXIT, "exit" }, + { TDM_THREAD_CB_DISPLAY_OUTPUT_CREATE, "output-create" }, + { TDM_THREAD_CB_OUTPUT_DESTROY, "output-destroy" }, { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, @@ -254,6 +257,7 @@ static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, { TDM_THREAD_CB_VBLANK_CREATE, "vblank-create" }, { TDM_THREAD_CB_HWC_COMMIT, "hwc-commit" }, + { TDM_THREAD_CB_VOUTPUT_COMMIT, "voutput-commit" }, }; TDM_TYPE_NAME_FN(cb_type) diff --git a/src/tdm_private.h b/src/tdm_private.h index 5e1ed84..fd1fdae 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -88,10 +88,17 @@ tdm_display_get(void); int tdm_module_check_abi(tdm_private_module *private_module, int abimaj, int abimin); +tdm_error +tdm_display_call_thread_cb_output_create(tdm_private_display *private_display, tdm_output *output); +void +tdm_display_thread_cb_output_create(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); void * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp); tdm_private_output * tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend); +unsigned int +tdm_display_find_empty_output_pipe(tdm_private_display *private_display); + void * tdm_display_find_hwc_stamp(tdm_private_display *private_display, double stamp); @@ -101,6 +108,10 @@ tdm_display_find_private_hwc(tdm_private_display *private_display, tdm_hwc *hwc_ tdm_error tdm_output_init(tdm_private_display *private_display); +tdm_error +tdm_output_call_thread_cb_destroy(tdm_private_output *private_output); +void +tdm_output_thread_cb_destroy(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); void tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); void @@ -127,6 +138,10 @@ void tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data); void tdm_output_remove_commit_handler_internal(tdm_output *output, tdm_output_commit_handler func, void *user_data); + +void +tdm_output_request_mode_set(tdm_output *output, unsigned int index); + void tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data); @@ -242,6 +257,29 @@ tdm_config_deinit(void); void tdm_monitor_server_command(tdm_display *dpy, const char *options, char *reply, int *len); +/* virtual */ +tdm_voutput * +tdm_voutput_create(tdm_display *dpy, const char *name, tdm_error *error); +tdm_error +tdm_voutput_destroy(tdm_voutput *voutput); +tdm_error +tdm_voutput_set_available_mode(tdm_voutput *voutput, const tdm_output_mode *modes, int count); +tdm_error +tdm_voutput_set_physical_size(tdm_voutput *voutput, unsigned int mmwidth, unsigned int mmheight); +tdm_error +tdm_voutput_connect(tdm_voutput *voutput); +tdm_error +tdm_voutput_disconnect(tdm_voutput *voutput); +tdm_error +tdm_voutput_set_commit_func(tdm_voutput *voutput, tdm_voutput_commit_handler func); +tdm_error +tdm_voutput_attach_buffer(tdm_voutput *voutput, tbm_surface_h buffer); +tdm_error +tdm_voutput_commit_buffer(tdm_voutput *voutput); +tdm_error +tdm_voutput_commit_done(tdm_voutput *voutput); +void * +tdm_display_find_private_voutput(tdm_private_display *private_display, double stamp); #ifdef __cplusplus } #endif diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 37adf72..993be0e 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -99,6 +99,7 @@ typedef enum { typedef struct _tdm_private_module tdm_private_module; typedef struct _tdm_private_display tdm_private_display; typedef struct _tdm_private_output tdm_private_output; +typedef struct _tdm_private_voutput tdm_private_voutput; typedef struct _tdm_private_layer tdm_private_layer; typedef struct _tdm_private_hwc tdm_private_hwc; typedef struct _tdm_private_hwc_window tdm_private_hwc_window; @@ -107,11 +108,15 @@ typedef struct _tdm_private_capture tdm_private_capture; typedef struct _tdm_private_loop tdm_private_loop; typedef struct _tdm_private_server tdm_private_server; typedef struct _tdm_private_thread tdm_private_thread; +typedef struct _tdm_private_output_create_handler tdm_private_output_create_handler; +typedef struct _tdm_private_output_destroy_handler tdm_private_output_destroy_handler; typedef struct _tdm_private_output_change_handler tdm_private_output_change_handler; typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler; typedef struct _tdm_private_output_vblank_handler tdm_private_output_vblank_handler; +typedef struct _tdm_private_output_mode_change_handler tdm_private_output_mode_change_handler; typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler; typedef struct _tdm_private_hwc_commit_handler tdm_private_hwc_commit_handler; +typedef struct _tdm_private_voutput_commit_handler tdm_private_voutput_commit_handler; typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer; @@ -129,6 +134,7 @@ struct _tdm_private_module { tdm_display_capability capabilities; tdm_func_display func_display; tdm_func_output func_output; + tdm_func_voutput func_voutput; tdm_func_layer func_layer; tdm_func_hwc func_hwc; tdm_func_hwc_window func_hwc_window; @@ -142,6 +148,7 @@ struct _tdm_private_module { /* output, pp list */ struct list_head output_list; + struct list_head voutput_list; struct list_head pp_list; struct list_head capture_list; @@ -163,6 +170,8 @@ struct _tdm_private_display { #endif struct list_head module_list; + tdm_private_module *dummy_module; + tdm_private_module *virtual_module; tdm_private_module *current_module; //setted only when loading tdm_private_module *pp_module; //pp-support backend tdm_private_module *capture_module; //TODO: remove later @@ -170,6 +179,8 @@ struct _tdm_private_display { /* for event handling */ tdm_private_loop *private_loop; + struct list_head output_create_handler_list; + int print_fps; }; @@ -177,6 +188,7 @@ struct _tdm_private_output { struct list_head link; tdm_private_module *private_module; + tdm_private_voutput *private_voutput; int index; double stamp; @@ -210,6 +222,7 @@ struct _tdm_private_output { tdm_event_loop_source *vblank_timeout_timer; unsigned int vblank_timeout_timer_expired; + struct list_head destroy_handler_list; struct list_head change_handler_list; void **layers_ptr; @@ -226,6 +239,34 @@ struct _tdm_private_output { /* hwc */ int need_set_target_info; tdm_private_hwc *private_hwc; + + /* virtual */ + char name[TDM_NAME_LEN]; + struct list_head mode_change_request_handler_list; +}; + +struct _tdm_private_voutput { + struct list_head link; + + tdm_private_module *private_module; + + int regist_commit_cb; + + struct list_head voutput_commit_handler_list; + + int index; + + tdm_private_display *private_display; + tdm_private_output *private_output; + + tdm_voutput *voutput_backend; + + char name[TDM_NAME_LEN]; + tdm_output_mode *modes; + int mode_count; + unsigned int mmwidth; + unsigned int mmheight; + int connect_status; }; struct _tdm_private_layer { @@ -263,6 +304,9 @@ struct _tdm_private_layer { double fps_stamp; unsigned int fps_count; + + /* virtual */ + tbm_surface_h commiting_buffer; }; struct _tdm_private_hwc { @@ -384,6 +428,26 @@ struct _tdm_private_output_vblank_handler { pid_t owner_tid; }; +struct _tdm_private_output_create_handler { + struct list_head link; + + tdm_private_display *private_display; + tdm_output_create_handler func; + void *user_data; + + pid_t owner_tid; +}; + +struct _tdm_private_output_destroy_handler { + struct list_head link; + + tdm_private_output *private_output; + tdm_output_destroy_handler func; + void *user_data; + + pid_t owner_tid; +}; + struct _tdm_private_output_change_handler { struct list_head link; @@ -404,6 +468,24 @@ struct _tdm_private_output_commit_handler { pid_t owner_tid; }; +struct _tdm_private_voutput_commit_handler { + struct list_head link; + + tdm_private_voutput *private_voutput; + tdm_voutput_commit_func func; + void *user_data; + + pid_t owner_tid; +}; + +struct _tdm_private_output_mode_change_handler { + struct list_head link; + + tdm_private_output *private_output; + tdm_output_mode_change_request_handler func; + void *user_data; +}; + struct _tdm_private_hwc_commit_handler { struct list_head link; @@ -458,6 +540,8 @@ typedef struct _tdm_capture_private_buffer { typedef enum { TDM_THREAD_CB_NONE, TDM_THREAD_CB_EXIT, /* special type to exit the tdm-thread */ + TDM_THREAD_CB_DISPLAY_OUTPUT_CREATE, + TDM_THREAD_CB_OUTPUT_DESTROY, TDM_THREAD_CB_OUTPUT_COMMIT, TDM_THREAD_CB_OUTPUT_VBLANK, TDM_THREAD_CB_OUTPUT_STATUS, @@ -467,10 +551,13 @@ typedef enum { TDM_THREAD_CB_VBLANK_SW, TDM_THREAD_CB_VBLANK_CREATE, TDM_THREAD_CB_HWC_COMMIT, + TDM_THREAD_CB_VOUTPUT_COMMIT, TDM_THREAD_CB_MAX, } tdm_thread_cb_type; typedef struct _tdm_thread_cb_base tdm_thread_cb_base; +typedef struct _tdm_thread_cb_display_output_create tdm_thread_cb_display_output_create; +typedef struct _tdm_thread_cb_output_destroy tdm_thread_cb_output_destroy; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank; typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; @@ -480,6 +567,7 @@ typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; typedef struct _tdm_thread_cb_vblank_create tdm_thread_cb_vblank_create; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_hwc_commit; +typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_voutput_commit; struct _tdm_thread_cb_base { tdm_thread_cb_type type; @@ -489,6 +577,15 @@ struct _tdm_thread_cb_base { unsigned int sync; }; +struct _tdm_thread_cb_display_output_create { + tdm_thread_cb_base base; + tdm_output *output; +}; + +struct _tdm_thread_cb_output_destroy { + tdm_thread_cb_base base; +}; + struct _tdm_thread_cb_output_vblank { tdm_thread_cb_base base; unsigned int sequence; -- 2.7.4