[hwc] use TDM_OUTPUT_CAPABILITY_HWC instead of TDM_DISPLAY_CAPABILITY_HWC
[platform/core/uifw/libtdm.git] / src / tdm_pp.c
index a43d257..ab95105 100644 (file)
 #include "tdm_private.h"
 #include "tdm_helper.h"
 
-typedef struct _tdm_pp_private_buffer {
-       tbm_surface_h src;
-       tbm_surface_h dst;
-       struct list_head link;
-       struct list_head commit_link;
-} tdm_pp_private_buffer;
-
 #define PP_FUNC_ENTRY() \
        tdm_func_pp *func_pp; \
        tdm_private_display *private_display; \
@@ -78,7 +71,7 @@ _tdm_pp_print_list(struct list_head *list)
                        break;
        }
 
-       TDM_INFO("\t %s", str);
+       TDM_WRN("\t %s", str);
 }
 
 static tdm_pp_private_buffer *
@@ -141,7 +134,7 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst,
                char str[TDM_PATH_LEN];
                static int i;
                snprintf(str, TDM_PATH_LEN, "pp_dst_%03d", i++);
-               tdm_helper_dump_buffer_str(dst, str);
+               tdm_helper_dump_buffer_str(dst, tdm_debug_dump_dir, str);
        }
 
        if (tdm_debug_module & TDM_DEBUG_BUFFER)
@@ -157,8 +150,11 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst,
 
        if ((pp_buffer = _tdm_pp_find_tbm_buffers(&private_pp->buffer_list, src, dst))) {
                LIST_DEL(&pp_buffer->link);
+               LIST_DELINIT(&pp_buffer->commit_link);
 
                _pthread_mutex_unlock(&private_display->lock);
+               if (private_pp->done_func)
+                       private_pp->done_func(private_pp, src, dst, private_pp->done_user_data);
                tdm_buffer_unref_backend(src);
                tdm_buffer_unref_backend(dst);
                _pthread_mutex_lock(&private_display->lock);
@@ -168,7 +164,7 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst,
 }
 
 INTERN tdm_private_pp *
-tdm_pp_find_stamp(tdm_private_display *private_display, unsigned long stamp)
+tdm_pp_find_stamp(tdm_private_display *private_display, double stamp)
 {
        tdm_private_pp *private_pp = NULL;
 
@@ -228,7 +224,7 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error)
                return NULL;
        }
 
-       private_pp->stamp = tdm_helper_get_time_in_millis();
+       private_pp->stamp = tdm_helper_get_time();
        while (tdm_pp_find_stamp(private_display, private_pp->stamp))
                private_pp->stamp++;
 
@@ -252,6 +248,7 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp)
        tdm_private_display *private_display;
        tdm_func_pp *func_pp;
        tdm_pp_private_buffer *b = NULL, *bb = NULL;
+       struct list_head clone_list;
 
        TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
 
@@ -269,22 +266,40 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp)
                TDM_WRN("pp(%p) not finished:", private_pp);
                _tdm_pp_print_list(&private_pp->pending_buffer_list);
 
+               LIST_INITHEAD(&clone_list);
                LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->pending_buffer_list, link) {
                        LIST_DEL(&b->link);
+                       LIST_ADDTAIL(&b->link, &clone_list);
+               }
+
+               _pthread_mutex_unlock(&private_display->lock);
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &clone_list, link) {
+                       LIST_DEL(&b->link);
+                       tdm_buffer_unref_backend(b->src);
+                       tdm_buffer_unref_backend(b->dst);
+                       free(b);
                }
+               _pthread_mutex_lock(&private_display->lock);
        }
 
        if (!LIST_IS_EMPTY(&private_pp->buffer_list)) {
                TDM_WRN("pp(%p) not finished:", private_pp);
                _tdm_pp_print_list(&private_pp->buffer_list);
 
+               LIST_INITHEAD(&clone_list);
                LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->buffer_list, link) {
                        LIST_DEL(&b->link);
-                       _pthread_mutex_unlock(&private_display->lock);
+                       LIST_ADDTAIL(&b->link, &clone_list);
+               }
+
+               _pthread_mutex_unlock(&private_display->lock);
+               LIST_FOR_EACH_ENTRY_SAFE(b, bb, &clone_list, link) {
+                       LIST_DEL(&b->link);
                        tdm_buffer_unref_backend(b->src);
                        tdm_buffer_unref_backend(b->dst);
-                       _pthread_mutex_lock(&private_display->lock);
+                       free(b);
                }
+               _pthread_mutex_lock(&private_display->lock);
        }
 
        private_pp->stamp = 0;
@@ -336,6 +351,32 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
        ret = func_pp->pp_set_info(private_pp->pp_backend, info);
        TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
+       private_pp->info = *info;
+
+       _pthread_mutex_unlock(&private_display->lock);
+
+       return ret;
+}
+
+EXTERN tdm_error
+tdm_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data)
+{
+       tdm_private_display *private_display;
+       tdm_private_pp *private_pp;
+       tdm_error ret = TDM_ERROR_NONE;
+
+       TDM_RETURN_VAL_IF_FAIL(pp != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_pp = (tdm_private_pp*)pp;
+       private_display = private_pp->private_display;
+
+       TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       private_pp->done_func = func;
+       private_pp->done_user_data = user_data;
+
        _pthread_mutex_unlock(&private_display->lock);
 
        return ret;
@@ -375,10 +416,10 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
                char str[TDM_PATH_LEN];
                static int i;
                snprintf(str, TDM_PATH_LEN, "pp_src_%03d", i++);
-               tdm_helper_dump_buffer_str(src, str);
+               tdm_helper_dump_buffer_str(src, tdm_debug_dump_dir, str);
        }
 
-       pp_buffer = calloc(1, sizeof *pp_buffer);
+       pp_buffer = calloc(1, sizeof * pp_buffer);
        if (!pp_buffer) {
                _pthread_mutex_unlock(&private_display->lock);
                TDM_ERR("alloc failed");
@@ -437,15 +478,27 @@ tdm_pp_commit(tdm_pp *pp)
        TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
 
        LIST_FOR_EACH_ENTRY_SAFE(b, bb, &commit_buffer_list, commit_link) {
+               LIST_DELINIT(&b->commit_link);
+
                if (!_tdm_pp_find_buffer(&private_pp->buffer_list, b))
                        continue;
 
-               LIST_DEL(&b->commit_link);
-
                if (ret != TDM_ERROR_NONE) {
+                       /* Not to call the user release handler when failed.
+                        * Do we have to call this function here really?
+                        * User better use set_done_handler to know when pp is done. Using
+                        * buffer_release_handler is not good.
+                        */
+                       tdm_buffer_remove_release_handler_internal(b->src);
+                       tdm_buffer_remove_release_handler_internal(b->dst);
+
+                       _pthread_mutex_unlock(&private_display->lock);
                        tdm_buffer_unref_backend(b->src);
                        tdm_buffer_unref_backend(b->dst);
+                       _pthread_mutex_lock(&private_display->lock);
                        LIST_DEL(&b->link);
+
+                       free(b);
                }
        }