From: Hyunil Date: Tue, 21 Feb 2017 06:17:37 +0000 (+0900) Subject: Support flushing packet by calling sub thread X-Git-Tag: accepted/tizen/common/20170303.090915^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F23%2F115723%2F2;p=platform%2Fcore%2Fmultimedia%2Flibmm-evas-renderer.git Support flushing packet by calling sub thread Change-Id: I39c2ace47907911cf05e765b395f49b0e42d89c4 Signed-off-by: Hyunil --- diff --git a/packaging/libmm-evas-renderer.spec b/packaging/libmm-evas-renderer.spec index 7b04a05..cac9923 100644 --- a/packaging/libmm-evas-renderer.spec +++ b/packaging/libmm-evas-renderer.spec @@ -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 diff --git a/src/include/mm_evas_renderer.h b/src/include/mm_evas_renderer.h index 7e2df0f..83b1f26 100644 --- a/src/include/mm_evas_renderer.h +++ b/src/include/mm_evas_renderer.h @@ -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 */ diff --git a/src/mm_evas_renderer.c b/src/mm_evas_renderer.c index d50124e..d5b0d70 100755 --- a/src/mm_evas_renderer.c +++ b/src/mm_evas_renderer.c @@ -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();