X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftdm_buffer.c;h=97857b42fde613722c94980598bba9874a2dd528;hb=efb743bd507754d6c6b97a168b3af7316e1bfcc8;hp=149b944e2f1404b0e531c3729d6ded8c5488b4fc;hpb=7760ef17c78e7cbe8d2991c3b2f1bb02d8392d28;p=platform%2Fcore%2Fuifw%2Flibtdm.git diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 149b944..97857b4 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -1,255 +1,278 @@ /************************************************************************** - -libtdm - -Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: Eunchul Kim , - JinYoung Jeon , - Taeheon Kim , - YoungJun Cho , - SooChan Lim , - Boram Park - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "tdm.h" #include "tdm_private.h" -#include "tdm_list.h" static int tdm_buffer_key; #define TDM_BUFFER_KEY ((unsigned long)&tdm_buffer_key) -typedef struct _tdm_buffer_func_info -{ - tdm_buffer_release_handler release_func; - tdm_buffer_destroy_handler destroy_func; - void *user_data; +typedef struct _tdm_buffer_func_info { + tdm_buffer_release_handler release_func; + tdm_buffer_destroy_handler destroy_func; + void *user_data; - struct list_head link; + 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; -} 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; + 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) { + TDM_NEVER_GET_HERE(); + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("%p", buf_info->buffer); + } - if (buf_info->backend_ref_count > 0) - TDM_NEVER_GET_HERE(); + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) { + LIST_DEL(&func_info->link); + free(func_info); + } - LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) - { - LIST_DEL(&func_info->link); - free(func_info); - } + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) + func_info->destroy_func(buf_info->buffer, func_info->user_data); - LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) - func_info->destroy_func(buf_info->buffer, func_info->user_data); + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) { + LIST_DEL(&func_info->link); + free(func_info); + } - LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) - { - LIST_DEL(&func_info->link); - free(func_info); - } + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("%p destroyed", buf_info->buffer); - free(buf_info); + free(buf_info); } -static tdm_buffer_info* -_tdm_buffer_get_info(tbm_surface_h buffer) +INTERN tdm_buffer_info * +tdm_buffer_get_info(tbm_surface_h buffer) { - tdm_buffer_info *buf_info = NULL; - tbm_bo bo; - - bo = tbm_surface_internal_get_bo(buffer, 0); - TDM_RETURN_VAL_IF_FAIL(bo != NULL, NULL); - - tbm_bo_get_user_data(bo, TDM_BUFFER_KEY, (void**)&buf_info); - - if (!buf_info) - { - buf_info = calloc(1, sizeof(tdm_buffer_info)); - TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL); - - buf_info->buffer = buffer; - - LIST_INITHEAD(&buf_info->release_funcs); - LIST_INITHEAD(&buf_info->destroy_funcs); - - tbm_bo_add_user_data(bo, TDM_BUFFER_KEY, _tdm_buffer_destroy_info); - tbm_bo_set_user_data(bo, TDM_BUFFER_KEY, buf_info); - } - - return buf_info; + tdm_buffer_info *buf_info = NULL; + + if (!tbm_surface_internal_get_user_data(buffer, TDM_BUFFER_KEY, (void **)&buf_info)) { + buf_info = calloc(1, sizeof(tdm_buffer_info)); + TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL); + + buf_info->buffer = buffer; + + LIST_INITHEAD(&buf_info->release_funcs); + LIST_INITHEAD(&buf_info->destroy_funcs); + LIST_INITHEAD(&buf_info->link); + + if (!tbm_surface_internal_add_user_data(buffer, TDM_BUFFER_KEY, _tdm_buffer_destroy_info)) { + TDM_ERR("FAIL to create user_data for surface %p", buffer); + free(buf_info); + return NULL; + } + if (!tbm_surface_internal_set_user_data(buffer, TDM_BUFFER_KEY, buf_info)) { + TDM_ERR("FAIL to set user_data for surface %p", buffer); + tbm_surface_internal_delete_user_data(buffer, TDM_BUFFER_KEY); + free(buf_info); + return NULL; + } + + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("%p created", buf_info->buffer); + } + + return buf_info; } EXTERN tdm_error tdm_buffer_add_release_handler(tbm_surface_h buffer, - tdm_buffer_release_handler func, void *user_data) + tdm_buffer_release_handler func, void *user_data) { - tdm_buffer_info *buf_info; - tdm_buffer_func_info *func_info; + tdm_buffer_info *buf_info; + tdm_buffer_func_info *func_info = NULL; - TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); + 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); - TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY); + 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)); - TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY); + LIST_FOR_EACH_ENTRY(func_info, &buf_info->release_funcs, link) { + if (func_info->release_func == func && func_info->user_data == user_data) { + TDM_ERR("can't add twice"); + return TDM_ERROR_BAD_REQUEST; + } + } - func_info->release_func = func; - func_info->user_data = user_data; + func_info = calloc(1, sizeof(tdm_buffer_func_info)); + TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY); - LIST_ADD(&func_info->link, &buf_info->release_funcs); + func_info->release_func = func; + func_info->user_data = user_data; - return TDM_ERROR_NONE; + LIST_ADDTAIL(&func_info->link, &buf_info->release_funcs); + + return TDM_ERROR_NONE; } EXTERN void -tdm_buffer_remove_release_handler(tbm_surface_h buffer, tdm_buffer_release_handler func, void *user_data) +tdm_buffer_remove_release_handler(tbm_surface_h buffer, + tdm_buffer_release_handler func, void *user_data) { - tdm_buffer_info *buf_info; - tdm_buffer_func_info *func_info = NULL, *next = NULL; + tdm_buffer_info *buf_info; + tdm_buffer_func_info *func_info = NULL, *next = NULL; - TDM_RETURN_IF_FAIL(buffer != NULL); - TDM_RETURN_IF_FAIL(func != NULL); + TDM_RETURN_IF_FAIL(buffer != NULL); + TDM_RETURN_IF_FAIL(func != NULL); - buf_info = _tdm_buffer_get_info(buffer); - TDM_RETURN_IF_FAIL(buf_info != NULL); + 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) - { - if (func_info->release_func != func || func_info->user_data != user_data) - continue; + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) { + if (func_info->release_func != func || func_info->user_data != user_data) + continue; - LIST_DEL(&func_info->link); - free(func_info); + LIST_DEL(&func_info->link); + free(func_info); - return; - } + return; + } } - EXTERN tbm_surface_h tdm_buffer_ref_backend(tbm_surface_h buffer) { - tdm_buffer_info *buf_info; + tdm_buffer_info *buf_info; + + TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL); - TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL); + buf_info = tdm_buffer_get_info(buffer); + TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL); - 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); - buf_info->backend_ref_count++; + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("buffer(%p) backend_ref_count(%d)", buffer, buf_info->backend_ref_count); - return buffer; + return buffer; } EXTERN void tdm_buffer_unref_backend(tbm_surface_h buffer) { - tdm_buffer_info *buf_info; - tdm_buffer_func_info *func_info = NULL, *next = NULL; + tdm_buffer_info *buf_info; + tdm_buffer_func_info *func_info = NULL, *next = NULL; - TDM_RETURN_IF_FAIL(buffer != NULL); + TDM_RETURN_IF_FAIL(buffer != NULL); - buf_info = _tdm_buffer_get_info(buffer); - TDM_RETURN_IF_FAIL(buf_info != NULL); + buf_info = tdm_buffer_get_info(buffer); + TDM_RETURN_IF_FAIL(buf_info != NULL); - buf_info->backend_ref_count--; + buf_info->backend_ref_count--; - if (buf_info->backend_ref_count > 0) - return; + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("buffer(%p) backend_ref_count(%d)", buffer, buf_info->backend_ref_count); - 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); - } + if (buf_info->backend_ref_count > 0) { + tbm_surface_internal_unref(buffer); + return; + } + + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("buffer(%p) released", buffer); + + tbm_surface_internal_ref(buffer); + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) + func_info->release_func(buffer, func_info->user_data); + tbm_surface_internal_unref(buffer); + + tbm_surface_internal_unref(buffer); } EXTERN tdm_error -tdm_buffer_add_destroy_handler(tbm_surface_h buffer, tdm_buffer_destroy_handler func, void *user_data) +tdm_buffer_add_destroy_handler(tbm_surface_h buffer, + tdm_buffer_destroy_handler func, void *user_data) { - tdm_buffer_info *buf_info; - tdm_buffer_func_info *func_info; + tdm_buffer_info *buf_info; + tdm_buffer_func_info *func_info = NULL; - TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); + 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); - TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY); + 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)); - TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY); + LIST_FOR_EACH_ENTRY(func_info, &buf_info->destroy_funcs, link) { + if (func_info->destroy_func == func && func_info->user_data == user_data) { + TDM_ERR("can't add twice"); + return TDM_ERROR_BAD_REQUEST; + } + } - func_info->destroy_func = func; - func_info->user_data = user_data; + func_info = calloc(1, sizeof(tdm_buffer_func_info)); + TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY); - LIST_ADD(&func_info->link, &buf_info->destroy_funcs); + func_info->destroy_func = func; + func_info->user_data = user_data; - return TDM_ERROR_NONE; + LIST_ADDTAIL(&func_info->link, &buf_info->destroy_funcs); + + return TDM_ERROR_NONE; } EXTERN void -tdm_buffer_remove_destroy_handler(tbm_surface_h buffer, tdm_buffer_destroy_handler func, void *user_data) +tdm_buffer_remove_destroy_handler(tbm_surface_h buffer, + tdm_buffer_destroy_handler func, void *user_data) { - tdm_buffer_info *buf_info; - tdm_buffer_func_info *func_info = NULL, *next = NULL; + tdm_buffer_info *buf_info; + tdm_buffer_func_info *func_info = NULL, *next = NULL; - TDM_RETURN_IF_FAIL(buffer != NULL); - TDM_RETURN_IF_FAIL(func != NULL); + TDM_RETURN_IF_FAIL(buffer != NULL); + TDM_RETURN_IF_FAIL(func != NULL); - buf_info = _tdm_buffer_get_info(buffer); - TDM_RETURN_IF_FAIL(buf_info != NULL); + 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) - { - if (func_info->destroy_func != func || func_info->user_data != user_data) - continue; + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) { + if (func_info->destroy_func != func || func_info->user_data != user_data) + continue; - LIST_DEL(&func_info->link); - free(func_info); + LIST_DEL(&func_info->link); + free(func_info); - return; - } + return; + } } +