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
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.
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.
*/
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);
*/
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.
*/
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
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
typedef void tdm_output;
/**
+ * @brief The tdm voutput object
+ */
+typedef void tdm_voutput;
+
+/**
* @brief The tdm layer object
*/
typedef void tdm_layer;
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.
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,
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
/* 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"
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" },
{ 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)
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);
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
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);
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
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;
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;
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;
/* output, pp list */
struct list_head output_list;
+ struct list_head voutput_list;
struct list_head pp_list;
struct list_head capture_list;
#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
/* for event handling */
tdm_private_loop *private_loop;
+ struct list_head output_create_handler_list;
+
int print_fps;
};
struct list_head link;
tdm_private_module *private_module;
+ tdm_private_voutput *private_voutput;
int index;
double stamp;
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;
/* 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 {
double fps_stamp;
unsigned int fps_count;
+
+ /* virtual */
+ tbm_surface_h commiting_buffer;
};
struct _tdm_private_hwc {
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;
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;
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,
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;
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;
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;