Support flushing packet by calling sub thread 23/115723/2 accepted/tizen_common accepted/tizen_ivi accepted/tizen_mobile accepted/tizen_tv accepted/tizen_wearable accepted/tizen/common/20170303.090915 accepted/tizen/ivi/20170303.070016 accepted/tizen/mobile/20170303.065905 accepted/tizen/tv/20170303.065931 accepted/tizen/unified/20170309.033315 accepted/tizen/wearable/20170303.065955 submit/tizen/20170303.015115 submit/tizen_unified/20170308.100408
authorHyunil <hyunil46.park@samsung.com>
Tue, 21 Feb 2017 06:17:37 +0000 (15:17 +0900)
committerHyunil <hyunil46.park@samsung.com>
Thu, 2 Mar 2017 04:48:42 +0000 (13:48 +0900)
Change-Id: I39c2ace47907911cf05e765b395f49b0e42d89c4
Signed-off-by: Hyunil <hyunil46.park@samsung.com>
packaging/libmm-evas-renderer.spec
src/include/mm_evas_renderer.h
src/mm_evas_renderer.c

index 7b04a05..cac9923 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-evas-renderer
 Summary:    Multimedia Framework Evas Renderer Library
-Version:    0.0.12
+Version:    0.0.13
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 7e2df0f..83b1f26 100644 (file)
@@ -60,7 +60,8 @@ extern "C" {
 
 typedef enum {
        UPDATE_VISIBILITY,
-       UPDATE_TBM_SURF
+       UPDATE_TBM_SURF,
+       UPDATE_FLUSH_BUFFER
 } update_info;
 
 typedef struct {
@@ -115,10 +116,10 @@ typedef struct {
        /* lock */
        GMutex mp_lock; /* media_packet free lock */
        GMutex idx_lock; /* to keep value of cur_idx */
+       GMutex write_lock; /* ecore pipe write lock */
 
        /* flush buffer */
        flush_info *flush_buffer;
-       gboolean retrieve_packet; /* after flush buffer is made by API, flush will be executed in main thread callback */
        gboolean keep_screen;
 
        /* rendered callback */
index d50124e..d5b0d70 100755 (executable)
@@ -172,14 +172,6 @@ static void _evas_render_pre_cb(void *data, Evas *e, void *event_info)
                return;
        }
 
-       /* flush will be executed in this callback normally,
-       because native_surface_set must be called in main thread */
-       if (evas_info->retrieve_packet) {
-               g_mutex_lock(&evas_info->idx_lock);
-               if (_flush_packets(evas_info) != MM_ERROR_NONE)
-                       LOGE("flushing packets is failed");
-               g_mutex_unlock(&evas_info->idx_lock);
-       }
        MMER_FLEAVE();
 }
 
@@ -221,14 +213,23 @@ static void _evas_pipe_cb(void *data, void *buffer, update_info info)
 
        LOGD("evas_info : %p, type : %d, evas_info->eo : %p", evas_info, info, evas_info->eo);
 
-       if (info != UPDATE_TBM_SURF && info != UPDATE_VISIBILITY) {
+       if (info != UPDATE_TBM_SURF && info != UPDATE_VISIBILITY && info != UPDATE_FLUSH_BUFFER) {
                LOGW("invalid info type : %d", info);
                g_mutex_unlock(&evas_info->mp_lock);
                return;
        }
 
+       if (info == UPDATE_FLUSH_BUFFER) {
+               if (_flush_packets(evas_info) != MM_ERROR_NONE) {
+                       LOGE("flushing packets is failed");
+               }
+               g_mutex_unlock(&evas_info->mp_lock);
+               return;
+       }
+
        if (info == UPDATE_VISIBILITY) {
                if (!evas_info->visible) {
+                       /* surface set must be called by main thread */
                        evas_object_image_native_surface_set(evas_info->eo, NULL);
                        evas_object_hide(evas_info->eo);
                        LOGI("object hide..");
@@ -241,14 +242,15 @@ static void _evas_pipe_cb(void *data, void *buffer, update_info info)
                }
        }
 
+       g_mutex_lock(&evas_info->idx_lock);
        if ((evas_info->cur_idx == -1) || !evas_info->pkt_info[evas_info->cur_idx].tbm_surf) {
                LOGW("cur_idx %d, tbm_surf may be NULL", evas_info->cur_idx);
+               g_mutex_unlock(&evas_info->idx_lock);
                g_mutex_unlock(&evas_info->mp_lock);
                return;
        }
        /* perhaps, it is needed to skip setting when state is pause */
 
-       g_mutex_lock(&evas_info->idx_lock);
        /* index */
        gint cur_idx = evas_info->cur_idx;
        gint prev_idx = evas_info->pkt_info[cur_idx].prev;
@@ -315,6 +317,7 @@ static void _evas_pipe_cb(void *data, void *buffer, update_info info)
                g_cnt_out++;
 #endif
        if (evas_info->visible) {
+               /* surface set must be called by main thread */
                evas_object_image_native_surface_set(evas_info->eo, &surf);
                LOGD("native surface set finish");
        } else {
@@ -570,6 +573,7 @@ static int _flush_packets(mm_evas_info *evas_info)
                surf.data.tbm.buffer = evas_info->flush_buffer->tbm_surf;
                surf.data.tbm.rot = evas_info->rotate_angle;
                surf.data.tbm.flip = evas_info->flip;
+               /* surface set must be called by main thread */
                evas_object_image_native_surface_set(evas_info->eo, &surf);
 
                LOGD("flush_buffer surf(%p), rotate(%d), flip(%d)", evas_info->flush_buffer->tbm_surf, evas_info->rotate_angle, evas_info->flip);
@@ -581,7 +585,7 @@ static int _flush_packets(mm_evas_info *evas_info)
        LOGD("sent packet %d", evas_info->sent_buffer_cnt);
 
        /* destroy all packets */
-       g_mutex_lock(&evas_info->mp_lock);
+       g_mutex_lock(&evas_info->idx_lock);
        for (i = 0; i < MAX_PACKET_NUM; i++) {
                if (evas_info->pkt_info[i].packet) {
                        LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
@@ -605,10 +609,9 @@ static int _flush_packets(mm_evas_info *evas_info)
                LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
        evas_info->sent_buffer_cnt = 0;
        evas_info->cur_idx = -1;
-       g_mutex_unlock(&evas_info->mp_lock);
+       g_mutex_unlock(&evas_info->idx_lock);
 
        evas_object_image_pixels_dirty_set(evas_info->eo, EINA_TRUE);
-       evas_info->retrieve_packet = FALSE;
 
        MMER_FLEAVE();
 
@@ -704,6 +707,8 @@ static int _mm_evas_renderer_create(mm_evas_info **evas_info)
        }
        g_mutex_init(&ptr->mp_lock);
        g_mutex_init(&ptr->idx_lock);
+       g_mutex_init(&ptr->write_lock);
+
 
        MMER_FLEAVE();
 
@@ -727,6 +732,8 @@ static int _mm_evas_renderer_destroy(mm_evas_info **evas_info)
        ret = _mm_evas_renderer_reset(ptr);
        g_mutex_clear(&ptr->mp_lock);
        g_mutex_clear(&ptr->idx_lock);
+       g_mutex_clear(&ptr->write_lock);
+
 
        g_free(ptr);
        ptr = NULL;
@@ -777,7 +784,7 @@ static int _mm_evas_renderer_reset(mm_evas_info *evas_info)
 {
        MMER_FENTER();
        MM_CHECK_NULL(evas_info);
-       g_mutex_lock(&evas_info->idx_lock);
+       g_mutex_lock(&evas_info->mp_lock);
 
        int i;
        int ret = MM_ERROR_NONE;
@@ -801,7 +808,7 @@ static int _mm_evas_renderer_reset(mm_evas_info *evas_info)
        if (evas_info->flush_buffer)
                _mm_evas_renderer_release_flush_buffer(evas_info);
 
-       g_mutex_lock(&evas_info->mp_lock);
+       g_mutex_lock(&evas_info->idx_lock);
        for (i = 0; i < MAX_PACKET_NUM; i++) {
                if (evas_info->pkt_info[i].packet) {
                        /* destroy all packets */
@@ -821,13 +828,13 @@ static int _mm_evas_renderer_reset(mm_evas_info *evas_info)
                        evas_info->pkt_info[i].prev = -1;
                }
        }
-       g_mutex_unlock(&evas_info->mp_lock);
+       g_mutex_unlock(&evas_info->idx_lock);
        if (evas_info->sent_buffer_cnt != 0)
                LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
        evas_info->sent_buffer_cnt = 0;
        evas_info->cur_idx = -1;
 
-       g_mutex_unlock(&evas_info->idx_lock);
+       g_mutex_unlock(&evas_info->mp_lock);
 
        MMER_FLEAVE();
 
@@ -953,6 +960,7 @@ static int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info)
                LOGD("native surface exists");
                surf->data.tbm.rot = evas_info->rotate_angle;
                surf->data.tbm.flip = evas_info->flip;
+               /* surface set must be called by main thread */
                evas_object_image_native_surface_set(evas_info->eo, surf);
 
                _mm_evas_renderer_update_geometry(evas_info, &result);
@@ -985,27 +993,27 @@ static int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool
        pid_t pid = getpid();
        pid_t tid = syscall(SYS_gettid);
 
-       /* write and this API can be called at the same time.
-       so lock is needed for counting sent_buffer_cnt correctly */
-       g_mutex_lock(&evas_info->idx_lock);
+       /* this API can be call by sub thread */
+       LOGD("pid [%d], tid [%d]", pid, tid);
 
        /* make flush buffer */
        if (keep_screen)
                ret = _mm_evas_renderer_make_flush_buffer(evas_info);
        evas_info->keep_screen = keep_screen;
 
-       LOGD("pid [%d], tid [%d]", pid, tid);
-       if (pid == tid) {
-               /* in this case, we deem it is main thread */
-               if (_flush_packets(evas_info) != MM_ERROR_NONE) {
-                       LOGE("flushing packets is failed");
+       if (evas_info->epipe) {
+               g_mutex_lock(&evas_info->write_lock);
+               ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_FLUSH_BUFFER);
+               if (!ret) {
+                       LOGW("fail to ecore_pipe_write() for updating visibility\n");
                        ret = MM_ERROR_EVASRENDER_INTERNAL;
+               } else {
+                       ret = MM_ERROR_NONE;
                }
+               g_mutex_unlock(&evas_info->write_lock);
        } else {
-               /* it will be executed to write flush buffer and destroy media packets in pre_cb */
-               evas_info->retrieve_packet = TRUE;
+               LOGW("there is no epipe. we cant update it");
        }
-       g_mutex_unlock(&evas_info->idx_lock);
 
        MMER_FLEAVE();
 
@@ -1223,6 +1231,7 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
                handle->sent_buffer_cnt++;
                LOGD("sent packet %d", handle->sent_buffer_cnt);
 
+               g_mutex_lock(&handle->write_lock);
                ret = ecore_pipe_write(handle->epipe, handle, UPDATE_TBM_SURF);
                if (!ret) {
                        handle->pkt_info[index].packet = NULL;
@@ -1231,8 +1240,10 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
                        handle->cur_idx = handle->pkt_info[index].prev;
                        handle->sent_buffer_cnt--;
                        LOGW("Failed to ecore_pipe_write() for updating tbm surf\n");
+                       g_mutex_unlock(&handle->write_lock);
                        goto ERROR;
                }
+               g_mutex_unlock(&handle->write_lock);
        } else {
                LOGW("no tbm_surf");
                goto ERROR;
@@ -1327,13 +1338,15 @@ int mm_evas_renderer_set_visible(MMHandleType handle, bool visible)
        evas_info->visible = visible;
 
        if (evas_info->epipe) {
-               ret = ecore_pipe_write(evas_info->epipe, &visible, UPDATE_VISIBILITY);
+               g_mutex_lock(&evas_info->write_lock);
+               ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_VISIBILITY);
                if (!ret) {
                        LOGW("fail to ecore_pipe_write() for updating visibility\n");
                        ret = MM_ERROR_EVASRENDER_INTERNAL;
                } else {
                        ret = MM_ERROR_NONE;
                }
+               g_mutex_unlock(&evas_info->write_lock);
        } else {
                LOGW("there is no epipe. we cant update it");
        }
@@ -1397,7 +1410,7 @@ int mm_evas_renderer_set_rotation(MMHandleType handle, int rotate)
 
        /* FIXME: pause state only */
        if (evas_info->epipe) {
-               g_mutex_lock(&evas_info->idx_lock);
+               g_mutex_lock(&evas_info->write_lock);
                ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
                if (!ret) {
                        LOGW("fail to ecore_pipe_write() for updating visibility\n");
@@ -1405,7 +1418,7 @@ int mm_evas_renderer_set_rotation(MMHandleType handle, int rotate)
                } else {
                        ret = MM_ERROR_NONE;
                }
-               g_mutex_unlock(&evas_info->idx_lock);
+               g_mutex_unlock(&evas_info->write_lock);
        }
        MMER_FLEAVE();
 
@@ -1464,7 +1477,7 @@ int mm_evas_renderer_set_geometry(MMHandleType handle, int mode)
        /* ecore_pipe_write is needed, because of setting ratio for letterbox mode */
        /* FIXME: pause state only */
        if (evas_info->epipe) {
-               g_mutex_lock(&evas_info->idx_lock);
+               g_mutex_lock(&evas_info->write_lock);
                ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
                if (!ret) {
                        LOGW("fail to ecore_pipe_write() for updating visibility\n");
@@ -1472,7 +1485,7 @@ int mm_evas_renderer_set_geometry(MMHandleType handle, int mode)
                } else {
                        ret = MM_ERROR_NONE;
                }
-               g_mutex_unlock(&evas_info->idx_lock);
+               g_mutex_unlock(&evas_info->write_lock);
        }
        MMER_FLEAVE();
 
@@ -1527,7 +1540,7 @@ int mm_evas_renderer_set_roi_area(MMHandleType handle, int x, int y, int w, int
 
        /* pipe_write could be needed because ratio can be changed on pause state */
        if (evas_info->epipe) {
-               g_mutex_lock(&evas_info->idx_lock);
+               g_mutex_lock(&evas_info->write_lock);
                ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
                if (!ret) {
                        LOGW("fail to ecore_pipe_write() for updating visibility\n");
@@ -1535,7 +1548,7 @@ int mm_evas_renderer_set_roi_area(MMHandleType handle, int x, int y, int w, int
                } else {
                        ret = MM_ERROR_NONE;
                }
-               g_mutex_unlock(&evas_info->idx_lock);
+               g_mutex_unlock(&evas_info->write_lock);
        }
 
        MMER_FLEAVE();
@@ -1604,7 +1617,7 @@ int mm_evas_renderer_set_flip(MMHandleType handle, int flip)
 
        /* FIXME: pause state only */
        if (evas_info->epipe) {
-               g_mutex_lock(&evas_info->idx_lock);
+               g_mutex_lock(&evas_info->write_lock);
                ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
                if (!ret) {
                        LOGW("fail to ecore_pipe_write() for updating visibility\n");
@@ -1612,7 +1625,7 @@ int mm_evas_renderer_set_flip(MMHandleType handle, int flip)
                } else {
                        ret = MM_ERROR_NONE;
                }
-               g_mutex_unlock(&evas_info->idx_lock);
+               g_mutex_unlock(&evas_info->write_lock);
        }
 
        MMER_FLEAVE();