fix TDM buffer management 94/61794/1
authorBoram Park <boram1288.park@samsung.com>
Thu, 10 Mar 2016 13:37:51 +0000 (22:37 +0900)
committerBoram Park <boram1288.park@samsung.com>
Thu, 10 Mar 2016 13:37:51 +0000 (22:37 +0900)
  - enhance logs
  - use pending_list to rollback if commit is failed
  - increase buffer ref_count if commit is successed

Change-Id: I6823202d9c1764c99d14378a1f37d55e47672c08

src/tdm_buffer.c
src/tdm_capture.c
src/tdm_display.c
src/tdm_pp.c
src/tdm_private.h

index 9b591f83b9cba424692b9c221557774e8d578d10..7ab6c2160cccb331eeaa6bc94b54741089501acb 100644 (file)
@@ -52,27 +52,17 @@ typedef struct _tdm_buffer_func_info {
        struct list_head link;
 } tdm_buffer_func_info;
 
-typedef struct _tdm_buffer_info {
-       tbm_surface_h buffer;
-
-       /* ref_count for backend */
-       int backend_ref_count;
-
-       struct list_head release_funcs;
-       struct list_head destroy_funcs;
-
-       struct list_head *list;
-       struct list_head link;
-} tdm_buffer_info;
-
 static void
 _tdm_buffer_destroy_info(void *user_data)
 {
        tdm_buffer_info *buf_info = (tdm_buffer_info *)user_data;
        tdm_buffer_func_info *func_info = NULL, *next = NULL;
 
-       if (buf_info->backend_ref_count > 0)
+       if (buf_info->backend_ref_count > 0) {
                TDM_NEVER_GET_HERE();
+               if (tdm_debug_buffer)
+                       TDM_INFO("%p", buf_info->buffer);
+       }
 
        LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
                LIST_DEL(&func_info->link);
@@ -87,14 +77,14 @@ _tdm_buffer_destroy_info(void *user_data)
                free(func_info);
        }
 
-       if (buf_info->list)
-               LIST_DEL(&buf_info->link);
+       if (tdm_debug_buffer)
+               TDM_INFO("%p destroyed", buf_info->buffer);
 
        free(buf_info);
 }
 
-static tdm_buffer_info *
-_tdm_buffer_get_info(tbm_surface_h buffer)
+tdm_buffer_info *
+tdm_buffer_get_info(tbm_surface_h buffer)
 {
        tdm_buffer_info *buf_info = NULL;
        tbm_bo bo;
@@ -116,6 +106,9 @@ _tdm_buffer_get_info(tbm_surface_h buffer)
 
                tbm_bo_add_user_data(bo, TDM_BUFFER_KEY, _tdm_buffer_destroy_info);
                tbm_bo_set_user_data(bo, TDM_BUFFER_KEY, buf_info);
+
+               if (tdm_debug_buffer)
+                       TDM_INFO("%p created", buf_info->buffer);
        }
 
        return buf_info;
@@ -131,7 +124,7 @@ tdm_buffer_add_release_handler(tbm_surface_h buffer,
        TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       buf_info = _tdm_buffer_get_info(buffer);
+       buf_info = tdm_buffer_get_info(buffer);
        TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
 
        func_info = calloc(1, sizeof(tdm_buffer_func_info));
@@ -155,7 +148,7 @@ tdm_buffer_remove_release_handler(tbm_surface_h buffer,
        TDM_RETURN_IF_FAIL(buffer != NULL);
        TDM_RETURN_IF_FAIL(func != NULL);
 
-       buf_info = _tdm_buffer_get_info(buffer);
+       buf_info = tdm_buffer_get_info(buffer);
        TDM_RETURN_IF_FAIL(buf_info != NULL);
 
        LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
@@ -177,10 +170,11 @@ tdm_buffer_ref_backend(tbm_surface_h buffer)
 
        TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL);
 
-       buf_info = _tdm_buffer_get_info(buffer);
+       buf_info = tdm_buffer_get_info(buffer);
        TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL);
 
        buf_info->backend_ref_count++;
+       tbm_surface_internal_ref(buffer);
 
        return buffer;
 }
@@ -193,19 +187,22 @@ tdm_buffer_unref_backend(tbm_surface_h buffer)
 
        TDM_RETURN_IF_FAIL(buffer != NULL);
 
-       buf_info = _tdm_buffer_get_info(buffer);
+       buf_info = tdm_buffer_get_info(buffer);
        TDM_RETURN_IF_FAIL(buf_info != NULL);
 
        buf_info->backend_ref_count--;
-
-       if (buf_info->backend_ref_count > 0)
+       if (buf_info->backend_ref_count > 0) {
+               tbm_surface_internal_unref(buffer);
                return;
+       }
 
        LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
                tbm_surface_internal_ref(buffer);
                func_info->release_func(buffer, func_info->user_data);
                tbm_surface_internal_unref(buffer);
        }
+
+       tbm_surface_internal_unref(buffer);
 }
 
 EXTERN tdm_error
@@ -218,7 +215,7 @@ tdm_buffer_add_destroy_handler(tbm_surface_h buffer,
        TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
        TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       buf_info = _tdm_buffer_get_info(buffer);
+       buf_info = tdm_buffer_get_info(buffer);
        TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
 
        func_info = calloc(1, sizeof(tdm_buffer_func_info));
@@ -242,7 +239,7 @@ tdm_buffer_remove_destroy_handler(tbm_surface_h buffer,
        TDM_RETURN_IF_FAIL(buffer != NULL);
        TDM_RETURN_IF_FAIL(func != NULL);
 
-       buf_info = _tdm_buffer_get_info(buffer);
+       buf_info = tdm_buffer_get_info(buffer);
        TDM_RETURN_IF_FAIL(buf_info != NULL);
 
        LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) {
@@ -256,59 +253,37 @@ tdm_buffer_remove_destroy_handler(tbm_surface_h buffer,
        }
 }
 
-INTERN void
-tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer)
+INTERN tbm_surface_h
+tdm_buffer_list_get_first_entry(struct list_head *list)
 {
-       tdm_buffer_info *buf_info;
-
-       TDM_RETURN_IF_FAIL(list != NULL);
-       TDM_RETURN_IF_FAIL(buffer != NULL);
-
-       buf_info = _tdm_buffer_get_info(buffer);
-       TDM_RETURN_IF_FAIL(buf_info != NULL);
-
-       if (buf_info->list) {
-               TDM_ERR("%p already added other list\n", buffer);
-               return;
-       }
-
-       buf_info->list = list;
-       LIST_ADD(&buf_info->link, list);
-}
-
-INTERN void
-tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer)
-{
-       tdm_buffer_info *buf_info;
-
-       TDM_RETURN_IF_FAIL(list != NULL);
-       TDM_RETURN_IF_FAIL(buffer != NULL);
+       tdm_buffer_info *buf_info = NULL;
 
-       buf_info = _tdm_buffer_get_info(buffer);
-       TDM_RETURN_IF_FAIL(buf_info != NULL);
+       TDM_RETURN_VAL_IF_FAIL(list != NULL, NULL);
 
-       if (buf_info->list != list) {
-               TDM_WRN("%p is not in %p list", buffer, list);
-               return;
-       }
+       buf_info = container_of((list)->next, buf_info, link);
 
-       LIST_DEL(&buf_info->link);
+       return buf_info->buffer;
 }
 
 INTERN void
-tdm_buffer_dump_list(struct list_head *list, char *str, int len)
+tdm_buffer_list_dump(struct list_head *list)
 {
        tdm_buffer_info *buf_info = NULL;
+       char str[256], *p;
+       int len = sizeof (str);
 
        TDM_RETURN_IF_FAIL(list != NULL);
 
+       p = str;
        LIST_FOR_EACH_ENTRY(buf_info, list, link) {
                if (len > 0) {
-                       int l = snprintf(str, len, " %p", buf_info->buffer);
-                       str += l;
+                       int l = snprintf(p, len, " %p", buf_info->buffer);
+                       p += l;
                        len -= l;
                }
                else
                        break;
        }
+
+       TDM_INFO("\t %s", str);
 }
index 6c3fed6904251e2ecee8d21069d41dfc35014b41..14ebc3d2e85ad9123ef496f2ad1fc5dfca75007f 100644 (file)
@@ -57,9 +57,21 @@ _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer,
 {
        tdm_private_capture *private_capture = user_data;
        tdm_private_display *private_display = private_capture->private_display;
+       tdm_buffer_info *buf_info;
+       tbm_surface_h first_entry;
        int lock_after_cb_done = 0;
        int ret;
 
+       if (tdm_debug_buffer)
+               TDM_INFO("capture(%p) done: %p", private_capture, buffer);
+
+       first_entry = tdm_buffer_list_get_first_entry(&private_capture->buffer_list);
+       if (first_entry != buffer)
+               TDM_ERR("%p is skipped", first_entry);
+
+       if ((buf_info = tdm_buffer_get_info(buffer)))
+               LIST_DEL(&buf_info->link);
+
        ret = pthread_mutex_trylock(&private_display->lock);
        if (ret == 0)
                pthread_mutex_unlock(&private_display->lock);
@@ -68,11 +80,6 @@ _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer,
                lock_after_cb_done = 1;
        }
 
-       if (tdm_debug_buffer)
-               TDM_INFO("done: %p", buffer);
-
-       tdm_buffer_remove_list(&private_capture->buffer_list, buffer);
-
        tdm_buffer_unref_backend(buffer);
 
        if (lock_after_cb_done)
@@ -117,7 +124,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output,
        ret = func_capture->capture_set_done_handler(capture_backend,
                        _tdm_caputre_cb_done, private_capture);
        if (ret != TDM_ERROR_NONE) {
-               TDM_ERR("set capture_done_handler failed");
+               TDM_ERR("capture(%p) set capture_done_handler failed", private_capture);
                func_capture->capture_destroy(capture_backend);
                if (error)
                        *error = ret;
@@ -131,6 +138,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output,
        private_capture->private_layer = NULL;
        private_capture->capture_backend = capture_backend;
 
+       LIST_INITHEAD(&private_capture->pending_buffer_list);
        LIST_INITHEAD(&private_capture->buffer_list);
 
        if (error)
@@ -179,6 +187,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer,
        private_capture->private_layer = private_layer;
        private_capture->capture_backend = capture_backend;
 
+       LIST_INITHEAD(&private_capture->pending_buffer_list);
        LIST_INITHEAD(&private_capture->buffer_list);
 
        if (error)
@@ -191,6 +200,7 @@ INTERN void
 tdm_capture_destroy_internal(tdm_private_capture *private_capture)
 {
        tdm_func_capture *func_capture;
+       tdm_buffer_info *b = NULL, *bb = NULL;
 
        if (!private_capture)
                return;
@@ -200,11 +210,20 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture)
        func_capture = &private_capture->private_display->func_capture;
        func_capture->capture_destroy(private_capture->capture_backend);
 
+       if (!LIST_IS_EMPTY(&private_capture->pending_buffer_list)) {
+               TDM_ERR("capture(%p) not finished:", private_capture);
+               tdm_buffer_list_dump(&private_capture->pending_buffer_list);
+
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link)
+                       LIST_DEL(&b->link);
+       }
+
        if (!LIST_IS_EMPTY(&private_capture->buffer_list)) {
-               char str[256] = {0,};
-               tdm_buffer_dump_list(&private_capture->buffer_list, str, 256);
-               if (strlen(str) > 0)
-                       TDM_WRN("not finished: %s buffers", str);
+               TDM_ERR("capture(%p) not finished:", private_capture);
+               tdm_buffer_list_dump(&private_capture->buffer_list);
+
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->buffer_list, link)
+                       LIST_DEL(&b->link);
        }
 
        free(private_capture);
@@ -241,6 +260,7 @@ tdm_capture_set_info(tdm_capture *capture, tdm_info_capture *info)
        }
 
        ret = func_capture->capture_set_info(private_capture->capture_backend, info);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
        pthread_mutex_unlock(&private_display->lock);
 
@@ -261,16 +281,19 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer)
                return TDM_ERROR_NONE;
        }
 
-       tdm_buffer_ref_backend(buffer);
        ret = func_capture->capture_attach(private_capture->capture_backend, buffer);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
-       if (ret == TDM_ERROR_NONE)
-               tdm_buffer_add_list(&private_capture->buffer_list, buffer);
+       if (ret == TDM_ERROR_NONE) {
+               tdm_buffer_info *buf_info;
 
-       if (tdm_debug_buffer) {
-               char str[256] = {0,};
-               tdm_buffer_dump_list(&private_capture->buffer_list, str, 256);
-               TDM_INFO("attached: %s", str);
+               if ((buf_info = tdm_buffer_get_info(buffer)))
+                       LIST_ADDTAIL(&buf_info->link, &private_capture->pending_buffer_list);
+
+               if (tdm_debug_buffer) {
+                       TDM_INFO("capture(%p) attached:", private_capture);
+                       tdm_buffer_list_dump(&private_capture->buffer_list);
+               }
        }
 
        pthread_mutex_unlock(&private_display->lock);
@@ -281,6 +304,8 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer)
 EXTERN tdm_error
 tdm_capture_commit(tdm_capture *capture)
 {
+       tdm_buffer_info *b = NULL, *bb = NULL;
+
        CAPTURE_FUNC_ENTRY();
 
        pthread_mutex_lock(&private_display->lock);
@@ -291,6 +316,18 @@ tdm_capture_commit(tdm_capture *capture)
        }
 
        ret = func_capture->capture_commit(private_capture->capture_backend);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
+
+       if (ret == TDM_ERROR_NONE) {
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link) {
+                       LIST_DEL(&b->link);
+                       tdm_buffer_ref_backend(b->buffer);
+                       LIST_ADDTAIL(&b->link, &private_capture->buffer_list);
+               }
+       } else {
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link)
+                       LIST_DEL(&b->link);
+       }
 
        pthread_mutex_unlock(&private_display->lock);
 
index 479f8053678b5ed926f53b9af109df56f44d3aef..7f4857ab25df01fb3099e4392eb1ce430c2e5bb0 100644 (file)
@@ -676,6 +676,11 @@ _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
 
                private_layer->showing_buffer = private_layer->waiting_buffer;
                private_layer->waiting_buffer = NULL;
+
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
+                                private_layer, private_layer->waiting_buffer,
+                                private_layer->showing_buffer);
        }
 
        if (commit_handler->func) {
@@ -763,9 +768,7 @@ _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
 
        ret = func_output->output_commit(private_output->output_backend, sync,
                                         commit_handler);
-       if (ret != TDM_ERROR_NONE) {
-               return ret;
-       }
+       TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
 
        if (!private_output->regist_commit_cb) {
                private_output->regist_commit_cb = 1;
@@ -1042,8 +1045,8 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
                return TDM_ERROR_NONE;
        }
 
-       TDM_INFO("layer info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
-                info->src_config.size.h, info->src_config.size.v,
+       TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
+                private_layer, info->src_config.size.h, info->src_config.size.v,
                 info->src_config.pos.x, info->src_config.pos.y,
                 info->src_config.pos.w, info->src_config.pos.h,
                 FOURCC_STR(info->src_config.format),
@@ -1052,6 +1055,7 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
                 info->transform);
 
        ret = func_layer->layer_set_info(private_layer->layer_backend, info);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
        pthread_mutex_unlock(&private_display->lock);
 
@@ -1086,6 +1090,7 @@ EXTERN tdm_error
 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
 {
        tdm_func_layer *func_layer;
+
        LAYER_FUNC_ENTRY();
 
        TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
@@ -1101,15 +1106,24 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
                return TDM_ERROR_NONE;
        }
 
-       if (private_layer->waiting_buffer) {
-               pthread_mutex_unlock(&private_display->lock);
-               tdm_buffer_unref_backend(private_layer->waiting_buffer);
-               pthread_mutex_lock(&private_display->lock);
-       }
+       ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
-       private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
+       if (ret == TDM_ERROR_NONE) {
+               /* FIXME: should save to pending_buffer first. And after committing
+                * successfully, need to move to waiting_buffer.
+                */
+               if (private_layer->waiting_buffer) {
+                       pthread_mutex_unlock(&private_display->lock);
+                       tdm_buffer_unref_backend(private_layer->waiting_buffer);
+                       pthread_mutex_lock(&private_display->lock);
+               }
 
-       ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
+               private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) waiting_buffer(%p)",
+                                private_layer, private_layer->waiting_buffer);
+       }
 
        pthread_mutex_unlock(&private_display->lock);
 
@@ -1131,6 +1145,10 @@ tdm_layer_unset_buffer(tdm_layer *layer)
                tdm_buffer_unref_backend(private_layer->waiting_buffer);
                pthread_mutex_lock(&private_display->lock);
                private_layer->waiting_buffer = NULL;
+
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) waiting_buffer(%p)",
+                                private_layer, private_layer->waiting_buffer);
        }
 
        if (private_layer->showing_buffer) {
@@ -1138,6 +1156,10 @@ tdm_layer_unset_buffer(tdm_layer *layer)
                tdm_buffer_unref_backend(private_layer->showing_buffer);
                pthread_mutex_lock(&private_display->lock);
                private_layer->showing_buffer = NULL;
+
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) showing_buffer(%p)",
+                                private_layer, private_layer->showing_buffer);
        }
 
        private_layer->usable = 1;
@@ -1148,6 +1170,7 @@ tdm_layer_unset_buffer(tdm_layer *layer)
        }
 
        ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
        pthread_mutex_unlock(&private_display->lock);
 
@@ -1174,26 +1197,34 @@ _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
        if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
                    private_layer->buffer_queue, &surface) ||
            surface == NULL) {
-               TDM_ERR("tbm_surface_queue_acquire() failed surface:%p", surface);
+               TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
+                       private_layer, surface);
                pthread_mutex_unlock(&private_display->lock);
                return;
        }
 
-       if (private_layer->waiting_buffer) {
-               pthread_mutex_unlock(&private_display->lock);
-               tdm_buffer_unref_backend(private_layer->waiting_buffer);
-               tbm_surface_queue_release(private_layer->buffer_queue,
-                                         private_layer->waiting_buffer);
-               pthread_mutex_lock(&private_display->lock);
-       }
+       ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
-       private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
+       if (ret == TDM_ERROR_NONE) {
+               if (private_layer->waiting_buffer) {
+                       pthread_mutex_unlock(&private_display->lock);
+                       tdm_buffer_unref_backend(private_layer->waiting_buffer);
+                       tbm_surface_queue_release(private_layer->buffer_queue,
+                                                 private_layer->waiting_buffer);
+                       pthread_mutex_lock(&private_display->lock);
+               }
+
+               private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
 
-       func_layer->layer_set_buffer(private_layer->layer_backend, surface);
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) waiting_buffer(%p)",
+                                private_layer, private_layer->waiting_buffer);
 
-       ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
-       if (ret != TDM_ERROR_NONE)
-               TDM_ERR("_tdm_output_commit() is fail");
+               ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
+               if (ret != TDM_ERROR_NONE)
+                       TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
+       }
 
        pthread_mutex_unlock(&private_display->lock);
 }
@@ -1252,6 +1283,10 @@ tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
                                          private_layer->waiting_buffer);
                private_layer->waiting_buffer = NULL;
                pthread_mutex_lock(&private_display->lock);
+
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) waiting_buffer(%p)",
+                                private_layer, private_layer->waiting_buffer);
        }
 
        private_layer->buffer_queue = buffer_queue;
@@ -1283,6 +1318,10 @@ tdm_layer_unset_buffer_queue(tdm_layer *layer)
                                          private_layer->waiting_buffer);
                private_layer->waiting_buffer = NULL;
                pthread_mutex_lock(&private_display->lock);
+
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) waiting_buffer(%p)",
+                                private_layer, private_layer->waiting_buffer);
        }
 
        if (private_layer->showing_buffer) {
@@ -1292,6 +1331,10 @@ tdm_layer_unset_buffer_queue(tdm_layer *layer)
                                          private_layer->showing_buffer);
                pthread_mutex_lock(&private_display->lock);
                private_layer->showing_buffer = NULL;
+
+               if (tdm_debug_buffer)
+                       TDM_INFO("layer(%p) showing_buffer(%p)",
+                                private_layer, private_layer->showing_buffer);
        }
 
        tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, NULL, NULL);
@@ -1338,7 +1381,7 @@ tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
        func_layer = &private_display->func_layer;
 
        if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
-               TDM_ERR("layer is not video layer");
+               TDM_ERR("layer(%p) is not video layer", private_layer);
                pthread_mutex_unlock(&private_display->lock);
                return TDM_ERROR_INVALID_PARAMETER;
        }
index 829446607c09271ca528218565a681c301c568fd..8f4386028ffdcf03889c4f48327f1ede91640fb9 100644 (file)
@@ -57,9 +57,28 @@ _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst,
 {
        tdm_private_pp *private_pp = user_data;
        tdm_private_display *private_display = private_pp->private_display;
+       tdm_buffer_info *buf_info;
+       tbm_surface_h first_entry;
        int lock_after_cb_done = 0;
        int ret;
 
+       if (tdm_debug_buffer)
+               TDM_INFO("pp(%p) done: src(%p) dst(%p)", private_pp, src, dst);
+
+       first_entry = tdm_buffer_list_get_first_entry(&private_pp->src_buffer_list);
+       if (first_entry != src)
+               TDM_ERR("src(%p) is skipped", first_entry);
+
+       first_entry = tdm_buffer_list_get_first_entry(&private_pp->dst_buffer_list);
+       if (first_entry != dst)
+               TDM_ERR("dst(%p) is skipped", first_entry);
+
+       if ((buf_info = tdm_buffer_get_info(src)))
+               LIST_DEL(&buf_info->link);
+
+       if ((buf_info = tdm_buffer_get_info(dst)))
+               LIST_DEL(&buf_info->link);
+
        ret = pthread_mutex_trylock(&private_display->lock);
        if (ret == 0)
                pthread_mutex_unlock(&private_display->lock);
@@ -68,11 +87,6 @@ _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst,
                lock_after_cb_done = 1;
        }
 
-       if (tdm_debug_buffer)
-               TDM_INFO("done: %p", src);
-
-       tdm_buffer_remove_list(&private_pp->buffer_list, src);
-
        tdm_buffer_unref_backend(src);
        tdm_buffer_unref_backend(dst);
 
@@ -117,7 +131,7 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error)
 
        ret = func_pp->pp_set_done_handler(pp_backend, _tdm_pp_cb_done, private_pp);
        if (ret != TDM_ERROR_NONE) {
-               TDM_ERR("set pp_done_handler failed");
+               TDM_ERR("spp(%p) et pp_done_handler failed", private_pp);
                func_pp->pp_destroy(pp_backend);
                if (error)
                        *error = ret;
@@ -128,7 +142,10 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error)
        private_pp->private_display = private_display;
        private_pp->pp_backend = pp_backend;
 
-       LIST_INITHEAD(&private_pp->buffer_list);
+       LIST_INITHEAD(&private_pp->src_pending_buffer_list);
+       LIST_INITHEAD(&private_pp->dst_pending_buffer_list);
+       LIST_INITHEAD(&private_pp->src_buffer_list);
+       LIST_INITHEAD(&private_pp->dst_buffer_list);
 
        if (error)
                *error = TDM_ERROR_NONE;
@@ -139,22 +156,50 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error)
 INTERN void
 tdm_pp_destroy_internal(tdm_private_pp *private_pp)
 {
+       tdm_private_display *private_display;
        tdm_func_pp *func_pp;
+       tdm_buffer_info *b = NULL, *bb = NULL;
 
        if (!private_pp)
                return;
 
-       func_pp = &private_pp->private_display->func_pp;
+       private_display = private_pp->private_display;
+       func_pp = &private_display->func_pp;
 
        LIST_DEL(&private_pp->link);
 
        func_pp->pp_destroy(private_pp->pp_backend);
 
-       if (!LIST_IS_EMPTY(&private_pp->buffer_list)) {
-               char str[256] = {0,};
-               tdm_buffer_dump_list(&private_pp->buffer_list, str, 256);
-               if (strlen(str) > 0)
-                       TDM_WRN("not finished: %s buffers", str);
+       if (!LIST_IS_EMPTY(&private_pp->src_pending_buffer_list)) {
+               TDM_ERR("pp(%p) not finished:", private_pp);
+               tdm_buffer_list_dump(&private_pp->src_pending_buffer_list);
+
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link)
+                       LIST_DEL(&b->link);
+       }
+
+       if (!LIST_IS_EMPTY(&private_pp->dst_pending_buffer_list)) {
+               TDM_ERR("pp(%p) not finished:", private_pp);
+               tdm_buffer_list_dump(&private_pp->dst_pending_buffer_list);
+
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link)
+                       LIST_DEL(&b->link);
+       }
+
+       if (!LIST_IS_EMPTY(&private_pp->src_buffer_list)) {
+               TDM_ERR("pp(%p) not finished:", private_pp);
+               tdm_buffer_list_dump(&private_pp->src_buffer_list);
+
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_buffer_list, link)
+                       LIST_DEL(&b->link);
+       }
+
+       if (!LIST_IS_EMPTY(&private_pp->dst_buffer_list)) {
+               TDM_ERR("pp(%p) not finished:", private_pp);
+               tdm_buffer_list_dump(&private_pp->dst_buffer_list);
+
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_buffer_list, link)
+                       LIST_DEL(&b->link);
        }
 
        free(private_pp);
@@ -190,8 +235,8 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
                return TDM_ERROR_NONE;
        }
 
-       TDM_INFO("pp info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) sync(%d) flags(%x)",
-                info->src_config.size.h, info->src_config.size.v,
+       TDM_INFO("pp(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) sync(%d) flags(%x)",
+                private_pp, info->src_config.size.h, info->src_config.size.v,
                 info->src_config.pos.x, info->src_config.pos.y,
                 info->src_config.pos.w, info->src_config.pos.h,
                 FOURCC_STR(info->src_config.format),
@@ -202,6 +247,7 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
                 info->transform, info->sync, info->flags);
 
        ret = func_pp->pp_set_info(private_pp->pp_backend, info);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
        pthread_mutex_unlock(&private_display->lock);
 
@@ -223,17 +269,23 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
                return TDM_ERROR_NONE;
        }
 
-       tdm_buffer_ref_backend(src);
-       tdm_buffer_ref_backend(dst);
        ret = func_pp->pp_attach(private_pp->pp_backend, src, dst);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
+
+       if (ret == TDM_ERROR_NONE) {
+               tdm_buffer_info *buf_info;
 
-       if (ret == TDM_ERROR_NONE)
-               tdm_buffer_add_list(&private_pp->buffer_list, src);
+               if ((buf_info = tdm_buffer_get_info(src)))
+                       LIST_ADDTAIL(&buf_info->link, &private_pp->src_pending_buffer_list);
 
-       if (tdm_debug_buffer) {
-               char str[256] = {0,};
-               tdm_buffer_dump_list(&private_pp->buffer_list, str, 256);
-               TDM_INFO("attached: %s", str);
+               if ((buf_info = tdm_buffer_get_info(dst)))
+                       LIST_ADDTAIL(&buf_info->link, &private_pp->dst_pending_buffer_list);
+
+               if (tdm_debug_buffer) {
+                       TDM_INFO("pp(%p) attached:", private_pp);
+                       tdm_buffer_list_dump(&private_pp->src_pending_buffer_list);
+                       tdm_buffer_list_dump(&private_pp->dst_pending_buffer_list);
+               }
        }
 
        pthread_mutex_unlock(&private_display->lock);
@@ -244,6 +296,8 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
 EXTERN tdm_error
 tdm_pp_commit(tdm_pp *pp)
 {
+       tdm_buffer_info *b = NULL, *bb = NULL;
+
        PP_FUNC_ENTRY();
 
        pthread_mutex_lock(&private_display->lock);
@@ -254,6 +308,26 @@ tdm_pp_commit(tdm_pp *pp)
        }
 
        ret = func_pp->pp_commit(private_pp->pp_backend);
+       TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
+
+       if (ret == TDM_ERROR_NONE) {
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link) {
+                       LIST_DEL(&b->link);
+                       tdm_buffer_ref_backend(b->buffer);
+                       LIST_ADDTAIL(&b->link, &private_pp->src_buffer_list);
+               }
+
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link) {
+                       LIST_DEL(&b->link);
+                       tdm_buffer_ref_backend(b->buffer);
+                       LIST_ADDTAIL(&b->link, &private_pp->dst_buffer_list);
+               }
+       } else {
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link)
+                       LIST_DEL(&b->link);
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link)
+                       LIST_DEL(&b->link);
+       }
 
        pthread_mutex_unlock(&private_display->lock);
 
index 9ac18ba5f7a14a072f662232d2aa485c01ee1eba..fb0f7adbb78f61aba6447ffe5140d21bdda12aeb 100644 (file)
@@ -221,6 +221,7 @@ struct _tdm_private_layer {
        tdm_caps_layer caps;
        tdm_layer *layer_backend;
 
+       tbm_surface_h pending_buffer;
        tbm_surface_h waiting_buffer;
        tbm_surface_h showing_buffer;
        tbm_surface_queue_h buffer_queue;
@@ -237,7 +238,10 @@ struct _tdm_private_pp {
 
        tdm_pp *pp_backend;
 
-       struct list_head buffer_list;
+       struct list_head src_pending_buffer_list;
+       struct list_head dst_pending_buffer_list;
+       struct list_head src_buffer_list;
+       struct list_head dst_buffer_list;
 };
 
 struct _tdm_private_capture {
@@ -251,6 +255,7 @@ struct _tdm_private_capture {
 
        tdm_capture *capture_backend;
 
+       struct list_head pending_buffer_list;
        struct list_head buffer_list;
 };
 
@@ -270,6 +275,19 @@ struct _tdm_private_commit_handler {
        void *user_data;
 };
 
+typedef struct _tdm_buffer_info {
+       tbm_surface_h buffer;
+
+       /* ref_count for backend */
+       int backend_ref_count;
+
+       struct list_head release_funcs;
+       struct list_head destroy_funcs;
+
+       struct list_head *list;
+       struct list_head link;
+} tdm_buffer_info;
+
 tdm_private_pp *
 tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error);
 void
@@ -284,12 +302,13 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer,
 void
 tdm_capture_destroy_internal(tdm_private_capture *private_capture);
 
+/* utility buffer functions for private */
+tdm_buffer_info*
+tdm_buffer_get_info(tbm_surface_h buffer);
+tbm_surface_h
+tdm_buffer_list_get_first_entry(struct list_head *list);
 void
-tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer);
-void
-tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer);
-void
-tdm_buffer_dump_list(struct list_head *list, char *str, int len);
+tdm_buffer_list_dump(struct list_head *list);
 
 #ifdef __cplusplus
 }