virtual: add virtual output mode set test to tdm_test 77/187877/2
authorJunkyeong Kim <jk0430.kim@samsung.com>
Wed, 29 Aug 2018 06:49:05 +0000 (15:49 +0900)
committerJunkyeong Kim <jk0430.kim@samsung.com>
Wed, 29 Aug 2018 06:51:20 +0000 (15:51 +0900)
fix mutex set error

Change-Id: I29a3867022fb2e68d4810528ea038ff69726dcf7
Signed-off-by: Junkyeong Kim <jk0430.kim@samsung.com>
client/tdm_client.c
haltests/src/tc_tdm_client.cpp
src/tdm_output.c
src/tdm_server.c
tools/tdm_test_client.c
tools/tdm_test_server.c

index 136a08a..0edcc0e 100644 (file)
@@ -1238,12 +1238,18 @@ tdm_client_output_set_mode(tdm_client_output *output, int index)
 
        pthread_mutex_lock(&private_client->lock);
 
-       if (private_output->available_modes.count - 1 < index)
+       if (private_output->available_modes.count - 1 < index) {
+               pthread_mutex_unlock(&private_client->lock);
                return TDM_ERROR_INVALID_PARAMETER;
+       }
 
        if ((private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) ||
-               (private_output->available_modes.count == 0))
+               (private_output->available_modes.count == 0)) {
+               pthread_mutex_unlock(&private_client->lock);
                return TDM_ERROR_BAD_REQUEST;
+       }
+
+       TDM_DBG("mode_set request : %d", index);
 
        wl_tdm_output_set_mode(private_output->output, index);
 
@@ -2037,11 +2043,12 @@ tdm_client_voutput_cb_commit(void *data, struct wl_tdm_voutput *wl_voutput)
                if (h->func)
                        h->func(private_voutput, buffer, h->user_data);
        }
-       pthread_mutex_lock(&private_client->lock);
 
        /* if no added commit_handler call commit done immediately */
        if (LIST_IS_EMPTY(&private_voutput->commit_handler_list))
                tdm_client_voutput_commit_done(private_voutput);
+
+       pthread_mutex_lock(&private_client->lock);
 }
 
 void
@@ -2196,10 +2203,14 @@ void
 tdm_client_voutput_destroy(tdm_client_voutput *voutput)
 {
        tdm_private_client_voutput *private_voutput = (tdm_private_client_voutput *)voutput;
+       tdm_private_client *private_client;
        tdm_client_voutput_commit_handler_info *h = NULL, *hh = NULL;
 
        if (!private_voutput)
                return;
+       private_client = private_voutput->private_client;
+
+       pthread_mutex_lock(&private_client->lock);
 
        if (!(LIST_IS_EMPTY(&private_voutput->buffer_list))) {
                tdm_private_client_buffer *cb = NULL, *cbb = NULL;
@@ -2241,12 +2252,16 @@ tdm_client_voutput_destroy(tdm_client_voutput *voutput)
        LIST_DEL(&private_voutput->link);
 
        free(private_voutput);
+
+       pthread_mutex_unlock(&private_client->lock);
 }
 
 tdm_error
 tdm_client_voutput_set_available_modes(tdm_client_voutput *voutput, const tdm_client_output_mode *modes, int count)
 {
        tdm_private_client_voutput *private_voutput;
+       tdm_private_client *private_client;
+       tdm_error ret = TDM_ERROR_NONE;
 
        TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
 
@@ -2254,9 +2269,19 @@ tdm_client_voutput_set_available_modes(tdm_client_voutput *voutput, const tdm_cl
                return TDM_ERROR_INVALID_PARAMETER;
 
        private_voutput = (tdm_private_client_voutput *)voutput;
+       private_client = private_voutput->private_client;
+
+       if (!private_voutput->private_output) {
+               private_voutput->private_output = tdm_client_voutput_get_client_output(private_voutput, &ret);
+               TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, TDM_ERROR_OPERATION_FAILED);
+       }
 
-       if (private_voutput->private_output->connection == TDM_OUTPUT_CONN_STATUS_CONNECTED)
+       pthread_mutex_lock(&private_client->lock);
+
+       if (private_voutput->private_output->connection != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
+               pthread_mutex_unlock(&private_client->lock);
                return TDM_ERROR_BAD_REQUEST;
+       }
 
        if (private_voutput->available_modes.modes)
                free(private_voutput->available_modes.modes);
@@ -2269,6 +2294,8 @@ tdm_client_voutput_set_available_modes(tdm_client_voutput *voutput, const tdm_cl
                memcpy(private_voutput->available_modes.modes, modes, sizeof(tdm_client_output_mode) * count);
        }
 
+       pthread_mutex_unlock(&private_client->lock);
+
        return TDM_ERROR_NONE;
 }
 
@@ -2276,19 +2303,33 @@ tdm_error
 tdm_client_voutput_set_physical_size(tdm_client_voutput *voutput, unsigned int mmWidth, unsigned int mmHeight)
 {
        tdm_private_client_voutput *private_voutput;
+       tdm_private_client *private_client;
+       tdm_error ret = TDM_ERROR_NONE;
 
        TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(mmWidth != 0, TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(mmHeight != 0, TDM_ERROR_INVALID_PARAMETER);
 
        private_voutput = (tdm_private_client_voutput *)voutput;
+       private_client = private_voutput->private_client;
 
-       if (private_voutput->private_output->connection == TDM_OUTPUT_CONN_STATUS_CONNECTED)
+       if (!private_voutput->private_output) {
+               private_voutput->private_output = tdm_client_voutput_get_client_output(private_voutput, &ret);
+               TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, TDM_ERROR_OPERATION_FAILED);
+       }
+
+       pthread_mutex_lock(&private_client->lock);
+
+       if (private_voutput->private_output->connection != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
+               pthread_mutex_unlock(&private_client->lock);
                return TDM_ERROR_BAD_REQUEST;
+       }
 
        private_voutput->mmwidth = mmWidth;
        private_voutput->mmheight = mmHeight;
 
+       pthread_mutex_unlock(&private_client->lock);
+
        return TDM_ERROR_NONE;
 }
 
@@ -2370,16 +2411,25 @@ tdm_error
 tdm_client_voutput_commit_done(tdm_client_voutput *voutput)
 {
        tdm_private_client_voutput *private_voutput;
+       tdm_private_client *private_client;
        tbm_surface_h buffer = NULL;
 
        TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        private_voutput = (tdm_private_client_voutput *)voutput;
+       TDM_RETURN_VAL_IF_FAIL(private_voutput->attach_buffer != NULL, TDM_ERROR_NONE);
+
+       private_client = private_voutput->private_client;
+
+       pthread_mutex_lock(&private_client->lock);
+
        buffer = (tbm_surface_h)wl_buffer_get_user_data(private_voutput->attach_buffer->wl_buffer);
        tbm_surface_internal_unref(buffer);
        private_voutput->attach_buffer = NULL;
        wl_tdm_voutput_commit_done(private_voutput->wl_voutput);
 
+       pthread_mutex_unlock(&private_client->lock);
+
        return TDM_ERROR_NONE;
 }
 
@@ -2388,6 +2438,7 @@ tdm_client_voutput_get_client_output(tdm_client_voutput *voutput, tdm_error *err
 {
        tdm_private_client_voutput *private_voutput;
        tdm_private_client_output *private_output = NULL;
+       tdm_private_client *private_client;
        tdm_error ret = TDM_ERROR_NONE;
 
        if (error)
@@ -2401,10 +2452,16 @@ tdm_client_voutput_get_client_output(tdm_client_voutput *voutput, tdm_error *err
        }
 
        private_voutput = (tdm_private_client_voutput *)voutput;
+       private_client = private_voutput->private_client;
 
-       if (private_voutput->get_output)
+       pthread_mutex_lock(&private_client->lock);
+
+       if (private_voutput->get_output) {
+               pthread_mutex_unlock(&private_client->lock);
                return private_voutput->private_output;
+       }
 
+       pthread_mutex_unlock(&private_client->lock);
        private_output = (tdm_private_client_output *)tdm_client_get_output(private_voutput->private_client, private_voutput->name, &ret);
        if (!private_output) {
                TDM_ERR("tdm_client_voutput_get_client_output get private_output fail");
@@ -2412,10 +2469,13 @@ tdm_client_voutput_get_client_output(tdm_client_voutput *voutput, tdm_error *err
                        *error = ret;
                return NULL;
        }
+       pthread_mutex_lock(&private_client->lock);
        private_output->voutput = private_voutput;
        private_voutput->private_output = private_output;
        private_voutput->get_output = 1;
 
+       pthread_mutex_unlock(&private_client->lock);
+
        return private_output;
 }
 
@@ -2443,15 +2503,21 @@ tdm_client_output_connect(tdm_client_output *output)
 {
        tdm_private_client_output *private_output;
        tdm_private_client_voutput *private_voutput = NULL;
+       tdm_private_client *private_client;
 
        TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        private_output = (tdm_private_client_output *)output;
        if (!private_output->voutput) return TDM_ERROR_INVALID_PARAMETER;
        private_voutput = private_output->voutput;
+       private_client = private_voutput->private_client;
 
-       TDM_RETURN_VAL_IF_FAIL(private_output->connection != TDM_OUTPUT_CONN_STATUS_CONNECTED,
-                                                  TDM_ERROR_BAD_REQUEST);
+       pthread_mutex_lock(&private_client->lock);
+
+       if (private_output->connection != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_NONE;
+       }
 
        if (!private_output->watch_output_changes)
                private_output->connection = TDM_OUTPUT_CONN_STATUS_CONNECTED;
@@ -2463,6 +2529,8 @@ tdm_client_output_connect(tdm_client_output *output)
        /* To Do : change voutput to output */
        wl_tdm_voutput_connect(private_voutput->wl_voutput);
 
+       pthread_mutex_unlock(&private_client->lock);
+
        return TDM_ERROR_NONE;
 }
 
@@ -2471,15 +2539,21 @@ tdm_client_output_disconnect(tdm_client_output *output)
 {
        tdm_private_client_output *private_output;
        tdm_private_client_voutput *private_voutput = NULL;
+       tdm_private_client *private_client;
 
        TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        private_output = (tdm_private_client_output *)output;
        if (!private_output->voutput) return TDM_ERROR_INVALID_PARAMETER;
        private_voutput = private_output->voutput;
+       private_client = private_voutput->private_client;
 
-       TDM_RETURN_VAL_IF_FAIL(private_output->connection != TDM_OUTPUT_CONN_STATUS_DISCONNECTED,
-                                                  TDM_ERROR_BAD_REQUEST);
+       pthread_mutex_lock(&private_client->lock);
+
+       if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
+               pthread_mutex_unlock(&private_client->lock);
+               return TDM_ERROR_NONE;
+       }
 
        if (!private_output->watch_output_changes)
                private_output->connection = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
@@ -2487,5 +2561,7 @@ tdm_client_output_disconnect(tdm_client_output *output)
        /* To Do : change voutput to output */
        wl_tdm_voutput_disconnect(private_voutput->wl_voutput);
 
+       pthread_mutex_unlock(&private_client->lock);
+
        return TDM_ERROR_NONE;
 }
index c2b2c20..3d609ef 100644 (file)
@@ -850,6 +850,7 @@ TEST_P(TDMClient, ClientOutputSetMode)
        ASSERT_EQ(PrepareOutput(), true);
 
        ASSERT_EQ(tdm_client_output_get_available_modes(output, &modes, &count), TDM_ERROR_NONE);
+       ASSERT_GT(count, -1);
 
        printf("count:%d\n", count);
 
index 7d73c1d..4430a80 100644 (file)
@@ -1300,7 +1300,6 @@ tdm_output_call_mode_set_request(tdm_output *output, unsigned int index)
        tdm_private_output_mode_change_handler *mode_change_handler = NULL;
 
        TDM_RETURN_IF_FAIL(private_output != NULL);
-       TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
 
        if (LIST_IS_EMPTY(&private_output->mode_change_request_handler_list))
                return;
index 453e10e..66a0d76 100644 (file)
@@ -642,9 +642,9 @@ _tdm_server_output_cb_set_mode(struct wl_client *client, struct wl_resource *res
        ret = tdm_output_get_available_modes(output_info->output, &modes, &count);
        TDM_RETURN_IF_FAIL(index < count);
 
-       tdm_output_call_mode_set_request(output_info->output, index);
+       TDM_DBG("mode set request to index:%d", index);
 
-       return;
+       tdm_output_call_mode_set_request(output_info->output, index);
 }
 
 static const struct wl_tdm_output_interface tdm_output_implementation = {
index cac60a8..d780eb1 100644 (file)
@@ -566,11 +566,18 @@ _voutput_commit(tdm_client_voutput *voutput, tbm_surface_h buffer, void *user_da
        TDM_EXIT_IF_FAIL(data != NULL);
        TDM_EXIT_IF_FAIL(buffer != NULL);
 
-       if (count < 10)
+       if ((count < 10) || (count >=51 && count < 60))
                _dump_buffer(buffer, count);
        count++;
 
-       if (count == 70) {
+       if (count == 50) {
+               tdm_client_output_mode *modes;
+               int count = 0;
+
+               printf("client: %d commited(%p), mode change request to index 1\n", count, buffer);
+               tdm_client_output_get_available_modes(data->output, &modes, &count);
+               tdm_client_output_set_mode(data->output, count - 1);
+       } else if (count == 70) {
                printf("client: %d commited(%p), disconnect\n", count, buffer);
                tdm_client_output_disconnect(data->output);
        } else {
@@ -613,14 +620,14 @@ _voutput_output_handler(tdm_client_output *output, tdm_output_change_type type,
 _voutput_make_available_mode(tdm_client_output_mode *modes, int count)
 {
        int i;
-       for (i = 0; i < count; i++) {
+       for (i = 0 ; i < count; i++) {
                modes[i].clock = 25200;
-               modes[i].hdisplay = 640;
+               modes[i].hdisplay = 640 * (count - i);
                modes[i].hsync_start = 656;
                modes[i].hsync_end = 752;
                modes[i].htotal = 800;
                modes[i].hskew = 0;
-               modes[i].vdisplay = 480;
+               modes[i].vdisplay = 480 * (count - i);
                modes[i].vsync_start = 490;
                modes[i].vsync_end = 492;
                modes[i].vtotal = 525;
index 98b10db..af48e5c 100644 (file)
@@ -312,6 +312,8 @@ struct _tdm_test_server_voutput {
        tdm_layer *layer;
        tbm_surface_h bufs[3];
        int buf_idx;
+       int need_mode_change;
+       int index;
 };
 
 struct _tdm_test_server {
@@ -337,6 +339,7 @@ static void output_setup(tdm_test_server_output *o);
 static void layer_show_buffer(tdm_test_server_layer *l, tbm_surface_h b);
 static void capture_attach(tdm_test_server_capture *c, tbm_surface_h b);
 static void _vlayer_show_buffer(tdm_test_server_voutput *voutput);
+static void _voutput_layer_init(tdm_test_server_voutput *voutput);
 
 static char*
 parse_size(tdm_size *size, char *arg)
@@ -809,6 +812,37 @@ get_tts_buffer(tbm_surface_h b)
 }
 
 static void
+_voutput_buff_deinit(tdm_test_server_voutput *voutput)
+{
+       int i;
+
+       for (i = 0; i < 3; i++) {
+               if (!voutput->bufs[i]) continue;
+
+               tbm_surface_destroy(voutput->bufs[i]);
+               voutput->bufs[i] = NULL;
+       }
+}
+
+static void
+_voutput_buff_init(tdm_test_server_voutput *voutput)
+{
+       tdm_output *output = voutput->output;
+       const tdm_output_mode *mode;
+       tdm_error ret = TDM_ERROR_NONE;
+       int i;
+
+       ret = tdm_output_get_mode(output, &mode);
+       TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
+
+       for (i = 0; i < 3; i++) {
+               tbm_surface_h b = tbm_surface_internal_create_with_flags(mode->hdisplay, mode->vdisplay, DEFAULT_FORMAT, 0);
+               TDM_EXIT_IF_FAIL(b != NULL);
+               tdm_test_buffer_fill(b, i);
+               voutput->bufs[i] = b;
+       }
+}
+static void
 _vlayer_cb_commit(tdm_layer *layer, unsigned int sequence,
                                unsigned int tv_sec, unsigned int tv_usec, void *user_data)
 {
@@ -817,13 +851,42 @@ _vlayer_cb_commit(tdm_layer *layer, unsigned int sequence,
        tdm_output_conn_status status;
        tdm_error ret;
 
-       printf("voutput cb commit:\t %d: l(%p) b(%p)\n", voutput->buf_idx, voutput->layer, voutput->bufs[voutput->buf_idx]);
+       printf("voutput cb:\t %d: l(%p) b(%p)\n", voutput->buf_idx, voutput->layer, voutput->bufs[voutput->buf_idx]);
 
        ret = tdm_output_get_conn_status(voutput->output, &status);
        TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
 
        if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) return;
 
+       if (voutput->need_mode_change) {
+               const tdm_output_mode *modes;
+               int count = 0;
+
+               tdm_output_get_available_modes(voutput->output, &modes, &count);
+               if (count > voutput->index) {
+                       const tdm_output_mode *mode, *current;
+
+                       ret = tdm_output_get_mode(voutput->output, &current);
+                       TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
+
+                       mode = &modes[voutput->index];
+
+                       if (mode != current) {
+                               printf("mode change to %d (%dx%d, %d)\n",
+                                       voutput->index, mode->hdisplay, mode->vdisplay, mode->vrefresh);
+                               _voutput_buff_deinit(voutput);
+                               _voutput_buff_init(voutput);
+
+                               ret = tdm_output_set_mode(voutput->output, mode);
+                               TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
+
+                               _voutput_layer_init(voutput);
+                               voutput->buf_idx = 2;
+                       }
+               }
+               voutput->need_mode_change = 0;
+       }
+
        voutput->buf_idx++;
        _vlayer_show_buffer(voutput);
 }
@@ -848,25 +911,6 @@ _vlayer_show_buffer(tdm_test_server_voutput *voutput)
 }
 
 static void
-_voutput_buff_init(tdm_test_server_voutput *voutput)
-{
-       tdm_output *output = voutput->output;
-       const tdm_output_mode *mode;
-       tdm_error ret = TDM_ERROR_NONE;
-       int i;
-
-       ret = tdm_output_get_mode(output, &mode);
-       TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
-
-       for (i = 0; i < 3; i++) {
-               tbm_surface_h b = tbm_surface_internal_create_with_flags(mode->hdisplay, mode->vdisplay, DEFAULT_FORMAT, 0);
-               TDM_EXIT_IF_FAIL(b != NULL);
-               tdm_test_buffer_fill(b, i);
-               voutput->bufs[i] = b;
-       }
-}
-
-static void
 _voutput_layer_init(tdm_test_server_voutput *voutput)
 {
        tdm_output *output = voutput->output;
@@ -993,22 +1037,41 @@ _tdm_test_server_cb_output_change(tdm_output *output, tdm_output_change_type typ
 }
 
 static void
+_tdm_test_server_cb_output_mode_change(tdm_output *output, unsigned int index, void *user_data)
+{
+       tdm_test_server_voutput *voutput = NULL;
+       const tdm_output_mode *modes;
+       int count = 0;
+       tdm_error ret;
+
+       voutput = (tdm_test_server_voutput *)user_data;
+       TDM_EXIT_IF_FAIL(voutput != NULL);
+
+       ret = tdm_output_get_available_modes(output, &modes, &count);
+       TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_RETURN_IF_FAIL(index < count);
+
+       voutput->need_mode_change = 1;
+       voutput->index = index;
+
+       printf("mode change request. index:%d\n", index);
+}
+
+static void
 _tdm_output_cb_destroy_handler(tdm_output *output, void *user_data)
 {
        tdm_test_server_voutput *voutput = NULL;
-       int i;
 
        voutput = (tdm_test_server_voutput *)user_data;
        TDM_EXIT_IF_FAIL(voutput != NULL);
 
+       tdm_output_remove_mode_change_request_handler(output, _tdm_test_server_cb_output_mode_change, voutput);
        tdm_output_remove_change_handler(output, _tdm_test_server_cb_output_change, voutput);
        tdm_output_remove_destroy_handler(output, _tdm_output_cb_destroy_handler, voutput);
 
        LIST_DEL(&voutput->link);
 
-       for (i = 0; i < 3; i++) {
-               tbm_surface_destroy(voutput->bufs[i]);
-       }
+       _voutput_buff_deinit(voutput);
 
        printf("voutput: %p destroy\n", voutput);
 
@@ -1033,6 +1096,9 @@ _tdm_output_cb_create_handler(tdm_display *dpy, tdm_output *output, void *user_d
        ret = tdm_output_add_change_handler(output, _tdm_test_server_cb_output_change, voutput);
        TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
 
+       ret = tdm_output_add_mode_change_request_handler(output, _tdm_test_server_cb_output_mode_change, voutput);
+       TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
+
        ret = tdm_output_add_destroy_handler(output, _tdm_output_cb_destroy_handler, voutput);
        TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
 
@@ -1107,9 +1173,7 @@ destroy(tdm_test_server *data)
        }
 
        LIST_FOR_EACH_ENTRY_SAFE(v, vv, &data->voutput_list, link) {
-               for (int i = 0; i < 3; i++) {
-                       tbm_surface_destroy(v->bufs[i]);
-               }
+               _voutput_buff_deinit(v);
                LIST_DEL(&v->link);
                free(v);
        }