From c7a1e27882423a5c106cb0c0f7ed653959563648 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 2 Sep 2016 10:08:53 +0900 Subject: [PATCH 01/16] fix the layer's crop rect Change-Id: Id618bbbb7a026a631d1db0f72f4ae8472a471c42 --- tools/tdm_test_server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index d59c6ce..3e4e797 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -1223,6 +1223,8 @@ pp_setup(tdm_test_server_pp *p, tbm_surface_h sb, tbm_surface_h db) printf(" fps(%d) transform(%s)\n", p->fps, tdm_transform_str(p->info.transform)); printf("\toutput_idx(%d) layer_idx(%d)\n", p->l->o->idx, p->l->idx); + p->l->info.src_config = p->info.dst_config; + layer_setup(p->l, db); /* tdm_event_loop_xxx() function is not for the display server. It's for TDM @@ -1343,6 +1345,8 @@ capture_setup(tdm_test_server_capture *c, tbm_surface_h b) printf(" transform(%s)\n", tdm_transform_str(c->info.transform)); printf("\toutput_idx(%d) layer_idx(%d)\n", c->l->o->idx, c->l->idx); + c->l->info.src_config = c->info.dst_config; + layer_setup(c->l, b); } -- 2.7.4 From 412e9698d51d36edb5390c391ce73d54f2beb3ad Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 2 Sep 2016 15:55:42 +0900 Subject: [PATCH 02/16] Revert "fix the layer's crop rect" we can set the layer's crop rect with -l option. we don't need this patch. This reverts commit c7a1e27882423a5c106cb0c0f7ed653959563648. Change-Id: Iabbb4458c003005e583fd587bf5ba84aed860a4e --- tools/tdm_test_server.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index 3e4e797..d59c6ce 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -1223,8 +1223,6 @@ pp_setup(tdm_test_server_pp *p, tbm_surface_h sb, tbm_surface_h db) printf(" fps(%d) transform(%s)\n", p->fps, tdm_transform_str(p->info.transform)); printf("\toutput_idx(%d) layer_idx(%d)\n", p->l->o->idx, p->l->idx); - p->l->info.src_config = p->info.dst_config; - layer_setup(p->l, db); /* tdm_event_loop_xxx() function is not for the display server. It's for TDM @@ -1345,8 +1343,6 @@ capture_setup(tdm_test_server_capture *c, tbm_surface_h b) printf(" transform(%s)\n", tdm_transform_str(c->info.transform)); printf("\toutput_idx(%d) layer_idx(%d)\n", c->l->o->idx, c->l->idx); - c->l->info.src_config = c->info.dst_config; - layer_setup(c->l, b); } -- 2.7.4 From a839cbdd816b1153003f16a9a6b3c4ca129b1602 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 2 Sep 2016 16:47:27 +0900 Subject: [PATCH 03/16] correct the wrong behavior when the sequence value reaches the MAX(4,294,967,295) - The sequence value of tdm client vblank will start 1 always. - When the sequence reaches MAX, then it will become 0 at the next vblank. Change-Id: Ie66cf5ac717246e309e6e2d86eb5c0b1fc2e71c7 --- client/tdm_client.h | 2 -- src/tdm_vblank.c | 64 ++++++++++++++++++++++++----------------------------- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/client/tdm_client.h b/client/tdm_client.h index 1c2ef7d..e7df780 100644 --- a/client/tdm_client.h +++ b/client/tdm_client.h @@ -385,8 +385,6 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli * #tdm_client_vblank_set_enable_fake sets true. Once #tdm_client_vblank_wait_seq * returns TDM_ERROR_NONE, the user client vblank handler(#tdm_client_vblank_handler) * SHOULD be called on reaching the target sequence. - * If the sequence value is 0, the result will be the same with calling - * #tdm_client_vblank_wait with (interval = 1). * @param[in] vblank The client vblank object * @param[in] sequence The target sequence number * @param[in] func The user client vblank handler diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 8ff13e5..777a5ff 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -52,6 +52,16 @@ * - use a tdm_event_loop_source object only. */ +#define TDM_VBLANK_UINT_MAX 4294967295U +#define TDM_VBLANK_UINT_1Q 1073741823U /* UINT_MAX / 4 */ +#define TDM_VBLANK_UINT_3Q 3221225471U /* UINT_MAX / 4 * 3 */ + +/* (seq < TDM_VBLANK_UINT_1Q && TDM_VBLANK_UINT_3Q < last_seq) means + * that the sequence value has reached the max value and started from 0 again. + */ +#define TDM_VBLANK_SEQ_REACHED_MAX(seq, last_seq) \ + ((seq) < TDM_VBLANK_UINT_1Q && TDM_VBLANK_UINT_3Q < (last_seq)) + #define VER(fmt, arg...) TDM_ERR("[%p] "fmt, private_vblank, ##arg) #define VWR(fmt, arg...) TDM_WRN("[%p] "fmt, private_vblank, ##arg) #define VIN(fmt, arg...) TDM_INFO("[%p] "fmt, private_vblank, ##arg) @@ -89,7 +99,6 @@ typedef struct _tdm_private_vblank { /* for HW */ double HW_vblank_gap; struct list_head HW_wait_list; - unsigned int HW_seq_margin; /* for SW */ tdm_event_loop_source *SW_timer; @@ -508,24 +517,6 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, return; } - /* sequence is the relative value of fps. If fps = 10, sequence should be - * increased by 10 during 1 second. - */ - sequence /= private_vblank->quotient; - - /* If VBLANK_TYPE_SW_FAKE, HW sequeuce can become less than SW sequeuce. - * so we will correct it with HW_seq_margin. - */ - if (private_vblank->last_seq > sequence) { - unsigned long last, tv; - last = (unsigned long)private_vblank->last_tv_sec * 1000000 + private_vblank->last_tv_usec; - tv = (unsigned long)tv_sec * 1000000 + tv_usec; - private_vblank->HW_seq_margin = ((tv - last) / (unsigned long)private_vblank->vblank_gap) + 1; - private_vblank->HW_seq_margin += private_vblank->last_seq - sequence; - } - - sequence += private_vblank->HW_seq_margin; - if (wait_info->type == VBLANK_TYPE_HW_SW) { unsigned long target; tdm_error ret; @@ -535,7 +526,6 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, target = (unsigned long)tv_sec * 1000000 + tv_usec; target += (private_vblank->offset * 1000); - wait_info->target_seq = sequence; wait_info->target_sec = target / 1000000; wait_info->target_usec = target % 1000000; @@ -554,14 +544,14 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, } if (tdm_debug_module & TDM_DEBUG_VBLANK) - VIN("wait(%p) sequence(%u) done", wait_info, sequence); + VIN("wait(%p) sequence(%u) done", wait_info, wait_info->target_seq); - private_vblank->last_seq = sequence; + private_vblank->last_seq = wait_info->target_seq; private_vblank->last_tv_sec = tv_sec; private_vblank->last_tv_usec = tv_usec; if (wait_info->func) - wait_info->func(private_vblank, TDM_ERROR_NONE, sequence, + wait_info->func(private_vblank, TDM_ERROR_NONE, wait_info->target_seq, tv_sec, tv_usec, wait_info->user_data); LIST_DEL(&wait_info->link); @@ -580,10 +570,11 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) hw_interval = wait_info->interval * private_vblank->quotient; - if (private_vblank->last_tv_sec != 0) { - unsigned long last, prev, req, curr; + if (private_vblank->last_tv_sec == 0) + wait_info->target_seq = 1; + else { + unsigned long last, prev, req, curr, target; unsigned int skip = 0; - unsigned int hw_skip; last = (unsigned long)private_vblank->last_tv_sec * 1000000 + private_vblank->last_tv_usec; req = (unsigned long)wait_info->req_sec * 1000000 + wait_info->req_usec; @@ -592,9 +583,14 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) prev = last + skip * private_vblank->vblank_gap; curr = tdm_helper_get_time_in_micros(); - hw_skip = (unsigned int)((curr - prev) / private_vblank->HW_vblank_gap); + target = prev; + while (target < curr) + target += private_vblank->vblank_gap; + + hw_interval = (unsigned int)((target - curr) / private_vblank->HW_vblank_gap) + 1; - hw_interval -= hw_skip; + wait_info->target_seq = private_vblank->last_seq; + wait_info->target_seq += (target - last) / (unsigned long)private_vblank->vblank_gap; if (tdm_debug_module & TDM_DEBUG_VBLANK) VIN("wait(%p) last(%4lu) req(%4lu) prev(%4lu) curr(%4lu) skip(%d) hw_interval(%d)", @@ -602,9 +598,6 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) skip, hw_interval); } - if (hw_interval < 1) - hw_interval = 1; - ret = tdm_output_wait_vblank(private_vblank->output, hw_interval, 0, _tdm_vblank_cb_vblank_HW, wait_info); @@ -802,12 +795,13 @@ tdm_vblank_wait_seq(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_u TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); - if (sequence == 0) { - interval = 1; - } else if (private_vblank->last_seq == 0) { + /* if the sequence of vblank reaches the max value, sequence can be 0. */ + + if (private_vblank->last_seq == 0) { TDM_WRN("can't calculate interval with sequence(%u)", sequence); interval = 1; - } else if (sequence > private_vblank->last_seq) { + } else if (sequence > private_vblank->last_seq || + TDM_VBLANK_SEQ_REACHED_MAX(sequence, private_vblank->last_seq)) { unsigned long last, curr, seq_target; last = (unsigned long)private_vblank->last_tv_sec * 1000000 + private_vblank->last_tv_usec; -- 2.7.4 From 4d8e77f316461dd71fcdedaca6287850b61f9bb9 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 5 Sep 2016 09:36:04 +0900 Subject: [PATCH 04/16] packaging: version up to 1.4.1 Change-Id: I1ce41b74b145cd04645aad4cf135209787ce136f --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 2817a78..09f770a 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,5 +1,5 @@ Name: libtdm -Version: 1.4.0 +Version: 1.4.1 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From fdfaec9a35e9070061c6b58e96c78f8787a478e2 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 6 Sep 2016 11:49:25 +0900 Subject: [PATCH 05/16] set request time to current time if 0 Change-Id: Ib1a02d1863e108f36dc402427d988de134d129f5 --- src/tdm_vblank.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 777a5ff..d652925 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -736,6 +736,13 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, return TDM_ERROR_OUT_OF_MEMORY; } + /* set request time to current time if 0. This function seems to be called in server side. */ + if (req_sec == 0 && req_usec == 0) { + unsigned long curr = tdm_helper_get_time_in_micros(); + req_sec = curr / 1000000; + req_usec = curr % 1000000; + } + LIST_INITHEAD(&wait_info->link); LIST_ADDTAIL(&wait_info->valid_link, &valid_wait_list); wait_info->stamp = ++stamp; -- 2.7.4 From 1ee56b583cbad79312acd5c2360dd7987082eda8 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 6 Sep 2016 11:53:21 +0900 Subject: [PATCH 06/16] enhance debugging log Change-Id: Ie4b0ec51db5defc266b76d352176ecc368593d33 --- src/tdm_vblank.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index d652925..03947d2 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -464,7 +464,7 @@ _tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank) if (ms_delay < 1) ms_delay = 1; - if (tdm_debug_module & TDM_DEBUG_VBLANK) + if (tdm_debug_module & TDM_DEBUG_VBLANK || ms_delay > 5000) VIN("wait(%p) curr(%4lu) target(%4lu) ms_delay(%d)", first_wait_info, curr, target, ms_delay); @@ -592,7 +592,7 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) wait_info->target_seq = private_vblank->last_seq; wait_info->target_seq += (target - last) / (unsigned long)private_vblank->vblank_gap; - if (tdm_debug_module & TDM_DEBUG_VBLANK) + if (tdm_debug_module & TDM_DEBUG_VBLANK || hw_interval > 300) VIN("wait(%p) last(%4lu) req(%4lu) prev(%4lu) curr(%4lu) skip(%d) hw_interval(%d)", wait_info, last, req - last, prev - last, curr - last, skip, hw_interval); -- 2.7.4 From 7a9f9a94ac10db94e996bee29568690ac8a8a5c4 Mon Sep 17 00:00:00 2001 From: Konstantin Drabeniuk Date: Mon, 12 Sep 2016 17:25:31 +0300 Subject: [PATCH 07/16] [libtdm] Move unit tests from ws-testcase and change test framework 1) change unit testing framework (Check to gtest); 2) move unit test from the ws-testcase project to the project libtdm. Change-Id: If3548b87c8e39108ec2ff7050f6c6324ec8cfaeb Signed-off-by: Konstantin Drabeniuk --- Makefile.am | 5 + configure.ac | 10 +- packaging/libtdm.spec | 21 +- ut/Makefile.am | 37 + ut/src/main_tests.cpp | 35 + ut/src/ut_tdm.cpp | 201 ++ ut/src/ut_tdm_backend.cpp | 270 ++ ut/src/ut_tdm_buffer.cpp | 266 ++ ut/src/ut_tdm_capture.cpp | 464 ++++ ut/src/ut_tdm_display.cpp | 3393 +++++++++++++++++++++++ ut/src/ut_tdm_event_loop.cpp | 424 +++ ut/src/ut_tdm_helper.cpp | 136 + ut/src/ut_tdm_pp.cpp | 263 ++ ut/stubs/pthread_stubs.h | 23 + ut/stubs/stdlib_stubs.h | 34 + ut/stubs/tbm_bufmgr.h | 1025 +++++++ ut/stubs/tbm_stubs.cpp | 110 + ut/stubs/tbm_stubs.h | 36 + ut/stubs/tbm_surface.h | 742 +++++ ut/stubs/tbm_surface_internal.h | 367 +++ ut/stubs/tbm_surface_queue.h | 125 + ut/stubs/tbm_type.h | 26 + ut/stubs/tdm_capture_stubs.h | 79 + ut/stubs/tdm_display_stubs.h | 269 ++ ut/stubs/tdm_helper_stubs.h | 47 + ut/stubs/tdm_list_stubs.h | 78 + ut/stubs/tdm_log.cpp | 26 + ut/stubs/tdm_pp_stubs.h | 50 + ut/stubs/tdm_server.cpp | 12 + ut/stubs/tdm_thread.cpp | 39 + ut/stubs/tdm_vblank.cpp | 123 + ut/stubs/wayland-server-core.h | 210 ++ ut/stubs/wayland-tbm-drm-auth-client-protocol.h | 50 + 33 files changed, 8994 insertions(+), 2 deletions(-) create mode 100644 ut/Makefile.am create mode 100644 ut/src/main_tests.cpp create mode 100644 ut/src/ut_tdm.cpp create mode 100644 ut/src/ut_tdm_backend.cpp create mode 100644 ut/src/ut_tdm_buffer.cpp create mode 100644 ut/src/ut_tdm_capture.cpp create mode 100644 ut/src/ut_tdm_display.cpp create mode 100644 ut/src/ut_tdm_event_loop.cpp create mode 100644 ut/src/ut_tdm_helper.cpp create mode 100644 ut/src/ut_tdm_pp.cpp create mode 100644 ut/stubs/pthread_stubs.h create mode 100644 ut/stubs/stdlib_stubs.h create mode 100644 ut/stubs/tbm_bufmgr.h create mode 100644 ut/stubs/tbm_stubs.cpp create mode 100644 ut/stubs/tbm_stubs.h create mode 100644 ut/stubs/tbm_surface.h create mode 100644 ut/stubs/tbm_surface_internal.h create mode 100644 ut/stubs/tbm_surface_queue.h create mode 100644 ut/stubs/tbm_type.h create mode 100644 ut/stubs/tdm_capture_stubs.h create mode 100644 ut/stubs/tdm_display_stubs.h create mode 100644 ut/stubs/tdm_helper_stubs.h create mode 100644 ut/stubs/tdm_list_stubs.h create mode 100644 ut/stubs/tdm_log.cpp create mode 100644 ut/stubs/tdm_pp_stubs.h create mode 100644 ut/stubs/tdm_server.cpp create mode 100644 ut/stubs/tdm_thread.cpp create mode 100644 ut/stubs/tdm_vblank.cpp create mode 100644 ut/stubs/wayland-server-core.h create mode 100644 ut/stubs/wayland-tbm-drm-auth-client-protocol.h diff --git a/Makefile.am b/Makefile.am index 1908008..292911f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,9 @@ + +if HAVE_UTEST +SUBDIRS = . include protocol common src client tools ut +else SUBDIRS = . include protocol common src client tools +endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libtdm.pc diff --git a/configure.ac b/configure.ac index 9679295..f460e0a 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,7 @@ AM_MAINTAINER_MODE([enable]) # Check for programs AC_PROG_CC +AC_PROG_CXX AC_USE_SYSTEM_EXTENSIONS AC_SYS_LARGEFILE @@ -30,6 +31,12 @@ LT_INIT([disable-static]) # Enable quiet compiles on automake 1.11. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AC_ARG_WITH(utest, AS_HELP_STRING([--with-utest=yes/no], [whether build/run unit tests or not]), + [ utest="$withval" ], + [ utest="no" ]) + +AM_CONDITIONAL(HAVE_UTEST, test "x$utest" = "xyes") + AC_PATH_PROG([wayland_scanner], [wayland-scanner]) if test x$wayland_scanner = x; then AC_MSG_ERROR([wayland-scanner is needed to compile]) @@ -84,7 +91,8 @@ AC_OUTPUT([ src/Makefile client/libtdm-client.pc client/Makefile - tools/Makefile]) + tools/Makefile + ut/Makefile]) echo "" echo "$PACKAGE_STRING will be compiled with:" diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 09f770a..6a0a1cf 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,3 +1,5 @@ +%bcond_with utest + Name: libtdm Version: 1.4.1 Release: 0 @@ -12,6 +14,10 @@ BuildRequires: pkgconfig(ttrace) BuildRequires: pkgconfig(wayland-server) BuildRequires: pkgconfig(pixman-1) +%if %{with utest} +BuildRequires: gtest-devel +%endif + %description Common user library of Tizen Display Manager : libtdm front-end library @@ -56,11 +62,21 @@ This contains libtdm tools for fundamental testing cp %{SOURCE1001} . %build -%reconfigure --disable-static \ +UTEST="no" + +%if %{with utest} +UTEST="yes" +%endif + +%reconfigure --disable-static --with-utest=${UTEST} \ CFLAGS="${CFLAGS} -Wall -Werror" \ LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed" make %{?_smp_mflags} +%if %{with utest} +make -C ut check +%endif + %install rm -rf %{buildroot} mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license @@ -109,6 +125,9 @@ rm -f %{_unitdir_user}/default.target.wants/tdm-socket-user.path %{_unitdir}/tdm-socket.service %{_unitdir_user}/tdm-socket-user.path %{_unitdir_user}/tdm-socket-user.service +%if %{with utest} +%{_bindir}/ut +%endif %files devel %manifest %{name}.manifest diff --git a/ut/Makefile.am b/ut/Makefile.am new file mode 100644 index 0000000..4e6cd6f --- /dev/null +++ b/ut/Makefile.am @@ -0,0 +1,37 @@ +bin_PROGRAMS = ut + +ut_SOURCES = \ + src/main_tests.cpp \ + src/ut_tdm.cpp \ + src/ut_tdm_backend.cpp \ + src/ut_tdm_buffer.cpp \ + src/ut_tdm_capture.cpp \ + src/ut_tdm_display.cpp \ + src/ut_tdm_event_loop.cpp \ + src/ut_tdm_helper.cpp \ + src/ut_tdm_pp.cpp \ + stubs/tbm_stubs.cpp \ + stubs/tdm_log.cpp \ + stubs/tdm_thread.cpp \ + stubs/tdm_server.cpp \ + stubs/tdm_vblank.cpp + +ut_CXXFLAGS = \ + $(CXXFLAGS) \ + $(TDM_CFLAGS) \ + -I../src \ + -I../include \ + -I./src \ + -I./stubs \ + -fpermissive \ + -Wno-unused-variable + +ut_LDFLAGS = \ + ${LDFLAGS} \ + $(TDM_LIBS) \ + -lgtest \ + -ldl \ + -pthread + +check: + ./ut diff --git a/ut/src/main_tests.cpp b/ut/src/main_tests.cpp new file mode 100644 index 0000000..50d2725 --- /dev/null +++ b/ut/src/main_tests.cpp @@ -0,0 +1,35 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/ut/src/ut_tdm.cpp b/ut/src/ut_tdm.cpp new file mode 100644 index 0000000..17a5af3 --- /dev/null +++ b/ut/src/ut_tdm.cpp @@ -0,0 +1,201 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock + +#include "tdm.c" + +#include "tdm_private.h" + +static tdm_private_display ut_private_display; + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; + g_private_display = NULL; +} + +/* tdm_display_update */ + +TEST(tdm_display_update, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_update(NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_deinit */ + +TEST(tdm_display_deinit, work_flow_success_1) +{ + tdm_private_display *dpy; + unsigned int expected = 2; + unsigned int actual; + + _init_test(); + + dpy = calloc(1, sizeof(tdm_private_display)); + g_private_display = dpy; + dpy->init_count = 3; + + tdm_display_deinit(dpy); + + actual = dpy->init_count; + + free(dpy); + + ASSERT_NE(g_private_display, NULL); + ASSERT_EQ(actual, expected); +} + +/* tdm_display_init() */ +TEST(tdm_display_init, work_flow_success_7) +{ + int actual; + int expected = 1; + + _init_test(); + + PTHREAD_MUTEX_INIT_ERROR = 1; + FREE_CALLED = 0; + + tdm_display_init(NULL); + + actual = FREE_CALLED; + + ASSERT_EQ(actual, expected); +} + +TEST(tdm_display_init, work_flow_success_6) +{ + tdm_private_display *actual; + tdm_private_display *expected; + + _init_test(); + + PTHREAD_MUTEX_INIT_ERROR = 1; + + actual = tdm_display_init(NULL); + + expected = NULL; + + ASSERT_EQ(actual, expected); +} + +TEST(tdm_display_init, work_flow_success_5) +{ + tdm_error error; + tdm_error expected_error; + + _init_test(); + + error = TDM_ERROR_BAD_REQUEST; + PTHREAD_MUTEX_INIT_ERROR = 1; + + tdm_display_init(&error); + + expected_error = TDM_ERROR_OPERATION_FAILED; + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_init, work_flow_success_4) +{ + tdm_private_display *actual; + tdm_private_display *expected = NULL; + + _init_test(); + + CALLOC_ERROR = 1; + + actual = tdm_display_init(NULL); + + ASSERT_EQ(actual, expected); +} + +TEST(tdm_display_init, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_BAD_REQUEST; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + + _init_test(); + + CALLOC_ERROR = 1; + + tdm_display_init(&error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_init, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_BAD_REQUEST; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + g_private_display = &ut_private_display; + + tdm_display_init(&error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_init, work_flow_success_1) +{ + tdm_private_display *actual; + tdm_private_display *expected = &ut_private_display; + + _init_test(); + + g_private_display = &ut_private_display; + + actual = tdm_display_init(NULL); + + ASSERT_TRUE(actual == expected); +} diff --git a/ut/src/ut_tdm_backend.cpp b/ut/src/ut_tdm_backend.cpp new file mode 100644 index 0000000..79465d9 --- /dev/null +++ b/ut/src/ut_tdm_backend.cpp @@ -0,0 +1,270 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock + +#include "tdm_backend.c" + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; +} + +/* tdm_backend_register_func_capture */ + +TEST(tdm_backend_register_func_capture, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + tdm_func_capture func_capture; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + error = tdm_backend_register_func_capture(&dpy, &func_capture); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_capture, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_BAD_MODULE; + tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + error = tdm_backend_register_func_capture(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_capture, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_func_capture func_capture; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_capture(NULL, &func_capture); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_backend_register_func_pp */ + +TEST(tdm_backend_register_func_pp, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + tdm_func_pp func_pp; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + error = tdm_backend_register_func_pp(&dpy, &func_pp); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_pp, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_BAD_MODULE; + tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + error = tdm_backend_register_func_pp(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_pp, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_func_pp func_pp; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_pp(NULL, &func_pp); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_backend_register_func_layer */ + +TEST(tdm_backend_register_func_layer, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + tdm_func_layer func_layer; + tdm_backend_module module; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.module_data = &module; + + error = tdm_backend_register_func_layer(&dpy, &func_layer); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_layer, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_layer(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_layer, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_func_layer func_layer; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_layer(NULL, &func_layer); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_backend_register_func_output */ + +TEST(tdm_backend_register_func_output, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + tdm_func_output func_output; + tdm_backend_module module; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.module_data = &module; + + error = tdm_backend_register_func_output(&dpy, &func_output); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_output, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_output(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_output, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_func_output func_output; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_output(NULL, &func_output); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_backend_register_func_display */ + +TEST(tdm_backend_register_func_display, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + tdm_func_display func_display; + tdm_backend_module module; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.module_data = &module; + + error = tdm_backend_register_func_display(&dpy, &func_display); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_display, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_display(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_backend_register_func_display, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_func_display func_display; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_backend_register_func_display(NULL, &func_display); + + ASSERT_EQ(error, expected_error); +} diff --git a/ut/src/ut_tdm_buffer.cpp b/ut/src/ut_tdm_buffer.cpp new file mode 100644 index 0000000..7c37c2b --- /dev/null +++ b/ut/src/ut_tdm_buffer.cpp @@ -0,0 +1,266 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" +#include "tdm_list_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock + +#include "tdm_buffer.c" + +void tdm_buffer_release_handler_f(tbm_surface_h buffer, void *user_data) {} + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; +} + +/* tdm_buffer_list_get_first_entry */ + +TEST(tdm_buffer_list_get_first_entry, null_ptr_fail_1) +{ + tbm_surface_h expected = NULL; + tbm_surface_h actual; + + _init_test(); + + actual = tdm_buffer_list_get_first_entry(NULL); + + ASSERT_TRUE(actual == expected); +} + +/* tdm_buffer_ref_backend */ + +TEST(tdm_buffer_ref_backend, work_flow_success_2) +{ + struct _tbm_surface buffer; + tbm_surface_h not_expected = NULL; + tbm_surface_h actual; + + _init_test(); + + TBM_BO_GET_USER_DATA_NULL = 1; + CALLOC_RETURN_BUFFER = 1; + actual = tdm_buffer_ref_backend(&buffer); + + ASSERT_TRUE(actual != not_expected); +} + +TEST(tdm_buffer_ref_backend, work_flow_success_1) +{ + struct _tbm_surface buffer; + tbm_surface_h actual; + tbm_surface_h expected = NULL; + + _init_test(); + + TBM_BO_GET_USER_DATA_NULL = 1; + CALLOC_ERROR = 1; + + actual = tdm_buffer_ref_backend(&buffer); + + ASSERT_TRUE(actual == expected); +} + + +TEST(tdm_buffer_ref_backend, null_ptr_fail_1) +{ + tbm_surface_h expected = NULL; + tbm_surface_h actual; + + _init_test(); + + actual = tdm_buffer_ref_backend(NULL); + + ASSERT_TRUE(actual == expected); +} + +/* tdm_buffer_add_release_handler */ + +TEST(tdm_buffer_add_release_handler, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_BUSY; + struct _tbm_surface buffer; + int data = 1; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + error = + tdm_buffer_add_release_handler(&buffer, tdm_buffer_release_handler_f, + &data); + + ASSERT_EQ(error, expected_error); + +} + +TEST(tdm_buffer_add_release_handler, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tbm_surface buffer; + int data = 1; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + + _init_test(); + + CALLOC_ERROR = 1; + error = + tdm_buffer_add_release_handler(&buffer, tdm_buffer_release_handler_f, + &data); + + ASSERT_EQ(error, expected_error); + +} + +TEST(tdm_buffer_add_release_handler, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tbm_surface buffer; + int data = 1; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + + _init_test(); + + TBM_BO_GET_USER_DATA_NULL = 1; + CALLOC_ERROR = 1; + error = + tdm_buffer_add_release_handler(&buffer, tdm_buffer_release_handler_f, + &data); + + ASSERT_EQ(error, expected_error); + +} + +TEST(tdm_buffer_add_release_handler, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tbm_surface buffer; + int data = 1; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + + _init_test(); + + TBM_BO_GET_USER_DATA_NULL = 1; + CALLOC_ERROR = 1; + error = + tdm_buffer_add_release_handler(&buffer, tdm_buffer_release_handler_f, + &data); + + ASSERT_EQ(error, expected_error); + +} + +TEST(tdm_buffer_add_release_handler, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tbm_surface buffer; + int data = 1; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_buffer_add_release_handler(&buffer, NULL, &data); + + ASSERT_EQ(error, expected_error); + +} + +TEST(tdm_buffer_add_release_handler, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + int data = 1; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = + tdm_buffer_add_release_handler(NULL, tdm_buffer_release_handler_f, + &data); + + ASSERT_EQ(error, expected_error); + +} + +/* tdm_buffer_get_info */ + +TEST(tdm_buffer_get_info, work_flow_success_3) +{ + struct _tbm_surface buffer; + tdm_buffer_info *actual; + tdm_buffer_info *not_expected = NULL; + + _init_test(); + + TBM_BO_GET_USER_DATA_NULL = 1; + + actual = tdm_buffer_get_info(&buffer); + + ASSERT_TRUE(actual != not_expected); + free(actual); +} + +TEST(tdm_buffer_get_info, work_flow_success_2) +{ + struct _tbm_surface buffer; + tdm_buffer_info *actual; + tdm_buffer_info *expected = NULL; + + _init_test(); + + TBM_BO_GET_USER_DATA_NULL = 1; + CALLOC_ERROR = 1; + actual = tdm_buffer_get_info(&buffer); + + ASSERT_TRUE(actual == expected); +} + +TEST(tdm_buffer_get_info, work_flow_success_1) +{ + struct _tbm_surface buffer; + tdm_buffer_info *not_expected = NULL; + tdm_buffer_info *actual; + + _init_test(); + + actual = tdm_buffer_get_info(&buffer); + + ASSERT_TRUE(actual != not_expected); +} diff --git a/ut/src/ut_tdm_capture.cpp b/ut/src/ut_tdm_capture.cpp new file mode 100644 index 0000000..2671bb5 --- /dev/null +++ b/ut/src/ut_tdm_capture.cpp @@ -0,0 +1,464 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" +#include "tdm_list_stubs.h" +#include "tdm_capture_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock + +#include "tdm_capture.c" + +/* UNIT TESTS */ + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; + OUTPUT_CREATE_CAPTURE_ERROR = 0; + CAPTURE_SET_DONE_HANDLER_ERROR = 0; + LAYER_CREATE_CAPTURE_ERROR = 0; + CAPTURE_SET_INFO_ERROR = 0; + CAPTURE_ATTACH_ERROR = 0; + CAPTURE_COMMIT_ERROR = 0; +} + +/* tdm_capture_commit */ + +TEST(tdm_capture_commit, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_capture capture; + struct _tdm_private_display private_display; + tdm_private_output private_output; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + capture.private_display = &private_display; + private_display.func_capture.capture_commit = capture_commit; + CALLOC_RETURN_BUFFER = 1; + capture.private_output = &private_output; + private_output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_capture_commit(&capture); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_capture_commit, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_capture capture; + struct _tdm_private_display private_display; + tdm_private_output private_output; + tdm_error not_expected_error = TDM_ERROR_NONE; + + _init_test(); + + capture.private_display = &private_display; + private_display.func_capture.capture_commit = capture_commit; + CAPTURE_COMMIT_ERROR = 1; + capture.private_output = &private_output; + private_output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_capture_commit(&capture); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_capture_commit, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + struct _tdm_private_capture capture; + struct _tdm_private_display private_display; + tdm_private_output private_output; + + _init_test(); + + capture.private_display = &private_display; + private_display.func_capture.capture_commit = NULL; + capture.private_output = &private_output; + private_output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_capture_commit(&capture); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_capture_commit, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_BAD_REQUEST; + struct _tdm_private_capture capture; + struct _tdm_private_display private_display; + tdm_private_output private_output; + + _init_test(); + + capture.private_display = &private_display; + private_display.func_capture.capture_commit = NULL; + capture.private_output = &private_output; + private_output.current_dpms_value = TDM_OUTPUT_DPMS_OFF; + + error = tdm_capture_commit(&capture); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_capture_commit, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_capture_commit(NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_capture_attach */ + +TEST(tdm_capture_attach, null_ptr_fail_2) +{ + struct _tbm_surface buffer; + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_capture capture; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_capture_attach(&capture, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_capture_attach, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tbm_surface buffer; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_capture_attach(NULL, &buffer); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_capture_set_info */ + +TEST(tdm_capture_set_info, work_flow_success_2) +{ + tdm_info_capture info; + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_capture capture; + struct _tdm_private_display private_display; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + capture.private_display = &private_display; + private_display.func_capture.capture_set_info = capture_set_info; + + error = tdm_capture_set_info(&capture, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_capture_set_info, work_flow_success_1) +{ + tdm_info_capture info; + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_capture capture; + struct _tdm_private_display private_display; + tdm_error expected_error = TDM_ERROR_OPERATION_FAILED; + + _init_test(); + + capture.private_display = &private_display; + private_display.func_capture.capture_set_info = capture_set_info; + CAPTURE_SET_INFO_ERROR = 1; + + error = tdm_capture_set_info(&capture, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_capture_set_info, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_capture capture; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_capture_set_info(&capture, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_capture_set_info, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_info_capture info; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_capture_set_info(NULL, &info); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_capture_create_layer_internal */ + +TEST(tdm_capture_create_layer_internal, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_layer private_layer; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *not_expected = NULL; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + private_layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_create_capture = layer_create_capture; + private_display.func_capture.capture_destroy = capture_destroy; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + actual = tdm_capture_create_layer_internal(&private_layer, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual != not_expected); + free(actual); +} + +TEST(tdm_capture_create_layer_internal, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_layer private_layer; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *expected = NULL; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + + _init_test(); + + private_layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_create_capture = layer_create_capture; + private_display.func_capture.capture_destroy = capture_destroy; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + CALLOC_ERROR = 1; + + actual = tdm_capture_create_layer_internal(&private_layer, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual == expected); +} + +TEST(tdm_capture_create_layer_internal, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_layer private_layer; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *expected = NULL; + + _init_test(); + + private_layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_create_capture = layer_create_capture; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + LAYER_CREATE_CAPTURE_ERROR = 1; + + actual = tdm_capture_create_layer_internal(&private_layer, &error); + + ASSERT_TRUE(actual == expected); +} + +TEST(tdm_capture_create_layer_internal, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_layer private_layer; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *expected = NULL; + tdm_error expected_error = TDM_ERROR_NO_CAPABILITY; + + _init_test(); + + private_layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_PP; + + actual = tdm_capture_create_layer_internal(&private_layer, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual == expected); +} + +/* tc_tdm_capture_create_output_internal */ + +TEST(tdm_capture_create_output_internal, work_flow_success_5) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *not_expected = NULL; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + private_output.private_display = &private_display; + private_display.func_output.output_create_capture = output_create_capture; + private_display.func_capture.capture_destroy = capture_destroy; + private_display.func_capture.capture_set_done_handler = + capture_set_done_handler; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + actual = tdm_capture_create_output_internal(&private_output, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual != not_expected); + free(actual); +} + +TEST(tdm_capture_create_output_internal, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *expected = NULL; + tdm_error expected_error = TDM_ERROR_OPERATION_FAILED; + + _init_test(); + + private_output.private_display = &private_display; + private_display.func_output.output_create_capture = output_create_capture; + private_display.func_capture.capture_destroy = capture_destroy; + private_display.func_capture.capture_set_done_handler = capture_set_done_handler; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + CAPTURE_SET_DONE_HANDLER_ERROR = 1; + + actual = tdm_capture_create_output_internal(&private_output, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual == expected); +} + +TEST(tdm_capture_create_output_internal, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *expected = NULL; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + + _init_test(); + + private_output.private_display = &private_display; + private_display.func_output.output_create_capture = output_create_capture; + private_display.func_capture.capture_destroy = capture_destroy; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + CALLOC_ERROR = 1; + + actual = tdm_capture_create_output_internal(&private_output, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual == expected); +} + +TEST(tdm_capture_create_output_internal, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *expected = NULL; + tdm_error expected_error = TDM_ERROR_OPERATION_FAILED; + + _init_test(); + + private_output.private_display = &private_display; + private_display.func_output.output_create_capture = output_create_capture; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + OUTPUT_CREATE_CAPTURE_ERROR = 1; + + actual = tdm_capture_create_output_internal(&private_output, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual == expected); +} + +TEST(tdm_capture_create_output_internal, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_output private_output; + struct _tdm_private_display private_display; + tdm_private_capture *actual; + tdm_private_capture *expected = NULL; + tdm_error expected_error = TDM_ERROR_NO_CAPABILITY; + + _init_test(); + + private_output.private_display = &private_display; + private_display.capabilities = TDM_DISPLAY_CAPABILITY_PP; + actual = tdm_capture_create_output_internal(&private_output, &error); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(actual == expected); +} diff --git a/ut/src/ut_tdm_display.cpp b/ut/src/ut_tdm_display.cpp new file mode 100644 index 0000000..da51852 --- /dev/null +++ b/ut/src/ut_tdm_display.cpp @@ -0,0 +1,3393 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" +#include "tdm_list_stubs.h" +#include "tdm_display_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock +#define tdm_pp_create_internal ut_tdm_pp_create_internal +#define tdm_capture_create_output_internal ut_tdm_capture_create_output_internal +#define tdm_buffer_ref_backend ut_tdm_buffer_ref_backend +#define tdm_thread_get_fd ut_tdm_thread_get_fd +#define tdm_event_loop_get_fd ut_tdm_event_loop_get_fd +#define tdm_capture_create_layer_internal ut_tdm_capture_create_layer_internal +#define poll ut_poll +#define tdm_thread_handle_cb ut_tdm_thread_handle_cb +#define tdm_event_loop_dispatch ut_tdm_event_loop_dispatch + +#include "tdm_display.c" + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; + DISPLAY_GET_FD_ERROR = 0; + TDM_PP_CREATE_INTERNAL_ERROR = 0; + OUTPUT_SET_PROPERTY_ERROR = 0; + OUTPUT_GET_PROPERTY_ERROR = 0; + OUTPUT_WAIT_VBLANK_ERROR = 0; + OUTPUT_SET_VBLANK_HANDLER = 0; + OUTPUT_COMMIT_ERROR = 0; + OUTPUT_SET_COMMIT_HANDLER = 0; + OUTPUT_SET_MODE_ERROR = 0; + OUTPUT_SET_DPMS_ERROR = 0; + OUTPUT_GET_DPMS_ERROR = 0; + TDM_CAPTURE_CREATE_OUTPUT_INTENAL_ERROR = 0; + LAYER_SET_PROPERTY_ERROR = 0; + LAYER_GET_PROPERTY_ERROR = 0; + LAYER_SET_INFO_ERROR = 0; + LAYER_SET_BUFFER_ERROR = 0; + LAYER_UNSET_BUFFER_ERROR = 0; + LAYER_SET_VIDEO_POS_ERROR = 0; + CAPTURE_CREATE_LAYER_INTERNAL_ERROR = 0; + TDM_THREAD_HANDLE_ERROR = 0; + TDM_EVENT_LOOP_DISPATCH_ERROR = 0; +} + +/* UNIT TESTS */ + +/* tdm_layer_create_capture() */ + +TEST(tdm_layer_create_capture, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + tdm_layer_create_capture(&layer, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_create_capture, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + CAPTURE_CREATE_LAYER_INTERNAL_ERROR = 1; + + tdm_layer_create_capture(&layer, &error); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_create_capture, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + tdm_layer_create_capture(NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_set_video_pos() */ + +TEST(tdm_layer_set_video_pos, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_video_pos = layer_set_video_pos; + layer.caps.capabilities = TDM_LAYER_CAPABILITY_VIDEO; + + error = tdm_layer_set_video_pos(&layer, 5); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_video_pos, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_video_pos = layer_set_video_pos; + layer.caps.capabilities = TDM_LAYER_CAPABILITY_VIDEO; + LAYER_SET_VIDEO_POS_ERROR = 1; + + error = tdm_layer_set_video_pos(&layer, 5); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_set_video_pos, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_video_pos = NULL; + layer.caps.capabilities = TDM_LAYER_CAPABILITY_VIDEO; + + error = tdm_layer_set_video_pos(&layer, 5); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_video_pos, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + layer.caps.capabilities = TDM_LAYER_CAPABILITY_GRAPHIC; + + error = tdm_layer_set_video_pos(&layer, 5); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_video_pos, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_layer_set_video_pos(NULL, 5); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_is_usable() */ + +TEST(tdm_layer_is_usable, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + unsigned int usable = rand(); + unsigned int expected_usable = rand(); + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + layer.usable = expected_usable; + + error = tdm_layer_is_usable(&layer, &usable); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(usable, expected_usable); +} + +TEST(tdm_layer_is_usable, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_is_usable(&layer, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_is_usable, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + unsigned int usable = rand(); + + _init_test(); + + error = tdm_layer_is_usable(NULL, &usable); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_unset_buffer_queue() */ + +TEST(tdm_layer_unset_buffer_queue, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + layer.waiting_buffer = NULL; + layer.showing_buffer = NULL; + private_display.func_layer.layer_unset_buffer = layer_unset_buffer; + + error = tdm_layer_unset_buffer_queue(&layer); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_unset_buffer_queue, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + layer.waiting_buffer = NULL; + layer.showing_buffer = NULL; + private_display.func_layer.layer_unset_buffer = layer_unset_buffer; + LAYER_UNSET_BUFFER_ERROR = 1; + + error = tdm_layer_unset_buffer_queue(&layer); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_unset_buffer_queue, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + layer.waiting_buffer = NULL; + layer.showing_buffer = NULL; + private_display.func_layer.layer_unset_buffer = NULL; + + error = tdm_layer_unset_buffer_queue(&layer); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_unset_buffer_queue, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_layer_unset_buffer_queue(NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_set_buffer_queue() */ + +TEST(tdm_layer_set_buffer_queue, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + struct _tbm_surface_queue buffer_queue; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_buffer = layer_set_buffer; + layer.buffer_queue = NULL; + layer.waiting_buffer = NULL; + + error = tdm_layer_set_buffer_queue(&layer, &buffer_queue); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_buffer_queue, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + struct _tbm_surface_queue buffer_queue; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_buffer = layer_set_buffer; + layer.buffer_queue = &buffer_queue; + + error = tdm_layer_set_buffer_queue(&layer, &buffer_queue); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_buffer_queue, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + struct _tbm_surface_queue buffer_queue; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_buffer = NULL; + + error = tdm_layer_set_buffer_queue(&layer, &buffer_queue); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_buffer_queue, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_set_buffer_queue(&layer, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_buffer_queue, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + struct _tbm_surface_queue buffer_queue; + + _init_test(); + + error = tdm_layer_set_buffer_queue(NULL, &buffer_queue); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_unset_buffer() */ + +TEST(tdm_layer_unset_buffer, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + layer.waiting_buffer = NULL; + layer.showing_buffer = NULL; + private_display.func_layer.layer_unset_buffer = layer_unset_buffer; + + error = tdm_layer_unset_buffer(&layer); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_unset_buffer, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + layer.waiting_buffer = NULL; + layer.showing_buffer = NULL; + private_display.func_layer.layer_unset_buffer = layer_unset_buffer; + LAYER_UNSET_BUFFER_ERROR = 1; + + error = tdm_layer_unset_buffer(&layer); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_unset_buffer, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + layer.waiting_buffer = NULL; + layer.showing_buffer = NULL; + private_display.func_layer.layer_unset_buffer = NULL; + + error = tdm_layer_unset_buffer(&layer); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_unset_buffer, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_layer_unset_buffer(NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_set_buffer() */ + +TEST(tdm_layer_set_buffer, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + struct _tbm_surface buffer; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + layer.waiting_buffer = NULL; + private_display.func_layer.layer_set_buffer = layer_set_buffer; + + error = tdm_layer_set_buffer(&layer, &buffer); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_buffer, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + struct _tbm_surface buffer; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_buffer = layer_set_buffer; + LAYER_SET_BUFFER_ERROR = 1; + + error = tdm_layer_set_buffer(&layer, &buffer); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_set_buffer, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + struct _tbm_surface buffer; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_buffer = NULL; + + error = tdm_layer_set_buffer(&layer, &buffer); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_buffer, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_set_buffer(&layer, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_buffer, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + struct _tbm_surface buffer; + + _init_test(); + + error = tdm_layer_set_buffer(NULL, &buffer); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_get_info() */ + +TEST(tdm_layer_get_info, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_info_layer info; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_get_info = layer_set_info; + + error = tdm_layer_get_info(&layer, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_info, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_info_layer info; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_get_info = layer_set_info; + LAYER_SET_INFO_ERROR = 1; + + error = tdm_layer_get_info(&layer, &info); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_get_info, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_info_layer info; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_get_info = NULL; + + error = tdm_layer_get_info(&layer, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_info, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_info(&layer, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_info, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_info_layer info; + + _init_test(); + + error = tdm_layer_get_info(NULL, &info); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_set_info() */ + +TEST(tdm_layer_set_info, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_info_layer info; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_info = layer_set_info; + + error = tdm_layer_set_info(&layer, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_info, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_info_layer info; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_info = layer_set_info; + LAYER_SET_INFO_ERROR = 1; + + error = tdm_layer_set_info(&layer, &info); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_set_info, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_info_layer info; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_info = NULL; + + error = tdm_layer_set_info(&layer, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_info, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_set_info(&layer, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_info, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_info_layer info; + + _init_test(); + + error = tdm_layer_set_info(NULL, &info); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_get_property() */ + +TEST(tdm_layer_get_property, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_get_property = layer_get_property; + + error = tdm_layer_get_property(&layer, 1, &value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_property, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_get_property = layer_get_property; + LAYER_GET_PROPERTY_ERROR = 1; + + error = tdm_layer_get_property(&layer, 1, &value); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_get_property, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_value value; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_get_property = NULL; + + error = tdm_layer_get_property(&layer, 1, &value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_property, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_property(&layer, 1, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_property, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_value value; + + _init_test(); + + error = tdm_layer_get_property(NULL, 1, &value); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_set_property() */ + +TEST(tdm_layer_set_property, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_property = layer_set_property; + + error = tdm_layer_set_property(&layer, 1, value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_property, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_property = layer_set_property; + LAYER_SET_PROPERTY_ERROR = 1; + + error = tdm_layer_set_property(&layer, 1, value); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_layer_set_property, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_value value; + tdm_private_layer layer; + tdm_private_output private_output; + tdm_private_display private_display; + + _init_test(); + + layer.private_output = &private_output; + private_output.private_display = &private_display; + private_display.func_layer.layer_set_property = NULL; + + error = tdm_layer_set_property(&layer, 1, value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_set_property, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_value value; + + _init_test(); + + error = tdm_layer_set_property(NULL, 1, value); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_get_zpos() */ + +TEST(tdm_layer_get_zpos, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + layer.private_output = &private_output; + unsigned int zpos; + unsigned int expected_zpos = 547; + + _init_test(); + + layer.caps.zpos = expected_zpos; + + error = tdm_layer_get_zpos(&layer, &zpos); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(zpos, expected_zpos); +} + +TEST(tdm_layer_get_zpos, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_zpos(&layer, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_zpos, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + unsigned int zpos; + + _init_test(); + + error = tdm_layer_get_zpos(NULL, &zpos); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_get_available_properties() */ + +TEST(tdm_layer_get_available_properties, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + const tdm_prop *props; + tdm_prop p; + int count; + tdm_prop *expected_props = &p; + int expected_count = 468; + + _init_test(); + + layer.private_output = &private_output; + layer.caps.props = expected_props; + layer.caps.prop_count = expected_count; + + error = tdm_layer_get_available_properties(&layer, &props, &count); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(props == expected_props); + ASSERT_EQ(count, expected_count); +} + +TEST(tdm_layer_get_available_properties, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + const tdm_prop *props; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_available_properties(&layer, &props, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_available_properties, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + int count; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_available_properties(&layer, NULL, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_available_properties, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + const tdm_prop *props; + int count; + + _init_test(); + + error = tdm_layer_get_available_properties(NULL, &props, &count); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_get_available_formats() */ + +TEST(tdm_layer_get_available_formats, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_layer layer; + tdm_private_output private_output; + const tbm_format *formats; + tbm_format f; + int count; + tbm_format *expected_formats = &f; + int expected_count = 468; + + _init_test(); + + layer.private_output = &private_output; + layer.caps.formats = expected_formats; + layer.caps.format_count = expected_count; + + error = tdm_layer_get_available_formats(&layer, &formats, &count); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(formats == expected_formats); + ASSERT_EQ(count, expected_count); +} + +TEST(tdm_layer_get_available_formats, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + const tbm_format *formats; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_available_formats(&layer, &formats, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_available_formats, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + int count; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_available_formats(&layer, NULL, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_available_formats, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + const tbm_format *formats; + int count; + + _init_test(); + + error = tdm_layer_get_available_formats(NULL, &formats, &count); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_layer_get_capabilities() */ + +TEST(tdm_layer_get_capabilities, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_layer_capability capabilities = TDM_LAYER_CAPABILITY_SCALE; + tdm_layer_capability expected_capabilities = TDM_LAYER_CAPABILITY_GRAPHIC; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + layer.caps.capabilities = expected_capabilities; + + error = tdm_layer_get_capabilities(&layer, &capabilities); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(capabilities, expected_capabilities); +} + +TEST(tdm_layer_get_capabilities, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_layer layer; + tdm_private_output private_output; + + _init_test(); + + layer.private_output = &private_output; + + error = tdm_layer_get_capabilities(&layer, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_layer_get_capabilities, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_layer_capability capabilities = TDM_LAYER_CAPABILITY_SCALE; + + _init_test(); + + error = tdm_layer_get_capabilities(NULL, &capabilities); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_create_capture() */ + +TEST(tdm_output_create_capture, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + + _init_test(); + + tdm_output_create_capture(&output, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_create_capture, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_output output; + + _init_test(); + + TDM_CAPTURE_CREATE_OUTPUT_INTENAL_ERROR = 1; + + tdm_output_create_capture(&output, &error); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_create_capture, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + tdm_output_create_capture(NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_dpms() */ + +TEST(tdm_output_get_dpms, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_output_dpms dpms_value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_get_dpms = output_get_dpms; + + error = tdm_output_get_dpms(&output, &dpms_value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_dpms, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_output_dpms dpms_value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_get_dpms = output_get_dpms; + OUTPUT_GET_DPMS_ERROR = 1; + + error = tdm_output_get_dpms(&output, &dpms_value); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_get_dpms, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_output_dpms dpms_value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_get_dpms = NULL; + + error = tdm_output_get_dpms(&output, &dpms_value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_dpms, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_output_dpms dpms_value; + + _init_test(); + + error = tdm_output_get_dpms(NULL, &dpms_value); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_set_dpms() */ + +TEST(tdm_output_set_dpms, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_output_dpms dpms_value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_dpms = output_set_dpms; + + error = tdm_output_set_dpms(&output, dpms_value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_set_dpms, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_output_dpms dpms_value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_dpms = output_set_dpms; + OUTPUT_SET_DPMS_ERROR = 1; + + error = tdm_output_set_dpms(&output, dpms_value); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_set_dpms, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_output_dpms dpms_value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_dpms = NULL; + + error = tdm_output_set_dpms(&output, dpms_value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_set_dpms, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_output_dpms dpms_value; + + _init_test(); + + error = tdm_output_set_dpms(NULL, dpms_value); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_mode() */ + +TEST(tdm_output_get_mode, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NONE; + const tdm_output_mode *mode; + tdm_private_output output; + tdm_output_mode expected_mode; + output.current_mode = &expected_mode; + + _init_test(); + + error = tdm_output_get_mode(&output, &mode); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(mode == &expected_mode); +} + +TEST(tdm_output_get_mode, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_mode(&output, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_mode, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + const tdm_output_mode *mode; + + _init_test(); + + error = tdm_output_get_mode(NULL, &mode); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_set_mode() */ + +TEST(tdm_output_set_mode, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_output_mode mode; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_mode = output_set_mode; + + error = tdm_output_set_mode(&output, &mode); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_set_mode, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_output_mode mode; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_mode = output_set_mode; + OUTPUT_SET_MODE_ERROR = 1; + + error = tdm_output_set_mode(&output, &mode); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_set_mode, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_output_mode mode; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_mode = NULL; + + error = tdm_output_set_mode(&output, &mode); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_set_mode, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_set_mode(&output, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_set_mode, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_output_mode mode; + + _init_test(); + + error = tdm_output_set_mode(NULL, &mode); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_commit() */ + +TEST(tdm_output_commit, work_flow_success_7) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_DPMS_OFF; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_commit = NULL; + output.current_dpms_value = TDM_OUTPUT_DPMS_OFF; + + error = tdm_output_commit(&output, 0, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_commit, work_flow_success_6) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_commit = output_commit; + private_display.func_output.output_set_commit_handler = + output_set_commit_handler; + output.regist_commit_cb = 1; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_commit(&output, 0, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_commit, work_flow_success_5) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_commit = output_commit; + private_display.func_output.output_set_commit_handler = + output_set_commit_handler; + output.regist_commit_cb = 0; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_commit(&output, 0, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_commit, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_commit = output_commit; + private_display.func_output.output_set_commit_handler = + output_set_commit_handler; + output.regist_commit_cb = 0; + OUTPUT_COMMIT_ERROR = 1; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_commit(&output, 0, NULL, NULL); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_commit, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_commit = output_commit; + OUTPUT_COMMIT_ERROR = 1; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_commit(&output, 0, NULL, NULL); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_commit, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_commit = output_commit; + CALLOC_ERROR = 1; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_commit(&output, 0, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_commit, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_commit = NULL; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_commit(&output, 0, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_commit, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_output_commit(NULL, 0, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + + +/* tdm_output_wait_vblank() */ + +TEST(tdm_output_wait_vblank, work_flow_success_7) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_DPMS_OFF; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_wait_vblank = NULL; + output.current_dpms_value = TDM_OUTPUT_DPMS_STANDBY; + + error = tdm_output_wait_vblank(&output, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_wait_vblank, work_flow_success_6) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_wait_vblank = output_wait_vblank; + private_display.func_output.output_set_vblank_handler = + output_set_vblank_handler; + output.regist_vblank_cb = 1; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_wait_vblank(&output, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_wait_vblank, work_flow_success_5) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_wait_vblank = output_wait_vblank; + private_display.func_output.output_set_vblank_handler = + output_set_vblank_handler; + output.regist_vblank_cb = 0; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_wait_vblank(&output, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_wait_vblank, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_wait_vblank = output_wait_vblank; + private_display.func_output.output_set_vblank_handler = + output_set_vblank_handler; + OUTPUT_SET_VBLANK_HANDLER = 1; + output.regist_vblank_cb = 0; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_wait_vblank(&output, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_wait_vblank, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_wait_vblank = output_wait_vblank; + OUTPUT_WAIT_VBLANK_ERROR = 1; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_wait_vblank(&output, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_wait_vblank, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_wait_vblank = output_wait_vblank; + CALLOC_ERROR = 1; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_wait_vblank(&output, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_wait_vblank, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_wait_vblank = NULL; + output.current_dpms_value = TDM_OUTPUT_DPMS_ON; + + error = tdm_output_wait_vblank(&output, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_wait_vblank, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_output_wait_vblank(NULL, 1, 1, + ut_tdm_output_vblank_handler, NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_property() */ + +TEST(tdm_output_get_property, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_get_property = output_get_property; + + error = tdm_output_get_property(&output, 1, &value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_property, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_get_property = output_get_property; + OUTPUT_GET_PROPERTY_ERROR = 1; + + error = tdm_output_get_property(&output, 1, &value); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_get_property, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_value value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_get_property = NULL; + + error = tdm_output_get_property(&output, 1, &value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_property, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_property(&output, 1, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_property, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_value value; + + _init_test(); + + error = tdm_output_get_property(NULL, 1, &value); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_set_property() */ + +TEST(tdm_output_set_property, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_property = output_set_property; + + error = tdm_output_set_property(&output, 1, value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_set_property, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_value value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_property = output_set_property; + OUTPUT_SET_PROPERTY_ERROR = 1; + + error = tdm_output_set_property(&output, 1, value); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_output_set_property, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_value value; + tdm_private_output output; + tdm_private_display private_display; + + _init_test(); + + output.private_display = &private_display; + private_display.func_output.output_set_property = NULL; + + error = tdm_output_set_property(&output, 1, value); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_set_property, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_value value; + + _init_test(); + + error = tdm_output_set_property(NULL, 1, value); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_pipe() */ + +TEST(tdm_output_get_pipe, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + unsigned int pipe; + unsigned int expected_pipe = 4869; + + _init_test(); + + output.pipe = expected_pipe; + + error = tdm_output_get_pipe(&output, &pipe); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(pipe, expected_pipe); +} + +TEST(tdm_output_get_pipe, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_pipe(&output, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_pipe, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + unsigned int pipe; + + _init_test(); + + error = tdm_output_get_pipe(NULL, &pipe); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_subpixel() */ + +TEST(tdm_output_get_subpixel, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + unsigned int subpixel; + unsigned int expected_subpixel = 4869; + + _init_test(); + + output.caps.subpixel = expected_subpixel; + + error = tdm_output_get_subpixel(&output, &subpixel); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(subpixel, expected_subpixel); +} + +TEST(tdm_output_get_subpixel, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_subpixel(&output, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_subpixel, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + unsigned int subpixel; + + _init_test(); + + error = tdm_output_get_subpixel(NULL, &subpixel); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_physical_size() */ + +TEST(tdm_output_get_physical_size, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + unsigned int mmWidth; + unsigned int expected_mmWidth = 445; + unsigned int mmHeight; + unsigned int expected_mmHeight = 4547; + + _init_test(); + + output.caps.mmWidth = expected_mmWidth; + output.caps.mmHeight = expected_mmHeight; + + error = tdm_output_get_physical_size(&output, &mmWidth, &mmHeight); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(mmWidth, expected_mmWidth); + ASSERT_EQ(mmHeight, expected_mmHeight); +} + +TEST(tdm_output_get_physical_size, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + unsigned int mmHeight; + unsigned int expected_mmHeight = 4547; + + _init_test(); + + output.caps.mmHeight = expected_mmHeight; + + error = tdm_output_get_physical_size(&output, NULL, &mmHeight); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(mmHeight, expected_mmHeight); +} + +TEST(tdm_output_get_physical_size, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + unsigned int mmWidth; + unsigned int expected_mmWidth = 445; + + _init_test(); + + output.caps.mmWidth = expected_mmWidth; + + error = tdm_output_get_physical_size(&output, &mmWidth, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(mmWidth, expected_mmWidth); +} + +TEST(tdm_output_get_physical_size, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_output_get_physical_size(NULL, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_available_size() */ + +TEST(tdm_output_get_available_size, work_flow_6) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + int min_w; + int expected_min_w = 200; + int min_h; + int expected_min_h = 100; + int max_w; + int expected_max_w = 2000; + int max_h; + int expected_max_h = 1000; + int preferred_align; + int expected_preferred_align = 456; + + _init_test(); + + output.caps.min_w = expected_min_w; + output.caps.min_h = expected_min_h; + output.caps.max_w = expected_max_w; + output.caps.max_h = expected_max_h; + output.caps.preferred_align = expected_preferred_align; + + error = tdm_output_get_available_size(&output, &min_w, &min_h, &max_w, + &max_h, &preferred_align); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(preferred_align, expected_preferred_align); + ASSERT_EQ(min_w, expected_min_w); + ASSERT_EQ(min_h, expected_min_h); + ASSERT_EQ(max_w, expected_max_w); + ASSERT_EQ(max_h, expected_max_h); + ASSERT_EQ(preferred_align, expected_preferred_align); +} + +TEST(tdm_output_get_available_size, work_flow_5) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + int preferred_align; + int expected_preferred_align = 456; + + _init_test(); + + output.caps.preferred_align = expected_preferred_align; + + error = tdm_output_get_available_size(&output, NULL, NULL, NULL, + NULL, &preferred_align); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(preferred_align, expected_preferred_align); +} + +TEST(tdm_output_get_available_size, work_flow_4) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + int max_h; + int expected_max_h = 1000; + + _init_test(); + + output.caps.max_h = expected_max_h; + + error = tdm_output_get_available_size(&output, NULL, NULL, NULL, + &max_h, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(max_h, expected_max_h); +} + +TEST(tdm_output_get_available_size, work_flow_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + int max_w; + int expected_max_w = 2000; + + _init_test(); + + output.caps.max_w = expected_max_w; + + error = tdm_output_get_available_size(&output, NULL, NULL, + &max_w, NULL, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(max_w, expected_max_w); +} + +TEST(tdm_output_get_available_size, work_flow_2) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + int min_h; + int expected_min_h = 100; + + _init_test(); + + output.caps.min_h = expected_min_h; + + error = tdm_output_get_available_size(&output, NULL, &min_h, + NULL, NULL, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(min_h, expected_min_h); +} + +TEST(tdm_output_get_available_size, work_flow_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + int min_w; + int expected_min_w = 200; + + _init_test(); + + output.caps.min_w = expected_min_w; + + error = tdm_output_get_available_size(&output, &min_w, NULL, + NULL, NULL, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(min_w, expected_min_w); +} + +TEST(tdm_output_get_available_size, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_output_get_available_size(NULL, NULL, NULL, NULL, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_available_modes() */ + +TEST(tdm_output_get_available_modes, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + const tdm_output_mode *modes; + int count; + tdm_output_mode m; + const tdm_output_mode *expected_modes = &m; + int expected_count = 14; + + _init_test(); + + output.caps.modes = &m; + output.caps.mode_count = expected_count; + + error = tdm_output_get_available_modes(&output, &modes, &count); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(modes == expected_modes); + ASSERT_EQ(count, expected_count); +} + +TEST(tdm_output_get_available_modes, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + const tdm_output_mode *modes; + + _init_test(); + + error = tdm_output_get_available_modes(&output, &modes, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_available_modes, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + int count; + + _init_test(); + + error = tdm_output_get_available_modes(&output, NULL, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_available_modes, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + const tdm_output_mode *modes; + int count; + + _init_test(); + + error = tdm_output_get_available_modes(NULL, &modes, &count); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_available_properties() */ + +TEST(tdm_output_get_available_properties, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + const tdm_prop *props; + int count; + tdm_prop p; + const tdm_prop *expected_props = &p; + int expected_count = 14; + + _init_test(); + + output.caps.props = &p; + output.caps.prop_count = expected_count; + + error = tdm_output_get_available_properties(&output, &props, &count); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(props == expected_props); + ASSERT_EQ(count, expected_count); +} + +TEST(tdm_output_get_available_properties, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + const tdm_prop *props; + + _init_test(); + + error = tdm_output_get_available_properties(&output, &props, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_available_properties, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + int count; + + _init_test(); + + error = tdm_output_get_available_properties(&output, NULL, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_available_properties, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + const tdm_prop *props; + int count; + + _init_test(); + + error = tdm_output_get_available_properties(NULL, &props, &count); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_layer() */ + +TEST(tdm_output_get_layer, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + + _init_test(); + + tdm_output_get_layer(&output, 1, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_layer, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + tdm_output_get_layer(NULL, 1, &error); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_layer_count() */ + +TEST(tdm_output_get_layer_count, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + int count; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_layer_count(&output, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_layer_count, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_layer_count(&output, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_layer_count, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + int count; + + _init_test(); + + error = tdm_output_get_layer_count(NULL, &count); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_output_type() */ + +TEST(tdm_output_get_output_type, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + tdm_output_type type = TDM_OUTPUT_TYPE_DVID; + tdm_output_type expected_type = TDM_OUTPUT_TYPE_VGA; + + _init_test(); + + output.caps.type = expected_type; + + error = tdm_output_get_output_type(&output, &type); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(type, expected_type); +} + +TEST(tdm_output_get_output_type, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_output_type(&output, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_output_type, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_output_type type = TDM_OUTPUT_TYPE_DVID; + + _init_test(); + + error = tdm_output_get_output_type(NULL, &type); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_conn_status() */ + +TEST(tdm_output_get_conn_status, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; + tdm_output_conn_status expected_status = TDM_OUTPUT_CONN_STATUS_CONNECTED; + tdm_private_output output; + + _init_test(); + + output.caps.status = TDM_OUTPUT_CONN_STATUS_CONNECTED; + + error = tdm_output_get_conn_status(&output, &status); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(status, expected_status); +} + +TEST(tdm_output_get_conn_status, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_conn_status(&output, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_conn_status, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_output_conn_status status; + + _init_test(); + + error = tdm_output_get_conn_status(NULL, &status); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_output_get_model_info() */ + +TEST(tdm_output_get_model_info, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + const char *maker; + const char *model; + const char *name; + char *expected_maker = output.caps.maker; + char *expected_model = output.caps.model; + char *expected_name = output.caps.name; + + _init_test(); + + error = tdm_output_get_model_info(&output, &maker, &model, &name); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(maker == expected_maker); + ASSERT_TRUE(model == expected_model); + ASSERT_TRUE(name == expected_name); +} + +TEST(tdm_output_get_model_info, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_output output; + + _init_test(); + + error = tdm_output_get_model_info(&output, NULL, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_output_get_model_info, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_output_get_model_info(NULL, NULL, NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_create_pp() */ + +TEST(tdm_display_create_pp, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + + _init_test(); + + tdm_display_create_pp(&dpy, &error); + + ASSERT_EQ(error, expected_error); + +} + +TEST(tdm_display_create_pp, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + + _init_test(); + + TDM_PP_CREATE_INTERNAL_ERROR = 1; + + tdm_display_create_pp(&dpy, &error); + + ASSERT_NE(error, not_expected_error); + +} + +TEST(tdm_display_create_pp, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + tdm_display_create_pp(NULL, &error); + + ASSERT_EQ(error, expected_error); + +} + +/* tdm_display_handle_events() */ + +TEST(tdm_display_handle_events, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + tdm_private_loop private_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.private_thread = NULL; + + error = tdm_display_handle_events(&dpy); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_handle_events, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + tdm_private_loop private_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.private_thread = NULL; + TDM_EVENT_LOOP_DISPATCH_ERROR = 1; + + error = tdm_display_handle_events(&dpy); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_display_handle_events, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + tdm_private_loop private_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.private_thread = (tdm_private_thread *) 1; + + error = tdm_display_handle_events(&dpy); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_handle_events, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_handle_events(NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_fd() */ + +TEST(tdm_display_get_fd, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + int fd; + struct _tdm_private_display dpy; + tdm_private_loop private_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.private_thread = NULL; + + error = tdm_display_get_fd(&dpy, &fd); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_fd, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + struct _tdm_private_display dpy; + + _init_test(); + + error = tdm_display_get_fd(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_fd, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + int fd; + + _init_test(); + + error = tdm_display_get_fd(NULL, &fd); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_output() */ + +TEST(tdm_display_get_output, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error; + struct _tdm_private_display dpy; + + _init_test(); + + tdm_display_get_output(&dpy, 1, &error); + + expected_error = TDM_ERROR_NONE; + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_output, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error; + expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + tdm_display_get_output(NULL, 1, &error); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_output_count() */ + +TEST(tdm_display_get_output_count, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error; + struct _tdm_private_display dpy; + int count; + + _init_test(); + + error = tdm_display_get_output_count(&dpy, &count); + + expected_error = TDM_ERROR_NONE; + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_output_count, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error; + struct _tdm_private_display dpy; + + _init_test(); + + error = tdm_display_get_output_count(&dpy, NULL); + + expected_error = TDM_ERROR_INVALID_PARAMETER; + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_output_count, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + int count; + + _init_test(); + + error = tdm_display_get_output_count(NULL, &count); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_catpure_available_formats() */ + +TEST(tdm_display_get_catpure_available_formats, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + const tbm_format *format; + int count; + tbm_format expected_format = 2; + int expected_count = 3; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + dpy.caps_capture.format_count = expected_count; + dpy.caps_capture.formats = &expected_format; + + error = tdm_display_get_catpure_available_formats(&dpy, &format, &count); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(format == &expected_format); + ASSERT_EQ(count, expected_count); +} + +TEST(tdm_display_get_catpure_available_formats, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + const tbm_format *format; + int count; + tdm_error expected_error = TDM_ERROR_NO_CAPABILITY; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + + error = tdm_display_get_catpure_available_formats(&dpy, &format, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_catpure_available_formats, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + const tbm_format *format; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_catpure_available_formats(&dpy, &format, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_catpure_available_formats, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + int count; + + _init_test(); + + error = tdm_display_get_catpure_available_formats(&dpy, NULL, &count); + + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_catpure_available_formats, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + const tbm_format *format; + int count; + + _init_test(); + + error = tdm_display_get_catpure_available_formats(NULL, &format, &count); + + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_capture_capabilities() */ + +TEST(tdm_display_get_capture_capabilities, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_capture_capability capability = TDM_CAPTURE_CAPABILITY_SCALE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_capture_capability expected_capability = TDM_CAPTURE_CAPABILITY_LAYER; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + dpy.caps_capture.capabilities = TDM_CAPTURE_CAPABILITY_LAYER; + + error = tdm_display_get_capture_capabilities(&dpy, &capability); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(capability, expected_capability); +} + +TEST(tdm_display_get_capture_capabilities, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_capture_capability capability = TDM_CAPTURE_CAPABILITY_SCALE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NO_CAPABILITY; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + + error = tdm_display_get_capture_capabilities(&dpy, &capability); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_capture_capabilities, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_capture_capabilities(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_capture_capabilities, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_capture_capability capability = TDM_CAPTURE_CAPABILITY_SCALE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_capture_capabilities(NULL, &capability); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_pp_available_size() */ + +TEST(tdm_display_get_pp_available_size, work_flow_success_7) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + int min_w = 0; + int expected_min_w = 200; + int min_h = 0; + int expected_min_h = 100; + int max_w = 0; + int expected_max_w = 2000; + int max_h = 0; + int expected_max_h = 1000; + int preferred_align = 0; + int expected_preferred_align = 500; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.min_w = expected_min_w; + dpy.caps_pp.min_h = expected_min_h; + dpy.caps_pp.max_w = expected_max_w; + dpy.caps_pp.max_h = expected_max_h; + dpy.caps_pp.preferred_align = expected_preferred_align; + + error = tdm_display_get_pp_available_size(&dpy, &min_w, &min_h, &max_w, + &max_h, &preferred_align); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(min_w, expected_min_w); + ASSERT_EQ(min_h, expected_min_h); + ASSERT_EQ(max_w, expected_max_w); + ASSERT_EQ(max_h, expected_max_h); + ASSERT_EQ(preferred_align, expected_preferred_align); +} + +TEST(tdm_display_get_pp_available_size, work_flow_success_6) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + int preferred_align = 0; + int expected_preferred_align = 500; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.preferred_align = expected_preferred_align; + + error = tdm_display_get_pp_available_size(&dpy, NULL, NULL, NULL, NULL, + &preferred_align); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(preferred_align, expected_preferred_align); +} + +TEST(tdm_display_get_pp_available_size, work_flow_success_5) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + int max_h = 0; + int expected_max_h = 1000; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.max_h = expected_max_h; + + error = tdm_display_get_pp_available_size(&dpy, NULL, NULL, NULL, + &max_h, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(max_h, expected_max_h); +} + +TEST(tdm_display_get_pp_available_size, work_flow_success_4) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + int max_w = 0; + int expected_max_w = 2000; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.max_w = expected_max_w; + + error = tdm_display_get_pp_available_size(&dpy, NULL, NULL, &max_w, + NULL, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(max_w, expected_max_w); +} + +TEST(tdm_display_get_pp_available_size, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + int min_h = 0; + int expected_min_h = 100; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.min_h = expected_min_h; + + error = tdm_display_get_pp_available_size(&dpy, NULL, &min_h, NULL, + NULL, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(min_h, expected_min_h); +} + +TEST(tdm_display_get_pp_available_size, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + int min_w = 0; + int expected_min_w = 200; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.min_w = expected_min_w; + + error = tdm_display_get_pp_available_size(&dpy, &min_w, NULL, NULL, + NULL, NULL); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(min_w, expected_min_w); +} + +TEST(tdm_display_get_pp_available_size, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NO_CAPABILITY; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + error = tdm_display_get_pp_available_size(&dpy, NULL, NULL, NULL, + NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_pp_available_size, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_pp_available_size(NULL, NULL, NULL, NULL, + NULL, NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_pp_available_formats() */ + +TEST(tdm_display_get_pp_available_formats, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + struct _tdm_private_display dpy; + const tbm_format *format; + int count; + tbm_format expected_format = 2; + int expected_count = 3; + tdm_error expected_error = TDM_ERROR_NONE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.format_count = expected_count; + dpy.caps_pp.formats = &expected_format; + + error = tdm_display_get_pp_available_formats(&dpy, &format, &count); + + ASSERT_EQ(error, expected_error); + ASSERT_TRUE(format == &expected_format); + ASSERT_EQ(count, expected_count); +} + +TEST(tdm_display_get_pp_available_formats, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + const tbm_format *format; + int count; + tdm_error expected_error = TDM_ERROR_NO_CAPABILITY; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + error = tdm_display_get_pp_available_formats(&dpy, &format, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_pp_available_formats, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + const tbm_format *format; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_pp_available_formats(&dpy, &format, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_pp_available_formats, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + int count; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_pp_available_formats(&dpy, NULL, &count); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_pp_available_formats, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + const tbm_format *format; + int count; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_pp_available_formats(NULL, &format, &count); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_pp_capabilities() */ + +TEST(tdm_display_get_pp_capabilities, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_pp_capability capability = TDM_PP_CAPABILITY_SCALE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_pp_capability expected_capability = TDM_PP_CAPABILITY_TRANSFORM; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_PP; + dpy.caps_pp.capabilities = TDM_PP_CAPABILITY_TRANSFORM; + + error = tdm_display_get_pp_capabilities(&dpy, &capability); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(capability, expected_capability); +} + +TEST(tdm_display_get_pp_capabilities, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_pp_capability capability = TDM_PP_CAPABILITY_SCALE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NO_CAPABILITY; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + error = tdm_display_get_pp_capabilities(&dpy, &capability); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_pp_capabilities, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_pp_capabilities(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_pp_capabilities, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_pp_capability capability = TDM_PP_CAPABILITY_SCALE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_pp_capabilities(NULL, &capability); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_display_get_capabilities() */ + +TEST(tdm_display_get_capabilities, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_display_capability capability = TDM_DISPLAY_CAPABILITY_PP; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_display_capability expected_capability = TDM_DISPLAY_CAPABILITY_CAPTURE; + + _init_test(); + + dpy.capabilities = TDM_DISPLAY_CAPABILITY_CAPTURE; + + error = tdm_display_get_capabilities(&dpy, &capability); + + ASSERT_EQ(error, expected_error); + ASSERT_EQ(capability, expected_capability); +} + +TEST(tdm_display_get_capabilities, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + struct _tdm_private_display dpy; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_capabilities(&dpy, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_display_get_capabilities, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_display_capability capability = TDM_DISPLAY_CAPABILITY_CAPTURE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_display_get_capabilities(NULL, &capability); + + ASSERT_EQ(error, expected_error); +} diff --git a/ut/src/ut_tdm_event_loop.cpp b/ut/src/ut_tdm_event_loop.cpp new file mode 100644 index 0000000..514e7c1 --- /dev/null +++ b/ut/src/ut_tdm_event_loop.cpp @@ -0,0 +1,424 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock + +#include "tdm_event_loop.c" + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; + WL_EVENT_LOOP_ADD_FD_ERROR = 0; + WL_EVENT_SOURCE_FD_UPDATE_ERROR = 0; + WL_EVENT_LOOP_ADD_TIMER_ERROR = 0; + WL_EVENT_SOURCE_TIMER_UPDATE_ERROR = 0; +} + +/* HELPER FUNCTIONS */ + +tdm_error ut_tdm_event_loop_fd_handler(int fd, tdm_event_loop_mask mask, + void *user_data) { } + +tdm_error ut_tdm_event_loop_timer_handler(void *user_data) { } + +/* UNIT TESTS */ + +/* tdm_event_loop_source_timer_update */ + +TEST(tdm_event_loop_source_timer, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_event_loop_source_timer source; + + _init_test(); + + error = tdm_event_loop_source_timer_update(&source, 100); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_source_timer, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OPERATION_FAILED; + tdm_event_loop_source_timer source; + + _init_test(); + + WL_EVENT_SOURCE_TIMER_UPDATE_ERROR = 1; + + error = tdm_event_loop_source_timer_update(&source, 100); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_source_timer_update, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_event_loop_source_timer_update(NULL, 100); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_event_loop_add_timer_handler */ + +TEST(tdm_event_loop_add_timer_handler, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OUT_OF_MEMORY; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_display dpy; + tdm_private_loop private_loop; + tdm_event_loop_source_timer *timer_source; + struct wl_event_loop wl_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = &wl_loop; + + timer_source = + tdm_event_loop_add_timer_handler(&dpy, + ut_tdm_event_loop_timer_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); + free(timer_source); +} + +TEST(tdm_event_loop_add_timer_handler, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + tdm_private_display dpy; + tdm_private_loop private_loop; + struct wl_event_loop wl_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = &wl_loop; + WL_EVENT_LOOP_ADD_TIMER_ERROR = 1; + + tdm_event_loop_add_timer_handler(&dpy, ut_tdm_event_loop_timer_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_timer_handler, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + tdm_private_display dpy; + tdm_private_loop private_loop; + struct wl_event_loop wl_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = &wl_loop; + CALLOC_ERROR = 1; + + tdm_event_loop_add_timer_handler(&dpy, ut_tdm_event_loop_timer_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_timer_handler, null_ptr_fail_4) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + tdm_private_loop private_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = NULL; + + tdm_event_loop_add_timer_handler(&dpy, ut_tdm_event_loop_timer_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_timer_handler, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + + _init_test(); + + dpy.private_loop = NULL; + + tdm_event_loop_add_timer_handler(&dpy, ut_tdm_event_loop_timer_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_timer_handler, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_display dpy; + + _init_test(); + + tdm_event_loop_add_timer_handler(&dpy, NULL, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_timer_handler, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + tdm_event_loop_add_timer_handler(NULL, ut_tdm_event_loop_timer_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_event_loop_source_fd_update */ + +TEST(tdm_event_loop_source_fd_update, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_event_loop_mask mask; + tdm_event_loop_source_fd source; + + _init_test(); + + error = tdm_event_loop_source_fd_update(&source, mask); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_source_fd_update, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OPERATION_FAILED; + tdm_event_loop_mask mask; + tdm_event_loop_source_fd source; + + _init_test(); + + WL_EVENT_SOURCE_FD_UPDATE_ERROR = 1; + + error = tdm_event_loop_source_fd_update(&source, mask); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_source_fd_update, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_event_loop_mask mask; + + _init_test(); + + error = tdm_event_loop_source_fd_update(NULL, mask); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_event_loop_add_fd_handler */ + +TEST(tdm_event_loop_add_fd_handler, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_INVALID_PARAMETER; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_event_loop_mask mask; + tdm_private_display dpy; + tdm_private_loop private_loop; + struct wl_event_loop wl_loop; + tdm_event_loop_source_fd *fd_source; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = &wl_loop; + + fd_source = + tdm_event_loop_add_fd_handler(&dpy, 5, mask, + ut_tdm_event_loop_fd_handler, + NULL, &error); + free(fd_source); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_fd_handler, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + tdm_event_loop_mask mask; + tdm_private_display dpy; + tdm_private_loop private_loop; + struct wl_event_loop wl_loop; + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = &wl_loop; + WL_EVENT_LOOP_ADD_FD_ERROR = 1; + + tdm_event_loop_add_fd_handler(&dpy, 5, mask, ut_tdm_event_loop_fd_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_fd_handler, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_OUT_OF_MEMORY; + tdm_event_loop_mask mask; + tdm_private_display dpy; + tdm_private_loop private_loop; + struct wl_event_loop wl_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = &wl_loop; + CALLOC_ERROR = 1; + + tdm_event_loop_add_fd_handler(&dpy, 5, mask, ut_tdm_event_loop_fd_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_fd_handler, null_ptr_fail_5) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_event_loop_mask mask; + tdm_private_display dpy; + tdm_private_loop private_loop; + + _init_test(); + + dpy.private_loop = &private_loop; + private_loop.wl_loop = NULL; + + tdm_event_loop_add_fd_handler(&dpy, 5, mask, ut_tdm_event_loop_fd_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_fd_handler, null_ptr_fail_4) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_event_loop_mask mask; + tdm_private_display dpy; + + _init_test(); + + dpy.private_loop = NULL; + + tdm_event_loop_add_fd_handler(&dpy, 5, mask, ut_tdm_event_loop_fd_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_fd_handler, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_event_loop_mask mask; + tdm_private_display dpy; + + _init_test(); + + tdm_event_loop_add_fd_handler(&dpy, 5, mask, NULL, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_fd_handler, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_event_loop_mask mask; + tdm_private_display dpy; + + _init_test(); + + tdm_event_loop_add_fd_handler(&dpy, -1, mask, ut_tdm_event_loop_fd_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_event_loop_add_fd_handler, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_event_loop_mask mask; + + _init_test(); + + tdm_event_loop_add_fd_handler(NULL, 5, mask, ut_tdm_event_loop_fd_handler, + NULL, &error); + + ASSERT_EQ(error, expected_error); +} diff --git a/ut/src/ut_tdm_helper.cpp b/ut/src/ut_tdm_helper.cpp new file mode 100644 index 0000000..5e69797 --- /dev/null +++ b/ut/src/ut_tdm_helper.cpp @@ -0,0 +1,136 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" +#include "tdm_helper_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock +#define getenv ut_getenv +#define sscanf ut_sscanf +#define fcntl ut_fcntl +#define dup ut_dup + +#include "tdm_helper.c" + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; + GETENV_ERROR = 0; + SSCANF_ERROR = 0; + FCNTL_ERROR = 0; + DUP_ERROR = 0; +} + +/* UNIT TESTS */ + +/* tdm_helper_get_fd() */ + +TEST(tdm_helper_get_fd, work_flow_success_5) +{ + const char *env = "env"; + int fd; + + _init_test(); + + fd = tdm_helper_get_fd(env); + + ASSERT_GE(fd, 0); +} + +TEST(tdm_helper_get_fd, work_flow_success_4) +{ + const char *env = "env"; + int expected_fd = -1; + int fd; + + _init_test(); + + DUP_ERROR = 1; + + fd = tdm_helper_get_fd(env); + + ASSERT_EQ(fd, expected_fd); +} + +TEST(tdm_helper_get_fd, work_flow_success_3) +{ + const char *env = "env"; + int fd; + int expected_fd = -1; + + _init_test(); + + FCNTL_ERROR = 1; + + fd = tdm_helper_get_fd(env); + + ASSERT_EQ(fd, expected_fd); +} + +TEST(tdm_helper_get_fd, work_flow_success_2) +{ + const char *env = "env"; + int expected_fd = -1; + int fd; + + _init_test(); + + SSCANF_ERROR = 1; + + fd = tdm_helper_get_fd(env); + + ASSERT_EQ(fd, expected_fd); +} + +TEST(tdm_helper_get_fd, work_flow_success_1) +{ + const char *env = "env"; + int fd; + int expected_fd = -1; + + _init_test(); + + GETENV_ERROR = 1; + + fd = tdm_helper_get_fd(env); + + ASSERT_EQ(fd, expected_fd); +} diff --git a/ut/src/ut_tdm_pp.cpp b/ut/src/ut_tdm_pp.cpp new file mode 100644 index 0000000..2255894 --- /dev/null +++ b/ut/src/ut_tdm_pp.cpp @@ -0,0 +1,263 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * + * 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. + * +**************************************************************************/ + +#include "gtest/gtest.h" + +#include "tbm_stubs.h" +#include "pthread_stubs.h" +#include "stdlib_stubs.h" +#include "tdm_list_stubs.h" +#include "tdm_pp_stubs.h" + +#define pthread_mutex_lock ut_pthread_mutex_lock +#define calloc ut_calloc +#define free ut_free +#define pthread_mutex_init ut_pthread_mutex_init +#define pthread_mutex_unlock ut_pthread_mutex_unlock +#define tdm_buffer_get_info ut_tdm_buffer_get_info +#define tdm_buffer_list_dump ut_tdm_buffer_list_dump +#define tdm_buffer_ref_backend ut_tdm_buffer_ref_backend + +#include "tdm_pp.c" + +static void _init_test() +{ + TBM_BUFMGR_DEINIT_CALLED = 0; + TBM_BO_GET_USER_DATA_NULL = 0; + PTHREAD_MUTEX_INIT_ERROR = 0; + CALLOC_ERROR = 0; + CALLOC_RETURN_BUFFER = 0; + FREE_CALLED = 0; + PP_SET_INFO_ERROR = 0; + PP_ATACH_ERROR = 0; + PP_COMMIT_ERROR = 0; +} + +/* UNIT TESTS */ + +/* tdm_pp_commit */ + +TEST(tdm_pp_commit, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_private_pp pp; + tdm_private_display private_display; + + _init_test(); + + pp.private_display = &private_display; + private_display.func_pp.pp_commit = pp_commit; + + error = tdm_pp_commit(&pp); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_pp_commit, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_private_pp pp; + tdm_private_display private_display; + + _init_test(); + + pp.private_display = &private_display; + private_display.func_pp.pp_commit = pp_commit; + PP_COMMIT_ERROR = 1; + + error = tdm_pp_commit(&pp); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_pp_commit, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_private_pp pp; + tdm_private_display private_display; + + _init_test(); + + pp.private_display = &private_display; + private_display.func_pp.pp_commit = NULL; + + error = tdm_pp_commit(&pp); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_pp_commit, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + + _init_test(); + + error = tdm_pp_commit(NULL); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_pp_attach */ + +TEST(tdm_pp_attach, null_ptr_fail_3) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_pp pp; + tdm_private_display private_display; + struct _tbm_surface src; + + _init_test(); + + pp.private_display = &private_display; + + error = tdm_pp_attach(&pp, &src, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_pp_attach, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_pp pp; + tdm_private_display private_display; + struct _tbm_surface dst; + + _init_test(); + + pp.private_display = &private_display; + + error = tdm_pp_attach(&pp, NULL, &dst); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_pp_attach, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + struct _tbm_surface src; + struct _tbm_surface dst; + + _init_test(); + + error = tdm_pp_attach(NULL, &src, &dst); + + ASSERT_EQ(error, expected_error); +} + +/* tdm_pp_set_info */ + +TEST(tdm_pp_set_info, work_flow_success_3) +{ + tdm_error error = TDM_ERROR_OPERATION_FAILED; + tdm_error expected_error = TDM_ERROR_NONE; + tdm_info_pp info; + tdm_private_pp pp; + tdm_private_display private_display; + + _init_test(); + + pp.private_display = &private_display; + private_display.func_pp.pp_set_info = pp_set_info; + + error = tdm_pp_set_info(&pp, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_pp_set_info, work_flow_success_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error not_expected_error = TDM_ERROR_NONE; + tdm_info_pp info; + tdm_private_pp pp; + tdm_private_display private_display; + + _init_test(); + + pp.private_display = &private_display; + private_display.func_pp.pp_set_info = pp_set_info; + PP_SET_INFO_ERROR = 1; + + error = tdm_pp_set_info(&pp, &info); + + ASSERT_NE(error, not_expected_error); +} + +TEST(tdm_pp_set_info, work_flow_success_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_NOT_IMPLEMENTED; + tdm_info_pp info; + tdm_private_pp pp; + tdm_private_display private_display; + + _init_test(); + + pp.private_display = &private_display; + private_display.func_pp.pp_set_info = NULL; + + error = tdm_pp_set_info(&pp, &info); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_pp_set_info, null_ptr_fail_2) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_private_pp pp; + tdm_private_display private_display; + + _init_test(); + + pp.private_display = &private_display; + + error = tdm_pp_set_info(&pp, NULL); + + ASSERT_EQ(error, expected_error); +} + +TEST(tdm_pp_set_info, null_ptr_fail_1) +{ + tdm_error error = TDM_ERROR_NONE; + tdm_error expected_error = TDM_ERROR_INVALID_PARAMETER; + tdm_info_pp info; + + _init_test(); + + error = tdm_pp_set_info(NULL, &info); + + ASSERT_EQ(error, expected_error); +} diff --git a/ut/stubs/pthread_stubs.h b/ut/stubs/pthread_stubs.h new file mode 100644 index 0000000..62ab53f --- /dev/null +++ b/ut/stubs/pthread_stubs.h @@ -0,0 +1,23 @@ +#ifndef _PTHREAD_STUBS_H +#define _PTHREAD_STUBS_H + +#include +#include + +static int PTHREAD_MUTEX_INIT_ERROR; + +static int ut_pthread_mutex_lock(pthread_mutex_t * __mutex) { } + +static int ut_pthread_mutex_unlock(pthread_mutex_t * __mutex) { } + +static int ut_pthread_mutex_init(pthread_mutex_t * __mutex, + const pthread_mutexattr_t * __mutexattr) +{ + if (PTHREAD_MUTEX_INIT_ERROR) { + return PTHREAD_MUTEX_INIT_ERROR; + } + + return 0; +} + +#endif /* _PTHREAD_STUBS_H */ diff --git a/ut/stubs/stdlib_stubs.h b/ut/stubs/stdlib_stubs.h new file mode 100644 index 0000000..9af270e --- /dev/null +++ b/ut/stubs/stdlib_stubs.h @@ -0,0 +1,34 @@ +#ifndef _STDLIB_STUBS_H +#define _STDLIB_STUBS_H + +#include +#include "tdm_list_stubs.h" +#include "tdm.h" +#include "tdm_private.h" + +static int CALLOC_ERROR; +static int CALLOC_RETURN_BUFFER; +static int FREE_CALLED; + +static tdm_buffer_info buffer; + +static void *ut_calloc(size_t nmemb, size_t size) +{ + if (CALLOC_ERROR) { + return NULL; + } + + if (CALLOC_RETURN_BUFFER) { + return &buffer; + } + + return calloc(nmemb, size); +} + +static void ut_free(void *ptr) +{ + FREE_CALLED = 1; + free(ptr); +} + +#endif /* _STDLIB_STUBS_H */ diff --git a/ut/stubs/tbm_bufmgr.h b/ut/stubs/tbm_bufmgr.h new file mode 100644 index 0000000..dc4fd59 --- /dev/null +++ b/ut/stubs/tbm_bufmgr.h @@ -0,0 +1,1025 @@ +#ifndef _TBM_BUFMGR_H_ +#define _TBM_BUFMGR_H_ + +#include +#include + +/* tbm error base : this error base is same as TIZEN_ERROR_TBM in tizen_error.h */ +#ifndef TBM_ERROR_BASE +#define TBM_ERROR_BASE -0x02830000 +#endif + +/** + * \file tbm_bufmgr.h + * \brief Tizen Buffer Manager + */ + +/** + * @brief Definition for the tizen buffer manager + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _tbm_bufmgr *tbm_bufmgr; + +/** + * @brief Definition for the tizen buffer object + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _tbm_bo *tbm_bo; +/** + * @brief Definition for the key associated with the buffer object + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef uint32_t tbm_key; +/** + * @brief Definition for the file descripter of the system buffer manager + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef int32_t tbm_fd; + +/* TBM_DEVICE_TYPE */ + +/** + * @brief Definition for the device type to get the default handle + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_DEVICE_DEFAULT 0 +/** + * @brief Definition for the device type to get the virtual memory + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_DEVICE_CPU 1 +/** + * @brief Definition for the device type to get the 2D memory handle + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_DEVICE_2D 2 +/** + * @brief Definition for the device type to get the 3D memory handle + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_DEVICE_3D 3 +/** + * @brief Definition for the device type to get the multimedia handle + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_DEVICE_MM 4 + +/* TBM_OPTION */ + +/** + * @brief Definition for the access option to read + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_OPTION_READ (1 << 0) +/** + * @brief Definition for the access option to write + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_OPTION_WRITE (1 << 1) +/** + * @brief Definition for the vendor specific option that depends on the backend + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_OPTION_VENDOR (0xffff0000) + +/* unneeded version 2.0 */ +/** + * @brief Definition for the cache invalidate + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_CACHE_INV 0x01 +/** + * @brief Definition for the cache clean + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_CACHE_CLN 0x02 +/* unneeded version 2.0 */ + +/** + * @brief tbm_bo_handle abstraction of the memory handle by TBM_DEVICE_TYPE + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef union _tbm_bo_handle { + void *ptr; + int32_t s32; + uint32_t u32; + int64_t s64; + uint64_t u64; +} tbm_bo_handle; + +/** + * @brief Enumeration of bo memory type + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +enum TBM_BO_FLAGS { + TBM_BO_DEFAULT = 0, /**< default memory: it depends on the backend */ + TBM_BO_SCANOUT = (1 << 0), /**< scanout memory */ + TBM_BO_NONCACHABLE = (1 << 1), /**< non-cachable memory */ + TBM_BO_WC = (1 << 2), /**< write-combine memory */ + TBM_BO_VENDOR = (0xffff0000), /**< vendor specific memory: it depends on the backend */ +}; + +/** + * @brief Enumeration for tbm error type. + * @since_tizen 2.4 + */ +typedef enum { + TBM_ERROR_NONE = 0, /**< Successful */ + TBM_BO_ERROR_GET_FD_FAILED = TBM_ERROR_BASE | 0x0101, /**< failed to get fd failed */ + TBM_BO_ERROR_HEAP_ALLOC_FAILED = TBM_ERROR_BASE | 0x0102, /**< failed to allocate the heap memory */ + TBM_BO_ERROR_LOAD_MODULE_FAILED = TBM_ERROR_BASE | 0x0103,/**< failed to load module*/ + TBM_BO_ERROR_THREAD_INIT_FAILED = TBM_ERROR_BASE | 0x0104,/**< failed to initialize the pthread */ + TBM_BO_ERROR_BO_ALLOC_FAILED = TBM_ERROR_BASE | 0x0105, /**< failed to allocate tbm_bo */ + TBM_BO_ERROR_INIT_STATE_FAILED = TBM_ERROR_BASE | 0x0106, /**< failed to initialize the state of tbm_bo */ + TBM_BO_ERROR_IMPORT_FAILED = TBM_ERROR_BASE | 0x0107, /**< failed to import the handle of tbm_bo */ + TBM_BO_ERROR_IMPORT_FD_FAILED = TBM_ERROR_BASE | 0x0108, /**< failed to import fd of tbm_bo */ + TBM_BO_ERROR_EXPORT_FAILED = TBM_ERROR_BASE | 0x0109, /**< failed to export the handle of the tbm_bo */ + TBM_BO_ERROR_EXPORT_FD_FAILED = TBM_ERROR_BASE | 0x01010, /**< failed to export fd of tbm_bo */ + TBM_BO_ERROR_GET_HANDLE_FAILED = TBM_ERROR_BASE | 0x0111, /**< failed to get the tbm_bo_handle */ + TBM_BO_ERROR_LOCK_FAILED = TBM_ERROR_BASE | 0x0112, /**< failed to lock the tbm_bo */ + TBM_BO_ERROR_MAP_FAILED = TBM_ERROR_BASE | 0x0113, /**< failed to map the tbm_bo to get the tbm_bo_handle */ + TBM_BO_ERROR_UNMAP_FAILED = TBM_ERROR_BASE | 0x0114, /**< failed to unmap the tbm_bo */ + TBM_BO_ERROR_SWAP_FAILED = TBM_ERROR_BASE | 0x0115, /**< failed to swap the tbm_bos */ + TBM_BO_ERROR_DUP_FD_FAILED = TBM_ERROR_BASE | 0x0116, /**< failed to duplicate fd */ +} tbm_error_e; + +/** + * @brief Enumeration of tbm buffer manager capability. + * @since_tizen 2.4 + */ +enum TBM_BUFMGR_CAPABILITY { + TBM_BUFMGR_CAPABILITY_NONE = 0, /**< Not Support capability*/ + TBM_BUFMGR_CAPABILITY_SHARE_KEY = (1 << 0), /**< Support sharing buffer by tbm key */ + TBM_BUFMGR_CAPABILITY_SHARE_FD = (1 << 1), /**< Support sharing buffer by tbm fd */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Functions for buffer manager */ + +/** + * @brief Initializes the buffer manager. + * @details If fd is lower than zero, fd is get drm fd in tbm_bufmgr_init function\n + * The user can decide the lock type and cache flush type with the environment variables, which are BUFMGR_LOCK_TYPE and BUFMGR_MAP_CACHE.\n + * \n + * BUFMGR_LOCK default is once\n + * once : The previous bo which is locked is unlock when the new bo is trying to be locked\n + * always : The new bo is locked until the previous bo which is locked is unlocked\n + * never : Every bo is never locked.\n + * \n + * BUFMGR_MAP_CACHE default is true\n + * true : use map cache flushing\n + * false : to use map cache flushing + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] fd : file descripter of the system buffer manager + * @return a buffer manager + * @retval #tbm_bufmgr + * @see tbm_bufmgr_deinit(); + * @par Example + @code + #include + int bufmgr_fd; + + setenv("BUFMGR_LOCK_TYPE", "once", 1); + setenv("BUFMGR_MAP_CACHE", "true", 1); + + tbm_bufmgr bufmgr; + bufmgr = tbm_bufmgr_init (bufmgr_fd); + + .... + + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_bufmgr tbm_bufmgr_init(int fd); + +/** + * @brief Deinitializes the buffer manager. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bufmgr : the buffer manager + * @see tbm_bufmgr_init() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_error_e error; + bufmgr = tbm_bufmgr_init (bufmgr_fd); + if (!bufmgr) + { + error = tbm_get_last_error (); + ... + } + + .... + + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +void tbm_bufmgr_deinit(tbm_bufmgr bufmgr); + +/* Functions for bo */ + +/** + * @brief Allocates the buffer object. + * @details This function create tbm_bo and set reference count to 1.\n + * The user can craete tbm_bo with memory type flag #TBM_BO_FLAGS\n\n + * #TBM_BO_DEFAULT indecates default memory: it depends on the backend\n + * #TBM_BO_SCANOUT indecates scanout memory\n + * #TBM_BO_NONCACHABLE indecates non-cachable memory\n + * #TBM_BO_WC indecates write-combine memory\n + * #TBM_BO_VENDOR indecates vendor specific memory: it depends on the tbm backend + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bufmgr : the buffer manager + * @param[in] size : the size of buffer object + * @param[in] flags : the flags of memory type + * @return a buffer object + * @retval #tbm_bo + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo; + tbm_error_e error; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + if (!bo) + { + error = tbm_get_last_error (); + ... + } + + .... + + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_bo tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags); + +/** + * @brief Increases the reference count of bo. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @return a buffer object + * @retval #tbm_bo + * @see tbm_bo_unref() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + + ... + + bo = tbm_bo_ref (bo); + + .... + + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_bo tbm_bo_ref(tbm_bo bo); + +/** + * @brief Decreases the reference count of bo + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @see tbm_bo_ref() + * @see tbm_bo_alloc() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +void tbm_bo_unref(tbm_bo bo); + +/** + * @brief Maps the buffer object according to the device type and the option. + * @details Cache flushing and Locking is executed, while tbm_bo is mapping in the proper condition according to the device type and the access option.\n + * If the cache flush type of bufmgr set true, the map cache flushing is executed + * If the lock type of bufmgr set once, the previous bo which is locked is unlock when the new bo is trying to be locked.\n + * If the lock type of bufmgr set always, the new bo is locked until the previous bo which is locked is unlocked.\n + * If the lock type of bufmgr set never, Every bo is never locked.\n\n + * #TBM_DEVICE_DEFAULT indecates the default handle.\n + * #TBM_DEVICE_2D indecates the 2D memory handle.\n + * #TBM_DEVICE_3D indecates the 3D memory handle.\n + * #TBM_DEVICE_CPU indecates the virtual memory handle.\n + * #TBM_DEVICE_MM indecates the multimedia handle.\n\n + * #TBM_OPTION_READ indecates the accss option to read.\n + * #TBM_OPTION_WRITE indecates the access option to write.\n + * #TBM_OPTION_VENDOR indecates the vendor specific option that depends on the backend. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @param[in] device : the device type to get a handle + * @param[in] opt : the option to access the buffer object + * @return the handle of the buffer object + * @exception #TBM_ERROR_NONE Success + * @exception #TBM_ERROR_BO_LOCK_FAILED tbm_bo lock failed + * @exception #TBM_ERROR_BO_MAP_FAILED tbm_bo map failed + * @retval #tbm_bo + * @see tbm_bo_unmap() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + tbm_bo_handle handle; + tbm_error_e error; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + + ... + + handle = tbm_bo_map (bo, TBM_DEVICE_2D, TBM_OPTION_READ|TBM_OPTION_WRITE); + if (handle.ptr == NULL) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unmap (bo); + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_bo_handle tbm_bo_map(tbm_bo bo, int device, int opt); + +/** + * @brief Unmaps the buffer object. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @return 1 if this function succeeds, otherwise 0. + * @see tbm_bo_map() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo + tbm_bo_handle handle; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + + ... + + handle = tbm_bo_map (bo, TBM_DEVICE_2D, TBM_OPTION_READ|TBM_OPTION_WRITE); + + ... + + tbm_bo_unmap (bo); + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +int tbm_bo_unmap(tbm_bo bo); + +/** + * @brief Gets the tbm_bo_handle according to the device type. + * @details The tbm_bo_handle can be get without the map of the tbm_bo.\n + * In this case, TBM does not guarantee the lock and the cache flush of the tbm_bo.\n\n + * #TBM_DEVICE_DEFAULT indecates the default handle.\n + * #TBM_DEVICE_2D indecates the 2D memory handle.\n + * #TBM_DEVICE_3D indecates the 3D memory handle.\n + * #TBM_DEVICE_CPU indecates the virtual memory handle.\n + * #TBM_DEVICE_MM indecates the multimedia handle. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @param[in] device : the device type to get a handle + * @return the handle of the buffer object + * @retval #tbm_bo_handle + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + tbm_bo_handle handle; + tbm_error_e error; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + + ... + + handle = tbm_bo_get_handle (bo, TBM_DEVICE_2D); + if (handle.ptr == NULL) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_bo_handle tbm_bo_get_handle(tbm_bo bo, int device); + +/** + * @brief Exports the buffer object by key. + * @details The tbm_bo can be exported to the anther process with the unique key associated with the the tbm_bo. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @return key associated with the buffer object + * @retval #tbm_key + * @see tbm_bo_import() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo; + tbm_key key; + tbm_error_e error; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + key = tbm_bo_export (bo); + if (key == 0) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_key tbm_bo_export(tbm_bo bo); + +/** + * @brief Exports the buffer object by fd. + * @details The tbm_bo can be exported to the anther process with the unique fd associated with the the tbm_bo. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks You must release the fd using close(). + * @param[in] bo : the buffer object + * @return fd associated with the buffer object + * @retval #tbm_fd + * @see tbm_bo_import_fd() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_fd bo_fd; + tbm_bufmgr bufmgr; + tbm_bo; + tbm_error_e error; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + bo_fd = tbm_bo_export (bo); + if (bo_fd == 0) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_fd tbm_bo_export_fd(tbm_bo bo); + +/** + * @brief Imports the buffer object associated with the key. + * @details The reference count of the tbm_bo is 1. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bufmgr : the buffer manager + * @param[in] key : the key associated with the buffer object + * @return a buffer object + * @retval #tbm_bo + * @see tbm_bo_export() + * @par Example + @code + #include + + int bufmgr_fd; + int bo_key; + tbm_bufmgr bufmgr; + tbm_bo; + tbm_error_e error; + + ... + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_import (bufmgr, key); + if (bo == NULL) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_bo tbm_bo_import(tbm_bufmgr bufmgr, tbm_key key); + +/** + * @brief Imports the buffer object associated with the fd. + * @details The reference count of the tbm_bo is 1. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks You must release the fd using close(). + * @param[in] bufmgr : the buffer manager + * @param[in] fd : the fd associated with the buffer object + * @return a buffer object + * @retval #tbm_bo + * @see tbm_bo_export_fd() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_fd bo_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + tbm_error_e error; + + ... + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_import_fd (bo_fd); + if (bo == 0) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_bo tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd); + +/** + * @brief Gets the size of a bo. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @return 1 if this function succeeds, otherwise 0. + * @see tbm_bo_alloc() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo; + int size; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + size = tbm_bo_size (bo); + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +int tbm_bo_size(tbm_bo bo); + +/** + * @brief Gets the state where the buffer object is locked. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @return 1 if this bo is locked, otherwise 0. + * @see tbm_bo_map() + * @see tbm_bo_unmap() + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + + ... + + if (tbm_bo_locked (bo)) + { + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode +*/ +int tbm_bo_locked(tbm_bo bo); + +/** + * @brief Swaps the buffer object. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo1 : the buffer object + * @param[in] bo2 : the buffer object + * @return 1 if this function succeeds, otherwise 0. + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo1; + tbm_bo bo2; + int ret; + tbm_error_e error; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo1 = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + bo2 = tbm_bo_alloc (bufmgr, 256 * 256, TBM_BO_DEFAULT); + + ... + + ret = tbm_bo_swap (bo1, bo2); + if (ret == 0) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unref (bo1); + tbm_bo_unref (bo2); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +int tbm_bo_swap(tbm_bo bo1, tbm_bo bo2); + +/** + * @brief Called when the user data is deleted in buffer object. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] user_data User_data to be passed to callback function + * @pre The callback must be registered using tbm_bo_add_user_data().\n + * tbm_bo_delete_user_data() must be called to invoke this callback. + * @see tbm_bo_add_user_data() + * @see tbm_bo_delete_user_data() + */ +typedef void (*tbm_data_free) (void *user_data); + +/** + * @brief Adds a user_data to the buffer object. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @param[in] key : the key associated with the user_data + * @param[in] data_free_func : the function pointer to free the user_data + * @return 1 if this function succeeds, otherwise 0. + * @post tbm_data_free() will be called under certain conditions, after calling tbm_bo_delete_user_data(). + * @see tbm_data_free() + * @see tbm_bo_set_user_data() + * @see tbm_bo_get_user_data() + * @see tbm_bo_delete_user_data() + * @par Example + @code + #include + + void example_data_free (void *user_data) + { + char *data = (char*) user_data; + free(data); + } + + int main() + { + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + char *user_data; + char *get_data; + int ret; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + user_data = (char*) malloc (sizeof(char) * 128); + + ... + + tbm_bo_add_user_data (bo, 1, example_data_free); + tbm_bo_set_user_data (bo, 1, user_data); + + ... + + ret = tbm_bo_get_user_data (bo, 1, &get_data); + tbm_bo_delete_user_data (bo, 1); + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + } + @endcode + */ + +int tbm_bo_add_user_data(tbm_bo bo, unsigned long key, + tbm_data_free data_free_func); + +/** + * @brief Deletes the user_data in the buffer object. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @param[in] key : the key associated with the user_date + * @return 1 if this function succeeds, otherwise 0. + * @see tbm_bo_add_user_data() + * @see tbm_bo_get_user_data() + * @see tbm_bo_delete_user_data() + * @par Example + @code + #include + + void example_data_free (void *user_data) + { + char *data = (char*) user_data; + free(data); + } + + int main() + { + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + char *user_data; + char *get_data; + int ret; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + user_data = (char*) malloc (sizeof(char) * 128); + + ... + + tbm_bo_add_user_data (bo, 1, example_data_free); + tbm_bo_set_user_data (bo, 1, user_data); + + ... + + ret = tbm_bo_get_user_data (bo, 1, &get_data); + tbm_bo_delete_user_data (bo, 1); + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + } + @endcode + */ +int tbm_bo_delete_user_data(tbm_bo bo, unsigned long key); + +/** + * @brief Sets a user_date to the buffer object. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @param[in] key : the key associated with the user_date + * @param[in] data : a pointer of the user_data + * @return 1 if this function succeeds, otherwise 0. + * @see tbm_bo_add_user_data() + * @see tbm_bo_set_user_data() + * @see tbm_bo_delete_user_data() + * @par Example + @code + #include + + void example_data_free (void *user_data) + { + char *data = (char*) user_data; + free(data); + } + + int main() + { + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + char *user_data; + char *get_data; + int ret; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + user_data = (char*) malloc (sizeof(char) * 128); + + ... + + tbm_bo_add_user_data (bo, 1, example_data_free); + tbm_bo_set_user_data (bo, 1, user_data); + + ... + + ret = tbm_bo_get_user_data (bo, 1, &get_data); + tbm_bo_delete_user_data (bo, 1); + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + } + @endcode + */ +int tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data); + +/** + * @brief Gets a user_data from the buffer object with the key. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bo : the buffer object + * @param[in] key : the key associated with the user_date + * @param[out] data : to get the user data + * @return 1 if this function succeeds, otherwise 0. + * @see tbm_bo_add_user_data() + * @see tbm_bo_set_user_data() + * @see tbm_bo_get_user_data() + * @par Example + @code + #include + + void example_data_free (void *user_data) + { + char *data = (char*) user_data; + free(data); + } + + int main() + { + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + char *user_data; + char *get_data; + int ret; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + user_data = (char*) malloc (sizeof(char) * 128); + + ... + + tbm_bo_add_user_data (bo, 1, example_data_free); + tbm_bo_set_user_data (bo, 1, user_data); + + ... + + ret = tbm_bo_get_user_data (bo, 1, &get_data); + tbm_bo_delete_user_data (bo, 1); + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + } + @endcode + */ +int tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data); + +/** + * @brief Gets the latest tbm_error. + * @since_tizen 2.4 + * @return the latest tbm_error + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo bo; + tbm_bo_handle handle; + tbm_error_e error; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + if (!bo) + { + error = tbm_get_last_error (); + ... + } + + ... + + handle = tbm_bo_map (bo, TBM_DEVICE_2D, TBM_OPTION_READ|TBM_OPTION_WRITE); + if (handle.ptr == NULL) + { + error = tbm_get_last_error (); + ... + } + + ... + + tbm_bo_unmap (bo); + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_error_e tbm_get_last_error(void); + +/** + * @brief Gets the tbm buffer capability. + * @since_tizen 2.4 + * @param[in] bufmgr : the buffer manager + * @return the tbm bufmgr capability + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + unsigned int capability; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + + capability = tbm_bufmgr_get_capability (bufmgr); + + tbm_bufmgr_deinit (bufmgr); + @endcode + */ +unsigned int tbm_bufmgr_get_capability(tbm_bufmgr bufmgr); + +/** + * @brief Gets the tbm bo flags. + * @since_tizen 2.4 + * @param[in] bo : the buffer object + * @return the tbm bo flags + * @see TBM_BO_FLAGS + * @par Example + @code + #include + + int bufmgr_fd; + tbm_bufmgr bufmgr; + tbm_bo; + int flags; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + flags = tbm_bo_get_flags (bo); + + ... + + tbm_bo_unref (bo); + tbm_bufmgr_deinit (bufmgr); + + @endcode + */ +int tbm_bo_get_flags(tbm_bo bo); + +/** + * @brief Print out the information of tbm_bos. + * @since_tizen 3.0 + * @param[in] bufmgr : the buffer manager + */ +void tbm_bufmgr_debug_show(tbm_bufmgr bufmgr); + +/** + * @brief Print out the trace of tbm_bos. + * @since_tizen 3.0 + * @param[in] bufmgr : the buffer manager + * @param[in] onoff : 1 is on, and 0 is off + */ +void tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff); + +int tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay); + +#ifdef __cplusplus +} +#endif +#endif /* _TBM_BUFMGR_H_ */ diff --git a/ut/stubs/tbm_stubs.cpp b/ut/stubs/tbm_stubs.cpp new file mode 100644 index 0000000..04868c0 --- /dev/null +++ b/ut/stubs/tbm_stubs.cpp @@ -0,0 +1,110 @@ +#include "tbm_stubs.h" + +#include + +tbm_bufmgr tbm_bufmgr_init(int fd) +{ + +} + +void tbm_bufmgr_deinit(tbm_bufmgr bufmgr) +{ + TBM_BUFMGR_DEINIT_CALLED = 1; +} + +tbm_bo tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx) +{ + if (!surface) { + return NULL; + } +} + +int tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data) +{ + if (TBM_BO_GET_USER_DATA_NULL) { + *data = NULL; + return; + } + + *data = "data"; +} + +int tbm_bo_add_user_data(tbm_bo bo, unsigned long key, + tbm_data_free data_free_func) +{ +} + +int tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data) +{ +} + +void tbm_surface_internal_ref(tbm_surface_h surface) +{ +} + +void tbm_surface_internal_unref(tbm_surface_h surface) +{ +} + +tbm_surface_queue_error_e tbm_surface_queue_acquire( + tbm_surface_queue_h surface_queue, tbm_surface_h *surface) +{ +} + +tbm_surface_queue_error_e tbm_surface_queue_release( + tbm_surface_queue_h surface_queue, tbm_surface_h surface) +{ +} + +tbm_surface_queue_error_e tbm_surface_queue_add_acquirable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, + void *data) +{ +} + +tbm_surface_queue_error_e tbm_surface_queue_add_destroy_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, + void *data) +{ +} + +tbm_surface_queue_error_e tbm_surface_queue_remove_acquirable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, + void *data) +{ +} + +tbm_surface_queue_error_e tbm_surface_queue_remove_destroy_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, + void *data) +{ +} + +int tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key, + void **data) +{ + return 0; +} + +int tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key, + tbm_data_free data_free_func) +{ + return 1; +} + +int tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key, + void *data) +{ +} + +int tbm_surface_map(tbm_surface_h surface, int opt, tbm_surface_info_s *info) +{ +} + +int tbm_surface_unmap(tbm_surface_h surface) +{ +} + +void tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type) +{ +} diff --git a/ut/stubs/tbm_stubs.h b/ut/stubs/tbm_stubs.h new file mode 100644 index 0000000..ede41e1 --- /dev/null +++ b/ut/stubs/tbm_stubs.h @@ -0,0 +1,36 @@ +#ifndef _TBM_STUBS_H +#define _TBM_STUBS_H + +#include +#include "tbm_bufmgr.h" +#include "tbm_surface_queue.h" + +static int TBM_BUFMGR_DEINIT_CALLED; +static int TBM_BO_GET_USER_DATA_NULL; + +struct _tbm_surface { + int temp; +}; + +struct _tbm_surface_queue { + int temp; +}; + +tbm_bufmgr tbm_bufmgr_init(int fd); + +void tbm_bufmgr_deinit(tbm_bufmgr bufmgr); + +tbm_bo tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx); + +int tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data); + +int tbm_bo_add_user_data(tbm_bo bo, unsigned long key, + tbm_data_free data_free_func); + +int tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data); + +void tbm_surface_internal_ref(tbm_surface_h surface); + +void tbm_surface_internal_unref(tbm_surface_h surface); + +#endif /* _TBM_STUBS_H */ diff --git a/ut/stubs/tbm_surface.h b/ut/stubs/tbm_surface.h new file mode 100644 index 0000000..445d421 --- /dev/null +++ b/ut/stubs/tbm_surface.h @@ -0,0 +1,742 @@ +#ifndef _TBM_SURFACE_H_ +#define _TBM_SURFACE_H_ + +/** + * @addtogroup CAPI_UI_TBM_SURFACE_MODULE + * @{ + */ + +#include +#include + +/** + * \file tbm_surface.h + * \brief TBM Surface + */ + +/** + * @brief Enumeration for tbm_surface error type. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum { + TBM_SURFACE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + TBM_SURFACE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + TBM_SURFACE_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid Operation */ +} tbm_surface_error_e; + +/** + * @brief Definition for the max number of TBM surface plane. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_SURF_PLANE_MAX 4 + +/* option to map the tbm_surface */ +/** + * @brief Definition for the access option to read. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_SURF_OPTION_READ (1 << 0) +/** + * @brief Definition for the access option to write. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_SURF_OPTION_WRITE (1 << 1) + +/** + * @brief Definition for the TBM plane struct. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _tbm_surface_plane { + unsigned char *ptr; /**< Plane pointer */ + uint32_t size; /**< Plane size */ + uint32_t offset; /**< Plane offset */ + uint32_t stride; /**< Plane stride */ + + void *reserved1; /**< Reserved pointer1 */ + void *reserved2; /**< Reserved pointer2 */ + void *reserved3; /**< Reserved pointer3 */ +} tbm_surface_plane_s; + +/** + * @brief Definition for the TBM surface information struct. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _tbm_surface_info { + uint32_t width; /**< TBM surface width */ + uint32_t height; /**< TBM surface height */ + tbm_format format; /**< TBM surface format*/ + uint32_t bpp; /**< TBM surface bbp */ + uint32_t size; /**< TBM surface size */ + + uint32_t num_planes; /**< The number of planes */ + tbm_surface_plane_s planes[TBM_SURF_PLANE_MAX]; /**< Array of planes */ + + void *reserved4; /**< Reserved pointer4 */ + void *reserved5; /**< Reserved pointer5 */ + void *reserved6; /**< Reserved pointer6 */ +} tbm_surface_info_s; + +#define __tbm_fourcc_code(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ + ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) + +/* color index */ +/** + * @brief Definition for the TBM surface format C8 ([7:0] C). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_C8 __tbm_fourcc_code('C', '8', ' ', ' ') + +/* 8 bpp RGB */ +/** + * @brief Definition for the TBM surface format RGB322 ([7:0] R:G:B 3:3:2). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGB332 __tbm_fourcc_code('R', 'G', 'B', '8') +/** + * @brief Definition for the TBM surface format RGB233 ([7:0] B:G:R 2:3:3). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGR233 __tbm_fourcc_code('B', 'G', 'R', '8') + +/* 16 bpp RGB */ +/** + * @brief Definition for the TBM surface format XRGB4444 ([15:0] x:R:G:B 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XRGB4444 __tbm_fourcc_code('X', 'R', '1', '2') +/** + * @brief Definition for the TBM surface format XBRG4444 ([15:0] x:B:G:R 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XBGR4444 __tbm_fourcc_code('X', 'B', '1', '2') +/** + * @brief Definition for the TBM surface format RGBX4444 ([15:0] R:G:B:x 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBX4444 __tbm_fourcc_code('R', 'X', '1', '2') +/** + * @brief Definition for the TBM surface format BGRX4444 ([15:0] B:G:R:x 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRX4444 __tbm_fourcc_code('B', 'X', '1', '2') + +/** + * @brief Definition for the TBM surface format ARGB4444 ([15:0] A:R:G:B 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ARGB4444 __tbm_fourcc_code('A', 'R', '1', '2') +/** + * @brief Definition for the TBM surface format ABGR4444 ([15:0] A:B:G:R 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ABGR4444 __tbm_fourcc_code('A', 'B', '1', '2') +/** + * @brief Definition for the TBM surface format RGBA4444 ([15:0] R:G:B:A 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBA4444 __tbm_fourcc_code('R', 'A', '1', '2') +/** + * @brief Definition for the TBM surface format BGRA4444 ([15:0] B:G:R:A 4:4:4:4 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRA4444 __tbm_fourcc_code('B', 'A', '1', '2') + +/** + * @brief Definition for the TBM surface format XRGB1555 ([15:0] x:R:G:B 1:5:5:5 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XRGB1555 __tbm_fourcc_code('X', 'R', '1', '5') +/** + * @brief Definition for the TBM surface format XBGR1555 ([15:0] x:B:G:R 1:5:5:5 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XBGR1555 __tbm_fourcc_code('X', 'B', '1', '5') +/** + * @brief Definition for the TBM surface format RGBX5551 ([15:0] R:G:B:x 5:5:5:1 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBX5551 __tbm_fourcc_code('R', 'X', '1', '5') +/** + * @brief Definition for the TBM surface format BGRX5551 ([15:0] B:G:R:x 5:5:5:1 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRX5551 __tbm_fourcc_code('B', 'X', '1', '5') + +/** + * @brief Definition for the TBM surface format ARGB1555 ([15:0] A:R:G:B 1:5:5:5 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ARGB1555 __tbm_fourcc_code('A', 'R', '1', '5') +/** + * @brief Definition for the TBM surface format ABGR1555 ([15:0] A:B:G:R 1:5:5:5 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ABGR1555 __tbm_fourcc_code('A', 'B', '1', '5') +/** + * @brief Definition for the TBM surface format RGBA5551 ([15:0] R:G:B:A 5:5:5:1 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBA5551 __tbm_fourcc_code('R', 'A', '1', '5') +/** + * @brief Definition for the TBM surface format BGRA5551 ([15:0] B:G:R:A 5:5:5:1 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRA5551 __tbm_fourcc_code('B', 'A', '1', '5') + +/** + * @brief Definition for the TBM surface format RGB565 ([15:0] R:G:B 5:6:5 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGB565 __tbm_fourcc_code('R', 'G', '1', '6') +/** + * @brief Definition for the TBM surface format BGR565 ([15:0] B:G:R 5:6:5 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGR565 __tbm_fourcc_code('B', 'G', '1', '6') + +/* 24 bpp RGB */ +/** + * @brief Definition for the TBM surface format RGB888 ([23:0] R:G:B little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGB888 __tbm_fourcc_code('R', 'G', '2', '4') +/** + * @brief Definition for the TBM surface format BGR888 ([23:0] B:G:R little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGR888 __tbm_fourcc_code('B', 'G', '2', '4') + +/* 32 bpp RGB */ +/** + * @brief Definition for the TBM surface format XRGB8888 ([31:0] x:R:G:B 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XRGB8888 __tbm_fourcc_code('X', 'R', '2', '4') +/** + * @brief Definition for the TBM surface format XBGR8888 ([31:0] x:B:G:R 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XBGR8888 __tbm_fourcc_code('X', 'B', '2', '4') +/** + * @brief Definition for the TBM surface format RGBX8888 ([31:0] R:G:B:x 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBX8888 __tbm_fourcc_code('R', 'X', '2', '4') +/** + * @brief Definition for the TBM surface format BGRX8888 ([31:0] B:G:R:x 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRX8888 __tbm_fourcc_code('B', 'X', '2', '4') + +/** + * @brief Definition for the TBM surface format ARGB8888 ([31:0] A:R:G:B 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ARGB8888 __tbm_fourcc_code('A', 'R', '2', '4') +/** + * @brief Definition for the TBM surface format ABGR8888 ([31:0] [31:0] A:B:G:R 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ABGR8888 __tbm_fourcc_code('A', 'B', '2', '4') +/** + * @brief Definition for the TBM surface format RGBA8888 ([31:0] R:G:B:A 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBA8888 __tbm_fourcc_code('R', 'A', '2', '4') +/** + * @brief Definition for the TBM surface format BGRA8888 ([31:0] B:G:R:A 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRA8888 __tbm_fourcc_code('B', 'A', '2', '4') + +/** + * @brief Definition for the TBM surface format XRGB2101010 ([31:0] x:R:G:B 2:10:10:10 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XRGB2101010 __tbm_fourcc_code('X', 'R', '3', '0') +/** + * @brief Definition for the TBM surface format XBGR2101010 ([31:0] x:B:G:R 2:10:10:10 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_XBGR2101010 __tbm_fourcc_code('X', 'B', '3', '0') +/** + * @brief Definition for the TBM surface format RGBX1010102 ([31:0] R:G:B:x 10:10:10:2 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBX1010102 __tbm_fourcc_code('R', 'X', '3', '0') +/** + * @brief Definition for the TBM surface format BGRX1010102 ([31:0] B:G:R:x 10:10:10:2 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRX1010102 __tbm_fourcc_code('B', 'X', '3', '0') + +/** + * @brief Definition for the TBM surface format ARGB2101010 ([31:0] A:R:G:B 2:10:10:10 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ARGB2101010 __tbm_fourcc_code('A', 'R', '3', '0') +/** + * @brief Definition for the TBM surface format ABGR2101010 ([31:0] A:B:G:R 2:10:10:10 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_ABGR2101010 __tbm_fourcc_code('A', 'B', '3', '0') +/** + * @brief Definition for the TBM surface format RGBA1010102 ([31:0] R:G:B:A 10:10:10:2 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_RGBA1010102 __tbm_fourcc_code('R', 'A', '3', '0') +/** + * @brief Definition for the TBM surface format BGRA1010102 ([31:0] B:G:R:A 10:10:10:2 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_BGRA1010102 __tbm_fourcc_code('B', 'A', '3', '0') /* */ + +/* packed YCbCr */ +/** + * @brief Definition for the TBM surface format YUYV ([31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YUYV __tbm_fourcc_code('Y', 'U', 'Y', 'V') +/** + * @brief Definition for the TBM surface format YVYU ([31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YVYU __tbm_fourcc_code('Y', 'V', 'Y', 'U') /* */ +/** + * @brief Definition for the TBM surface format UYVY ([31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_UYVY __tbm_fourcc_code('U', 'Y', 'V', 'Y') +/** + * @brief Definition for the TBM surface format VYUY ([31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_VYUY __tbm_fourcc_code('V', 'Y', 'U', 'Y') + +/** + * @brief Definition for the TBM surface format AYUV ([31:0] A:Y:Cb:Cr 8:8:8:8 little endian). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_AYUV __tbm_fourcc_code('A', 'Y', 'U', 'V') + +/* + * 2 plane YCbCr + * index 0 = Y plane, [7:0] Y + * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian + * or + * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian + */ +/** + * @brief Definition for the TBM surface format NV12 (2x2 subsampled Cr:Cb plane). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_NV12 __tbm_fourcc_code('N', 'V', '1', '2') +/** + * @brief Definition for the TBM surface format NV21 (2x2 subsampled Cb:Cr plane). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_NV21 __tbm_fourcc_code('N', 'V', '2', '1') /* */ +/** + * @brief Definition for the TBM surface format NV16 (2x1 subsampled Cr:Cb plane). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_NV16 __tbm_fourcc_code('N', 'V', '1', '6') +/** + * @brief Definition for the TBM surface format NV61 (2x1 subsampled Cb:Cr plane). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_NV61 __tbm_fourcc_code('N', 'V', '6', '1') + +/* + * 3 plane YCbCr + * index 0: Y plane, [7:0] Y + * index 1: Cb plane, [7:0] Cb + * index 2: Cr plane, [7:0] Cr + * or + * index 1: Cr plane, [7:0] Cr + * index 2: Cb plane, [7:0] Cb + */ +/** + * @brief Definition for the TBM surface format YUV410 (4x4 subsampled Cb (1) and Cr (2) planes). + */ +#define TBM_FORMAT_YUV410 __tbm_fourcc_code('Y', 'U', 'V', '9') +/** + * @brief Definition for the TBM surface format YVU410 (4x4 subsampled Cr (1) and Cb (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YVU410 __tbm_fourcc_code('Y', 'V', 'U', '9') +/** + * @brief Definition for the TBM surface format YUV411 (4x1 subsampled Cb (1) and Cr (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YUV411 __tbm_fourcc_code('Y', 'U', '1', '1') +/** + * @brief Definition for the TBM surface format YVU411 (4x1 subsampled Cr (1) and Cb (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YVU411 __tbm_fourcc_code('Y', 'V', '1', '1') +/** + * @brief Definition for the TBM surface format YUV420 (2x2 subsampled Cb (1) and Cr (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YUV420 __tbm_fourcc_code('Y', 'U', '1', '2') +/** + * @brief Definition for the TBM surface format YVU420 (2x2 subsampled Cr (1) and Cb (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YVU420 __tbm_fourcc_code('Y', 'V', '1', '2') +/** + * @brief Definition for the TBM surface format YUV422 (2x1 subsampled Cb (1) and Cr (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YUV422 __tbm_fourcc_code('Y', 'U', '1', '6') +/** + * @brief Definition for the TBM surface format YVU422 (2x1 subsampled Cr (1) and Cb (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YVU422 __tbm_fourcc_code('Y', 'V', '1', '6') +/** + * @brief Definition for the TBM surface format YUV444 (non-subsampled Cb (1) and Cr (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YUV444 __tbm_fourcc_code('Y', 'U', '2', '4') +/** + * @brief Definition for the TBM surface format YVU444 (non-subsampled Cr (1) and Cb (2) planes). + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define TBM_FORMAT_YVU444 __tbm_fourcc_code('Y', 'V', '2', '4') + +/* 2 plane YCbCr */ +/** + * @brief Definition for the TBM surface format NV12MT (tiled '64x32' & multi-plane version of NV12). + * @since_tizen 3.0 @endif + */ +#define TBM_FORMAT_NV12MT __tbm_fourcc_code('T', 'M', '1', '2') + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Queries surface format list and number of format supported by the system. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks You must release the formats using free(). + * + * @param[out] formats The format array which the system can support \n + * This pointer has to be freed by user. + * @param[out] num The number of formats + * + * @return #TBM_SURFACE_ERROR_NONE if this function succeeds, + * otherwise an error status value + * + * @retval #TBM_SURFACE_ERROR_NONE Success + * @retval #TBM_SURFACE_ERROR_INVALID_OPERATION Invalid operation + * + * @par Example + @code + #include + + uint32_t *formats; + uint32_t format_num; + int ret, i; + + if (tbm_surface_query_formats (&formats, &format_num)) + { + for( i = 0 ; i < format_num ; i++) + { + if (formats[i] == TBM_FORMAT_RGB332) + { + + .... + + free (formats); + @endcode + */ +int tbm_surface_query_formats(uint32_t **formats, uint32_t *num); + +/** + * @brief Creates the tbm_surface. + * @details This function creates the tbm_surface with the given width, height, and format. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remark The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * + * @param[in] width The width of surface + * @param[in] height The height of surface + * @param[in] format The format of surface + * + * @return #tbm_surface_h on success, + * otherwise @c NULL + * + * @retval #tbm_surface_h The TBM surface handle + * + * @exception #TBM_SURFACE_ERROR_NONE Success + * @exception #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * @exception #TBM_SURFACE_ERROR_INVALID_OPERATION Invalid operation + * + * @see tbm_surface_destroy() + * + * @par Example + @code + #include + + tbm_surface_h surface; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +tbm_surface_h tbm_surface_create(int width, int height, tbm_format format); + +/** + * @brief Destroys the tbm_surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] surface The #tbm_surface_h + * + * @return #TBM_SURFACE_ERROR_NONE on success, + * otherwise an error status value + * + * @retval #TBM_SURFACE_ERROR_NONE Success + * @retval #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see tbm_surface_create() + * + * @par Example + @code + #include + + tbm_surface_h surface; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_destroy(tbm_surface_h surface); + +/** + * @brief Maps the tbm_surface according to the access option. + * @details After mapping tbm_surface, the information of tbm_surface is assigned in #tbm_surface_info_s struct. \n + * The information of tbm_surface has width, height, format, bpp, size, number of planes and information of planes. \n + * The information of planes has stride, offset, size and pointer of plane. \n + * #TBM_SURF_OPTION_READ indicates access option to read. \n + * #TBM_SURF_OPTION_WRITE indicates access option to write. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] surface The #tbm_surface_h + * @param[in] opt The option to access the tbm_surface + * @param[out] info The information of the tbm_surface + * + * @return #TBM_SURFACE_ERROR_NONE on success, + * otherwise an error status value + * + * @retval #TBM_SURFACE_ERROR_NONE Success + * @retval #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #TBM_SURFACE_ERROR_INVALID_OPERATION Invalid operation + * + * @see tbm_surface_unmap(); + * + * @par Example + @code + #include + + tbm_surface_h surface; + tbm_surface_info_s info; + int ret; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + ret = tbm_surface_map (surface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, &info); + + ... + + tbm_surface_unmap (surface); + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_map(tbm_surface_h surface, int opt, tbm_surface_info_s *info); + +/** + * @brief Unmaps the tbm_surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] surface The #tbm_surface_h + * + * @return #TBM_SURFACE_ERROR_NONE on success, + * otherwise an error status value + * + * @retval #TBM_SURFACE_ERROR_NONE Success + * @retval #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see tbm_surface_map() + * + * @par Example + @code + #include + + tbm_surface_h surface; + tbm_surface_info_s info; + int ret; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + ret = tbm_surface_map (surface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, &info); + + ... + + tbm_surface_unmap (surface); + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_unmap(tbm_surface_h surface); + +/** + * @brief Gets the information of the tbm_surface. + * @details The information of tbm_surface is assigned in #tbm_surface_info_s struct. \n + * The information of tbm_surface has width, height, format, bpp, size, number of planes and information of planes. \n + * The information of planes has stride, offset, size and pointer of plane. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] surface The #tbm_surface_h + * @param[out] info The information of the tbm_surface + * + * @return #TBM_SURFACE_ERROR_NONE on success, + * otherwise an error status value + * + * @retval #TBM_SURFACE_ERROR_NONE Success + * @retval #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #TBM_SURFACE_ERROR_INVALID_OPERATION Invalid operation + * + * @see tbm_surface_map() + * + * @par Example + @code + #include + + tbm_surface_h surface; + tbm_surface_info_s info; + int ret; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + ret = tbm_surface_get_info (surface, &info); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_get_info(tbm_surface_h surface, tbm_surface_info_s *info); + +/** + * @brief Gets the width of the tbm_surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] surface The #tbm_surface_h + * + * @return The width of the tbm_surface on success, + * otherwise an error status value + * + * @retval #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * + * @par Example + @code + #include + + tbm_surface_h surface; + int width; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + + ... + + width = tbm_surface_get_width (surface); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_get_width(tbm_surface_h surface); + +/** + * @brief Gets the height of the tbm_surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] surface The #tbm_surface_h + * + * @return The height of the tbm_surface if this function succeeds, + * otherwise an error status value + * + * @retval #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * + * @par Example + @code + #include + + tbm_surface_h surface; + int height; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + + ... + + height = tbm_surface_get_height (surface); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_get_height(tbm_surface_h surface); + +/** + * @brief Gets the format of the tbm_surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remark The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * + * @param[in] surface The #tbm_surface_h + * + * @return The format of the tbm_surface on success, + * otherwise @c 0 on failure + * + * @retval #tbm_format The format of surface + * + * @exception #TBM_SURFACE_ERROR_NONE Success + * @exception #TBM_SURFACE_ERROR_INVALID_PARAMETER Invalid parameter + * + * @par Example + @code + #include + + tbm_surface_s surface; + tbm_format format; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_RGB332); + + ... + + format = tbm_surface_get_format (surface); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +tbm_format tbm_surface_get_format(tbm_surface_h surface); + +#ifdef __cplusplus +} +#endif +/** +* @} +*/ +#endif /* _TBM_SURFACE_H_ */ diff --git a/ut/stubs/tbm_surface_internal.h b/ut/stubs/tbm_surface_internal.h new file mode 100644 index 0000000..367adf6 --- /dev/null +++ b/ut/stubs/tbm_surface_internal.h @@ -0,0 +1,367 @@ +#ifndef _TBM_SURFACE_INTERNAL_H_ +#define _TBM_SURFACE_INTERNAL_H_ + +#include + + +/** + * @brief Queries formats which the system can support. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The formats must be released using free(). + * @param[in] bufmgr : the buffer manager + * @param[out] *formats : format array which the system can support. This pointer has to be freed by user. + * @param[out] num : the number of formats. + * @return a tbm_surface_h if this function succeeds, otherwise NULL + * @par Example + @code + #include + #include + + tbm_bufmgr bufmgr; + uint32_t *formats; + uint32_t format_num; + + bufmgr = tbm_bufmgr_create (-1); + ret = tbm_surface_internal_query_surpported_foramts (bufmgr, &formats, &format_num); + + ... + + free (foramts); + tbm_surface_bufmgr_deinit (bufmgr); + @endcode + */ +int tbm_surface_internal_query_supported_formats(uint32_t **formats, + uint32_t *num); + +/** + * @brief Creates the tbm_surface with memory type. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @details + * #TBM_BO_DEFAULT is default memory: it depends on the backend\n + * #TBM_BO_SCANOUT is scanout memory\n + * #TBM_BO_NONCACHABLE is non-cachable memory\n + * #TBM_BO_WC is write-combine memory\n + * #TBM_BO_VENDOR vendor specific memory: it depends on the tbm backend\n + * @param[in] bufmgr : the buffer manager + * @param[in] width : the width of surface + * @param[in] height : the height of surface + * @param[in] format : the format of surface + * @param[in] flags : the flags of memory type + * @return a tbm_surface_h if this function succeeds, otherwise NULL + * @retval #tbm_surface_h + * @par Example + @code + #include + #include + + int bufmgr_fd + tbm_bufmgr bufmgr; + tbm_surface_h surface; + uint32_t *format; + uint32_t format_num; + + bufmgr = tbm_bufmgr_create (bufmgr_fd); + surface = tbm_surface_internal_create_with_flags (128, 128, TBM_FORMAT_YUV420, TBM_BO_DEFAULT); + + ... + + tbm_surface_destroy (surface); + tbm_surface_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_surface_h tbm_surface_internal_create_with_flags(int width, int height, + int format, int flags); + +/** + * @brief Creates the tbm_surface with buffer objects. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] bufmgr : the buffer manager + * @param[in] width : the width of surface + * @param[in] height : the height of surface + * @param[in] format : the format of surface + * @param[in] *bos : the array pointer of buffer objects + * @param[in] num : the number of buffer objects + * @return a tbm_surface_h if this function succeeds, otherwise NULL + * @retval #tbm_surface_h + * @par Example + @code + #include + #include + #include + + int bufmgr_fd + tbm_bufmgr bufmgr; + tbm_surface_h surface; + tbm_surface_info_s info; + uint32_t *format; + uint32_t format_num; + tbm_bo bo[1]; + + bufmgr = tbm_bufmgr_init (bufmgr_fd); + bo[0] = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT); + + info.width = 128; + info.height = 128; + info.format = TBM_FORMAT_ARGB8888; + info.bpp = 32; + info.size = 65536; + info.num_planes = 1; + info.planes[0].size = 65536; + info.planes[0].offset = 0; + info.planes[0].stride = 512; + + surface = tbm_surface_internal_create_with_bos (&info, bo, 1); + + ... + + tbm_surface_destroy (surface); + tbm_surface_bufmgr_deinit (bufmgr); + @endcode + */ +tbm_surface_h tbm_surface_internal_create_with_bos(tbm_surface_info_s *info, + tbm_bo *bos, int num); + +/** + * @brief Destroy the tbm surface + TODO: + */ +void tbm_surface_internal_destroy(tbm_surface_h surface); + +/** + * @brief reference the tbm surface + TODO: + */ +void tbm_surface_internal_ref(tbm_surface_h surface); + +/** + * @brief unreference the tbm surface + TODO: + */ +void tbm_surface_internal_unref(tbm_surface_h surface); + +/** + * @brief Gets the number of buffer objects associated with the tbm_surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] surface : the tbm_surface_h + * @return the number of buffer objects associated with the tbm_surface_h, otherwise -1. + * @par Example + @code + #include + #include + + tbm_surface_h surface; + int num_bos; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_YUV420); + num_bos = tbm_surface_internal_get_num_bos (surface); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_internal_get_num_bos(tbm_surface_h surface); + +/** + * @brief Gets the buffor object by the bo_index. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] surface : the tbm_surface_h + * @param[in] bo_idx : the bo index in the the tbm_surface + * @return the buffer object, otherwise NULL. + * @retval #tbm_bo + * @par Example + @code + #include + #include + + tbm_surface_h surface; + int num_bos; + tbm_bo bo; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_YUV420); + num_bos = tbm_surface_internal_get_num_bos (surface); + + for (i=0 ; i < num_bos ; i++) + { + bo = tbm_surface_internal_get_bo (surface, i); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +tbm_bo tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx); + +/** + * @brief Gets the size of the surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] surface : the tbm_surface_h + * @return the size of tbm_surface, otherwise -1. + * @par Example + @code + #include + #include + + tbm_surface_h surface; + int size; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_YUV420); + size = tbm_surface_internal_get_size (surface); + + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_internal_get_size(tbm_surface_h surface); + +/** + * @brief Gets size, offset and pitch data of plane by the plane_index. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] surface : the tbm_surface_h + * @param[in] plane_idx : the bo index in the the tbm_surface + * @param[out] size : the size of plane in tbm_surface + * @param[out] offset : the offset of plane in tbm_surface + * @param[out] pitch : the pitch of plane in tbm_surface + * @return 1 if this function succeeds, otherwise 0. + * @par Example + @code + #include + #include + + tbm_surface_h surface; + uint32_t size, offset, pitch; + int ret; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_YUV420); + ret = tbm_surface_internal_get_plane_data (surface, 1, &size, &offset, &pitch); + + ... + + tbm_surface_destroy (surface); + @endcode + */ +int tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx, + uint32_t *size, uint32_t *offset, uint32_t *pitch); + +/** + * @brief Gets number of planes by the format. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] format : the format of surface + * @return number of planes by the format, otherwise 0. + * @par Example + @code + #include + #include + + int num; + + num = tbm_surface_internal_get_num_planes (TBM_FORMAT_YUV420); + + ... + + @endcode + */ +int tbm_surface_internal_get_num_planes(tbm_format format); + +/** + * @brief Gets bpp by the format. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] format : the format of surface + * @return bpp by the format, otherwise 0. + * @par Example + @code + #include + #include + + int bpp; + + bpp = tbm_surface_internal_get_bpp (TBM_FORMAT_YUV420); + + ... + + @endcode + */ +int tbm_surface_internal_get_bpp(tbm_format format); + +/** + * @brief Gets bo index of plane. + * @since_tizen 2.4 + * @param[in] surface : the tbm_surface_h + * @param[in] plane_idx : the bo index in the tbm_surface + * @return bo index of plane, otherwise -1. + * @par Example + @code + #include + #include + + int bo_idx; + tbm_surface_h surface; + + surface = tbm_surface_create (128, 128, TBM_FORMAT_YUV420); + bo_idx = tbm_surface_internal_get_plane_bo_idx (surface, 0); + + ... + + @endcode + */ +int tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx); + +/** + * @brief Set the pid to the tbm_surface for debugging. + * @since_tizen 3.0 + * @param[in] surface : the tbm_surface_h + * @param[in] pid : the pid + */ +void tbm_surface_internal_set_debug_pid(tbm_surface_h surface, + unsigned int pid); + +/** + * @brief Adds a user_data to the tbm surface. + * @since_tizen 3.0 + * @param[in] surface : the tbm surface. + * @param[in] key : the key associated with the user_data + * @param[in] data_free_func : the function pointer to free the user_data + * @return 1 if this function succeeds, otherwise 0. + * @post the tbm_surface_data_free() will be called under certain conditions, after calling tbm_surface_internal_delete_user_data(). + * @see tbm_surface_free() + * @see tbm_surface_set_user_data() + * @see tbm_surface_get_user_data() + * @see tbm_surface_delete_user_data() + */ +int tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key, + tbm_data_free data_free_func); + +/** + * @brief Sets a user_date to the tbm surface. + * @since_tizen 3.0 + * @param[in] surface : the tbm surface. + * @param[in] key : the key associated with the user_date + * @param[in] data : a pointer of the user_data + * @return 1 if this function succeeds, otherwise 0. + */ +int tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key, + void *data); + +/** + * @brief Gets a user_data from the tbm surface with the key. + * @since_tizen 3.0 + * @param[in] surface : the tbm surface. + * @param[in] key : the key associated with the user_date + * @param[out] data : to get the user data + * @return 1 if this function succeeds, otherwise 0. + */ +int tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key, + void **data); + +/** + * @brief Deletes the user_data in the tbm surface. + * @since_tizen 3.0 + * @param[in] surface : the tbm surface. + * @param[in] key : the key associated with the user_date + * @return 1 if this function succeeds, otherwise 0. + */ +int tbm_surface_internal_delete_user_data(tbm_surface_h surface, + unsigned long key); + +void tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type); + +#endif /* _TBM_SURFACE_INTERNAL_H_ */ diff --git a/ut/stubs/tbm_surface_queue.h b/ut/stubs/tbm_surface_queue.h new file mode 100644 index 0000000..a3216d3 --- /dev/null +++ b/ut/stubs/tbm_surface_queue.h @@ -0,0 +1,125 @@ +#ifndef _TBM_SURFACE_QUEUE_H_ +#define _TBM_SURFACE_QUEUE_H_ + +#include + +typedef enum { + TBM_SURFACE_QUEUE_ERROR_NONE = 0, /**< Successful */ + TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE = -1, + TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE = -2, + TBM_SURFACE_QUEUE_ERROR_EMPTY = -3, + TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER = -4, + TBM_SURFACE_QUEUE_ERROR_SURFACE_ALLOC_FAILED = -5, +} tbm_surface_queue_error_e; + +typedef struct _tbm_surface_queue *tbm_surface_queue_h; + +typedef void (*tbm_surface_queue_notify_cb) (tbm_surface_queue_h surface_queue, + void *data); + +typedef tbm_surface_h (*tbm_surface_alloc_cb) (tbm_surface_queue_h surface_queue, + void *data); + +typedef void (*tbm_surface_free_cb) (tbm_surface_queue_h surface_queue, + void *data, tbm_surface_h surface); + +#ifdef __cplusplus +extern "C" { +#endif + +tbm_surface_queue_error_e tbm_surface_queue_enqueue( + tbm_surface_queue_h surface_queue, tbm_surface_h surface); + +tbm_surface_queue_error_e tbm_surface_queue_dequeue( + tbm_surface_queue_h surface_queue, tbm_surface_h *surface); + +tbm_surface_queue_error_e tbm_surface_queue_release( + tbm_surface_queue_h surface_queue, tbm_surface_h surface); + +tbm_surface_queue_error_e tbm_surface_queue_acquire( + tbm_surface_queue_h surface_queue, tbm_surface_h *surface); + +int tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait); + +int tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait); + +void tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue); + +int tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue); + +int tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue); + +int tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue); + +int tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue); + +tbm_surface_queue_error_e tbm_surface_queue_reset( + tbm_surface_queue_h surface_queue, int width, int height, int format); + +tbm_surface_queue_error_e tbm_surface_queue_flush(tbm_surface_queue_h surface_queue); + +tbm_surface_queue_error_e tbm_surface_queue_add_reset_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_reset_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_add_destroy_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_destroy_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_add_dequeuable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_dequeuable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_add_acquirable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_acquirable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_set_alloc_cb( + tbm_surface_queue_h surface_queue, + tbm_surface_alloc_cb alloc_cb, + tbm_surface_free_cb free_cb, + void *data); + +/*The functions of queue factory*/ +tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width, + int height, int format, int flags); +tbm_surface_queue_h tbm_surface_queue_sequence_create(int queue_size, int width, + int height, int format, int flags); + + +/*DEPRECATED apis*/ +tbm_surface_queue_error_e tbm_surface_queue_set_destroy_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_set_dequeuable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_set_acquirable_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, + void *data); + +tbm_surface_queue_error_e tbm_surface_queue_set_reset_cb( + tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, + void *data); +#ifdef __cplusplus +} +#endif +#endif /* _TBM_SURFACE_H_ */ diff --git a/ut/stubs/tbm_type.h b/ut/stubs/tbm_type.h new file mode 100644 index 0000000..ff0a705 --- /dev/null +++ b/ut/stubs/tbm_type.h @@ -0,0 +1,26 @@ +#ifndef _TBM_TYPE_H_ +#define _TBM_TYPE_H_ + +/** + * @addtogroup CAPI_UI_TBM_SURFACE_MODULE + * @{ + */ + +#include + +/** + * @brief Definition for the Tizen buffer surface. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _tbm_surface *tbm_surface_h; +/** + * @brief Definition for the Tizen buffer surface format. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef uint32_t tbm_format; + +/** +* @} +*/ + +#endif /* _TBM_TYPE_H_ */ diff --git a/ut/stubs/tdm_capture_stubs.h b/ut/stubs/tdm_capture_stubs.h new file mode 100644 index 0000000..78a5e05 --- /dev/null +++ b/ut/stubs/tdm_capture_stubs.h @@ -0,0 +1,79 @@ +#ifndef _TDM_CAPTURE_STUBS_H +#define _TDM_CAPTURE_STUBS_H + +static int OUTPUT_CREATE_CAPTURE_ERROR; +static int CAPTURE_SET_DONE_HANDLER_ERROR; +static int LAYER_CREATE_CAPTURE_ERROR; +static int CAPTURE_SET_INFO_ERROR; +static int CAPTURE_ATTACH_ERROR; +static int CAPTURE_COMMIT_ERROR; + +static tdm_capture *output_create_capture(tdm_output *output, tdm_error *error) +{ + if (OUTPUT_CREATE_CAPTURE_ERROR) { + *error = TDM_ERROR_OPERATION_FAILED; + return NULL; + } + + *error = TDM_ERROR_NONE; + + return NULL; +} + +static void capture_destroy(tdm_capture *capture) +{ + +} + +static tdm_error capture_set_done_handler(tdm_capture *capture, + tdm_capture_done_handler func, void *user_data) +{ + if (CAPTURE_SET_DONE_HANDLER_ERROR) { + if (user_data) { + free(user_data); + } + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_capture *layer_create_capture(tdm_layer *layer, tdm_error *error) +{ + if (LAYER_CREATE_CAPTURE_ERROR) { + *error = TDM_ERROR_OPERATION_FAILED; + return NULL; + } + + *error = TDM_ERROR_NONE; + return NULL; +} + +static tdm_error capture_set_info(tdm_capture *capture, tdm_info_capture *info) +{ + if (CAPTURE_SET_INFO_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error capture_attach(tdm_capture *capture, tbm_surface_h buffer) +{ + if (CAPTURE_ATTACH_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error capture_commit(tdm_capture *capture) +{ + if (CAPTURE_COMMIT_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +#endif /* _TDM_CAPTURE_STUBS_H */ diff --git a/ut/stubs/tdm_display_stubs.h b/ut/stubs/tdm_display_stubs.h new file mode 100644 index 0000000..bc627bb --- /dev/null +++ b/ut/stubs/tdm_display_stubs.h @@ -0,0 +1,269 @@ +#ifndef _TDM_DISPLAY_STUBS_H +#define _TDM_DISPLAY_STUBS_H + +#include "tdm_private.h" + +static int DISPLAY_GET_FD_ERROR; +static int TDM_PP_CREATE_INTERNAL_ERROR; +static int OUTPUT_SET_PROPERTY_ERROR; +static int OUTPUT_GET_PROPERTY_ERROR; +static int OUTPUT_WAIT_VBLANK_ERROR; +static int OUTPUT_SET_VBLANK_HANDLER; +static int OUTPUT_COMMIT_ERROR; +static int OUTPUT_SET_COMMIT_HANDLER; +static int OUTPUT_SET_MODE_ERROR; +static int OUTPUT_SET_DPMS_ERROR; +static int OUTPUT_GET_DPMS_ERROR; +static int TDM_CAPTURE_CREATE_OUTPUT_INTENAL_ERROR; +static int LAYER_SET_PROPERTY_ERROR; +static int LAYER_GET_PROPERTY_ERROR; +static int LAYER_SET_INFO_ERROR; +static int LAYER_SET_BUFFER_ERROR; +static int LAYER_UNSET_BUFFER_ERROR; +static int LAYER_SET_VIDEO_POS_ERROR; +static int CAPTURE_CREATE_LAYER_INTERNAL_ERROR; +static int TDM_THREAD_HANDLE_ERROR; +static int TDM_EVENT_LOOP_DISPATCH_ERROR; + +static tdm_error display_get_fd(tdm_backend_data * bdata, int *fd) +{ + if (DISPLAY_GET_FD_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; + +} + +static tdm_private_pp *ut_tdm_pp_create_internal(tdm_private_display * + private_display, + tdm_error * error) +{ + if (TDM_PP_CREATE_INTERNAL_ERROR) { + if (error) { + *error = TDM_ERROR_OPERATION_FAILED; + } + return NULL; + } + + if (error) { + *error = TDM_ERROR_NONE; + } + return NULL; +} + +static tdm_error output_set_property(tdm_output * output, unsigned int id, + tdm_value value) +{ + if (OUTPUT_SET_PROPERTY_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error output_get_property(tdm_output * output, unsigned int id, + tdm_value * value) +{ + if (OUTPUT_GET_PROPERTY_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static void ut_tdm_output_vblank_handler(tdm_output * output, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, void *user_data) +{ + +} + +static tdm_error output_wait_vblank(tdm_output * output, int interval, int sync, + void *user_data) +{ + free(user_data); + if (OUTPUT_WAIT_VBLANK_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error output_set_vblank_handler(tdm_output * output, + tdm_output_vblank_handler func) +{ + if (OUTPUT_SET_VBLANK_HANDLER) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error output_commit(tdm_output * output, int sync, void *user_data) +{ + free(user_data); + if (OUTPUT_COMMIT_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error output_set_commit_handler(tdm_output * output, + tdm_output_commit_handler func) +{ + if (OUTPUT_SET_COMMIT_HANDLER) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error output_set_mode(tdm_output * output, const tdm_output_mode * mode) +{ + if (OUTPUT_SET_MODE_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error output_set_dpms(tdm_output * output, tdm_output_dpms dpms_value) +{ + if (OUTPUT_SET_DPMS_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error output_get_dpms(tdm_output * output, tdm_output_dpms dpms_value) +{ + if (OUTPUT_GET_DPMS_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_private_capture *ut_tdm_capture_create_output_internal(tdm_private_output + *private_output, + tdm_error *error) +{ + if (TDM_CAPTURE_CREATE_OUTPUT_INTENAL_ERROR) { + *error = TDM_ERROR_OPERATION_FAILED; + return NULL; + } + + *error = TDM_ERROR_NONE; + return NULL; +} + +static tdm_error layer_set_property(tdm_layer *layer, unsigned int id, + tdm_value value) +{ + if (LAYER_SET_PROPERTY_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error layer_get_property(tdm_layer *layer, unsigned int id, + tdm_value value) +{ + if (LAYER_GET_PROPERTY_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error layer_set_info(tdm_layer *layer, tdm_info_layer *info) +{ + if (LAYER_SET_INFO_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +tdm_error layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) +{ + if (LAYER_SET_BUFFER_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +tbm_surface_h ut_tdm_buffer_ref_backend(tbm_surface_h buffer) +{ +} + +tdm_error layer_unset_buffer(tdm_layer *layer) +{ + if (LAYER_UNSET_BUFFER_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static int ut_tdm_thread_get_fd(tdm_private_loop *private_loop) +{ + return 1; +} + +static int ut_tdm_event_loop_get_fd(tdm_private_display *private_display) +{ + return 1; +} + +static tdm_error layer_set_video_pos(tdm_layer *layer, int zpos) +{ + if (LAYER_SET_VIDEO_POS_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_private_capture * +ut_tdm_capture_create_layer_internal(tdm_private_layer *private_layer, + tdm_error *error) +{ + if (CAPTURE_CREATE_LAYER_INTERNAL_ERROR) { + *error = TDM_ERROR_OPERATION_FAILED; + return NULL; + } + + *error = TDM_ERROR_NONE; + return NULL; +} + +static int ut_poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + return 1; +} + +static tdm_error ut_tdm_thread_handle_cb(tdm_private_loop *private_loop) +{ + if (TDM_THREAD_HANDLE_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} +static tdm_error ut_tdm_event_loop_dispatch(tdm_private_display *private_display) +{ + if (TDM_EVENT_LOOP_DISPATCH_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +#endif /* _TDM_DISPLAY_STUBS_H */ diff --git a/ut/stubs/tdm_helper_stubs.h b/ut/stubs/tdm_helper_stubs.h new file mode 100644 index 0000000..f25b9a1 --- /dev/null +++ b/ut/stubs/tdm_helper_stubs.h @@ -0,0 +1,47 @@ +#ifndef _TDM_HELPER_STUBS_H +#define _TDM_HELPER_STUBS_H + +/* HELPER FUNCTIONS */ + +static int GETENV_ERROR; +static int SSCANF_ERROR; +static int FCNTL_ERROR; +static int DUP_ERROR; + +static char *ut_getenv(const char *name) +{ + if (GETENV_ERROR) { + return NULL; + } + + return "getenv"; +} + +static int ut_sscanf(const char *buf, const char *format, ...) +{ + if (SSCANF_ERROR) { + return -1; + } + + return 0; +} + +static int ut_fcntl(int fd, int cmd, ...) +{ + if (FCNTL_ERROR) { + return -1; + } + + return 0; +} + +static int ut_dup(int fd) +{ + if (DUP_ERROR) { + return -1; + } + + return 2; +} + +#endif /* _TDM_HELPER_STUBS_H */ diff --git a/ut/stubs/tdm_list_stubs.h b/ut/stubs/tdm_list_stubs.h new file mode 100644 index 0000000..bd483d4 --- /dev/null +++ b/ut/stubs/tdm_list_stubs.h @@ -0,0 +1,78 @@ +/** + * \file + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + * + * Is not threadsafe, so common operations need to + * be protected using an external mutex. + */ +#ifndef _U_DOUBLE_LIST_H_ +#define _U_DOUBLE_LIST_H_ + +#include + +struct list_head { + struct list_head *prev; + struct list_head *next; +}; + +static inline void list_inithead(struct list_head *item) { } + +static inline void list_add(struct list_head *item, struct list_head *list) { } + +static inline void list_addtail(struct list_head *item, struct list_head *list) { } + +static inline void list_replace(struct list_head *from, struct list_head *to) { } + +static inline void list_del(struct list_head *item) { } + +static inline void list_delinit(struct list_head *item) { } + +#define LIST_INITHEAD(__item) list_inithead(__item) +#define LIST_ADD(__item, __list) list_add(__item, __list) +#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list) +#define LIST_REPLACE(__from, __to) list_replace(__from, __to) +#define LIST_DEL(__item) list_del(__item) +#define LIST_DELINIT(__item) list_delinit(__item) + +#define LIST_ENTRY(__type, __item, __field) \ + ((__type *)(((char *)(__item)) - offsetof(__type, __field))) + +#define LIST_IS_EMPTY(__list) \ + ((__list)->next == (__list)) + +#ifndef container_of +#define container_of(ptr, sample, member) \ + (void *)((char *)(ptr) \ + - ((char *)&(sample)->member - (char *)(sample))) +#endif + +#define LIST_FOR_EACH_ENTRY(pos, head, member) \ + for (; \ + 1 < 0; \ + ) + +#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \ + for (; \ + 1 < 0; \ + ) + +#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \ + for (pos = container_of((head)->prev, pos, member), \ + storage = container_of(pos->member.prev, pos, member); \ + &pos->member != (head); \ + pos = storage, storage = container_of(storage->member.prev, storage, member)) + +#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \ + for (pos = container_of((start), pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.next, pos, member)) + +#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \ + for (pos = container_of((start), pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.prev, pos, member)) + +#define LIST_LENGTH(__item) 1 + +#endif /*_U_DOUBLE_LIST_H_*/ diff --git a/ut/stubs/tdm_log.cpp b/ut/stubs/tdm_log.cpp new file mode 100644 index 0000000..c450d2c --- /dev/null +++ b/ut/stubs/tdm_log.cpp @@ -0,0 +1,26 @@ +#include "tdm_log.h" + +void +tdm_log_enable_color(unsigned int enable) +{ +} + +void +tdm_log_enable_dlog(unsigned int enable) +{ +} + +void +tdm_log_enable_debug(unsigned int enable) +{ +} + +void +tdm_log_set_debug_level(int level) +{ +} + +void +tdm_log_print(int level, const char *fmt, ...) +{ +} diff --git a/ut/stubs/tdm_pp_stubs.h b/ut/stubs/tdm_pp_stubs.h new file mode 100644 index 0000000..24cdab1 --- /dev/null +++ b/ut/stubs/tdm_pp_stubs.h @@ -0,0 +1,50 @@ +#ifndef _TDM_PP_STUBS_H +#define _TDM_PP_STUBS_H + +static int PP_SET_INFO_ERROR; +static int PP_ATACH_ERROR; +static int PP_COMMIT_ERROR; + +static tdm_buffer_info *ut_tdm_buffer_get_info(tbm_surface_h buffer) +{ + +} + +static void ut_tdm_buffer_list_dump(struct list_head *list) +{ + +} + +static tbm_surface_h ut_tdm_buffer_ref_backend(tbm_surface_h buffer) +{ + +} + +static tdm_error pp_set_info(tdm_pp *pp, tdm_info_pp *info) +{ + if (PP_SET_INFO_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) +{ + if (PP_ATACH_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +static tdm_error pp_commit(tdm_pp *pp) +{ + if (PP_COMMIT_ERROR) { + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +#endif /* _TDM_PP_STUBS_H */ diff --git a/ut/stubs/tdm_server.cpp b/ut/stubs/tdm_server.cpp new file mode 100644 index 0000000..3ca97e0 --- /dev/null +++ b/ut/stubs/tdm_server.cpp @@ -0,0 +1,12 @@ +#include +#include "tdm_private.h" + +tdm_error +tdm_server_init(tdm_private_loop *private_loop) +{ +} + +void +tdm_server_deinit(tdm_private_loop *private_loop) +{ +} diff --git a/ut/stubs/tdm_thread.cpp b/ut/stubs/tdm_thread.cpp new file mode 100644 index 0000000..3c2cffb --- /dev/null +++ b/ut/stubs/tdm_thread.cpp @@ -0,0 +1,39 @@ +#include "tdm.h" +#include "tdm_private.h" + +int TDM_THREAD_IS_RUNNING = 0; + +tdm_error +tdm_thread_init(tdm_private_loop *private_loop) +{ +} + +void +tdm_thread_deinit(tdm_private_loop *private_loop) +{ +} + +int +tdm_thread_get_fd(tdm_private_loop *private_loop) +{ +} +tdm_error +tdm_thread_send_cb(tdm_private_loop *private_loop, tdm_thread_cb_base *base) +{ +} + +tdm_error +tdm_thread_handle_cb(tdm_private_loop *private_loop) +{ +} + +int +tdm_thread_in_display_thread(pid_t tid) +{ +} + +int +tdm_thread_is_running(void) +{ + return TDM_THREAD_IS_RUNNING; +} diff --git a/ut/stubs/tdm_vblank.cpp b/ut/stubs/tdm_vblank.cpp new file mode 100644 index 0000000..3d4c4f6 --- /dev/null +++ b/ut/stubs/tdm_vblank.cpp @@ -0,0 +1,123 @@ +#include "tdm.h" +#include "tdm_private.h" + +#define TDM_VBLANK_UINT_MAX 4294967295U +#define TDM_VBLANK_UINT_1Q 1073741823U /* UINT_MAX / 4 */ +#define TDM_VBLANK_UINT_3Q 3221225471U /* UINT_MAX / 4 * 3 */ + +#define TDM_VBLANK_SEQ_REACHED_MAX(seq, last_seq) \ + ((seq) < TDM_VBLANK_UINT_1Q && TDM_VBLANK_UINT_3Q < (last_seq)) + +#define VER(fmt, arg...) TDM_ERR("[%p] "fmt, private_vblank, ##arg) +#define VWR(fmt, arg...) TDM_WRN("[%p] "fmt, private_vblank, ##arg) +#define VIN(fmt, arg...) TDM_INFO("[%p] "fmt, private_vblank, ##arg) +#define VDB(fmt, arg...) TDM_DBG("[%p] "fmt, private_vblank, ##arg) + +typedef enum { + VBLANK_TYPE_SW, + VBLANK_TYPE_SW_FAKE, + VBLANK_TYPE_HW, + VBLANK_TYPE_HW_SW, +} tdm_vblank_wait_type; + +typedef struct _tdm_vblank_wait_info tdm_vblank_wait_info; + +typedef struct _tdm_private_vblank { + struct list_head link; + + tdm_display *dpy; + tdm_output *output; + tdm_output_dpms dpms; + unsigned int vrefresh; + + unsigned int check_HW_or_SW; + unsigned int fps; + int offset; + unsigned int enable_fake; + + double vblank_gap; + unsigned int quotient; + + unsigned int last_seq; + unsigned int last_tv_sec; + unsigned int last_tv_usec; + + /* for HW */ + double HW_vblank_gap; + struct list_head HW_wait_list; + + /* for SW */ + tdm_event_loop_source *SW_timer; + struct list_head SW_wait_list; +} tdm_private_vblank; + +struct _tdm_vblank_wait_info { + struct list_head link; + struct list_head valid_link; + + unsigned int stamp; + + unsigned int req_sec; + unsigned int req_usec; + unsigned int interval; + + tdm_vblank_handler func; + void *user_data; + tdm_private_vblank *private_vblank; + + tdm_vblank_wait_type type; + + unsigned int target_sec; + unsigned int target_usec; + unsigned int target_seq; +}; + +static struct list_head vblank_list; +static struct list_head valid_wait_list; +static unsigned int vblank_list_inited; +static unsigned int stamp = 0; + +static tdm_error _tdm_vblank_cb_vblank_SW(void *user_data); +static tdm_error _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info); + +tdm_vblank* +tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) +{ +} + +void +tdm_vblank_destroy(tdm_vblank *vblank) +{ +} + +tdm_error +tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps) +{ +} + +tdm_error +tdm_vblank_set_offset(tdm_vblank *vblank, int offset) +{ +} + +tdm_error +tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake) +{ +} + +unsigned int +tdm_vblank_get_enable_fake(tdm_vblank *vblank) +{ +} + +tdm_error +tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, + unsigned int interval, tdm_vblank_handler func, void *user_data) +{ +} + +tdm_error +tdm_vblank_wait_seq(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, + unsigned int sequence, tdm_vblank_handler func, void *user_data) +{ +} diff --git a/ut/stubs/wayland-server-core.h b/ut/stubs/wayland-server-core.h new file mode 100644 index 0000000..93e38ba --- /dev/null +++ b/ut/stubs/wayland-server-core.h @@ -0,0 +1,210 @@ +#ifndef WAYLAND_SERVER_CORE_H +#define WAYLAND_SERVER_CORE_H + +#include + +static int WL_EVENT_LOOP_ADD_FD_ERROR; +static int WL_EVENT_SOURCE_FD_UPDATE_ERROR; +static int WL_EVENT_LOOP_ADD_TIMER_ERROR; +static int WL_EVENT_SOURCE_TIMER_UPDATE_ERROR; + +enum { + WL_EVENT_READABLE = 0x01, + WL_EVENT_WRITABLE = 0x02, + WL_EVENT_HANGUP = 0x04, + WL_EVENT_ERROR = 0x08 +}; + +struct wl_interface { + int a; +}; + +struct wl_interface wl_tdm_interface; + +struct wl_interface wl_tdm_vblank_interface; + +typedef enum { + WL_TDM_ERROR_INVALID_NAME, + WL_TDM_ERROR_OPERATION_FAILED + +} wl_error; + +struct wl_display { + int a; +}; + +struct wl_tdm_interface { + void (*_tdm_server_cb_wait_vblank)(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, const char *name, int32_t interval); +}; + +struct wl_event_loop { + int temp; +}; + +struct wl_event_source { + int temp; +}; + +static void wl_display_flush_clients(struct wl_display *display) +{ + +} + +static struct wl_display *wl_display_create(void) +{ + +} + +static struct wl_event_loop *wl_display_get_event_loop(struct wl_display *display) +{ + +} + +static void wl_display_destroy(struct wl_display *display) +{ + +} + +static int wl_event_loop_get_fd(struct wl_event_loop *loop) +{ +} + +static void wl_resource_post_error(struct wl_resource *resource, + uint32_t code, const char *msg, ...) +{ + +} + +static struct wl_resource *wl_resource_create(struct wl_client *client, + const struct wl_interface *interface, + int version, uint32_t id) +{ + +} + +typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data, + uint32_t version, uint32_t id); + +static struct wl_global *wl_global_create(struct wl_display *display, + const struct wl_interface *interface, + int version, void *data, + wl_global_bind_func_t bind); + +static int wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout) +{ + +} + +typedef int (*wl_event_loop_fd_func_t)(int fd, uint32_t wl_mask, void *data); + +struct wl_event_source event_source; + +static struct wl_event_source *wl_event_loop_add_fd(struct wl_event_loop *loop, + int fd, uint32_t mask, + wl_event_loop_fd_func_t func, + void *data) +{ + if (WL_EVENT_LOOP_ADD_FD_ERROR) { + return NULL; + } + + return &event_source; +} + +static int wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask) +{ + if (WL_EVENT_SOURCE_FD_UPDATE_ERROR) { + return -1; + } + + return 1; +} + +typedef int (*wl_event_loop_timer_func_t) (void *data); + +static struct wl_event_source *wl_event_loop_add_timer(struct wl_event_loop *loop, + wl_event_loop_timer_func_t func, + void *data) +{ + if (WL_EVENT_LOOP_ADD_TIMER_ERROR) { + return NULL; + } + + return &event_source; +} + +static int wl_event_source_timer_update(struct wl_event_source *source, int ms_delay) +{ + if (WL_EVENT_SOURCE_TIMER_UPDATE_ERROR) { + return -1; + } + + return 1; +} + +static int wl_event_source_remove(struct wl_event_source *source) +{ + +} + +static uint32_t wl_resource_get_id(struct wl_resource *resource) +{ + +} + +static void wl_tdm_vblank_send_done(struct wl_resource *resource, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec) +{ + +} + +static void wl_resource_destroy(struct wl_resource *resource) +{ + +} + +static void *wl_resource_get_user_data(struct wl_resource *resource) +{ + +} + +static int wl_resource_get_version(struct wl_resource *resource) +{ + +} + +static void wl_resource_post_no_memory(struct wl_resource *resource) +{ + +} + +typedef void (*wl_resource_destroy_func_t) (struct wl_resource *resource); + +static void wl_resource_set_implementation(struct wl_resource *resource, + const void *implementation, + void *data, + wl_resource_destroy_func_t destroy) +{ + +} + +static void wl_client_post_no_memory(struct wl_client *client) +{ + +} + +static int wl_display_add_socket(struct wl_display *display, const char *name) +{ + +} + +static struct wl_global *wl_global_create(struct wl_display *display, + const struct wl_interface *interface, + int version, void *data, + wl_global_bind_func_t bind) +{ + +} + +#endif /* WAYLAND_SERVER_CORE_H */ diff --git a/ut/stubs/wayland-tbm-drm-auth-client-protocol.h b/ut/stubs/wayland-tbm-drm-auth-client-protocol.h new file mode 100644 index 0000000..35fe6af --- /dev/null +++ b/ut/stubs/wayland-tbm-drm-auth-client-protocol.h @@ -0,0 +1,50 @@ +#ifndef TBM_DRM_AUTH_CLIENT_PROTOCOL_H +#define TBM_DRM_AUTH_CLIENT_PROTOCOL_H + +#include +#include + +struct wl_client; +struct wl_resource; + +struct wl_tbm_drm_auth; + +extern const struct wl_interface wl_tbm_drm_auth_interface; + +struct wl_tbm_drm_auth_listener { + void (*authentication_info)(void *data, + struct wl_tbm_drm_auth *wl_tbm_drm_auth, + const char *device_name, + uint32_t capabilities, + int32_t auth_fd); +}; + +static inline int +wl_tbm_drm_auth_add_listener(struct wl_tbm_drm_auth *wl_tbm_drm_auth, + const struct wl_tbm_drm_auth_listener *listener, void *data) +{ +} + +#define WL_TBM_DRM_AUTH_GET_AUTHENTICATION_INFO 0 + +static inline void +wl_tbm_drm_auth_set_user_data(struct wl_tbm_drm_auth *wl_tbm_drm_auth, void *user_data) +{ +} + +static inline void * +wl_tbm_drm_auth_get_user_data(struct wl_tbm_drm_auth *wl_tbm_drm_auth) +{ +} + +static inline void +wl_tbm_drm_auth_destroy(struct wl_tbm_drm_auth *wl_tbm_drm_auth) +{ +} + +static inline void +wl_tbm_drm_auth_get_authentication_info(struct wl_tbm_drm_auth *wl_tbm_drm_auth) +{ +} + +#endif -- 2.7.4 From c54a52e8e8e7822b17b8930022eeffde9baa0121 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Sep 2016 13:21:53 +0900 Subject: [PATCH 08/16] fix dereference issue after null Change-Id: Icb79b4231ddacf9c8c2b183e3e535c3456a79a26 --- src/tdm_server.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tdm_server.c b/src/tdm_server.c index 37c50d9..6417fd9 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -271,7 +271,8 @@ _tdm_server_vblank_cb_wait_vblank(struct wl_client *client, struct wl_resource * return; wait_failed: wl_tdm_vblank_send_done(vblank_info->resource, req_id, 0, 0, 0, ret); - destroy_wait(wait_info); + if (wait_info) + destroy_wait(wait_info); } static void @@ -310,7 +311,8 @@ _tdm_server_vblank_cb_wait_vblank_seq(struct wl_client *client, struct wl_resour return; wait_failed: wl_tdm_vblank_send_done(vblank_info->resource, req_id, 0, 0, 0, ret); - destroy_wait(wait_info); + if (wait_info) + destroy_wait(wait_info); } static const struct wl_tdm_vblank_interface tdm_vblank_implementation = { -- 2.7.4 From b8674b3477d0ad874e950a5e200a38254bf0f7e6 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 20 Sep 2016 11:45:00 +0900 Subject: [PATCH 09/16] packaging: version up to 1.4.2 Change-Id: I9f9cba704ee410252cfef77a80e6366d96732e37 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 6a0a1cf..cb158ed 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.4.1 +Version: 1.4.2 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From f5a8e52620e9eb541fb008e4e987fe5ba9b43846 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Sep 2016 19:01:59 +0900 Subject: [PATCH 10/16] not dump a video layer Change-Id: I209b81bc6852b6469d5719e35129232adee3a342 --- src/tdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm.c b/src/tdm.c index 273fc27..ff2ca98 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -1099,7 +1099,7 @@ tdm_display_enable_dump(tdm_private_display *private_display, const char *dump_s tdm_private_layer *l = NULL; LIST_FOR_EACH_ENTRY(l, &o->layer_list, link) { char str[TDM_PATH_LEN]; - if (l->usable) + if (l->usable || l->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO) continue; snprintf(str, TDM_PATH_LEN, "layer_%d_%d", o->index, l->index); tdm_helper_dump_buffer_str(l->showing_buffer, path, str); -- 2.7.4 From 5ed6dcb5f0d2e118b1f8f5f96b80d5fc47be4211 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Sep 2016 12:44:34 +0900 Subject: [PATCH 11/16] fix wrong log Change-Id: I6825c3ac71de5b963832566715335e8ceceab92f --- src/tdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm.c b/src/tdm.c index ff2ca98..b04ab2d 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -1080,11 +1080,11 @@ tdm_display_enable_dump(tdm_private_display *private_display, const char *dump_s if (!strncmp(arg, "none", 4)) { tdm_debug_dump = 0; + TDM_SNPRINTF(reply, len, "path: %s\n", (tdm_debug_dump_dir)?:"unknown"); if (tdm_debug_dump_dir) { free(tdm_debug_dump_dir); tdm_debug_dump_dir = NULL; } - TDM_SNPRINTF(reply, len, "path: %s\n", path); goto done; } -- 2.7.4 From 88cf03c2066c785ce224fb6fe5557fc84f234d5d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sat, 24 Sep 2016 14:20:25 +0900 Subject: [PATCH 12/16] use double instead of unsigned long to avoid overflow Change-Id: I7001e10230cc57dc59df178b10d1a8b18f328a50 --- include/tdm_helper.h | 7 ++ src/tdm.c | 5 +- src/tdm_capture.c | 6 +- src/tdm_helper.c | 17 +---- src/tdm_macro.h | 4 ++ src/tdm_pp.c | 4 +- src/tdm_private.h | 29 ++++---- src/tdm_vblank.c | 177 +++++++++++++++++++++++++----------------------- tools/tdm_test_client.c | 20 +++--- 9 files changed, 135 insertions(+), 134 deletions(-) diff --git a/include/tdm_helper.h b/include/tdm_helper.h index 7342e5d..459b1b1 100644 --- a/include/tdm_helper.h +++ b/include/tdm_helper.h @@ -49,6 +49,13 @@ extern "C" { */ /** + * @brief Get the current time as a floating point value in seconds + * @return The number of seconds + */ +double +tdm_helper_get_time(void); + +/** * @brief Dump a buffer * @details * This function supports only if a buffer has below formats. diff --git a/src/tdm.c b/src/tdm.c index b04ab2d..384dbf1 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -74,8 +74,7 @@ _tdm_display_find_private_output(tdm_private_display *private_display, } INTERN tdm_private_output * -tdm_display_find_output_stamp(tdm_private_display *private_display, - unsigned long stamp) +tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp) { tdm_private_output *private_output = NULL; @@ -363,7 +362,7 @@ tdm_display_update_output(tdm_private_display *private_display, private_output = calloc(1, sizeof(tdm_private_output)); TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_OUT_OF_MEMORY); - private_output->stamp = tdm_helper_get_time_in_millis(); + private_output->stamp = tdm_helper_get_time(); while (tdm_display_find_output_stamp(private_display, private_output->stamp)) private_output->stamp++; diff --git a/src/tdm_capture.c b/src/tdm_capture.c index abf3f6d..da1a0e5 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -130,7 +130,7 @@ tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, } INTERN tdm_private_capture * -tdm_capture_find_stamp(tdm_private_display *private_display, unsigned long stamp) +tdm_capture_find_stamp(tdm_private_display *private_display, double stamp) { tdm_private_capture *private_capture = NULL; @@ -191,7 +191,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, return NULL; } - private_capture->stamp = tdm_helper_get_time_in_millis(); + private_capture->stamp = tdm_helper_get_time(); while (tdm_capture_find_stamp(private_display, private_capture->stamp)) private_capture->stamp++; @@ -249,7 +249,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, return NULL; } - private_capture->stamp = tdm_helper_get_time_in_millis(); + private_capture->stamp = tdm_helper_get_time(); while (tdm_capture_find_stamp(private_display, private_capture->stamp)) private_capture->stamp++; diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 69278fc..999bd1a 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -56,24 +56,13 @@ static const char *file_exts[2] = {"png", "yuv"}; int tdm_dump_enable; char *tdm_debug_dump_dir; -INTERN unsigned long -tdm_helper_get_time_in_millis(void) +EXTERN double +tdm_helper_get_time(void) { struct timespec tp; if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) - return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L); - - return 0; -} - -INTERN unsigned long -tdm_helper_get_time_in_micros(void) -{ - struct timespec tp; - - if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) - return (tp.tv_sec * 1000000) + (tp.tv_nsec / 1000L); + return (double)tp.tv_sec + ((double)tp.tv_nsec) / 1000000000.0; return 0; } diff --git a/src/tdm_macro.h b/src/tdm_macro.h index bc4c0bd..0dfd031 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -135,6 +135,10 @@ extern "C" { } \ } +#define TDM_TIME(sec, usec) ((double)(sec) + ((double)(usec)) / 1000000.0) +#define TDM_TIME_SEC(time) ((unsigned int)(time)) +#define TDM_TIME_USEC(time) (unsigned int)(((time) - (unsigned int)(time)) * 1000000.0) + #define C(b, m) (((b) >> (m)) & 0xFF) #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s)) #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0)) diff --git a/src/tdm_pp.c b/src/tdm_pp.c index cffaba0..1a61d7f 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -163,7 +163,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; @@ -223,7 +223,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++; diff --git a/src/tdm_private.h b/src/tdm_private.h index 2e12f46..37f753e 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -167,7 +167,7 @@ struct _tdm_private_output { struct list_head link; int index; - unsigned long stamp; + double stamp; tdm_private_display *private_display; @@ -222,7 +222,7 @@ struct _tdm_private_layer { struct _tdm_private_pp { struct list_head link; - unsigned long stamp; + double stamp; tdm_private_display *private_display; @@ -242,7 +242,7 @@ struct _tdm_private_capture { struct list_head link; struct list_head display_link; - unsigned long stamp; + double stamp; tdm_capture_target target; @@ -348,12 +348,11 @@ int tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, int abimin); tdm_private_output * -tdm_display_find_output_stamp(tdm_private_display *private_display, - unsigned long stamp); +tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp); 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_capture * -tdm_capture_find_stamp(tdm_private_display *private_display, unsigned long stamp); +tdm_capture_find_stamp(tdm_private_display *private_display, double stamp); void tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, @@ -445,7 +444,7 @@ struct _tdm_thread_cb_base { struct _tdm_thread_cb_output_vblank { tdm_thread_cb_base base; - unsigned long output_stamp; + double output_stamp; unsigned int sequence; unsigned int tv_sec; unsigned int tv_usec; @@ -454,21 +453,21 @@ struct _tdm_thread_cb_output_vblank { struct _tdm_thread_cb_output_status { tdm_thread_cb_base base; - unsigned long output_stamp; + double output_stamp; tdm_output_conn_status status; void *user_data; }; struct _tdm_thread_cb_output_dpms { tdm_thread_cb_base base; - unsigned long output_stamp; + double output_stamp; tdm_output_dpms dpms; void *user_data; }; struct _tdm_thread_cb_pp_done { tdm_thread_cb_base base; - unsigned long pp_stamp; + double pp_stamp; tbm_surface_h src; tbm_surface_h dst; void *user_data; @@ -476,7 +475,7 @@ struct _tdm_thread_cb_pp_done { struct _tdm_thread_cb_capture_done { tdm_thread_cb_base base; - unsigned long capture_stamp; + double capture_stamp; tbm_surface_h buffer; void *user_data; }; @@ -505,10 +504,8 @@ char * tdm_helper_dump_make_directory(const char *path, char *reply, int *len); void tdm_helper_dump_buffer_str(tbm_surface_h buffer, char *dir, char *str); -unsigned long -tdm_helper_get_time_in_millis(void); -unsigned long -tdm_helper_get_time_in_micros(void); +double +tdm_helper_get_time(void); extern pthread_mutex_t tdm_mutex_check_lock; extern int tdm_mutex_locked; diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 03947d2..bba2240 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -52,6 +52,9 @@ * - use a tdm_event_loop_source object only. */ +/* We expact "(unsigned int)(0.0016667 / 0.0016667) = 1". But it becomes 0. */ +#define TDM_TIME_MARGIN 0.0000001 + #define TDM_VBLANK_UINT_MAX 4294967295U #define TDM_VBLANK_UINT_1Q 1073741823U /* UINT_MAX / 4 */ #define TDM_VBLANK_UINT_3Q 3221225471U /* UINT_MAX / 4 * 3 */ @@ -93,8 +96,7 @@ typedef struct _tdm_private_vblank { unsigned int quotient; unsigned int last_seq; - unsigned int last_tv_sec; - unsigned int last_tv_usec; + double last_time; /* for HW */ double HW_vblank_gap; @@ -111,8 +113,7 @@ struct _tdm_vblank_wait_info { unsigned int stamp; - unsigned int req_sec; - unsigned int req_usec; + double req_time; unsigned int interval; tdm_vblank_handler func; @@ -121,8 +122,7 @@ struct _tdm_vblank_wait_info { tdm_vblank_wait_type type; - unsigned int target_sec; - unsigned int target_usec; + double target_time; unsigned int target_seq; }; @@ -192,13 +192,9 @@ _tdm_vblank_insert_wait(tdm_vblank_wait_info *wait_info, struct list_head *list) LIST_FOR_EACH_ENTRY(w, list, link) { if (wait_info->type == VBLANK_TYPE_SW) { - if (wait_info->target_sec == 0) + if (wait_info->target_time == 0) TDM_NEVER_GET_HERE(); - if (w->target_sec < wait_info->target_sec) { - found = w; - continue; - } - if (w->target_sec == wait_info->target_sec && w->target_usec <= wait_info->target_usec) { + if (w->target_time <= wait_info->target_time) { found = w; continue; } @@ -320,7 +316,7 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) private_vblank->output = output; private_vblank->dpms = dpms; private_vblank->vrefresh = mode->vrefresh; - private_vblank->HW_vblank_gap = (double)1000000 / private_vblank->vrefresh; + private_vblank->HW_vblank_gap = 1.0 / private_vblank->vrefresh; private_vblank->check_HW_or_SW = 1; private_vblank->fps = mode->vrefresh; @@ -442,7 +438,7 @@ static tdm_error _tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank) { tdm_vblank_wait_info *first_wait_info = NULL; - unsigned long curr, target; + double curr, target; int ms_delay; tdm_error ret; @@ -452,21 +448,22 @@ _tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank) } first_wait_info = container_of(private_vblank->SW_wait_list.next, first_wait_info, link); - curr = tdm_helper_get_time_in_micros(); - target = first_wait_info->target_sec * 1000000 + first_wait_info->target_usec; + curr = tdm_helper_get_time(); + target = first_wait_info->target_time; /* ms_delay should be more that 1 */ if (target < curr) ms_delay = 1; else - ms_delay = ceil((double)(target - curr) / 1000); + ms_delay = ceil((target - curr) * 1000.0); if (ms_delay < 1) ms_delay = 1; - if (tdm_debug_module & TDM_DEBUG_VBLANK || ms_delay > 5000) - VIN("wait(%p) curr(%4lu) target(%4lu) ms_delay(%d)", - first_wait_info, curr, target, ms_delay); + if (ms_delay > 5000) + VER("wait(%p) curr(%.6f) target(%.6f) ms_delay(%d)", first_wait_info, curr, target, ms_delay); + else if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("wait(%p) curr(%.6f) target(%.6f) ms_delay(%d)", first_wait_info, curr, target, ms_delay); tdm_display_lock(private_vblank->dpy); @@ -518,16 +515,15 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, } if (wait_info->type == VBLANK_TYPE_HW_SW) { - unsigned long target; tdm_error ret; LIST_DEL(&wait_info->link); - target = (unsigned long)tv_sec * 1000000 + tv_usec; - target += (private_vblank->offset * 1000); - - wait_info->target_sec = target / 1000000; - wait_info->target_usec = target % 1000000; + /* kernel sends the wrong time of first vblank event. and the time of + * second vblank is correct. + */ + wait_info->target_time = TDM_TIME(tv_sec, tv_usec); + wait_info->target_time += (((double)private_vblank->offset) / 1000.0); _tdm_vblank_insert_wait(wait_info, &private_vblank->SW_wait_list); @@ -546,9 +542,11 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, if (tdm_debug_module & TDM_DEBUG_VBLANK) VIN("wait(%p) sequence(%u) done", wait_info, wait_info->target_seq); + if (private_vblank->last_seq >= wait_info->target_seq) + TDM_ERR("last_seq(%u) target_seq(%u)", private_vblank->last_seq, wait_info->target_seq); + private_vblank->last_seq = wait_info->target_seq; - private_vblank->last_tv_sec = tv_sec; - private_vblank->last_tv_usec = tv_usec; + private_vblank->last_time = TDM_TIME(tv_sec, tv_usec); if (wait_info->func) wait_info->func(private_vblank, TDM_ERROR_NONE, wait_info->target_seq, @@ -570,32 +568,43 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) hw_interval = wait_info->interval * private_vblank->quotient; - if (private_vblank->last_tv_sec == 0) + if (private_vblank->last_time == 0) { + /* SW vblank starts from now. SW vblank doesn't need to be aligned with HW vblank. */ + private_vblank->last_seq = 0; + private_vblank->last_time = tdm_helper_get_time(); + + /* +1 ms to call the handler ASAP at the first. no matter for SW timer. */ wait_info->target_seq = 1; - else { - unsigned long last, prev, req, curr, target; - unsigned int skip = 0; + if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("wait(%p) last(%.6f) hw_interval(%d) target sequence(%u)", + wait_info, private_vblank->last_time, hw_interval, wait_info->target_seq); + } else { + double last, prev, req, curr, target, skip; - last = (unsigned long)private_vblank->last_tv_sec * 1000000 + private_vblank->last_tv_usec; - req = (unsigned long)wait_info->req_sec * 1000000 + wait_info->req_usec; + last = private_vblank->last_time; + req = wait_info->req_time; - skip = (unsigned int)((req - last) / private_vblank->vblank_gap); - prev = last + skip * private_vblank->vblank_gap; + skip = (req - last) / private_vblank->vblank_gap; + prev = last + private_vblank->vblank_gap * skip; - curr = tdm_helper_get_time_in_micros(); + curr = tdm_helper_get_time(); target = prev; while (target < curr) target += private_vblank->vblank_gap; - hw_interval = (unsigned int)((target - curr) / private_vblank->HW_vblank_gap) + 1; + hw_interval = (unsigned int)((target - curr) / private_vblank->HW_vblank_gap + TDM_TIME_MARGIN) + 1; wait_info->target_seq = private_vblank->last_seq; - wait_info->target_seq += (target - last) / (unsigned long)private_vblank->vblank_gap; + wait_info->target_seq += (unsigned int)((target - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN); - if (tdm_debug_module & TDM_DEBUG_VBLANK || hw_interval > 300) - VIN("wait(%p) last(%4lu) req(%4lu) prev(%4lu) curr(%4lu) skip(%d) hw_interval(%d)", - wait_info, last, req - last, prev - last, curr - last, - skip, hw_interval); + if (hw_interval > 300) + VER("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f) skip(%.0f) hw_interval(%d) target_seq(%u)", + wait_info, last, req - last, prev - last, curr - last, target - last, + skip, hw_interval, wait_info->target_seq); + else if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f) skip(%.0f) hw_interval(%d) target_seq(%u)", + wait_info, last, req - last, prev - last, curr - last, target - last, + skip, hw_interval, wait_info->target_seq); } ret = tdm_output_wait_vblank(private_vblank->output, hw_interval, 0, @@ -631,13 +640,14 @@ _tdm_vblank_cb_vblank_SW(void *user_data) if (tdm_debug_module & TDM_DEBUG_VBLANK) VIN("wait(%p) sequence(%u) done", first_wait_info, first_wait_info->target_seq); + if (private_vblank->last_seq >= first_wait_info->target_seq) + TDM_ERR("last_seq(%u) target_seq(%u)", private_vblank->last_seq, first_wait_info->target_seq); + private_vblank->last_seq = first_wait_info->target_seq; - private_vblank->last_tv_sec = first_wait_info->target_sec; - private_vblank->last_tv_usec = first_wait_info->target_usec; + private_vblank->last_time = first_wait_info->target_time; LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) { - if (w->target_sec != first_wait_info->target_sec || - w->target_usec != first_wait_info->target_usec) + if (w->target_time != first_wait_info->target_time) break; LIST_DEL(&w->link); @@ -645,7 +655,7 @@ _tdm_vblank_cb_vblank_SW(void *user_data) if (w->func) w->func(private_vblank, TDM_ERROR_NONE, w->target_seq, - w->target_sec, w->target_usec, + TDM_TIME_SEC(w->target_time), TDM_TIME_USEC(w->target_time), w->user_data); free(w); @@ -660,46 +670,42 @@ _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info) tdm_private_vblank *private_vblank = wait_info->private_vblank; tdm_error ret; - if (private_vblank->last_tv_sec == 0) { - unsigned long curr = tdm_helper_get_time_in_micros(); - + if (private_vblank->last_time == 0) { /* SW vblank starts from now. SW vblank doesn't need to be aligned with HW vblank. */ private_vblank->last_seq = 0; - private_vblank->last_tv_sec = curr / 1000000; - private_vblank->last_tv_usec = curr % 1000000; + private_vblank->last_time = tdm_helper_get_time(); /* +1 ms to call the handler ASAP at the first. no matter for SW timer. */ - curr += 1000; - wait_info->target_seq = 1; - wait_info->target_sec = curr / 1000000; - wait_info->target_usec = curr % 1000000; + wait_info->target_time = private_vblank->last_time + 0.001; + + if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("wait(%p) last(%.6f) target(%.6f) target sequence(%u)", + wait_info, private_vblank->last_time, wait_info->target_time, wait_info->target_seq); } else { - unsigned long last, prev, req, curr, target; - unsigned int skip; + double last, prev, req, curr, target, skip; - last = (unsigned long)private_vblank->last_tv_sec * 1000000 + private_vblank->last_tv_usec; - req = (unsigned long)wait_info->req_sec * 1000000 + wait_info->req_usec; + last = private_vblank->last_time; + req = wait_info->req_time; - skip = (unsigned int)((req - last) / private_vblank->vblank_gap); - prev = last + skip * private_vblank->vblank_gap; + skip = (req - last) / private_vblank->vblank_gap; + prev = last + private_vblank->vblank_gap * skip; - curr = tdm_helper_get_time_in_micros(); - target = prev + (unsigned long)(private_vblank->vblank_gap * wait_info->interval); + curr = tdm_helper_get_time(); + target = prev + private_vblank->vblank_gap * wait_info->interval; while (target < curr) - target += (unsigned long)private_vblank->vblank_gap; + target += private_vblank->vblank_gap; wait_info->target_seq = private_vblank->last_seq; - wait_info->target_seq += (target - last) / (unsigned long)private_vblank->vblank_gap; + wait_info->target_seq += (unsigned int)((target - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN); - wait_info->target_sec = target / 1000000; - wait_info->target_usec = target % 1000000; + wait_info->target_time = target; if (tdm_debug_module & TDM_DEBUG_VBLANK) - VIN("wait(%p) last(%4lu) req(%4lu) prev(%4lu) curr(%4lu) target(%4lu,%4lu)", + VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f,%.6f) target sequence(%u)", wait_info, last, req - last, prev - last, curr - last, - target, target - last); + target, target - last, wait_info->target_seq); } _tdm_vblank_insert_wait(wait_info, &private_vblank->SW_wait_list); @@ -738,16 +744,15 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, /* set request time to current time if 0. This function seems to be called in server side. */ if (req_sec == 0 && req_usec == 0) { - unsigned long curr = tdm_helper_get_time_in_micros(); - req_sec = curr / 1000000; - req_usec = curr % 1000000; + double curr = tdm_helper_get_time(); + req_sec = TDM_TIME_SEC(curr); + req_usec = TDM_TIME_USEC(curr); } LIST_INITHEAD(&wait_info->link); LIST_ADDTAIL(&wait_info->valid_link, &valid_wait_list); wait_info->stamp = ++stamp; - wait_info->req_sec = req_sec; - wait_info->req_usec = req_usec; + wait_info->req_time = TDM_TIME(req_sec, req_usec); wait_info->interval = interval; wait_info->func = func; wait_info->user_data = user_data; @@ -755,7 +760,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, if (private_vblank->check_HW_or_SW) { private_vblank->check_HW_or_SW = 0; - private_vblank->vblank_gap = (double)1000000 / private_vblank->fps; + private_vblank->vblank_gap = 1.0 / private_vblank->fps; private_vblank->quotient = private_vblank->vrefresh / private_vblank->fps; } @@ -809,33 +814,33 @@ tdm_vblank_wait_seq(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_u interval = 1; } else if (sequence > private_vblank->last_seq || TDM_VBLANK_SEQ_REACHED_MAX(sequence, private_vblank->last_seq)) { - unsigned long last, curr, seq_target; + double last, curr, seq_target; - last = (unsigned long)private_vblank->last_tv_sec * 1000000 + private_vblank->last_tv_usec; - curr = tdm_helper_get_time_in_micros(); - seq_target = last + (unsigned long)(private_vblank->vblank_gap * (sequence - private_vblank->last_seq)); + last = private_vblank->last_time; + curr = tdm_helper_get_time(); + seq_target = last + private_vblank->vblank_gap * (sequence - private_vblank->last_seq); /* If target is old or too close(1ms) to current, we call the handler immediately. * 2ms? it seems too much. */ if (seq_target < curr) { func(vblank, TDM_ERROR_NONE, sequence, - seq_target / 1000000, seq_target % 1000000, + TDM_TIME_SEC(seq_target), TDM_TIME_USEC(seq_target), user_data); return TDM_ERROR_NONE; - } else if ((seq_target - curr) < 1000) { /* 1ms */ + } else if ((seq_target - curr) < 0.001) { /* 1ms */ func(vblank, TDM_ERROR_NONE, sequence, - curr / 1000000, curr % 1000000, + TDM_TIME_SEC(curr), TDM_TIME_USEC(curr), user_data); return TDM_ERROR_NONE; } - interval = ((seq_target - curr) / (unsigned long)private_vblank->vblank_gap) + 1; + interval = (unsigned int)((seq_target - curr) / private_vblank->vblank_gap + TDM_TIME_MARGIN) + 1; } else { /* this seems error. But we handle this like normal to avoid the unexpected error in cliend side */ TDM_WRN("sequence(%u) should be over the last sequence(%u)", sequence, private_vblank->last_seq); func(vblank, TDM_ERROR_NONE, private_vblank->last_seq, - private_vblank->last_tv_sec, private_vblank->last_tv_usec, + TDM_TIME_SEC(private_vblank->last_time), TDM_TIME_USEC(private_vblank->last_time), user_data); return TDM_ERROR_NONE; } diff --git a/tools/tdm_test_client.c b/tools/tdm_test_client.c index ba9b257..bb80cc7 100644 --- a/tools/tdm_test_client.c +++ b/tools/tdm_test_client.c @@ -190,13 +190,13 @@ parse_args(tdm_test_client *data, int argc, char *argv[]) } } -static unsigned long -get_time_in_micros(void) +static double +get_time(void) { struct timespec tp; if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) - return (unsigned long)(tp.tv_sec * 1000000) + (tp.tv_nsec / 1000L); + return (double)tp.tv_sec + ((double)tp.tv_nsec) / 1000000000.0; return 0; } @@ -206,8 +206,8 @@ _client_vblank_handler(tdm_client_vblank *vblank, tdm_error error, unsigned int unsigned int tv_sec, unsigned int tv_usec, void *user_data) { tdm_test_client *data = user_data; - unsigned long cur, vbl; - static unsigned long p_vbl = 0; + double cur, vbl; + static double p_vbl = 0; data->waiting = 0; @@ -221,13 +221,13 @@ _client_vblank_handler(tdm_client_vblank *vblank, tdm_error error, unsigned int exit(0); } - cur = get_time_in_micros(); - vbl = (unsigned long)tv_sec * (unsigned long)1000000 + (unsigned long)tv_usec; + cur = get_time(); + vbl = (double)tv_sec + ((double)tv_usec) / 1000000.0; - printf("vblank : %ld us vbl(%lu)\n", vbl - p_vbl, vbl); + printf("vblank : %.6f us vbl(%.6f)\n", vbl - p_vbl, vbl); - if (cur - vbl > 2000) /* 2ms */ - printf("kernel -> tdm-client: %ld us\n", cur - vbl); + if (cur - vbl > 0.002) /* 2ms */ + printf("kernel -> tdm-client: %.0f us\n", (cur - vbl) * 1000000.0); p_vbl = vbl; } -- 2.7.4 From a8733f4923a4e6d2847f236314fff9d1973bc786 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 5 Sep 2016 20:18:35 +0900 Subject: [PATCH 13/16] export tdm vblank functions Change-Id: I3ec641732606e5f682a69b6207444da93c055bad --- include/tdm.h | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ include/tdm_types.h | 5 +++ src/tdm_private.h | 36 +++++------------- src/tdm_thread.c | 5 +++ src/tdm_vblank.c | 107 +++++++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 212 insertions(+), 41 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index 4fa6e21..ee7b160 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -820,6 +820,106 @@ void tdm_buffer_remove_release_handler(tbm_surface_h buffer, tdm_buffer_release_handler func, void *user_data); +/** + * @brief The handler of a vblank object + * @see #tdm_vblank_wait, #tdm_vblank_wait_seq + */ +typedef void (*tdm_vblank_handler)(tdm_vblank *vblank, tdm_error error, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data); + +/** + * @brief Create a vblank object + * @param[in] dpy A display object + * @param[in] output A output object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A vblank object + * @see #tdm_vblank_destroy + */ +tdm_vblank* +tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error); + +/** + * @brief Destroy a vblank object + * @param[in] vblank A vblank object + * @see #tdm_vblank_create + */ +void +tdm_vblank_destroy(tdm_vblank *vblank); + +/** + * @brief Set the fps to a vblank object + * @details Default is the @b vertical @b refresh @b rate of the given output. + * @param[in] vblank A vblank object + * @param[in] fps over 0 + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps); + +/** + * @brief Set the offset(milli-second) to a vblank object + * @details Default is @b 0. + * @param[in] vblank A vblank object + * @param[in] offset the offset(milli-second) + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_set_offset(tdm_vblank *vblank, int offset); + +/** + * @brief Enable/Disable the fake vblank to a vblank object + * @details + * If enable_fake == 0, #tdm_vblank_wait will return TDM_ERROR_DPMS_OFF + * when DPMS off. Otherwise, #tdm_vblank_wait will return TDM_ERROR_NONE + * as success. + * @param[in] vblank A vblank object + * @param[in] enable_fake 1:enable, 0:disable + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake); + +/** + * @brief Get the fake vblank + * @param[in] vblank A vblank object + * @return 1 if enable. Otherwise, 0. + */ +unsigned int +tdm_vblank_get_enable_fake(tdm_vblank *vblank); + +/** + * @brief Wait for a vblank + * @details + * Once #tdm_vblank_wait returns TDM_ERROR_NONE, the user vblank handler(#tdm_vblank_handler) + * SHOULD be called after the given interval. \n + * The sequence value of tdm_vblank_handler is the relative value of fps. + * If fps = 10, this sequence value should be increased by 10 during 1 second. + * @param[in] vblank A vblank object + * @param[in] req_sec The vblank request time(second) + * @param[in] req_usec The vblank request time(micro-second) + * @param[in] interval The vblank interval + * @param[in] func The user vblank handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, + unsigned int interval, tdm_vblank_handler func, void *user_data); + +/** + * @brief Wait for a vblank with the target sequence number + * @param[in] vblank A vblank object + * @param[in] req_sec The vblank request time(second) + * @param[in] req_usec The vblank request time(micro-second) + * @param[in] sequence The target sequence number + * @param[in] func The user client vblank handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_wait_seq(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, + unsigned int sequence, tdm_vblank_handler func, void *user_data); + #ifdef __cplusplus } #endif diff --git a/include/tdm_types.h b/include/tdm_types.h index b11b3f5..fd446cd 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -153,6 +153,11 @@ typedef void tdm_capture; typedef void tdm_pp; /** + * @brief The tdm vblank object + */ +typedef void tdm_vblank; + +/** * @brief The vblank handler * @see output_set_vblank_handler() function of #tdm_func_display */ diff --git a/src/tdm_private.h b/src/tdm_private.h index 37f753e..eb6f6d6 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -372,6 +372,8 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, void tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data); +tdm_error +tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp); void tdm_output_call_change_handler_internal(tdm_private_output *private_output, @@ -427,6 +429,7 @@ typedef enum { TDM_THREAD_CB_OUTPUT_DPMS, TDM_THREAD_CB_PP_DONE, TDM_THREAD_CB_CAPTURE_DONE, + TDM_THREAD_CB_VBLANK_SW, } tdm_thread_cb_type; typedef struct _tdm_thread_cb_base tdm_thread_cb_base; @@ -436,6 +439,7 @@ typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status; typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done; typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; +typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; struct _tdm_thread_cb_base { tdm_thread_cb_type type; @@ -480,6 +484,11 @@ struct _tdm_thread_cb_capture_done { void *user_data; }; +struct _tdm_thread_cb_vblank_sw { + tdm_thread_cb_base base; + double vblank_stamp; +}; + tdm_error tdm_thread_init(tdm_private_loop *private_loop); void @@ -579,33 +588,6 @@ tdm_display_enable_path(const char *path); tdm_error tdm_display_enable_ttrace_vblank(tdm_display *dpy, tdm_output *output, int enable); -/** - * @brief The tdm vblank object - */ -typedef void tdm_vblank; - -typedef void (*tdm_vblank_handler)(tdm_vblank *vblank, tdm_error error, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data); - -tdm_vblank* -tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error); -void -tdm_vblank_destroy(tdm_vblank *vblank); -tdm_error -tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps); -tdm_error -tdm_vblank_set_offset(tdm_vblank *vblank, int offset); -tdm_error -tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake); -unsigned int -tdm_vblank_get_enable_fake(tdm_vblank *vblank); -tdm_error -tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, - unsigned int interval, tdm_vblank_handler func, void *user_data); -tdm_error -tdm_vblank_wait_seq(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, - unsigned int sequence, tdm_vblank_handler func, void *user_data); - void tdm_monitor_server_command(tdm_display *dpy, const char *options, char *reply, int *len); diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 7c1067c..955c9b4 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -351,6 +351,11 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) tdm_capture_cb_done(capture_backend, capture_done->buffer, capture_done->user_data); break; } + case TDM_THREAD_CB_VBLANK_SW: { + tdm_thread_cb_vblank_sw *vblank_sw = (tdm_thread_cb_vblank_sw*)base; + tdm_vblank_cb_vblank_SW(NULL, vblank_sw->vblank_stamp); + break; + } default: break; } diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index bba2240..6696d78 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -82,6 +82,9 @@ typedef struct _tdm_vblank_wait_info tdm_vblank_wait_info; typedef struct _tdm_private_vblank { struct list_head link; + double stamp; + pid_t owner_tid; + tdm_display *dpy; tdm_output *output; tdm_output_dpms dpms; @@ -111,7 +114,7 @@ struct _tdm_vblank_wait_info { struct list_head link; struct list_head valid_link; - unsigned int stamp; + double stamp; double req_time; unsigned int interval; @@ -126,10 +129,11 @@ struct _tdm_vblank_wait_info { unsigned int target_seq; }; +static pthread_mutex_t vblank_list_lock; static struct list_head vblank_list; static struct list_head valid_wait_list; static unsigned int vblank_list_inited; -static unsigned int stamp = 0; +static double stamp = 0; static tdm_error _tdm_vblank_cb_vblank_SW(void *user_data); static tdm_error _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info); @@ -147,8 +151,28 @@ _print_list(struct list_head *list) } #endif +static inline tdm_private_vblank* +_tdm_vblank_find(double vblank_stamp) +{ + tdm_private_vblank *v = NULL; + + if (!vblank_stamp) + return 0; + + pthread_mutex_lock(&vblank_list_lock); + LIST_FOR_EACH_ENTRY(v, &vblank_list, link) { + if (v->stamp == vblank_stamp) { + pthread_mutex_unlock(&vblank_list_lock); + return v; + } + } + pthread_mutex_unlock(&vblank_list_lock); + + return 0; +} + static inline unsigned int -_tdm_vblank_check_valid(tdm_vblank_wait_info *wait_info) +_tdm_vblank_check_valid_wait(tdm_vblank_wait_info *wait_info) { tdm_vblank_wait_info *w = NULL; @@ -272,7 +296,7 @@ _tdm_vblank_cb_output_change(tdm_output *output, tdm_output_change_type type, } } -tdm_vblank* +EXTERN tdm_vblank* tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) { tdm_private_vblank *private_vblank; @@ -287,6 +311,12 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) *error = TDM_ERROR_NONE; if (!vblank_list_inited) { + if (pthread_mutex_init(&vblank_list_lock, NULL)) { + TDM_ERR("mutex init failed: %m"); + if (error) + *error = TDM_ERROR_OPERATION_FAILED; + return NULL; + } LIST_INITHEAD(&vblank_list); LIST_INITHEAD(&valid_wait_list); vblank_list_inited = 1; @@ -312,6 +342,8 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) tdm_output_add_change_handler(output, _tdm_vblank_cb_output_change, private_vblank); + private_vblank->stamp = ++stamp; + private_vblank->owner_tid = syscall(SYS_gettid); private_vblank->dpy = dpy; private_vblank->output = output; private_vblank->dpms = dpms; @@ -324,7 +356,9 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) LIST_INITHEAD(&private_vblank->HW_wait_list); LIST_INITHEAD(&private_vblank->SW_wait_list); + pthread_mutex_lock(&vblank_list_lock); LIST_ADD(&private_vblank->link, &vblank_list); + pthread_mutex_unlock(&vblank_list_lock); if (tdm_debug_module & TDM_DEBUG_VBLANK) VIN("created. vrefresh(%d) dpms(%d)", @@ -333,7 +367,7 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) return (tdm_vblank*)private_vblank; } -void +EXTERN void tdm_vblank_destroy(tdm_vblank *vblank) { tdm_private_vblank *private_vblank = vblank; @@ -342,7 +376,9 @@ tdm_vblank_destroy(tdm_vblank *vblank) if (!private_vblank) return; + pthread_mutex_lock(&vblank_list_lock); LIST_DEL(&private_vblank->link); + pthread_mutex_unlock(&vblank_list_lock); if (private_vblank->SW_timer) { tdm_display_lock(private_vblank->dpy); @@ -367,7 +403,7 @@ tdm_vblank_destroy(tdm_vblank *vblank) free(private_vblank); } -tdm_error +EXTERN tdm_error tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps) { tdm_private_vblank *private_vblank = vblank; @@ -387,7 +423,7 @@ tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps) return TDM_ERROR_NONE; } -tdm_error +EXTERN tdm_error tdm_vblank_set_offset(tdm_vblank *vblank, int offset) { tdm_private_vblank *private_vblank = vblank; @@ -406,7 +442,7 @@ tdm_vblank_set_offset(tdm_vblank *vblank, int offset) return TDM_ERROR_NONE; } -tdm_error +EXTERN tdm_error tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake) { tdm_private_vblank *private_vblank = vblank; @@ -424,7 +460,7 @@ tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake) return TDM_ERROR_NONE; } -unsigned int +EXTERN unsigned int tdm_vblank_get_enable_fake(tdm_vblank *vblank) { tdm_private_vblank *private_vblank = vblank; @@ -501,7 +537,7 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, tdm_vblank_wait_info *wait_info = user_data; tdm_private_vblank *private_vblank; - if (!_tdm_vblank_check_valid(wait_info)) { + if (!_tdm_vblank_check_valid_wait(wait_info)) { TDM_DBG("can't find wait(%p) from valid_wait_list", wait_info); return; } @@ -625,10 +661,45 @@ static tdm_error _tdm_vblank_cb_vblank_SW(void *user_data) { tdm_private_vblank *private_vblank = user_data; - tdm_vblank_wait_info *first_wait_info = NULL, *w = NULL, *ww = NULL; TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_OPERATION_FAILED); + return tdm_vblank_cb_vblank_SW(private_vblank, 0); +} + +INTERN tdm_error +tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp) +{ + tdm_private_vblank *private_vblank; + tdm_vblank_wait_info *first_wait_info = NULL, *w = NULL, *ww = NULL; + + TDM_RETURN_VAL_IF_FAIL(vblank || vblank_stamp > 0, TDM_ERROR_INVALID_PARAMETER); + + if (vblank) + private_vblank = vblank; + else { + private_vblank = _tdm_vblank_find(vblank_stamp); + if (!private_vblank) { + TDM_DBG("can't find vblank(%.0f) from valid_list", vblank_stamp); + return TDM_ERROR_NONE; + } + } + + if (private_vblank->owner_tid != syscall(SYS_gettid)) { + tdm_thread_cb_vblank_sw vblank_sw; + tdm_private_display *private_display = private_vblank->dpy; + tdm_error ret; + + vblank_sw.base.type = TDM_THREAD_CB_VBLANK_SW; + vblank_sw.base.length = sizeof vblank_sw; + vblank_sw.vblank_stamp = private_vblank->stamp; + + ret = tdm_thread_send_cb(private_display->private_loop, &vblank_sw.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + + return TDM_ERROR_NONE; + } + if (LIST_IS_EMPTY(&private_vblank->SW_wait_list)) { VER("no wait_info"); return TDM_ERROR_OPERATION_FAILED; @@ -653,10 +724,13 @@ _tdm_vblank_cb_vblank_SW(void *user_data) LIST_DEL(&w->link); LIST_DEL(&w->valid_link); - if (w->func) + if (w->func) { + tdm_display_unlock(private_vblank->dpy); w->func(private_vblank, TDM_ERROR_NONE, w->target_seq, TDM_TIME_SEC(w->target_time), TDM_TIME_USEC(w->target_time), w->user_data); + tdm_display_lock(private_vblank->dpy); + } free(w); } @@ -720,7 +794,7 @@ _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info) return TDM_ERROR_NONE; } -tdm_error +EXTERN tdm_error tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, unsigned int interval, tdm_vblank_handler func, void *user_data) { @@ -731,6 +805,11 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); + if (private_vblank->owner_tid != syscall(SYS_gettid)) { + TDM_ERR("SHOULD be called in the owner thread"); + return TDM_ERROR_BAD_REQUEST; + } + if (private_vblank->dpms != TDM_OUTPUT_DPMS_ON && !private_vblank->enable_fake) { VIN("can't wait a vblank because of DPMS off"); return TDM_ERROR_DPMS_OFF; @@ -797,7 +876,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, return TDM_ERROR_NONE; } -tdm_error +EXTERN tdm_error tdm_vblank_wait_seq(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, unsigned int sequence, tdm_vblank_handler func, void *user_data) { -- 2.7.4 From 7eeccf8f7ebb1e7139fbf7193c7b77d876bce821 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 26 Sep 2016 11:13:13 +0900 Subject: [PATCH 14/16] fix the wrong operation of SW timer skip variable should be unsigned int to correct the prev time Change-Id: Iea57ca5fbe7783c2b50cad6435d35f1fee0ba9f5 --- src/tdm_vblank.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 6696d78..8dc85e5 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -575,15 +575,26 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, VWR("couldn't update sw timer"); } - if (tdm_debug_module & TDM_DEBUG_VBLANK) - VIN("wait(%p) sequence(%u) done", wait_info, wait_info->target_seq); - if (private_vblank->last_seq >= wait_info->target_seq) TDM_ERR("last_seq(%u) target_seq(%u)", private_vblank->last_seq, wait_info->target_seq); + /* tv_sec & tv_usec shouldn't be zero. But sometimes they are zero in some hardware. + * We need to prohibit that last_time becomes zero because "last_time == 0" means + * that a tdm_vblank object is just created and doesn't have the first vblank event. + * If last_time becomes 0, it would make issue. + */ + if (tv_sec == 0 && tv_usec == 0) { + double curr = tdm_helper_get_time(); + tv_sec = TDM_TIME_SEC(curr); + tv_usec = TDM_TIME_USEC(curr); + } + private_vblank->last_seq = wait_info->target_seq; private_vblank->last_time = TDM_TIME(tv_sec, tv_usec); + if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("wait(%p) last(%.6f) sequence(%u) done", wait_info, private_vblank->last_time, wait_info->target_seq); + if (wait_info->func) wait_info->func(private_vblank, TDM_ERROR_NONE, wait_info->target_seq, tv_sec, tv_usec, wait_info->user_data); @@ -612,15 +623,16 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) /* +1 ms to call the handler ASAP at the first. no matter for SW timer. */ wait_info->target_seq = 1; if (tdm_debug_module & TDM_DEBUG_VBLANK) - VIN("wait(%p) last(%.6f) hw_interval(%d) target sequence(%u)", + VIN("wait(%p) last(%.6f) hw_itvl(%d) targ_seq(%u)", wait_info, private_vblank->last_time, hw_interval, wait_info->target_seq); } else { - double last, prev, req, curr, target, skip; + double last, prev, req, curr, target; + unsigned int skip; last = private_vblank->last_time; req = wait_info->req_time; - skip = (req - last) / private_vblank->vblank_gap; + skip = (unsigned int)((req - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN); prev = last + private_vblank->vblank_gap * skip; curr = tdm_helper_get_time(); @@ -634,12 +646,12 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) wait_info->target_seq += (unsigned int)((target - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN); if (hw_interval > 300) - VER("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f) skip(%.0f) hw_interval(%d) target_seq(%u)", - wait_info, last, req - last, prev - last, curr - last, target - last, + VER("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) hw_itvl(%d) targ_seq(%u)", + wait_info, last, req - last, prev - last, curr - last, target, target - last, skip, hw_interval, wait_info->target_seq); else if (tdm_debug_module & TDM_DEBUG_VBLANK) - VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f) skip(%.0f) hw_interval(%d) target_seq(%u)", - wait_info, last, req - last, prev - last, curr - last, target - last, + VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) hw_itvl(%d) targ_seq(%u)", + wait_info, last, req - last, prev - last, curr - last, target, target - last, skip, hw_interval, wait_info->target_seq); } @@ -708,15 +720,15 @@ tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp) first_wait_info = container_of(private_vblank->SW_wait_list.next, first_wait_info, link); TDM_RETURN_VAL_IF_FAIL(first_wait_info != NULL, TDM_ERROR_OPERATION_FAILED); - if (tdm_debug_module & TDM_DEBUG_VBLANK) - VIN("wait(%p) sequence(%u) done", first_wait_info, first_wait_info->target_seq); - if (private_vblank->last_seq >= first_wait_info->target_seq) TDM_ERR("last_seq(%u) target_seq(%u)", private_vblank->last_seq, first_wait_info->target_seq); private_vblank->last_seq = first_wait_info->target_seq; private_vblank->last_time = first_wait_info->target_time; + if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("wait(%p) last(%.6f) sequence(%u) done", first_wait_info, private_vblank->last_time, first_wait_info->target_seq); + LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) { if (w->target_time != first_wait_info->target_time) break; @@ -757,12 +769,13 @@ _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info) VIN("wait(%p) last(%.6f) target(%.6f) target sequence(%u)", wait_info, private_vblank->last_time, wait_info->target_time, wait_info->target_seq); } else { - double last, prev, req, curr, target, skip; + double last, prev, req, curr, target; + unsigned int skip; last = private_vblank->last_time; req = wait_info->req_time; - skip = (req - last) / private_vblank->vblank_gap; + skip = (unsigned int)((req - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN); prev = last + private_vblank->vblank_gap * skip; curr = tdm_helper_get_time(); @@ -777,9 +790,9 @@ _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info) wait_info->target_time = target; if (tdm_debug_module & TDM_DEBUG_VBLANK) - VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f,%.6f) target sequence(%u)", + VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) targ_seq(%u)", wait_info, last, req - last, prev - last, curr - last, - target, target - last, wait_info->target_seq); + target, target - last, skip, wait_info->target_seq); } _tdm_vblank_insert_wait(wait_info, &private_vblank->SW_wait_list); -- 2.7.4 From d38e832a18a618a867514cca119e27e1eafb96b8 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 26 Sep 2016 17:34:33 +0900 Subject: [PATCH 15/16] package version 1.4.3 Change-Id: I7b70c46cd52572598fbb2d08d025cb3d2fbc2f3e --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index cb158ed..6298383 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.4.2 +Version: 1.4.3 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 53f7581047500ef3042fe0745af9a658b55851f9 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 28 Sep 2016 15:17:51 +0900 Subject: [PATCH 16/16] not create the reduntant directory when done Change-Id: I09e9540baff6b232b45f2770070f824faeca2ef4 --- src/tdm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 384dbf1..bb26b97 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -1068,9 +1068,6 @@ tdm_display_enable_dump(tdm_private_display *private_display, const char *dump_s else path2++; - path = tdm_helper_dump_make_directory(path2, reply, len); - TDM_GOTO_IF_FAIL(path != NULL, done); - tdm_debug_dump = 0; snprintf(temp, sizeof(temp), "%s", dump_str); @@ -1087,6 +1084,9 @@ tdm_display_enable_dump(tdm_private_display *private_display, const char *dump_s goto done; } + path = tdm_helper_dump_make_directory(path2, reply, len); + TDM_GOTO_IF_FAIL(path != NULL, done); + if (!strncmp(arg, "current", 7)) { tdm_private_output *o = NULL; if (!private_display) { -- 2.7.4