From ceeb07117433a7aaecc0041df8162f43fd8e06de Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Fri, 9 Aug 2019 18:00:36 +0900 Subject: [PATCH 01/16] tdm_virtual: support hwc mode Change-Id: I0b8241af46e33dab41ce2ab2297871895f00519e Signed-off-by: Junkyeong Kim --- backends/virtual/Makefile.am | 2 + backends/virtual/tdm_virtual.c | 51 ++- backends/virtual/tdm_virtual.h | 168 +++++++++- backends/virtual/tdm_virtual_display.c | 181 +++++------ backends/virtual/tdm_virtual_hwc.c | 494 ++++++++++++++++++++++++++++++ backends/virtual/tdm_virtual_hwc.h | 8 + backends/virtual/tdm_virtual_hwc_window.c | 136 ++++++++ backends/virtual/tdm_virtual_hwc_window.h | 6 + src/tdm_backend.c | 20 +- src/tdm_hwc.c | 19 ++ 10 files changed, 981 insertions(+), 104 deletions(-) create mode 100644 backends/virtual/tdm_virtual_hwc.c create mode 100644 backends/virtual/tdm_virtual_hwc.h create mode 100644 backends/virtual/tdm_virtual_hwc_window.c create mode 100644 backends/virtual/tdm_virtual_hwc_window.h diff --git a/backends/virtual/Makefile.am b/backends/virtual/Makefile.am index 099b71e..d872dd9 100644 --- a/backends/virtual/Makefile.am +++ b/backends/virtual/Makefile.am @@ -10,5 +10,7 @@ libtdm_virtual_la_LIBADD = $(TDM_LIBS) $(top_builddir)/src/libtdm.la libtdm_virtual_la_SOURCES = \ tdm_virtual_display.c \ + tdm_virtual_hwc.c \ + tdm_virtual_hwc_window.c \ tdm_virtual.c diff --git a/backends/virtual/tdm_virtual.c b/backends/virtual/tdm_virtual.c index 580d440..dd64ae7 100644 --- a/backends/virtual/tdm_virtual.c +++ b/backends/virtual/tdm_virtual.c @@ -4,6 +4,8 @@ #include "tdm_virtual.h" +#define TDM_HWC 1 + static tdm_virtual_data *virtual_data; void @@ -31,6 +33,8 @@ tdm_virtual_init(tdm_display *dpy, tdm_error *error) tdm_func_display virtual_func_display; tdm_func_output virtual_func_output; tdm_func_voutput virtual_func_voutput; + tdm_func_hwc virtual_func_hwc; + tdm_func_hwc_window virtual_func_hwc_window; tdm_func_layer virtual_func_layer; tdm_error ret; @@ -56,6 +60,10 @@ tdm_virtual_init(tdm_display *dpy, tdm_error *error) return NULL; } +#if TDM_HWC + virtual_data->hwc_mode = 1; +#endif + LIST_INITHEAD(&virtual_data->voutput_list); LIST_INITHEAD(&virtual_data->output_list); LIST_INITHEAD(&virtual_data->buffer_list); @@ -74,13 +82,42 @@ tdm_virtual_init(tdm_display *dpy, tdm_error *error) virtual_func_output.output_set_vblank_handler = virtual_output_set_vblank_handler; virtual_func_output.output_commit = virtual_output_commit; virtual_func_output.output_set_commit_handler = virtual_output_set_commit_handler; - virtual_func_output.output_set_dpms = virtual_output_set_dpms; virtual_func_output.output_get_dpms = virtual_output_get_dpms; - virtual_func_output.output_set_mode = virtual_output_set_mode; virtual_func_output.output_get_mode = virtual_output_get_mode; virtual_func_output.output_set_status_handler = virtual_output_set_status_handler; + if (virtual_data->hwc_mode) { + virtual_func_output.output_get_hwc = virtual_output_get_hwc; + + memset(&virtual_func_hwc, 0, sizeof(virtual_func_hwc)); + virtual_func_hwc.hwc_create_window = virtual_hwc_create_window; + virtual_func_hwc.hwc_get_video_supported_formats = virtual_hwc_get_video_supported_formats; + virtual_func_hwc.hwc_get_video_available_properties = NULL; + virtual_func_hwc.hwc_get_capabilities = virtual_hwc_get_capabilities; + virtual_func_hwc.hwc_get_available_properties = virtual_hwc_get_available_properties; + virtual_func_hwc.hwc_get_client_target_buffer_queue = virtual_hwc_get_client_target_buffer_queue; + virtual_func_hwc.hwc_set_client_target_buffer = virtual_hwc_set_client_target_buffer; + virtual_func_hwc.hwc_validate = virtual_hwc_validate; + virtual_func_hwc.hwc_get_changed_composition_types = virtual_hwc_get_changed_composition_types; + virtual_func_hwc.hwc_accept_validation = virtual_hwc_accept_validation; + virtual_func_hwc.hwc_commit = virtual_hwc_commit; + virtual_func_hwc.hwc_set_commit_handler = virtual_hwc_set_commit_handler; + + memset(&virtual_func_hwc_window, 0, sizeof(virtual_func_hwc_window)); + virtual_func_hwc_window.hwc_window_destroy = virtual_hwc_window_destroy; + virtual_func_hwc_window.hwc_window_acquire_buffer_queue = NULL; // no need + virtual_func_hwc_window.hwc_window_release_buffer_queue = NULL; // no need + virtual_func_hwc_window.hwc_window_set_composition_type = virtual_hwc_window_set_composition_type; + virtual_func_hwc_window.hwc_window_set_buffer_damage = virtual_hwc_window_set_buffer_damage; + virtual_func_hwc_window.hwc_window_set_info = virtual_hwc_window_set_info; + virtual_func_hwc_window.hwc_window_set_buffer = virtual_hwc_window_set_buffer; + virtual_func_hwc_window.hwc_window_set_property = virtual_hwc_window_set_property; + virtual_func_hwc_window.hwc_window_get_property = virtual_hwc_window_get_property; + virtual_func_hwc_window.hwc_window_get_constraints = virtual_hwc_window_get_constraints; + virtual_func_hwc_window.hwc_window_set_name = virtual_hwc_window_set_name; + virtual_func_hwc_window.hwc_window_set_cursor_image = NULL; // no need + } memset(&virtual_func_voutput, 0, sizeof(virtual_func_voutput)); virtual_func_voutput.voutput_destroy = virtual_voutput_destroy; @@ -107,6 +144,16 @@ tdm_virtual_init(tdm_display *dpy, tdm_error *error) if (ret != TDM_ERROR_NONE) goto failed; + if (virtual_data->hwc_mode) { + ret = tdm_backend_register_func_hwc(dpy, &virtual_func_hwc); + if (ret != TDM_ERROR_NONE) + goto failed; + + ret = tdm_backend_register_func_hwc_window(dpy, &virtual_func_hwc_window); + if (ret != TDM_ERROR_NONE) + goto failed; + } + ret = tdm_backend_register_func_voutput(dpy, &virtual_func_voutput); if (ret != TDM_ERROR_NONE) goto failed; diff --git a/backends/virtual/tdm_virtual.h b/backends/virtual/tdm_virtual.h index 0a5c377..cc36d58 100644 --- a/backends/virtual/tdm_virtual.h +++ b/backends/virtual/tdm_virtual.h @@ -52,12 +52,50 @@ tdm_output *virtual_voutput_get_output(tdm_voutput *voutput, tdm_error *error); tdm_error virtual_voutput_set_commit_func(tdm_voutput *voutput, tdm_voutput_commit_handler commit_func); tdm_error virtual_voutput_commit_done(tdm_voutput *voutput); +tdm_hwc *virtual_output_get_hwc(tdm_output *output, tdm_error *error); +tdm_hwc_window *virtual_hwc_create_window(tdm_hwc *hwc, tdm_error *error); +tdm_error virtual_hwc_get_video_supported_formats(tdm_output *output, const tbm_format **formats, int *count); +tdm_error virtual_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities); +tdm_error virtual_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count); +tbm_surface_queue_h virtual_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error); +tdm_error virtual_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage); +tdm_error virtual_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types); +tdm_error virtual_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types); +tdm_error virtual_hwc_accept_validation(tdm_hwc *hwc); +tdm_error virtual_hwc_commit(tdm_hwc *hwc, int sync, void *user_data); +tdm_error virtual_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func); + +void virtual_hwc_window_destroy(tdm_hwc_window *hwc_window); +tdm_error virtual_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type); +tdm_error virtual_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage); +tdm_error virtual_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info); +tdm_error virtual_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface); +tdm_error virtual_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value); +tdm_error virtual_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value); +tdm_error virtual_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints); +tdm_error virtual_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name); + tdm_error virtual_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps); tdm_error virtual_layer_set_info(tdm_layer *layer, tdm_info_layer *info); tdm_error virtual_layer_get_info(tdm_layer *layer, tdm_info_layer *info); tdm_error virtual_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer); tdm_error virtual_layer_unset_buffer(tdm_layer *layer); +#define C(b,m) (((b) >> (m)) & 0xFF) +#define B(c,s) ((((unsigned int)(c)) & 0xff) << (s)) +#define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0)) +#define FOURCC_STR(id) C(id,0), C(id,8), C(id,16), C(id,24) + +#define IS_RGB(format) (format == TBM_FORMAT_XRGB8888 || format == TBM_FORMAT_ARGB8888 || \ + format == TBM_FORMAT_XBGR8888 || format == TBM_FORMAT_ABGR8888) + +#define RETURN_IF_FAIL(cond) { \ + if (!(cond)) { \ + TDM_ERR("'%s' failed", #cond); \ + return; \ + } \ +} + #define RETURN_VAL_IF_FAIL(cond, val) {\ if (!(cond)) {\ TDM_ERR("'%s' failed", #cond);\ @@ -72,16 +110,140 @@ tdm_error virtual_layer_unset_buffer(tdm_layer *layer); }\ } -typedef struct _tdm_virtual_data { +typedef struct _tdm_virtual_data tdm_virtual_data; +typedef struct _tdm_virtual_output_data tdm_virtual_output_data; +typedef struct _tdm_virtual_hwc_data tdm_virtual_hwc_data; +typedef struct _tdm_virtual_hwc_window_data tdm_virtual_hwc_window_data; +typedef struct _tdm_virtual_voutput_data tdm_virtual_voutput_data; +typedef struct _tdm_virtual_layer_data tdm_virtual_layer_data; +typedef struct _tdm_virtual_event_data tdm_virtual_event_data; + +typedef enum { + TDM_VIRTUAL_EVENT_TYPE_WAIT, + TDM_VIRTUAL_EVENT_TYPE_COMMIT, + TDM_VIRTUAL_EVENT_TYPE_VCOMMIT, +} tdm_virtual_event_type; + +struct _tdm_virtual_data { tdm_display *dpy; + int hwc_mode; int pipe[2]; struct list_head voutput_list; struct list_head output_list; struct list_head buffer_list; -} tdm_virtual_data; +}; -void tdm_virtual_display_destroy_output_list(tdm_virtual_data *virtual_data); +struct _tdm_virtual_output_data { + struct list_head link; + + /* data which are fixed at initializing */ + tdm_virtual_data *virtual_data; + tdm_virtual_voutput_data *voutput_data; + + char name[TDM_NAME_LEN]; /* output name */ + uint32_t pipe; + tdm_output_type connector_type; + struct list_head layer_list; + tdm_virtual_layer_data *primary_layer; + + tdm_output_dpms dpms; + + /* not fixed data below */ + tdm_output_vblank_handler vblank_func; + tdm_output_commit_handler commit_func; + void *commit_user_data; + + tdm_output_conn_status status; + tdm_output_status_handler status_func; + void *status_user_data; + + int mode_changed; + const tdm_output_mode *current_mode; + + tdm_event_loop_source *timer; + unsigned int timer_waiting; + struct list_head timer_event_list; + + /* hwc data */ + int hwc_enable; + tdm_virtual_hwc_data *hwc_data; +}; + +struct _tdm_virtual_hwc_data { + tdm_virtual_hwc_window_data *target_hwc_window; + + int need_validate; + int need_target_window; + int need_set_crtc; + + int target_window_zpos; + tdm_virtual_output_data *output_data; + struct list_head hwc_window_list; + + tdm_hwc_commit_handler commit_func; +}; + +struct _tdm_virtual_hwc_window_data { + struct list_head link; + + tdm_virtual_hwc_data *hwc_data; + + tdm_hwc_window_info info; + tbm_surface_h surface; + tdm_hwc_window_composition client_type; + tdm_hwc_window_composition validated_type; + int lzpos; + + char name[TDM_NAME_LEN]; +}; + +struct _tdm_virtual_voutput_data { + struct list_head link; + + /* data which are fixed at initializing */ + tdm_virtual_data *virtual_data; + tdm_virtual_output_data *output_data; + + char name[TDM_NAME_LEN]; /* output name */ + + tdm_voutput_commit_handler vcommit_func; + + tdm_output_mode *output_modes; + int mode_count; + + unsigned int mmwidth; + unsigned int mmheight; +}; + +struct _tdm_virtual_layer_data { + struct list_head link; + + /* data which are fixed at initializing */ + tdm_virtual_data *virtual_data; + tdm_virtual_output_data *output_data; + tdm_layer_capability capabilities; + int zpos; + + /* not fixed data below */ + tdm_info_layer info; + int info_changed; + + tbm_surface_h display_buffer; + int display_buffer_changed; +}; + +struct _tdm_virtual_event_data { + struct list_head link; + + tdm_virtual_event_type type; + tdm_virtual_output_data *output_data; + void *user_data; +}; + +void tdm_virtual_display_destroy_output_list(tdm_virtual_data *virtual_data); +tdm_virtual_layer_data *virtual_output_data_get_layer_data(tdm_virtual_output_data *output_data, int layer_zpos); +tdm_error virtual_hwc_initailize_target_window(tdm_hwc *hwc_data, int width, int height); #endif /* _TDM_VIRTUAL_H_ */ diff --git a/backends/virtual/tdm_virtual_display.c b/backends/virtual/tdm_virtual_display.c index ea3f5af..89f0769 100644 --- a/backends/virtual/tdm_virtual_display.c +++ b/backends/virtual/tdm_virtual_display.c @@ -4,98 +4,12 @@ #include "tdm_virtual.h" -typedef struct _tdm_virtual_output_data tdm_virtual_output_data; -typedef struct _tdm_virtual_voutput_data tdm_virtual_voutput_data; -typedef struct _tdm_virtual_layer_data tdm_virtual_layer_data; -typedef struct _tdm_virtual_event_data tdm_virtual_event_data; - -typedef enum { - TDM_VIRTUAL_EVENT_TYPE_WAIT, - TDM_VIRTUAL_EVENT_TYPE_COMMIT, - TDM_VIRTUAL_EVENT_TYPE_VCOMMIT, -} tdm_virtual_event_type; - -struct _tdm_virtual_event_data { - struct list_head link; - - tdm_virtual_event_type type; - tdm_virtual_output_data *output_data; - void *user_data; -}; - -struct _tdm_virtual_output_data { - struct list_head link; - - /* data which are fixed at initializing */ - tdm_virtual_data *virtual_data; - tdm_virtual_voutput_data *voutput_data; - - char name[TDM_NAME_LEN]; /* output name */ - uint32_t pipe; - tdm_output_type connector_type; - struct list_head layer_list; - tdm_virtual_layer_data *primary_layer; - - tdm_output_dpms dpms; - - /* not fixed data below */ - tdm_output_vblank_handler vblank_func; - tdm_output_commit_handler commit_func; - void *commit_user_data; - - tdm_output_conn_status status; - tdm_output_status_handler status_func; - void *status_user_data; - - int mode_changed; - const tdm_output_mode *current_mode; - - tdm_event_loop_source *timer; - unsigned int timer_waiting; - struct list_head timer_event_list; -}; - -struct _tdm_virtual_voutput_data { - struct list_head link; - - /* data which are fixed at initializing */ - tdm_virtual_data *virtual_data; - tdm_virtual_output_data *output_data; - - char name[TDM_NAME_LEN]; /* output name */ - - tdm_voutput_commit_handler vcommit_func; - - tdm_output_mode *output_modes; - int mode_count; - - unsigned int mmwidth; - unsigned int mmheight; -}; - - -struct _tdm_virtual_layer_data { - struct list_head link; - - /* data which are fixed at initializing */ - tdm_virtual_data *virtual_data; - tdm_virtual_output_data *output_data; - tdm_layer_capability capabilities; - int zpos; - - /* not fixed data below */ - tdm_info_layer info; - int info_changed; - - tbm_surface_h display_buffer; - int display_buffer_changed; -}; - static void _tdm_virtual_display_cb_event(tdm_virtual_output_data *output_data, tdm_virtual_event_data *event_data, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec) { tdm_virtual_voutput_data *voutput_data = NULL; + tdm_virtual_hwc_data *hwc_data; switch (event_data->type) { case TDM_VIRTUAL_EVENT_TYPE_WAIT: @@ -103,8 +17,20 @@ _tdm_virtual_display_cb_event(tdm_virtual_output_data *output_data, tdm_virtual_ output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data); break; case TDM_VIRTUAL_EVENT_TYPE_COMMIT: - if (output_data->commit_func) - output_data->commit_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data); + if (output_data->hwc_enable) { + hwc_data = output_data->hwc_data; + if (!hwc_data) { + TDM_ERR("no hwc_data"); + break; + } + + if (hwc_data->commit_func) + hwc_data->commit_func(hwc_data, sequence, + tv_sec, tv_usec, + event_data->user_data); + } else + if (output_data->commit_func) + output_data->commit_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data); break; case TDM_VIRTUAL_EVENT_TYPE_VCOMMIT: voutput_data = output_data->voutput_data; @@ -343,6 +269,9 @@ virtual_output_get_capability(tdm_output *output, tdm_caps_output *caps) caps->prop_count = 0; + if (output_data->virtual_data->hwc_mode) + caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC; + return TDM_ERROR_NONE; failed_get: memset(caps, 0, sizeof(tdm_caps_output)); @@ -361,6 +290,13 @@ virtual_output_get_layers(tdm_output *output, int *count, tdm_error *error) RETURN_VAL_IF_FAIL(output_data, NULL); RETURN_VAL_IF_FAIL(count, NULL); + if (output_data->virtual_data->hwc_mode) { + TDM_INFO("layers aren't supported in HWC mode"); + *count = 0; + ret = TDM_ERROR_NONE; + goto failed_get; + } + *count = 0; LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) (*count)++; @@ -566,10 +502,20 @@ tdm_error virtual_output_set_mode(tdm_output *output, const tdm_output_mode *mode) { tdm_virtual_output_data *output_data = output; + tdm_error ret = TDM_ERROR_NONE; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER); + /* create or replace the target_window when the output mode is set */ + if (output_data->virtual_data->hwc_mode) { + ret = virtual_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("create target hwc window failed (%d)", ret); + return ret; + } + } + output_data->current_mode = mode; output_data->mode_changed = 1; @@ -604,6 +550,45 @@ virtual_output_set_status_handler(tdm_output *output, return TDM_ERROR_NONE; } +tdm_hwc * +virtual_output_get_hwc(tdm_output *output, tdm_error *error) +{ + tdm_virtual_hwc_data *hwc_data = NULL; + tdm_virtual_output_data *output_data = output; + + if (!output_data) { + TDM_ERR("invalid params"); + if (error) + *error = TDM_ERROR_INVALID_PARAMETER; + return NULL; + } + + if (output_data->hwc_data) { + TDM_INFO("hwc_data already exists"); + if (error) + *error = TDM_ERROR_NONE; + return output_data->hwc_data; + } + + hwc_data = calloc(1, sizeof(tdm_virtual_hwc_data)); + if (!hwc_data) { + TDM_ERR("alloc failed"); + if (error) + *error = TDM_ERROR_OUT_OF_MEMORY; + return NULL; + } + hwc_data->output_data = output_data; + + LIST_INITHEAD(&hwc_data->hwc_window_list); + + output_data->hwc_data = hwc_data; + + if (error) + *error = TDM_ERROR_NONE; + + return hwc_data; +} + tdm_error virtual_voutput_set_available_mode(tdm_voutput *voutput, const tdm_output_mode *modes, int count) { @@ -875,6 +860,9 @@ virtual_display_voutput_create(tdm_backend_data *bdata, const char *name, tdm_er TDM_DBG("virtual output create(%s)(%p)(%p)", output_data->name, voutput_data, output_data); + if (output_data->virtual_data->hwc_mode) + output_data->hwc_enable = 1; + return voutput_data; create_fail: @@ -1005,3 +993,18 @@ virtual_voutput_commit_done(tdm_voutput *voutput) return TDM_ERROR_NONE; } +tdm_virtual_layer_data * +virtual_output_data_get_layer_data(tdm_virtual_output_data *output_data, int layer_zpos) +{ + tdm_virtual_layer_data *l = NULL; + + RETURN_VAL_IF_FAIL(output_data, NULL); + + LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link) { + if (l->zpos == layer_zpos) + return l; + } + + return NULL; +} + diff --git a/backends/virtual/tdm_virtual_hwc.c b/backends/virtual/tdm_virtual_hwc.c new file mode 100644 index 0000000..42031cc --- /dev/null +++ b/backends/virtual/tdm_virtual_hwc.c @@ -0,0 +1,494 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "tdm_virtual.h" + +#define MIN_WIDTH 32 + +#define NUM_LAYERS 1 +#define NUM_BUFFERS 3 + +#define NUM_UI_LAYERS 1 + +#define ZPOS_MAX 1 +#define ZPOS_0 0 +#define ZPOS_NONE -999 + +tbm_format hwc_window_video_formats[] = { + TBM_FORMAT_ARGB8888, + TBM_FORMAT_XRGB8888, +}; + +const char * +_comp_to_str(tdm_hwc_window_composition composition_type) +{ + if (composition_type == TDM_HWC_WIN_COMPOSITION_CLIENT) + return "CLIENT"; + else if (composition_type == TDM_HWC_WIN_COMPOSITION_DEVICE) + return "DEVICE"; + else if (composition_type == TDM_HWC_WIN_COMPOSITION_CURSOR) + return "CURSOR"; + else if (composition_type == TDM_HWC_WIN_COMPOSITION_VIDEO) + return "VIDEO"; + else if (composition_type == TDM_HWC_WIN_COMPOSITION_NONE) + return "SKIP"; + + return "unknown"; +} + +static void +_print_validate_result(tdm_virtual_hwc_data *hwc_data, tdm_hwc_window **composited_wnds, uint32_t num_wnds) +{ + tdm_virtual_hwc_window_data *hwc_window_data = NULL; + int i; + + for (i = 0; i < num_wnds; i++) { + hwc_window_data = composited_wnds[i]; + switch (hwc_window_data->validated_type) { + case TDM_HWC_WIN_COMPOSITION_CLIENT: + TDM_DBG(" window(%p) %s -> %s : lzpos(%d) -- {%s} on TARGET WINDOW", hwc_window_data, + _comp_to_str(hwc_window_data->client_type), + _comp_to_str(hwc_window_data->validated_type), + hwc_data->target_hwc_window->lzpos, + hwc_window_data->name ? hwc_window_data->name : "NONE"); + break; + case TDM_HWC_WIN_COMPOSITION_DEVICE: + case TDM_HWC_WIN_COMPOSITION_VIDEO: + case TDM_HWC_WIN_COMPOSITION_CURSOR: + case TDM_HWC_WIN_COMPOSITION_NONE: + TDM_DBG(" window(%p) %s -> %s : lzpos(%d) -- {%s}", hwc_window_data, + _comp_to_str(hwc_window_data->client_type), + _comp_to_str(hwc_window_data->validated_type), + hwc_window_data->lzpos, + hwc_window_data->name ? hwc_window_data->name : "NONE"); + break; + default: + break; + } + } +} + +static tbm_surface_queue_h +_virtual_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error) +{ + tdm_virtual_hwc_window_data *hwc_window_data = NULL; + tbm_surface_queue_h tqueue = NULL; + int width, height; + tbm_format format; + + if (error) + *error = TDM_ERROR_INVALID_PARAMETER; + + RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL); + + hwc_window_data = hwc_window; + + width = hwc_window_data->info.src_config.size.h; + height = hwc_window_data->info.src_config.size.v; + format = hwc_window_data->info.src_config.format; + + tqueue = tbm_surface_queue_create(NUM_BUFFERS, width, height, format, TBM_BO_SCANOUT); + if (error) + *error = TDM_ERROR_OPERATION_FAILED; + RETURN_VAL_IF_FAIL(tqueue != NULL, NULL); + + if (error) + *error = TDM_ERROR_NONE; + + return tqueue; +} + +static tdm_error +_virtual_hwc_layer_attach_window(tdm_virtual_layer_data *layer_data, tdm_virtual_hwc_window_data *hwc_window_data) +{ + tdm_error ret = TDM_ERROR_NONE; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED); + + if (hwc_window_data == NULL || hwc_window_data->surface == NULL) { + if (layer_data->display_buffer) + ret = virtual_layer_unset_buffer(layer_data); + RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + } else { + ret = virtual_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info)); + RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, TDM_ERROR_INVALID_PARAMETER); + ret = virtual_layer_set_buffer(layer_data, hwc_window_data->surface); + RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + } + + return ret; +} + +static tdm_error +_virtual_hwc_prepare_commit(tdm_virtual_hwc_data *hwc_data) +{ + tdm_virtual_layer_data *layer_data = NULL; + int use_layers_zpos[NUM_LAYERS] = {0,}; + int lzpos = 0; + + /* set target hwc window to the layer */ + if (hwc_data->need_target_window) { + layer_data = virtual_output_data_get_layer_data(hwc_data->output_data, hwc_data->target_hwc_window->lzpos); + _virtual_hwc_layer_attach_window(layer_data, hwc_data->target_hwc_window); + use_layers_zpos[hwc_data->target_hwc_window->lzpos] = 1; + } + + /* unset the unused layers */ + for (lzpos = 0; lzpos < NUM_LAYERS; lzpos++) { + if (use_layers_zpos[lzpos]) + continue; + + layer_data = virtual_output_data_get_layer_data(hwc_data->output_data, lzpos); + if (!layer_data) + continue; + + _virtual_hwc_layer_attach_window(layer_data, NULL); + } + + /* for debug */ + for (lzpos = NUM_LAYERS -1 ; lzpos >= 0; lzpos--) { + if (use_layers_zpos[lzpos]) + TDM_INFO(" lzpos(%d) : %s", lzpos, use_layers_zpos[lzpos] ? "SET" : "UNSET"); + } + + return TDM_ERROR_NONE; +} + +/* assign the validated_type to the composited_wnds + * assign the layer_zpos to the composited_wnds + */ +static void +_virtual_hwc_apply_policy(tdm_virtual_hwc_data *hwc_data , tdm_hwc_window **composited_wnds, uint32_t num_wnds) +{ + tdm_virtual_hwc_window_data *hwc_window_data = NULL; + tdm_virtual_hwc_window_data **composited_list = NULL; + int i = 0; + + composited_list = (tdm_virtual_hwc_window_data **)composited_wnds; + + /* initialize the validated_types */ + LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { + if (hwc_window_data->validated_type != TDM_HWC_WIN_COMPOSITION_NONE) + hwc_window_data->validated_type = TDM_HWC_WIN_COMPOSITION_NONE; + } + + /* use the target_window to commit when there is no window. */ + if (num_wnds == 0) { + hwc_data->need_target_window = 1; + hwc_data->target_hwc_window->lzpos = ZPOS_0; + return; + } + + /* use onyl target_window */ + for (i = 0; i < num_wnds; i++) { + composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT; + composited_list[i]->lzpos = ZPOS_NONE; + } + + hwc_data->need_target_window = 1; + hwc_data->target_hwc_window->lzpos = ZPOS_0; +} + +static int +_virtual_hwc_get_changed_number(tdm_virtual_hwc_data *hwc_data) +{ + int num = 0; + tdm_virtual_hwc_window_data *hwc_window_data = NULL; + + LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) { + if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE) + continue; + + if (hwc_window_data->client_type != hwc_window_data->validated_type) + num++; + } + + return num; +} + +tdm_hwc_window * +_virtual_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info, tdm_error *error) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + tdm_virtual_hwc_window_data *hwc_window_data = NULL; + + if (error) + *error = TDM_ERROR_NONE; + + if (!hwc_data) { + TDM_ERR("invalid params"); + if (error) + *error = TDM_ERROR_INVALID_PARAMETER; + return NULL; + } + + hwc_window_data = calloc(1, sizeof(tdm_virtual_hwc_window_data)); + if (!hwc_window_data) { + TDM_ERR("alloc failed"); + if (error) + *error = TDM_ERROR_OUT_OF_MEMORY; + return NULL; + } + + hwc_window_data->hwc_data = hwc_data; + + if (info) + memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)); + + LIST_INITHEAD(&hwc_window_data->link); + + return hwc_window_data; +} + +tdm_hwc_window * +virtual_hwc_create_window(tdm_hwc *hwc, tdm_error *error) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + tdm_virtual_hwc_window_data *hwc_window_data = NULL; + + RETURN_VAL_IF_FAIL(hwc_data, NULL); + + hwc_window_data = _virtual_hwc_create_window(hwc_data, NULL, error); + RETURN_VAL_IF_FAIL(hwc_window_data, NULL); + + LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list); + + TDM_DBG("hwc_window(%p) create", hwc_window_data); + if (error) + *error = TDM_ERROR_NONE; + + return hwc_window_data; +} + +tdm_error +virtual_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count) +{ + RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + // TODO: fix these formats. + *formats = hwc_window_video_formats; + *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format); + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities) +{ + RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER); + + *capabilities = 0; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + + RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + *props = NULL; + *count = 0; + + return TDM_ERROR_NONE; +} + +tbm_surface_queue_h +virtual_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + tbm_surface_queue_h tqueue = NULL; + + if (error) + *error = TDM_ERROR_INVALID_PARAMETER; + + RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL); + + if (hwc_data->target_hwc_window == NULL) { + if (error) + *error = TDM_ERROR_OPERATION_FAILED; + return NULL; + } + + tqueue = _virtual_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error); + RETURN_VAL_IF_FAIL(tqueue, NULL); + + if (error) + *error = TDM_ERROR_NONE; + + return tqueue; +} + +tdm_error +virtual_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + tdm_error err; + + RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window != NULL, TDM_ERROR_OPERATION_FAILED); + + TDM_INFO(" ==============Set Target Buffer Virtual================================="); + + err = virtual_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer); + RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err); + + err = virtual_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage); + RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err); + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + + RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER); + + TDM_DBG(" ==============Validate Virtual================================="); + + _virtual_hwc_apply_policy(hwc_data, composited_wnds, num_wnds); + + *num_types = _virtual_hwc_get_changed_number(hwc_data); + + _print_validate_result(hwc_data, composited_wnds, num_wnds); + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, + tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + tdm_virtual_hwc_window_data *hwc_window_data = NULL; + int num = 0; + + RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER); + + if ((hwc_wnds == NULL) || (composition_types == NULL)) { + *num_elements = _virtual_hwc_get_changed_number(hwc_data); + return TDM_ERROR_NONE; + } + + LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { + if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE) + continue; + + if (num >= *num_elements) + break; + + if (hwc_window_data->client_type != hwc_window_data->validated_type) { + composition_types[num] = hwc_window_data->validated_type; + hwc_wnds[num] = hwc_window_data; + num++; + } + } + + /* set real num of changed composition types */ + *num_elements = num; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_accept_validation(tdm_hwc *hwc) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + tdm_error ret = TDM_ERROR_NONE; + + RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, TDM_ERROR_INVALID_PARAMETER); + + TDM_DBG(" ==============Accept Changes Done Virtual================================="); + + ret = _virtual_hwc_prepare_commit(hwc_data); + RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_commit(tdm_hwc *hwc, int sync, void *user_data) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + tdm_virtual_output_data *output_data = NULL; + tdm_error ret; + + RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER); + + output_data = hwc_data->output_data; + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + + TDM_INFO(" ==============COMMIT Virtual================================="); + + ret = virtual_output_commit(output_data, sync, user_data); + RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func) +{ + tdm_virtual_hwc_data *hwc_data = hwc; + + RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); + + hwc_data->commit_func = func; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_initailize_target_window(tdm_hwc *hwc, int width, int height) +{ + tdm_hwc_window_info info = {0}; + tdm_error ret = TDM_ERROR_NONE; + tdm_virtual_hwc_window_data *target_hwc_window; + tdm_virtual_hwc_data *hwc_data = hwc; + + RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER); + + info.dst_pos.x = 0; + info.dst_pos.y = 0; + info.dst_pos.h = height; + info.dst_pos.w = width; + + info.src_config.pos.x = 0; + info.src_config.pos.y = 0; + info.src_config.pos.h = height; + info.src_config.pos.w = width; + + info.src_config.size.h = width; + info.src_config.size.v = height; + info.src_config.format = TBM_FORMAT_ARGB8888; + + target_hwc_window = _virtual_hwc_create_window(hwc_data, &info, &ret); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("create target hwc window failed (%d)", ret); + return TDM_ERROR_OPERATION_FAILED; + } + + if (hwc_data->target_hwc_window) + virtual_hwc_window_destroy(hwc_data->target_hwc_window); + + hwc_data->target_hwc_window = target_hwc_window; + hwc_data->need_set_crtc = 1; + + return TDM_ERROR_NONE; +} diff --git a/backends/virtual/tdm_virtual_hwc.h b/backends/virtual/tdm_virtual_hwc.h new file mode 100644 index 0000000..12bb05f --- /dev/null +++ b/backends/virtual/tdm_virtual_hwc.h @@ -0,0 +1,8 @@ +#ifndef _TDM_VIRTUAL_HWC_H_ +#define _TDM_VIRTUAL_HWC_H_ + +#include "tdm_virtual.h" + +tdm_error virtual_hwc_initailize_target_window(tdm_virtual_hwc_data *hwc_data, int width, int height); + +#endif /* _TDM_VIRTUAL_HWC_H_ */ diff --git a/backends/virtual/tdm_virtual_hwc_window.c b/backends/virtual/tdm_virtual_hwc_window.c new file mode 100644 index 0000000..81a9094 --- /dev/null +++ b/backends/virtual/tdm_virtual_hwc_window.c @@ -0,0 +1,136 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tdm_virtual.h" + +void +virtual_hwc_window_destroy(tdm_hwc_window *hwc_window) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + + RETURN_IF_FAIL(hwc_window_data != NULL); + + LIST_DEL(&hwc_window_data->link); + + free(hwc_window_data); +} + +tdm_error +virtual_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, + tdm_hwc_window_composition comp_type) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + tdm_virtual_hwc_data *hwc_data = hwc_window_data->hwc_data; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); + + /* change the client_type when it is different from one which has before */ + if (hwc_window_data->client_type == comp_type) + return TDM_ERROR_NONE; + + hwc_window_data->client_type = comp_type; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); + + //TODO:: + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + tdm_virtual_hwc_data *hwc_data; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); + hwc_data = hwc_window_data->hwc_data; + RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (!memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info))) + return TDM_ERROR_NONE; + + hwc_window_data->info = *info; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + tdm_error err = TDM_ERROR_OPERATION_FAILED; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err); + + if (hwc_window_data->surface == surface) + return TDM_ERROR_NONE; + + hwc_window_data->surface = surface; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); + + //TODO: + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); + + //TODO: + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(constraints != NULL, TDM_ERROR_INVALID_PARAMETER); + + // no constraints + *constraints = 0; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name) +{ + tdm_virtual_hwc_window_data *hwc_window_data = hwc_window; + + RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (!name) + return TDM_ERROR_NONE; + + snprintf(hwc_window_data->name, TDM_NAME_LEN, "%s", name); + + return TDM_ERROR_NONE; +} diff --git a/backends/virtual/tdm_virtual_hwc_window.h b/backends/virtual/tdm_virtual_hwc_window.h new file mode 100644 index 0000000..e698090 --- /dev/null +++ b/backends/virtual/tdm_virtual_hwc_window.h @@ -0,0 +1,6 @@ +#ifndef _TDM_VIRTUAL_HWC_WINDOW_H_ +#define _TDM_VIRTUAL_HWC_WINDOW_H_ + +#include "tdm_virtual.h" + +#endif /* _TDM_VIRTUAL_HWC_WINDOW_H_ */ diff --git a/src/tdm_backend.c b/src/tdm_backend.c index 12f6a2d..b0d1576 100644 --- a/src/tdm_backend.c +++ b/src/tdm_backend.c @@ -159,7 +159,7 @@ tdm_backend_register_func_layer(tdm_display *dpy, tdm_func_layer *func_layer) EXTERN tdm_error tdm_backend_register_func_hwc(tdm_display *dpy, tdm_func_hwc *func_hwc) { - tdm_backend_module *module; +// tdm_backend_module *module; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); @@ -168,10 +168,10 @@ tdm_backend_register_func_hwc(tdm_display *dpy, tdm_func_hwc *func_hwc) TDM_RETURN_VAL_IF_FAIL(func_hwc != NULL, TDM_ERROR_INVALID_PARAMETER); assert(private_display->current_module); - - module = private_display->current_module->module_data; - if (_check_abi_version(module, 2, 0) < 0) - return TDM_ERROR_BAD_MODULE; +// TODO : temp erase module check for virtual +// module = private_display->current_module->module_data; +// if (_check_abi_version(module, 2, 0) < 0) +// return TDM_ERROR_BAD_MODULE; private_display->current_module->func_hwc = *func_hwc; @@ -181,7 +181,7 @@ tdm_backend_register_func_hwc(tdm_display *dpy, tdm_func_hwc *func_hwc) EXTERN tdm_error tdm_backend_register_func_hwc_window(tdm_display *dpy, tdm_func_hwc_window *func_hwc_window) { - tdm_backend_module *module; +// tdm_backend_module *module; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); @@ -190,10 +190,10 @@ tdm_backend_register_func_hwc_window(tdm_display *dpy, tdm_func_hwc_window *func TDM_RETURN_VAL_IF_FAIL(func_hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); assert(private_display->current_module); - - module = private_display->current_module->module_data; - if (_check_abi_version(module, 2, 0) < 0) - return TDM_ERROR_BAD_MODULE; +// TODO : temp erase module check for virtual +// module = private_display->current_module->module_data; +// if (_check_abi_version(module, 2, 0) < 0) +// return TDM_ERROR_BAD_MODULE; private_display->current_module->func_hwc_window = *func_hwc_window; diff --git a/src/tdm_hwc.c b/src/tdm_hwc.c index 65f232c..f3537bc 100644 --- a/src/tdm_hwc.c +++ b/src/tdm_hwc.c @@ -528,6 +528,8 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d tdm_private_module *private_module; tdm_func_hwc *func_hwc = NULL; tdm_private_hwc_commit_handler *hwc_commit_handler = NULL; + tdm_private_voutput *private_voutput = NULL; + tdm_private_voutput_commit_handler *voutput_commit_handler = NULL; HWC_FUNC_ENTRY(); @@ -558,6 +560,14 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d if (tdm_debug_module & TDM_DEBUG_COMMIT) TDM_INFO("hwc(%d) commit", private_hwc->index); + if (private_module == private_display->virtual_module) { + if (!private_output->private_voutput) { + TDM_ERR("virtual module but don't have voutput"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_BAD_MODULE; + } + } + if (!private_hwc->regist_commit_cb) { private_hwc->regist_commit_cb = 1; ret = func_hwc->hwc_set_commit_handler(private_hwc->hwc_backend, _tdm_hwc_cb_commit); @@ -595,6 +605,15 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d hwc_commit_handler->user_data = user_data; hwc_commit_handler->owner_tid = syscall(SYS_gettid); + if (private_module == private_display->virtual_module) { + private_voutput = private_output->private_voutput; + + if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) { + voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link); + voutput_commit_handler->user_data = private_hwc->display_target_buffer; + } + } + ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); -- 2.7.4 From 856fe332170337c9c52583b4757e2a4a47ddc3b5 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 13 Aug 2019 14:02:54 +0900 Subject: [PATCH 02/16] Package version up to 2.9.3 Change-Id: I046ee4436411ee9cdc64f54a545952ea7ce1dfcf Signed-off-by: Junkyeong Kim --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index afc3d6d..dacbdee 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define HALTESTS_GCOV 0 Name: libtdm -Version: 2.9.2 +Version: 2.9.3 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From b564ac8bf2379f3c60c64e179c5697b4391d33d8 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Thu, 22 Aug 2019 02:30:29 +0000 Subject: [PATCH 03/16] Revert "tizen: Add additional unit for "unified" user session" This reverts commit c912cbe6b33ba30309388719316775e5fc44555a. We've optimized systemd-user without unified system/session. So, we revert the patch for unified system/session. Change-Id: I75ea2b0f4e6762d23cc31c0814953ccb69866e69 --- packaging/libtdm.spec | 10 ---------- service/tdm-socket-user@.path | 9 --------- service/tdm-socket-user@.service | 15 --------------- 3 files changed, 34 deletions(-) delete mode 100644 service/tdm-socket-user@.path delete mode 100644 service/tdm-socket-user@.service diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index dacbdee..8288f58 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -98,10 +98,6 @@ rm -rf %{buildroot} install -m 644 service/tdm-socket-user.service %{buildroot}%{_unitdir_user} install -m 644 service/tdm-socket-user.path %{buildroot}%{_unitdir_user} -%__mkdir_p %{buildroot}%{_unitdir} -install -m 644 service/tdm-socket-user@.service %{buildroot}%{_unitdir} -install -m 644 service/tdm-socket-user@.path %{buildroot}%{_unitdir} - %remove_docs @@ -109,13 +105,9 @@ install -m 644 service/tdm-socket-user@.path %{buildroot}%{_unitdir} %__mkdir_p %{_unitdir_user}/basic.target.wants ln -sf ../tdm-socket-user.path %{_unitdir_user}/basic.target.wants/ -%__mkdir_p %{_unitdir}/user-basic@.target.wants -ln -sf ../tdm-socket-user@.path %{_unitdir}/user-basic@.target.wants/ - %post -p /sbin/ldconfig %postun -p /sbin/ldconfig rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path -rm -f %{_unitdir}/user-basic@.target.wants/tdm-socket-user@.path %files %manifest %{name}.manifest @@ -127,8 +119,6 @@ rm -f %{_unitdir}/user-basic@.target.wants/tdm-socket-user@.path %attr(750,root,root) %{_bindir}/tdm-monitor %{_unitdir_user}/tdm-socket-user.path %{_unitdir_user}/tdm-socket-user.service -%{_unitdir}/tdm-socket-user@.path -%{_unitdir}/tdm-socket-user@.service %files devel %manifest %{name}.manifest diff --git a/service/tdm-socket-user@.path b/service/tdm-socket-user@.path deleted file mode 100644 index e71810c..0000000 --- a/service/tdm-socket-user@.path +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -PartOf=userlogin@%i.target -DefaultDependencies=no -After=systemd-logind.service -After=systemd-logind.service systemd-logind.service -Description=Wait for tdm-socket - -[Path] -PathExists=/run/tdm-socket diff --git a/service/tdm-socket-user@.service b/service/tdm-socket-user@.service deleted file mode 100644 index 4fca44d..0000000 --- a/service/tdm-socket-user@.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -PartOf=userlogin@%i.target -After=systemd-logind.service -After=display-manager.service systemd-logind.service -Description=Creating a link file for user to access tdm-socket -DefaultDependencies=no -Before=starter@%i.service - -[Service] -User=%i -Environment=DBUS_SESSION_BUS_ADDRESS=kernel:path=/sys/fs/kdbus/%i-user/bus;unix:path=/run/user/%i/bus -Environment=XDG_RUNTIME_DIR=/run/user/%i -SmackProcessLabel=User -Type=oneshot -ExecStart=/usr/bin/sh -c "while [ ! -e /run/tdm-socket ] ; do /usr/bin/sleep .1 ; done ;/usr/bin/ln -s /run/tdm-socket /run/user/%i/" -- 2.7.4 From 7b38a8ccd48715b5147e3c7388ee3815ea1e17ae Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Thu, 29 Aug 2019 19:48:16 +0900 Subject: [PATCH 04/16] add stdout log in tdm_display_init Change-Id: I971cabd91d5ff977a18bb5cd8869245cfbe0704b --- include/tdm_log.h | 14 ++++++++++++++ src/tdm.c | 21 ++++++++++++--------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/include/tdm_log.h b/include/tdm_log.h index de56386..0a9bbf3 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -116,6 +116,20 @@ extern unsigned int tdm_log_debug_level; } \ } while (0) +#define TDM_INIT_INFO(fmt, args...) \ + do { \ + if (tdm_log_debug_level >= TDM_LOG_LEVEL_INFO) { \ + struct timespec ts; \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + tdm_log_printf(TDM_LOG_LEVEL_INFO, "[%5d.%06d][%d][%s %d]"fmt, \ + (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \ + (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \ + tdm_log_print(TDM_LOG_LEVEL_INFO, "[%5d.%06d][%d][%s %d]"fmt, \ + (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \ + (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \ + } \ + } while (0) + #define TDM_NEVER_GET_HERE() TDM_WRN("** NEVER GET HERE **") #define TDM_DEPRECATED(str) \ do { \ diff --git a/src/tdm.c b/src/tdm.c index f20bfa4..c7289e8 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -805,7 +805,7 @@ _tdm_display_setup(tdm_private_display *private_display) tdm_output **outputs; int i, count = 0; - TDM_INFO("loading a %s backend", TDM_DUMMY_MODULE); + TDM_INIT_INFO("loading a %s backend", TDM_DUMMY_MODULE); ret = _tdm_display_load_module_with_file(private_display, TDM_DUMMY_MODULE); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed_update); TDM_GOTO_IF_FAIL(private_display->dummy_module != NULL, failed_update); @@ -825,7 +825,7 @@ _tdm_display_setup(tdm_private_display *private_display) virtual = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0); if (virtual) { - TDM_INFO("loading a %s backend", TDM_VIRTUAL_MODULE); + TDM_INIT_INFO("loading a %s backend", TDM_VIRTUAL_MODULE); ret = _tdm_display_load_module_with_file(private_display, TDM_VIRTUAL_MODULE); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed_update); TDM_GOTO_IF_FAIL(private_display->virtual_module != NULL, failed_update); @@ -1035,7 +1035,9 @@ _tdm_display_load_module_with_file(tdm_private_display *private_display, /* We don't care if backend_data is NULL or not. It's up to backend. */ TDM_TRACE_BEGIN("TDM_Init_Backend"); stamp = tdm_helper_get_time(); + TDM_INIT_INFO("init backend"); bdata = module_data->init((tdm_display *)private_display, &ret); + TDM_INIT_INFO("init backend done"); TDM_DBG("backend init() time: %.3f ms", (tdm_helper_get_time() - stamp) * 1000.0); TDM_TRACE_END(); @@ -1067,7 +1069,7 @@ _tdm_display_load_module_with_file(tdm_private_display *private_display, LIST_ADDTAIL(&private_module->link, &private_display->module_list); - TDM_INFO("Success to load '%s' module", module_data->name); + TDM_INIT_INFO("Success to load '%s' module", module_data->name); return TDM_ERROR_NONE; failed_load: @@ -1097,12 +1099,12 @@ _tdm_display_load_modules(tdm_private_display *private_display) arg = strtok_r(temp, TDM_CONFIG_DELIM, &end); while (arg) { - TDM_INFO("loading a %s backend", arg); + TDM_INIT_INFO("loading a %s backend", arg); ret = _tdm_display_load_module_with_file(private_display, arg); if (ret == TDM_ERROR_NONE) - TDM_INFO("%s backend loading success", arg); + TDM_INIT_INFO("%s backend loading success", arg); else - TDM_INFO("%s backend loading failed", arg); + TDM_INIT_INFO("%s backend loading failed", arg); arg = strtok_r(NULL, TDM_CONFIG_DELIM, &end); } @@ -1194,7 +1196,7 @@ tdm_display_init(tdm_error *error) goto failed_event; stamp2 = tdm_helper_get_time(); - TDM_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); + TDM_INIT_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; ret = tdm_vblank_init(private_display); @@ -1222,7 +1224,7 @@ tdm_display_init(tdm_error *error) goto failed_load; stamp2 = tdm_helper_get_time(); - TDM_INFO("loading backend time: %.3f ms", (stamp2 - stamp1) * 1000.0); + TDM_INIT_INFO("loading backend time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; #ifdef INIT_BUFMGR @@ -1245,6 +1247,7 @@ tdm_display_init(tdm_error *error) TDM_TRACE_BEGIN("TDM_Update_Display"); ret = _tdm_display_setup(private_display); + TDM_INIT_INFO("updating display"); TDM_TRACE_END(); if (ret != TDM_ERROR_NONE) goto failed_update; @@ -1284,7 +1287,7 @@ tdm_display_init(tdm_error *error) _pthread_mutex_unlock(&private_display->lock); pthread_mutex_unlock(&gLock); - TDM_INFO("init time: %.3f ms", (tdm_helper_get_time() - start) * 1000.0); + TDM_INIT_INFO("init time: %.3f ms", (tdm_helper_get_time() - start) * 1000.0); return (tdm_display *)private_display; -- 2.7.4 From 4f5b50a0e94c14988f634fd289af4d0d68dd9da5 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Fri, 30 Aug 2019 15:32:54 +0900 Subject: [PATCH 05/16] Package version up to 2.9.4 Change-Id: Id5280b3bbce59ac1200d4afdf5a7ccbf81202215 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 8288f58..42569cd 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define HALTESTS_GCOV 0 Name: libtdm -Version: 2.9.3 +Version: 2.9.4 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From d141eb55873b9e26972c30bb6aa90160553ee16a Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Fri, 6 Sep 2019 16:56:31 +0900 Subject: [PATCH 06/16] tdm_hwc: support tdm-monitor -fps function Change-Id: I4f11ab53483058283717c4b592cb44b989c1daec Signed-off-by: Junkyeong Kim --- src/tdm_hwc.c | 18 ++++++++++++++++++ src/tdm_private_types.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/tdm_hwc.c b/src/tdm_hwc.c index f3537bc..f6d1808 100644 --- a/src/tdm_hwc.c +++ b/src/tdm_hwc.c @@ -109,6 +109,24 @@ _tdm_hwc_thread_cb_commit(tdm_private_display *private_display, void *object, TDM_INFO("handler(%p)", hwc_commit_handler); } + /* LCOV_EXCL_START */ + if (private_display->print_fps) { + double curr = tdm_helper_get_time(); + if (private_hwc->fps_stamp == 0) { + private_hwc->fps_stamp = curr; + } else if ((curr - private_hwc->fps_stamp) > 1.0) { + TDM_INFO("hwc(%p,%d) fps: %d", + private_hwc, private_hwc->index, private_hwc->fps_count); + private_hwc->fps_count = 0; + private_hwc->fps_stamp = curr; + } else + private_hwc->fps_count++; + } else if (private_hwc->fps_stamp != 0) { + private_hwc->fps_stamp = 0; + private_hwc->fps_count = 0; + } + /* LCOV_EXCL_STOP */ + if (hwc_commit_handler->func) { _pthread_mutex_unlock(&private_display->lock); hwc_commit_handler->func(private_hwc, diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index dfea22a..a778e25 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -329,6 +329,9 @@ struct _tdm_private_hwc { tdm_hwc *hwc_backend; tbm_surface_h display_target_buffer; + + double fps_stamp; + unsigned int fps_count; }; struct _tdm_private_hwc_window { -- 2.7.4 From 67b749a49811a43bfec0cfbb1cdd4a631ae44c00 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 10 Sep 2019 14:13:55 +0900 Subject: [PATCH 07/16] Package version up to 2.9.5 Change-Id: Ic7c5cac389615a28df93542df59943ff4bc08298 Signed-off-by: Junkyeong Kim --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 42569cd..e9d6257 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define HALTESTS_GCOV 0 Name: libtdm -Version: 2.9.4 +Version: 2.9.5 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From d077eef0042ab7dbc6857ce8e2ec367b3fe90b2e Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 2 Oct 2019 13:15:04 +0900 Subject: [PATCH 08/16] tdm_output: change log 'dpms' to 'DPMS' Change-Id: I8a2d53631455b9cfef9dd0d799227662408bd567 Signed-off-by: Junkyeong Kim --- src/tdm_output.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 07cfa4a..d6e1cc3 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -433,7 +433,7 @@ tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_ private_output->current_dpms_value = dpms; private_output->waiting_dpms_change = 0; - TDM_INFO("output(%d) dpms async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); + TDM_INFO("output(%d) DPMS async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); ret = _tdm_output_call_thread_cb_dpms(private_output, dpms); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); @@ -1778,14 +1778,14 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) private_module = private_output->private_module; func_output = &private_module->func_output; - TDM_INFO("output(%d) dpms '%s'", private_output->pipe, tdm_dpms_str(dpms_value)); + TDM_INFO("output(%d) DPMS '%s'", private_output->pipe, tdm_dpms_str(dpms_value)); if (func_output->output_set_dpms) ret = func_output->output_set_dpms(private_output->output_backend, dpms_value); else { /* LCOV_EXCL_START */ ret = TDM_ERROR_NONE; - TDM_WRN("not implemented!!"); + TDM_WRN("DPMS not implemented!!"); goto done; /* LCOV_EXCL_STOP */ } @@ -1796,14 +1796,14 @@ done: private_output->current_dpms_value = dpms_value; _tdm_output_call_thread_cb_dpms(private_output, dpms_value); } - TDM_INFO("output(%d) dpms '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); + TDM_INFO("output(%d) DPMS '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); } else { tdm_output_dpms temp = TDM_OUTPUT_DPMS_OFF; /* update current_dpms_value forcely */ tdm_output_get_dpms_internal(output, &temp); - TDM_ERR("output(%d) set_dpms failed: dpms '%s'", private_output->pipe, tdm_dpms_str(temp)); + TDM_ERR("output(%d) set DPMS failed: dpms '%s'", private_output->pipe, tdm_dpms_str(temp)); } _pthread_mutex_unlock(&private_display->lock); @@ -1849,13 +1849,13 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) private_module = private_output->private_module; func_output = &private_module->func_output; if (!func_output->output_set_dpms_handler) { - TDM_WRN("not implemented: output_set_dpms_handler"); + TDM_WRN("not implemented DPMS: output_set_dpms_handler"); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NOT_IMPLEMENTED; } if (!func_output->output_set_dpms_async) { - TDM_WRN("not implemented: output_set_dpms_async"); + TDM_WRN("not implemented DPMS: output_set_dpms_async"); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NOT_IMPLEMENTED; } @@ -1866,12 +1866,12 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) tdm_output_cb_dpms, private_output); if (ret != TDM_ERROR_NONE) { _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("Can't set the dpms handler!!"); + TDM_ERR("Can't set the DPMS handler!!"); return ret; } } - TDM_INFO("output(%d) dpms async '%s'", private_output->pipe, tdm_dpms_str(dpms_value)); + TDM_INFO("output(%d) DPMS async '%s'", private_output->pipe, tdm_dpms_str(dpms_value)); ret = func_output->output_set_dpms_async(private_output->output_backend, dpms_value, &sync); @@ -1880,10 +1880,10 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) tdm_output_dpms temp = TDM_OUTPUT_DPMS_OFF; tdm_output_get_dpms_internal(output, &temp); - TDM_INFO("output(%d) dpms async '%s'(%s) done", private_output->pipe, tdm_dpms_str(dpms_value), tdm_dpms_str(temp)); + TDM_INFO("output(%d) DPMS async '%s'(%s) done", private_output->pipe, tdm_dpms_str(dpms_value), tdm_dpms_str(temp)); } else { private_output->waiting_dpms_change = 1; - TDM_INFO("output(%d) dpms async '%s' waiting", private_output->pipe, tdm_dpms_str(dpms_value)); + TDM_INFO("output(%d) DPMS async '%s' waiting", private_output->pipe, tdm_dpms_str(dpms_value)); } } else { tdm_output_dpms temp = TDM_OUTPUT_DPMS_OFF; @@ -1891,7 +1891,7 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) /* update current_dpms_value forcely */ tdm_output_get_dpms_internal(output, &temp); - TDM_ERR("output(%d) set_dpms_async failed: dpms '%s'", private_output->pipe, tdm_dpms_str(temp)); + TDM_ERR("output(%d) set DPMS async failed: dpms '%s'", private_output->pipe, tdm_dpms_str(temp)); } _pthread_mutex_unlock(&private_display->lock); @@ -1928,7 +1928,7 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) if (!func_output->output_get_dpms) { /* LCOV_EXCL_START */ *dpms_value = private_output->current_dpms_value; - TDM_WRN("not implemented!!"); + TDM_WRN("DPMS get not implemented!!"); return TDM_ERROR_NONE; /* LCOV_EXCL_STOP */ } @@ -1936,14 +1936,14 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) ret = func_output->output_get_dpms(private_output->output_backend, dpms_value); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ - TDM_ERR("output_get_dpms failed"); + TDM_ERR("output get DPMS failed"); *dpms_value = TDM_OUTPUT_DPMS_OFF; /* LCOV_EXCL_STOP */ } /* checking with backend's value */ if (*dpms_value != private_output->current_dpms_value) { - TDM_ERR("output(%d) dpms changed suddenly: %s -> %s", + TDM_ERR("output(%d) DPMS changed suddenly: %s -> %s", private_output->pipe, tdm_dpms_str(private_output->current_dpms_value), tdm_dpms_str(*dpms_value)); private_output->current_dpms_value = *dpms_value; -- 2.7.4 From 8a3c14ca5ee3453cbf84a9bb8cef5531ffdf6309 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 2 Oct 2019 13:16:10 +0900 Subject: [PATCH 09/16] Package version up to 2.9.6 Change-Id: If141ff350ea08c7c8124fba7e2af36f84a395165 Signed-off-by: Junkyeong Kim --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index e9d6257..db7f805 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define HALTESTS_GCOV 0 Name: libtdm -Version: 2.9.5 +Version: 2.9.6 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 7a105d2256426d58cb253253cd0ee1acb5054d5e Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 16 Oct 2019 19:04:28 +0900 Subject: [PATCH 10/16] tdm_hwc: make hwc_vblank set/unset function if set hwc vblank, use vblank instead of hwc commit handler. Change-Id: I9329473bb21dec6cee84fe60cd7e33eca80c2875 Signed-off-by: Junkyeong Kim --- src/tdm_hwc.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++-- src/tdm_private.h | 4 ++ src/tdm_private_types.h | 1 + 3 files changed, 127 insertions(+), 3 deletions(-) diff --git a/src/tdm_hwc.c b/src/tdm_hwc.c index f6d1808..3131ebd 100644 --- a/src/tdm_hwc.c +++ b/src/tdm_hwc.c @@ -70,6 +70,8 @@ TDM_RETURN_IF_FAIL(private_output != NULL); \ private_display = private_output->private_display +static int hwc_use_vblank; +static unsigned int hwc_vblank_fps; static tdm_private_hwc_window * _tdm_hwc_find_private_hwc_window(tdm_private_hwc *private_hwc, tdm_hwc_window *hwc_window_backend) @@ -152,6 +154,9 @@ _tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence, tdm_thread_cb_hwc_commit hwc_commit; tdm_error ret; + if (hwc_commit_handler && hwc_commit_handler->use_vblank) + return; + if (hwc_commit_handler) private_hwc = hwc_commit_handler->private_hwc; else @@ -171,6 +176,96 @@ _tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence, TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } +static void +_tdm_hwc_got_wait_vblank(unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + tdm_private_hwc_commit_handler *hwc_commit_handler = user_data; + tdm_private_hwc *private_hwc; + tdm_thread_cb_hwc_commit hwc_commit; + + private_hwc = hwc_commit_handler->private_hwc; + private_hwc->private_output->layer_waiting_vblank = 0; + + memset(&hwc_commit, 0, sizeof hwc_commit); + hwc_commit.base.type = TDM_THREAD_CB_HWC_COMMIT; + hwc_commit.base.length = sizeof hwc_commit; + hwc_commit.base.object_stamp = private_hwc->stamp; + hwc_commit.base.data = hwc_commit_handler; + hwc_commit.base.sync = 0; + hwc_commit.sequence = sequence; + hwc_commit.tv_sec = tv_sec; + hwc_commit.tv_usec = tv_usec; + + _tdm_hwc_thread_cb_commit(private_hwc->private_output->private_display, private_hwc, &hwc_commit.base, user_data); +} + +static void +_tdm_hwc_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + tdm_private_hwc_commit_handler *hwc_commit_handler = user_data; + tdm_private_output *private_output = NULL; + tdm_private_display *private_display; + + if (!hwc_commit_handler->use_vblank) + return; + + TDM_RETURN_IF_FAIL(hwc_commit_handler != NULL); + + private_output = hwc_commit_handler->private_hwc->private_output; + TDM_RETURN_IF_FAIL(private_output != NULL); + + private_display = private_output->private_display; + + _pthread_mutex_lock(&private_display->lock); + + _tdm_hwc_got_wait_vblank(sequence, tv_sec, tv_usec, user_data); + + _pthread_mutex_unlock(&private_display->lock); +} + +static tdm_error +_tdm_hwc_vblank(tdm_private_hwc *private_hwc, tdm_private_hwc_commit_handler *hwc_commit_handler) +{ + tdm_private_display *private_display; + tdm_private_output *private_output; + tdm_error ret = TDM_ERROR_NONE; + + private_output = private_hwc->private_output; + TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); + private_display = private_output->private_display; + + if (!private_output->vblank) { + /* tdm_vblank APIs is for server. it should be called in unlock status*/ + _pthread_mutex_unlock(&private_display->lock); + private_output->vblank = tdm_vblank_create(private_display, private_output, NULL); + _pthread_mutex_lock(&private_display->lock); + TDM_RETURN_VAL_IF_FAIL(private_output->vblank != NULL, TDM_ERROR_OPERATION_FAILED); + } + + if (!private_output->layer_waiting_vblank) { + ret = tdm_vblank_set_fps(private_output->vblank, hwc_vblank_fps); + if (ret != TDM_ERROR_NONE) + goto done; + + /* tdm_vblank APIs is for server. it should be called in unlock status*/ + _pthread_mutex_unlock(&private_display->lock); + ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_hwc_cb_wait_vblank, hwc_commit_handler); + _pthread_mutex_lock(&private_display->lock); + if (ret != TDM_ERROR_NONE) { + if (!TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) + goto done; + } + + hwc_commit_handler->use_vblank = 1; + private_output->layer_waiting_vblank = 1; + } + +done: + return ret; +} + INTERN tdm_error tdm_hwc_init(tdm_private_display *private_display) { @@ -179,6 +274,20 @@ tdm_hwc_init(tdm_private_display *private_display) return TDM_ERROR_NONE; } +INTERN void +tdm_hwc_set_vblank(unsigned int fps) +{ + hwc_use_vblank = 1; + hwc_vblank_fps = fps; +} + +INTERN void +tdm_hwc_unset_vblank(void) +{ + hwc_use_vblank = 0; + hwc_vblank_fps = 0; +} + EXTERN tdm_hwc_window * tdm_hwc_create_window(tdm_hwc *hwc, tdm_error *error) { @@ -635,9 +744,19 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); - if (tdm_debug_module & TDM_DEBUG_COMMIT) - TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)", - private_hwc->index, hwc_commit_handler, func, user_data); + if (hwc_use_vblank) { + ret = _tdm_hwc_vblank(private_hwc, hwc_commit_handler); + if (ret == TDM_ERROR_NONE) { + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("hwc(%d) backend commit: wait vblank handle(%p) func(%p) user_data(%p)", + private_hwc->index, hwc_commit_handler, func, user_data); + } else + goto commit_failed; + } else { + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)", + private_hwc->index, hwc_commit_handler, func, user_data); + } _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_private.h b/src/tdm_private.h index 33904da..e8e3c08 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -184,6 +184,10 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp); tdm_error tdm_hwc_init(tdm_private_display *private_display); +void +tdm_hwc_set_vblank(unsigned int fps); +void +tdm_hwc_unset_vblank(void); tdm_hwc_window * tdm_hwc_window_create_internal(tdm_private_hwc *private_hwc, tdm_error *error); void diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index a778e25..bbc83cd 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -501,6 +501,7 @@ struct _tdm_private_hwc_commit_handler { void *user_data; pid_t owner_tid; + int use_vblank; }; struct _tdm_private_layer_commit_handler { -- 2.7.4 From d2fa49d3857fe065de1eefcb8afb5acdc69ca346 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 16 Oct 2019 19:13:35 +0900 Subject: [PATCH 11/16] tdm_vblank: execute hwc_vblank set and unset when tdm_vblank_enable_global_fps called Change-Id: Ia6f39e191079ad8089337a5b54563c5bfc66887d Signed-off-by: Junkyeong Kim --- src/tdm_vblank.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 977e402..fe72c64 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -597,6 +597,12 @@ tdm_vblank_enable_global_fps(unsigned int enable, unsigned int fps) v->check_HW_or_SW = 1; } + + if (enable) + tdm_hwc_set_vblank(fps); + else + tdm_hwc_unset_vblank(); + pthread_mutex_unlock(&valid_list_lock); return TDM_ERROR_NONE; -- 2.7.4 From cfc2ab0711fd65a2060f28d360bd2fa298daf8e6 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 1 Nov 2019 13:15:27 +0900 Subject: [PATCH 12/16] package version up to 2.10.0 tizen 6.0 starts here. Change-Id: Id0d8986d728499f6c39b9674260a32c865707cc1 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index db7f805..de1a348 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define HALTESTS_GCOV 0 Name: libtdm -Version: 2.9.6 +Version: 2.10.0 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From aee1916ab7a92750dad9e3a9b71ddd5859be05d6 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 5 Nov 2019 17:14:52 +0900 Subject: [PATCH 13/16] tdm_virtual_hwc: fix a typing error Change-Id: I5c9215625205df38e17bc62cb951bf26c2236c75 Signed-off-by: Junkyeong Kim --- backends/virtual/tdm_virtual_hwc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/virtual/tdm_virtual_hwc.c b/backends/virtual/tdm_virtual_hwc.c index 42031cc..cd72e5c 100644 --- a/backends/virtual/tdm_virtual_hwc.c +++ b/backends/virtual/tdm_virtual_hwc.c @@ -182,7 +182,7 @@ _virtual_hwc_apply_policy(tdm_virtual_hwc_data *hwc_data , tdm_hwc_window **comp return; } - /* use onyl target_window */ + /* use only target_window */ for (i = 0; i < num_wnds; i++) { composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT; composited_list[i]->lzpos = ZPOS_NONE; -- 2.7.4 From 1f039353972978e5babb3cc6b09d76c82122e7f2 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 6 Nov 2019 14:05:56 +0900 Subject: [PATCH 14/16] tdm_client: add log to check vblank list validation Change-Id: I27bee79bf7f5b7bd87dd0815c9fbf4b0f897439b Signed-off-by: Junkyeong Kim --- client/tdm_client.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/client/tdm_client.c b/client/tdm_client.c index bde7a1f..543805c 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -225,6 +225,17 @@ _tdm_client_vblank_cb_stamp(void *data, struct wl_tdm_vblank *wl_tdm_vblank, uin } /* LCOV_EXCL_START */ +static int +_tdm_client_vblank_wait_list_validation_check(tdm_private_client_vblank *private_vblank) +{ + if (private_vblank->wait_list.next == NULL || private_vblank->wait_list.prev == NULL) { + TDM_ERR("vblank(%p) wait_list broken. prev(%p), next(%p) pid(%d)", + private_vblank, private_vblank->wait_list.prev, private_vblank->wait_list.next, getpid()); + } + + return 0; +} + static void _tdm_client_vblank_cb_done(void *data, struct wl_tdm_vblank *wl_tdm_vblank, uint32_t req_id, uint32_t sequence, uint32_t tv_sec, @@ -243,6 +254,8 @@ _tdm_client_vblank_cb_done(void *data, struct wl_tdm_vblank *wl_tdm_vblank, TDM_DBG("vblank(%p) req_id(%u) sequence(%u) time(%.6f)", private_vblank, req_id, sequence, TDM_TIME(tv_sec, tv_usec)); + _tdm_client_vblank_wait_list_validation_check(private_vblank); + LIST_FOR_EACH_ENTRY(w, &private_vblank->wait_list, link) { if (w->req_id != req_id) continue; -- 2.7.4 From bba097bfa37e259cd0d59e00b1f7d24db54fe5e9 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Thu, 12 Dec 2019 13:25:25 +0900 Subject: [PATCH 15/16] tdm_helper: set up error handling when dump png Change-Id: Id3c9d591057b3ab73358ab810fb551452ee7cba0 --- src/tdm_helper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 804a112..08477f1 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -136,6 +136,13 @@ _tdm_helper_dump_png(const char *file, const void *data, int width, return; } + if (setjmp(png_jmpbuf(pPngStruct))) { + /* if png has problem of writing the file, we get here */ + png_destroy_write_struct(&pPngStruct, &pPngInfo); + fclose(fp); + return; + } + png_init_io(pPngStruct, fp); png_set_IHDR(pPngStruct, pPngInfo, -- 2.7.4 From 00e93c2550c7ecf3af1ee6f6b52efdff19987e11 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Thu, 12 Dec 2019 13:58:27 +0900 Subject: [PATCH 16/16] package version up to 2.10.1 Change-Id: I56cac312280a9da8cf227acc36ca43d6b8936b1e --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index de1a348..35db5b4 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define HALTESTS_GCOV 0 Name: libtdm -Version: 2.10.0 +Version: 2.10.1 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4