utests: re-implementation 66/171066/7
authorBoram Park <boram1288.park@samsung.com>
Tue, 20 Feb 2018 11:33:25 +0000 (20:33 +0900)
committerBoram Park <boram1288.park@samsung.com>
Tue, 27 Feb 2018 00:38:04 +0000 (09:38 +0900)
Change-Id: Ie7de3a978c9d9334ab60dfe17165c91e28cbc0d1

17 files changed:
tools/buffers.c
utests/Makefile.am
utests/src/ut_tdm.h
utests/src/ut_tdm_buffer.cpp
utests/src/ut_tdm_capture.cpp
utests/src/ut_tdm_client.cpp
utests/src/ut_tdm_display.cpp
utests/src/ut_tdm_env.cpp [new file with mode: 0644]
utests/src/ut_tdm_event_loop.cpp
utests/src/ut_tdm_helper.cpp
utests/src/ut_tdm_hwc_window.cpp
utests/src/ut_tdm_layer.cpp
utests/src/ut_tdm_log.cpp [new file with mode: 0644]
utests/src/ut_tdm_main.cpp
utests/src/ut_tdm_output.cpp
utests/src/ut_tdm_pp.cpp
utests/src/ut_tdm_vblank.cpp

index 8b04b41..4d66f12 100644 (file)
@@ -37,6 +37,8 @@
 #include <tbm_bufmgr.h>
 #include <tbm_surface.h>
 
+/* LCOV_EXCL_START */
+
 #include "buffers.h"
 
 #define ALPHA_VALUE  100
@@ -950,3 +952,5 @@ tdm_test_buffer_fill(tbm_surface_h buffer, int pattern)
        fill_pattern(info.format, pattern, plane, info.width, info.height, info.planes[0].stride);
        tbm_surface_unmap(buffer);
 }
+
+/* LCOV_EXCL_END */
index 1c22d6a..90b01ac 100644 (file)
@@ -2,29 +2,32 @@ bin_PROGRAMS = tdm-utests
 
 tdm_utests_SOURCES = \
        src/ut_tdm_main.cpp \
-       src/ut_tdm_display.cpp \
-       src/ut_tdm_pp.cpp \
-       src/ut_tdm_capture.cpp \
-       src/ut_tdm_output.cpp \
-       src/ut_tdm_hwc_window.cpp \
+       src/ut_tdm_log.cpp \
+       src/ut_tdm_env.cpp \
+       src/ut_tdm_event_loop.cpp \
        src/ut_tdm_buffer.cpp \
        src/ut_tdm_helper.cpp \
-       src/ut_tdm_layer.cpp \
-       src/ut_tdm_event_loop.cpp \
        src/ut_tdm_vblank.cpp \
+       src/ut_tdm_display.cpp \
+       src/ut_tdm_output.cpp \
+       src/ut_tdm_layer.cpp \
+       src/ut_tdm_hwc_window.cpp \
+       src/ut_tdm_pp.cpp \
+       src/ut_tdm_capture.cpp \
        src/ut_tdm_client.cpp
 
+tdm_utests_SOURCES += \
+       ../tools/buffers.c
+
 tdm_utests_CXXFLAGS = \
        $(CXXFLAGS) \
        $(TDM_CFLAGS) \
        -I../src \
        -I../include \
        -I../client \
-       -I./src \
+       -I../tools \
        -I$(includedir)/gtest \
-       -fpermissive \
-       -rdynamic \
-       -DFAIL_ON_UNSUPPORTED
+       -fpermissive
 # The flag -w is used, because there are many warnings in libtdm's sources.
 # Warnings occur because we build project with g++.
 # In C++ we need to use explicit types conversion.
@@ -34,6 +37,7 @@ tdm_utests_LDFLAGS = \
        $(TDM_LIBS) \
        $(top_builddir)/src/libtdm.la \
        $(top_builddir)/client/libtdm-client.la \
+       $(top_builddir)/common/libtdm-common.la \
        -lgtest
 
 check:
index f8bff5c..0e3ff70 100644 (file)
-#ifndef UT_COMMON_H
-#define UT_COMMON_H
-#define SKIP_FLAG(FLAG) \
-do {\
-  if(!(FLAG)) {\
-        std::cout << "[  SKIPPED ]" << " not supported" << std::endl;\
-        return;\
-  }\
-} while(0)
-#endif // UT_COMMON_H
+#ifndef _UT_TDM_H_
+#define _UT_TDM_H_
+
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <limits.h>
+#include <vector>
+#include <list>
+#include <climits>
+#include <pthread.h>
+#include <gtest/gtest.h>
+
+extern "C" {
+#include <tbm_bufmgr.h>
+#include <tbm_drm_helper.h>
+}
+
+#include "tdm.h"
+#include "tdm_helper.h"
+#include "tdm_config.h"
+#include "tdm_log.h"
+#include "tdm_macro.h"
+#include "buffers.h"
+
+#define UT_TDM_BUFFER_ENABLE
+#define UT_TDM_CAPTURE_ENABLE
+#define UT_TDM_CLIENT_ENABLE
+#define UT_TDM_DISPLAY_ENABLE
+#define UT_TDM_ENV_ENABLE
+#define UT_TDM_EVENT_LOOP_ENABLE
+#define UT_TDM_HELPER_ENABLE
+#define UT_TDM_HWC_WINDOW_ENABLE
+#define UT_TDM_LAYER_ENABLE
+#define UT_TDM_LOG_ENABLE
+#define UT_TDM_OUTPUT_ENABLE
+#define UT_TDM_PP_ENABLE
+#define UT_TDM_VBLANK_ENABLE
+
+#undef TDM_DBG
+#define TDM_DBG(fmt, args...) \
+    tdm_log_print(TDM_LOG_LEVEL_DBG, fmt, ##args);
+#undef TDM_INFO
+#define TDM_INFO(fmt, args...) \
+    tdm_log_print(TDM_LOG_LEVEL_INFO, fmt, ##args);
+#undef TDM_WRN
+#define TDM_WRN(fmt, args...) \
+    tdm_log_print(TDM_LOG_LEVEL_WRN, fmt, ##args);
+#undef TDM_ERR
+#define TDM_ERR(fmt, args...) \
+    tdm_log_print(TDM_LOG_LEVEL_ERR, fmt, ##args);
+
+#define TDM_UT_ENTRY() \
+    TDM_INFO("--------------------------------------------- %s", typeid(*this).name())
+
+#define TDM_UT_CHECK_FLAG(FLAG) \
+       do {\
+               if(!(FLAG)) \
+                       TDM_INFO("[          ] not supported");\
+       } while(0)
+
+#define TDM_UT_SKIP_FLAG(FLAG) \
+       do {\
+               if(!(FLAG)) {\
+                       TDM_INFO("[  SKIPPED ] not supported");\
+                       return;\
+               }\
+       } while(0)
+
+#define TDM_UT_NEVER_GET_HERE() \
+       do {\
+               TDM_INFO("!!! TDM UT NEVER GET HERE !!!");\
+       } while(0)
+#define TDM_UT_RETURN_IF_FAIL(cond) { \
+       if (!(cond)) { \
+               TDM_ERR("[%s,%d] '%s' failed", __FUNCTION__, __LINE__, #cond); \
+               return; \
+       } \
+}
+#define TDM_UT_RETURN_FALSE_IF_FAIL(cond) { \
+       if (!(cond)) { \
+               TDM_ERR("[%s,%d] '%s' failed", __FUNCTION__, __LINE__, #cond); \
+               return false; \
+       } \
+}
+#define TDM_UT_GOTO_IF_FAIL(cond, dst) { \
+       if (!(cond)) { \
+               TDM_ERR("[%s,%d] '%s' failed", __FUNCTION__, __LINE__, #cond); \
+               goto dst; \
+       } \
+}
+
+#define TDM_UT_SIZE_ALIGN(value, base) (((value) + ((base) - 1)) & ~((base) - 1))
+
+#define TDM_UT_DUMP_DIR          "/tmp/tdm_dump"
+#define TDM_UT_INVALID_VALUE     -42
+#define TDM_UT_BUFFER_SIZE       256
+#define TDM_UT_VBLANK_NAME       "ut_tdm_vblank"
+
+using ::testing::TestWithParam;
+using ::testing::Bool;
+using ::testing::Values;
+using ::testing::Combine;
+
+class TDMEnv : public TestWithParam< ::testing::tuple<bool, bool, const char*> >
+{
+public:
+       void SetUp(void);
+       void TearDown(void);
+};
+
+class TDMDisplay : public TDMEnv
+{
+public:
+       tdm_display *dpy;
+       tbm_bufmgr bufmgr;
+
+       bool has_pp_cap;
+       bool has_capture_cap;
+
+       TDMDisplay();
+       void SetUp(void);
+       void TearDown(void);
+};
+
+class TDMOutput : public TDMDisplay
+{
+public:
+       bool has_outputs;
+       tdm_output **outputs;
+       int output_count;
+       TDMOutput();
+       void SetUp(void);
+       void TearDown(void);
+};
+
+#ifdef TIZEN_TEST_GCOV
+extern "C" void __gcov_flush(void);
+#endif
+
+bool ut_tdm_buffer_create(int width, int height, tbm_format format, int flags, bool fill,
+                                                 int count, tbm_surface_h *buffers);
+
+bool ut_tdm_output_mode_setting(tdm_output *output);
+bool ut_tdm_output_is_async_dpms_enable(tdm_output *output);
+bool ut_tdm_output_is_hwc_enable(tdm_output *output);
+bool ut_tdm_output_is_aod_enable(tdm_output *output);
+bool ut_tdm_output_is_connected(tdm_output *output);
+bool ut_tdm_output_prepare(tdm_display *dpy, tdm_output *output);
+bool ut_tdm_output_unset(tdm_display *dpy, tdm_output *output);
+double ut_tdm_output_get_vblank_interval_time(tdm_output *output);
+
+bool ut_tdm_layer_is_cursor_layer(tdm_layer *layer);
+bool ut_tdm_layer_is_primary_layer(tdm_layer *layer);
+bool ut_tdm_layer_is_video_layer(tdm_layer *layer);
+bool ut_tdm_layer_prepare_buffer(tdm_layer *layer, tbm_surface_h *buffers, int buffer_count);
+bool ut_tdm_layer_prepare_buffer_queue(tdm_layer *layer, tbm_surface_queue_h *buffer_queue);
+bool ut_tdm_layer_fill_info(tdm_layer *layer, int w, int h, tbm_format format, tdm_info_layer *info);
+unsigned int ut_tdm_layer_get_output_pipe(tdm_layer *layer);
+tbm_format ut_tdm_layer_find_best_format(tdm_layer *layer);
+
+bool ut_tdm_pp_fill_info(tbm_surface_h srcbuf, tbm_surface_h dstbuf, tdm_transform transform, tdm_info_pp *info);
+bool ut_tdm_capture_fill_info(tdm_output *output, tbm_surface_h buffer, tdm_transform transform,
+                                                         tdm_capture_type type, int frequency, tdm_info_capture *info);
+
+
+#endif // _UT_TDM_H_
index 6896547..71d14e9 100644 (file)
-#include "gtest/gtest.h"
+/**************************************************************************
+ *
+ * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
+ * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ *
+ * 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 "ut_tdm.h"
-#include "stdint.h"
 
-extern "C" {
-#include "tdm.h"
-#include "tdm_config.h"
-#include "tdm_backend.h"
-#include "tbm_bufmgr.h"
-#include "tbm_surface.h"
-#include "tbm_surface_internal.h"
-#include "tbm_drm_helper.h"
-}
+class TDMBuffer : public TDMDisplay {
+public:
+       tbm_surface_h buffer;
+       TDMBuffer();
+       void SetUp(void);
+       void TearDown(void);
+};
 
-class TDMBuffer: public ::testing::Test
+TDMBuffer::TDMBuffer()
 {
-protected:
-       static tbm_bufmgr tbm_bufmgr_s;
-       static int master_fd;
+       buffer = NULL;
+}
 
-       tbm_surface_h surface;
+void TDMBuffer::SetUp(void)
+{
+       TDMDisplay::SetUp();
 
-       tdm_error error;
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+}
 
-       static void SetEnv(void)
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
+void TDMBuffer::TearDown(void)
+{
+       if (buffer) {
+               tbm_surface_destroy(buffer);
+               buffer = NULL;
        }
+       TDMDisplay::TearDown();
+}
 
-       static void UnsetEnv(void)
-       {
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
+bool
+ut_tdm_buffer_create(int width, int height, tbm_format format, int flags, bool fill, int count, tbm_surface_h *buffers)
+{
+       for (int b = 0; b < count; b++) {
+               buffers[b] = tbm_surface_internal_create_with_flags(width, height, format, flags);
+               TDM_UT_GOTO_IF_FAIL(buffers[b] != NULL, failed);
+               if (fill)
+                       tdm_test_buffer_fill(buffers[b], PATTERN_SMPTE);
        }
 
-       static void SetUpTestCase()
-       {
-               SetEnv();
-               tbm_bufmgr_s = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(tbm_bufmgr_s == NULL);
-               master_fd = tbm_drm_helper_get_master_fd();
-       }
+       TDM_INFO("creating buffers done: width(%d) height(%d), format(%c%c%c%c) flags(%x) fill(%d), count(%d)",
+                        width, height, FOURCC_STR(format), flags, fill, count);
 
-       static void TearDownTestCase()
-       {
-               tbm_bufmgr_deinit(tbm_bufmgr_s);
-               tbm_bufmgr_s = NULL;
-
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_master_fd > -1)
-                               exit(1);
-                       close(master_fd);
+       return true;
+failed:
+       for (int b = 0; b < count; b++) {
+               if (buffers[b]) {
+                       tbm_surface_destroy(buffers[b]);
+                       buffers[b] = NULL;
                }
-
-               UnsetEnv();
-       }
-       void SetUp()
-       {
-               surface = tbm_surface_create(256, 256, TBM_FORMAT_ARGB8888);
-               ASSERT_TRUE(surface != NULL);
        }
-       void TearDown()
-       {
-               if (surface) {
-                       while (tbm_surface_internal_is_valid(surface))
-                               tbm_surface_destroy(surface);
-               }
-       }
-};
-
-tbm_bufmgr TDMBuffer::tbm_bufmgr_s = NULL;
-int TDMBuffer::master_fd = -42;
+       return false;
+}
 
+#ifdef UT_TDM_BUFFER_ENABLE
 
-static int handler_is_called = 0;
-static void release_handler(tbm_surface_h buffer, void *user_data)
-{
-       if (user_data == &handler_is_called)
-               handler_is_called = 1;
-}
-static void destroy_handler(tbm_surface_h buffer, void *user_data)
+TEST_P(TDMBuffer, BufferRefBackend)
 {
-       if (user_data == &handler_is_called)
-               handler_is_called = 1;
+       ASSERT_TRUE(tdm_buffer_ref_backend(buffer) == buffer);
+       tdm_buffer_unref_backend(buffer);
 }
 
-/* tbm_surface_h tdm_buffer_ref_backend(tbm_surface_h buffer) */
-TEST_F(TDMBuffer, RefFailNULL)
+TEST_P(TDMBuffer, BufferRefBackendNullOBject)
 {
-       tbm_surface_h buffer = NULL;
-
-       buffer = tdm_buffer_ref_backend(NULL);
-       ASSERT_EQ(NULL, buffer);
+       ASSERT_TRUE(tdm_buffer_ref_backend(NULL) == NULL);
 }
 
-TEST_F(TDMBuffer, RefSuccessful)
+TEST_P(TDMBuffer, BufferUnrefBackend)
 {
-       tbm_surface_h buffer = NULL;
-
-       buffer = tdm_buffer_ref_backend(surface);
-       ASSERT_EQ(buffer, surface);
-
-       buffer = tdm_buffer_ref_backend(surface);
-       ASSERT_EQ(buffer, surface);
-
+       tdm_buffer_unref_backend(buffer);
 }
 
-/* void tdm_buffer_unref_backend(tbm_surface_h buffer) */
-TEST_F(TDMBuffer, UnrefFailNULL)
+TEST_P(TDMBuffer, BufferUnrefBackendNullOBject)
 {
        tdm_buffer_unref_backend(NULL);
 }
 
-TEST_F(TDMBuffer, UnrefSuccessfulTwoRefUnref)
+static void
+_ut_tdm_buffer_destroy_cb(tbm_surface_h buffer, void *user_data)
 {
-       tbm_surface_h buffer = NULL;
-
-       buffer = tdm_buffer_ref_backend(surface);
-       ASSERT_EQ(buffer, surface);
-       buffer = tdm_buffer_ref_backend(surface);
-       ASSERT_EQ(buffer, surface);
-
-       // first unref
-       tdm_buffer_unref_backend(surface);
-       ASSERT_TRUE(tbm_surface_internal_is_valid(surface));
-
-       // second unref
-       tdm_buffer_unref_backend(surface);
-       ASSERT_TRUE(tbm_surface_internal_is_valid(surface));
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
 }
 
-TEST_F(TDMBuffer, UnrefSuccessfulWithoutRef)
+TEST_P(TDMBuffer, BufferAddDestroyHandler)
 {
-       tdm_buffer_unref_backend(surface);
-       ASSERT_FALSE(tbm_surface_internal_is_valid(surface));
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_destroy_handler(buffer, _ut_tdm_buffer_destroy_cb, &done) == TDM_ERROR_NONE);
+       tbm_surface_destroy(buffer);
+       buffer = NULL;
+       ASSERT_TRUE(done == true);
 }
 
-TEST_F(TDMBuffer, UnrefSuccessfulOneRefTwoUnref)
+TEST_P(TDMBuffer, BufferAddDestroyHandlerTwice)
 {
-       tbm_surface_h buffer = NULL;
-
-       buffer = tdm_buffer_ref_backend(surface);
-       ASSERT_EQ(buffer, surface);
-
-       tdm_buffer_unref_backend(surface);
-       ASSERT_TRUE(tbm_surface_internal_is_valid(surface));
-
-       tdm_buffer_unref_backend(surface);
-       ASSERT_FALSE(tbm_surface_internal_is_valid(surface));
+       ASSERT_TRUE(tdm_buffer_add_destroy_handler(buffer, _ut_tdm_buffer_destroy_cb, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_buffer_add_destroy_handler(buffer, _ut_tdm_buffer_destroy_cb, NULL) == TDM_ERROR_BAD_REQUEST);
 }
 
-/* tdm_error tdm_buffer_add_release_handler(tbm_surface_h buffer, tdm_buffer_release_handler func, void *user_data) */
-TEST_F(TDMBuffer, AddReleaseHandlerFailNULL)
+TEST_P(TDMBuffer, BufferAddDestroyHandlerNullObject)
 {
-       error = tdm_buffer_add_release_handler(NULL, release_handler, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
-
-       error = tdm_buffer_add_release_handler(surface, NULL, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
+       ASSERT_TRUE(tdm_buffer_add_destroy_handler(NULL, _ut_tdm_buffer_destroy_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMBuffer, AddReleaseHandlerSuccessful)
+TEST_P(TDMBuffer, BufferAddDestroyHandlerNullOther)
 {
-       error = tdm_buffer_add_release_handler(surface, release_handler, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-
-       handler_is_called = 0;
-       tdm_buffer_unref_backend(surface);
-       ASSERT_TRUE(handler_is_called);
+       ASSERT_TRUE(tdm_buffer_add_destroy_handler(buffer, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-
-/* void tdm_buffer_remove_release_handler(tbm_surface_h buffer, tdm_buffer_release_handler func, void *user_data) */
-TEST_F(TDMBuffer, RemoveReleaseHandlerFailNULL)
+TEST_P(TDMBuffer, BufferRemoveDestroyHandler)
 {
-       tdm_buffer_remove_release_handler(NULL, release_handler, &handler_is_called);
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_destroy_handler(buffer, _ut_tdm_buffer_destroy_cb, &done) == TDM_ERROR_NONE);
+       tdm_buffer_remove_destroy_handler(buffer, _ut_tdm_buffer_destroy_cb, &done);
+       tbm_surface_destroy(buffer);
+       buffer = NULL;
+       ASSERT_TRUE(done == false);
+}
 
-       tdm_buffer_remove_release_handler(surface, NULL, &handler_is_called);
+TEST_P(TDMBuffer, BufferRemoveDestroyHandlerDifferentData)
+{
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_destroy_handler(buffer, _ut_tdm_buffer_destroy_cb, &done) == TDM_ERROR_NONE);
+       tdm_buffer_remove_destroy_handler(buffer, _ut_tdm_buffer_destroy_cb, NULL);
+       tbm_surface_destroy(buffer);
+       buffer = NULL;
+       ASSERT_TRUE(done == true);
 }
 
-TEST_F(TDMBuffer, RemoveReleaseHandlerFailWithoutAdd)
+TEST_P(TDMBuffer, BufferRemoveDestroyHandlerNullObject)
 {
-       tdm_buffer_remove_release_handler(surface, release_handler, &handler_is_called);
+       tdm_buffer_remove_destroy_handler(NULL, _ut_tdm_buffer_destroy_cb, NULL);
 }
 
-TEST_F(TDMBuffer, RemoveReleaseHandlerSuccessful)
+TEST_P(TDMBuffer, BufferRemoveDestroyHandlerNullOther)
 {
-       error = tdm_buffer_add_release_handler(surface, release_handler, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       tdm_buffer_remove_destroy_handler(buffer, NULL, NULL);
+}
 
-       tdm_buffer_remove_release_handler(surface, release_handler, &handler_is_called);
+static void
+_ut_tdm_buffer_release_cb(tbm_surface_h buffer, void *user_data)
+{
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+}
 
-       handler_is_called = 0;
-       tdm_buffer_unref_backend(surface);
-       ASSERT_FALSE(handler_is_called);
+TEST_P(TDMBuffer, BufferAddReleaseHandler)
+{
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb, &done) == TDM_ERROR_NONE);
+       tdm_buffer_ref_backend(buffer);
+       ASSERT_TRUE(done == false);
+       tdm_buffer_unref_backend(buffer);
+       ASSERT_TRUE(done == true);
 }
 
-/* tdm_error tdm_buffer_add_destroy_handler(tbm_surface_h buffer, tdm_buffer_destroy_handler func, void *user_data) */
-TEST_F(TDMBuffer, AddDestroyHandlerFailNULL)
+TEST_P(TDMBuffer, BufferAddReleaseHandlerTwice)
 {
-       error = tdm_buffer_add_destroy_handler(NULL, destroy_handler, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb, NULL) == TDM_ERROR_BAD_REQUEST);
+}
 
-       error = tdm_buffer_add_destroy_handler(surface, NULL, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
+TEST_P(TDMBuffer, BufferAddReleaseHandlerNullObject)
+{
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(NULL, _ut_tdm_buffer_release_cb, &done) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(done == false);
 }
 
-TEST_F(TDMBuffer, AddDestroyHandlerSuccessful)
+TEST_P(TDMBuffer, BufferAddReleaseHandlerNullOther)
 {
-       error = tdm_buffer_add_destroy_handler(surface, destroy_handler, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-       handler_is_called = 0;
-       tbm_surface_internal_unref(surface);
-       ASSERT_TRUE(handler_is_called);
-       surface = NULL;
+TEST_P(TDMBuffer, BufferRemoveReleaseHandler)
+{
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb, &done) == TDM_ERROR_NONE);
+       tdm_buffer_ref_backend(buffer);
+       ASSERT_TRUE(done == false);
+       tdm_buffer_remove_release_handler(buffer, _ut_tdm_buffer_release_cb, &done);
+       tdm_buffer_unref_backend(buffer);
+       ASSERT_TRUE(done == false);
 }
 
-/* void tdm_buffer_remove_destroy_handler() */
-TEST_F(TDMBuffer, RemoveDestroyHandlerFailNULL)
+TEST_P(TDMBuffer, BufferRemoveReleaseHandlerDifferentData)
 {
-       tdm_buffer_remove_destroy_handler(NULL, release_handler, &handler_is_called);
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb, &done) == TDM_ERROR_NONE);
+       tdm_buffer_ref_backend(buffer);
+       ASSERT_TRUE(done == false);
+       tdm_buffer_remove_release_handler(buffer, _ut_tdm_buffer_release_cb, NULL);
+       tdm_buffer_unref_backend(buffer);
+       ASSERT_TRUE(done == true);
+}
 
-       tdm_buffer_remove_destroy_handler(surface, NULL, &handler_is_called);
+static void
+_ut_tdm_buffer_release_cb2(tbm_surface_h buffer, void *user_data)
+{
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+       tdm_buffer_remove_release_handler(buffer, _ut_tdm_buffer_release_cb2, user_data);
 }
 
-TEST_F(TDMBuffer, RemoveDestroyHandlerFailWithoutAdd)
+TEST_P(TDMBuffer, BufferRemoveReleaseHandlerInHandler)
 {
-       tdm_buffer_remove_destroy_handler(surface, release_handler, &handler_is_called);
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb2, &done) == TDM_ERROR_NONE);
+       tdm_buffer_ref_backend(buffer);
+       ASSERT_TRUE(done == false);
+       tdm_buffer_unref_backend(buffer);
+       ASSERT_TRUE(done == true);
+
+       done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb2, &done) == TDM_ERROR_NONE);
+       tdm_buffer_ref_backend(buffer);
+       ASSERT_TRUE(done == false);
+       tdm_buffer_unref_backend(buffer);
+       ASSERT_TRUE(done == true);
+
+       done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb2, &done) == TDM_ERROR_NONE);
+       tdm_buffer_ref_backend(buffer);
+       ASSERT_TRUE(done == false);
+       tdm_buffer_unref_backend(buffer);
+       ASSERT_TRUE(done == true);
 }
 
-TEST_F(TDMBuffer, RemoveDestroyHandlerSuccessful)
+TEST_P(TDMBuffer, BufferRemoveReleaseHandlerNullObject)
 {
-       error = tdm_buffer_add_destroy_handler(surface, release_handler, &handler_is_called);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       bool done = false;
+       ASSERT_TRUE(tdm_buffer_add_release_handler(buffer, _ut_tdm_buffer_release_cb, &done) == TDM_ERROR_NONE);
+       tdm_buffer_ref_backend(buffer);
+       ASSERT_TRUE(done == false);
+       tdm_buffer_remove_release_handler(NULL, _ut_tdm_buffer_release_cb, &done);
+       tdm_buffer_unref_backend(buffer);
+       ASSERT_TRUE(done == true);
+}
 
-       tdm_buffer_remove_destroy_handler(surface, release_handler, &handler_is_called);
+TEST_P(TDMBuffer, BufferRemoveReleaseHandlerNullOther)
+{
+       tdm_buffer_remove_release_handler(buffer, NULL, NULL);
+}
 
-       handler_is_called = 0;
-       tbm_surface_internal_unref(surface);
-       ASSERT_FALSE(handler_is_called);
+TEST_P(TDMBuffer, BufferRemoveReleaseHandlerNoAdd)
+{
+       tdm_buffer_remove_release_handler(buffer, _ut_tdm_buffer_release_cb, NULL);
 }
 
+INSTANTIATE_TEST_CASE_P(TDMBufferParams,
+                                               TDMBuffer,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
index 4ebcc5a..25c48f8 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
 #include "ut_tdm.h"
-#include "tdm.h"
-#include "tdm_config.h"
-extern "C" {
-#include "tbm_bufmgr.h"
-#include "tbm_drm_helper.h"
-}
-
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#include <vector>
-
-class TDMCaptureWithoutCreation : public testing::Test {
-protected:
-       tdm_display *dpy = nullptr;
-       tbm_bufmgr bufmgr = nullptr;
-       tdm_display_capability display_capability = (tdm_display_capability)0;
-       bool has_capture = false;
-       std::vector<tdm_output *> output_array;
-
-       virtual void SetEnvs()
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-       }
-
-       virtual void UnsetEnvs()
-       {
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
-       }
-
-       void SetUp(void)
-       {
-               tdm_error error = TDM_ERROR_NONE;
-               int output_count;
-
-               SetEnvs();
-
-               /* FIXME: fix the error. If we initialize TBM before TDM we get fail
-                * in the tdm_output_set_dpms */
-#if 0
-               bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(bufmgr == NULL);
-#endif
 
-               dpy = tdm_display_init(&error);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               ASSERT_FALSE(dpy == nullptr);
-
-               error = tdm_display_get_capabilities(dpy, &display_capability);
-#ifdef FAIL_ON_UNSUPPORTED
-               ASSERT_TRUE(display_capability & TDM_DISPLAY_CAPABILITY_CAPTURE);
-#endif
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               if (display_capability & TDM_DISPLAY_CAPABILITY_CAPTURE)
-                       has_capture = true;
-
-               ASSERT_TRUE(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE);
-
-               for (int i = 0; i < output_count; i++) {
-                       tdm_output *output = tdm_display_get_output(dpy, i, &error);
-
-                       if (TDM_ERROR_NONE != error || nullptr == output)
-                               continue;
-
-                       tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-                       if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status))
-                               continue;
-
-                       if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                               continue;
-
-                       output_array.push_back(output);
-               }
-       }
+class TDMCapture : public TDMOutput {
+public:
+       tdm_capture *capture;
+       tdm_capture_capability capabilities;
+       const tbm_format *formats;
+       int format_count;
+       int min_w;
+       int min_h;
+       int max_w;
+       int max_h;
+       int preferred_align;
 
-       void TearDown(void)
-       {
-               if (dpy)
-                       tdm_display_deinit(dpy);
-               if (bufmgr)
-                       tbm_bufmgr_deinit(bufmgr);
+       tbm_surface_h buffers[3];
 
-               UnsetEnvs();
-       }
-};
+       tdm_info_capture info;
 
-struct UtCapture
-{
        tdm_output *output;
-       const tdm_output_mode *output_mode;
-       tdm_capture *capture;
-       std::vector<tdm_layer *> layers;
-       UtCapture(tdm_output *, const tdm_output_mode *, tdm_capture *,  std::vector<tdm_layer *>);
-};
 
-UtCapture::UtCapture(tdm_output *_output, const tdm_output_mode *_output_mode,
-                                        tdm_capture *_capture, std::vector<tdm_layer *> _layers)
-{
-       output = _output;
-       output_mode = _output_mode;
-       capture = _capture;
-       layers = _layers;
-}
-
-class TDMCapture : public TDMCaptureWithoutCreation {
-protected:
-       const tbm_format *formats = nullptr;
-       int format_count = 0;
-       std::vector<UtCapture> captures;
-       std::vector<tbm_surface_h> buffers;
-       static int utCaptureDoneHandlerSuccessCounter;
-       friend void UtCaptureDoneHandler(tdm_capture *capture,
-                                                         tbm_surface_h buffer, void *user_data);
+       TDMCapture();
        void SetUp(void);
        void TearDown(void);
-       void UtCaptureGetInfo(UtCapture *capture, double scale, tdm_transform transform, tdm_info_capture *info);
-       void UtCaptureGetInfo(UtCapture *capture, tdm_info_capture *info);
-       tbm_surface_h UtCaptureCreateBuffer(UtCapture *capture);
-       tbm_surface_h UtCaptureCreateBuffer(int width, int height, tbm_format format, int scanout);
-       tbm_surface_h UtCaptureCreateBuffer(int width, int height, tbm_format format);
-};
 
-int TDMCapture::utCaptureDoneHandlerSuccessCounter = 0;
+       bool FindFormat(tbm_format fmt);
+       bool TestPrepareDefault(void);
+       bool TestPrepare(int output_idx, int w, int h, tbm_format fmt, tdm_transform t, tdm_capture_type c, int frequency);
+       void TestDone(void);
+       void DumpBuffers(int b, char *test);
+       void DestroyBuffers(void);
+};
 
-void UtCaptureDoneHandler(tdm_capture *capture,
-                                                 tbm_surface_h buffer, void *user_data)
+TDMCapture::TDMCapture()
 {
-       TDMCapture *fcapture = (TDMCapture *)user_data;
-
-       if (!fcapture)
-               return;
+       capture = NULL;
+       capabilities = (tdm_capture_capability)0;
+       formats = NULL;
+       format_count = 0;
+       min_w = min_h = max_w = max_h = preferred_align = -1;
 
-       for (tbm_surface_h buf : fcapture->buffers) {
-               if (buf == buffer) {
-                       fcapture->utCaptureDoneHandlerSuccessCounter++;
-                       break;
-               }
-       }
+       for (int b = 0; b < 3; b++)
+               buffers[b] = NULL;
+       memset(&info, 0, sizeof info);
+       output = NULL;
 }
 
 void TDMCapture::SetUp(void)
 {
-       tdm_error error;
+       TDMOutput::SetUp();
 
-       utCaptureDoneHandlerSuccessCounter = 0;
-
-       ASSERT_NO_FATAL_FAILURE(TDMCaptureWithoutCreation::SetUp());
+       tdm_error ret;
+       tdm_output *output;
 
-       if (!has_capture)
+       if (!has_capture_cap)
                return;
 
-       for (tdm_output *output : output_array) {
-               const tdm_output_mode *output_mode = nullptr;
-               int output_modes_cnt = 0;
-               const tdm_output_mode *output_modes;
-               int temp_layer_count = 0;
-               std::vector<tdm_layer *> layers;
-
-               error = tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int o = 0; o < output_count; o++) {
+               output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
 
-               for(int j = 0; j < output_modes_cnt; j++)
-                       if(output_modes[j].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
-                               output_mode = &output_modes[j];
-
-               ASSERT_NE(nullptr, output_mode);
-
-               if (TDM_ERROR_NONE != tdm_output_get_layer_count(output, &temp_layer_count))
-                       continue;
-               if (0 == temp_layer_count)
+               if (!ut_tdm_output_is_connected(output))
                        continue;
 
-               for (int i = 0; i < temp_layer_count; ++i) {
-                       tdm_layer *layer;
-                       layer = tdm_output_get_layer(output, i, &error);
-                       ASSERT_TRUE(TDM_ERROR_NONE == error);
-                       ASSERT_FALSE(NULL == layer);
-                       layers.push_back(layer);
-               }
-
-               tdm_capture *capture = tdm_output_create_capture(output, &error);
-               ASSERT_NE(nullptr, capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               captures.emplace_back(output, output_mode, capture, layers);
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, output) == true);
        }
-
-       error =
-               tdm_display_get_capture_available_formats(dpy, &formats, &format_count);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-       ASSERT_NE(nullptr, formats);
-       ASSERT_GE(format_count, 0);
 }
 
 void TDMCapture::TearDown(void)
 {
-       for (UtCapture & utCapture : captures)
-               tdm_capture_destroy(utCapture.capture);
+       if (capture)
+               tdm_capture_destroy(capture);
 
-       for (tbm_surface_h buffer : buffers) {
-               tbm_surface_destroy(buffer);
-       }
+       DestroyBuffers();
 
-       TDMCaptureWithoutCreation::TearDown();
+       TDMOutput::TearDown();
 }
 
-void TDMCapture::UtCaptureGetInfo(UtCapture *capture, double scale,
-                                                                 tdm_transform transform, tdm_info_capture *info)
+bool TDMCapture::TestPrepareDefault(void)
 {
-       memset((void *)info, 0, sizeof(tdm_info_capture));
+       tdm_error ret;
 
-       const tdm_output_mode *output_mode = capture->output_mode;
+       TDM_UT_RETURN_FALSE_IF_FAIL(has_outputs == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(outputs != NULL);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output_count > 0);
 
-       int w = output_mode->hdisplay * scale;
-       int h = output_mode->vdisplay * scale;
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_capabilities(dpy, &capabilities) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(capabilities > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_formats(dpy, &formats, &format_count) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(formats != NULL);
+       TDM_UT_RETURN_FALSE_IF_FAIL(format_count > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(min_w == -1 || min_w > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(min_h == -1 || min_h > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(max_w == -1 || max_w > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(max_h == -1 || max_h > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(preferred_align == -1 || preferred_align > 0);
 
-       if (transform == TDM_TRANSFORM_90 || transform == TDM_TRANSFORM_270 ||
-               transform == TDM_TRANSFORM_FLIPPED_90 || transform == TDM_TRANSFORM_FLIPPED_270) {
-               int tmp = w;
-               w = h;
-               h = tmp;
-       }
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       info->dst_config.size.h = w;
-       info->dst_config.size.v = h;
-       info->dst_config.pos.x = 0;
-       info->dst_config.pos.y = 0;
-       info->dst_config.pos.w = w;
-       info->dst_config.pos.h = h;
-       info->dst_config.format = formats[0];
-       info->transform = transform;
-       info->type = TDM_CAPTURE_TYPE_ONESHOT;
-}
+               capture = tdm_output_create_capture(outputs[o], &ret);
+               TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(capture != NULL);
 
-void TDMCapture::UtCaptureGetInfo(UtCapture *capture, tdm_info_capture *info)
-{
-       UtCaptureGetInfo(capture, 1.0, TDM_TRANSFORM_NORMAL, info);
-}
+               TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[0], 0, false, 3, buffers) == true);
+               TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_capture_fill_info(outputs[o], buffers[0], TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, &info) == true);
+               TDM_UT_RETURN_FALSE_IF_FAIL(tdm_capture_set_info(capture, &info) == TDM_ERROR_NONE);
 
-tbm_surface_h
-TDMCapture::UtCaptureCreateBuffer(UtCapture *capture)
-{
-       tbm_surface_h buffer;
+               output = outputs[o];
 
-       buffer = tbm_surface_create(capture->output_mode->hdisplay,
-                                                               capture->output_mode->vdisplay, formats[0]);
-       if (buffer)
-               buffers.push_back(buffer);
+               if (capture)
+                       break;
+       }
 
-       return buffer;
+       return (capture) ? true : false;
 }
 
-tbm_surface_h
-TDMCapture::UtCaptureCreateBuffer(int width, int height, tbm_format format, int scanout)
+bool TDMCapture::FindFormat(tbm_format fmt)
 {
-       tbm_surface_h buffer;
+       bool found = false;
 
-       if (scanout)
-               buffer = tbm_surface_internal_create_with_flags(width, height, format, TBM_BO_SCANOUT);
-       else
-               buffer = tbm_surface_internal_create_with_flags(width, height, format, TBM_BO_DEFAULT);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_capabilities(dpy, &capabilities) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(capabilities > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_formats(dpy, &formats, &format_count) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(formats != NULL);
+       TDM_UT_RETURN_FALSE_IF_FAIL(format_count > 0);
 
-       if (buffer)
-               buffers.push_back(buffer);
+       for (int f = 0; f < format_count; f++) {
+               if (formats[f] == fmt) {
+                       found = true;
+                       break;
+               }
+       }
 
-       return buffer;
+       return found;
 }
 
-tbm_surface_h
-TDMCapture::UtCaptureCreateBuffer(int width, int height, tbm_format format)
+bool TDMCapture::TestPrepare(int output_idx, int w, int h, tbm_format fmt, tdm_transform t, tdm_capture_type c, int frequency)
 {
-       return UtCaptureCreateBuffer(width, height, format, 0);
-}
+       tdm_error ret;
 
-class TDMCaptureCommit : public TDMCapture {
-public:
-private:
-       int epFd = -1;
-       int timerFd = -1;
-       int tdmFd = -1;
-       static const int timeLimitSec = 3;
-       static const int timeLimitNsec = 0;
-protected:
-       void SetUp(void);
-       void TearDown(void);
-       void UtHandleCaptureEvent();
-       int UtPrepareToCapture(double scale, tdm_transform transform, tdm_capture_type type);
-       int UtPrepareToCapture(double scale, tdm_transform transform);
-       int UtPrepareToCapture();
-};
-
-void TDMCaptureCommit::SetUp(void)
-{
-       struct epoll_event ep;
-       tdm_error error;
+       TDM_UT_RETURN_FALSE_IF_FAIL(has_outputs == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(outputs != NULL);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output_count > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output_count >= output_idx);
 
-       ASSERT_NO_FATAL_FAILURE(TDMCapture::SetUp());
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_capabilities(dpy, &capabilities) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(capabilities > 0);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_output_set_mode(utCapture.output, utCapture.output_mode);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(FindFormat(fmt) == true);
 
-               error = tdm_output_set_dpms(utCapture.output, TDM_OUTPUT_DPMS_ON);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(min_w == -1 || min_w > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(min_h == -1 || min_h > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(max_w == -1 || max_w > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(max_h == -1 || max_h > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(preferred_align == -1 || preferred_align > 0);
 
-               for (tdm_layer *layer : utCapture.layers) {
-                       int w, h;
-                       tdm_layer_capability lcapabilities;
-                       tbm_surface_h buffer;
-                       tdm_info_layer layer_info = {0};
+       capture = tdm_output_create_capture(outputs[output_idx], &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(capture != NULL);
 
-                       w = utCapture.output_mode->hdisplay;
-                       h = utCapture.output_mode->vdisplay;
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(w, h, fmt, 0, false, 3, buffers) == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_capture_fill_info(outputs[output_idx], buffers[0], t, c, frequency, &info) == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_capture_set_info(capture, &info) == TDM_ERROR_NONE);
 
-                       error = tdm_layer_get_capabilities(layer, &lcapabilities);
-                       ASSERT_EQ(TDM_ERROR_NONE, error);
-                       if (!(lcapabilities & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                               w = w / 2;
-                               h = h / 2;
-                       }
+       output = outputs[output_idx];
 
-                       buffer = UtCaptureCreateBuffer(w, h, TBM_FORMAT_ARGB8888, 1);
-                       ASSERT_NE(nullptr, buffer);
-
-                       layer_info.src_config.size.h = w;
-                       layer_info.src_config.size.v = h;
-                       layer_info.src_config.pos.x = 0;
-                       layer_info.src_config.pos.y = 0;
-                       layer_info.src_config.pos.w = w;
-                       layer_info.src_config.pos.h = h;
-                       layer_info.src_config.format = TBM_FORMAT_ARGB8888;
-                       layer_info.dst_pos.x = 0;
-                       layer_info.dst_pos.y = 0;
-                       layer_info.dst_pos.w = w;
-                       layer_info.dst_pos.h = h;
-                       layer_info.transform = TDM_TRANSFORM_NORMAL;
-
-                       error = tdm_layer_set_info(layer, &layer_info);
-                       ASSERT_EQ(TDM_ERROR_NONE, error);
-
-                       error = tdm_layer_set_buffer(layer, buffer);
-                       ASSERT_EQ(TDM_ERROR_NONE, error);
-               }
+       return true;
+}
 
-               error = tdm_output_commit(utCapture.output, 0, nullptr, nullptr);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+void TDMCapture::TestDone(void)
+{
+       if (capture) {
+               tdm_capture_destroy(capture);
+               capture = NULL;
        }
 
-       /* TODO: use output_commit_handle */
-       usleep(200000);
-
-       epFd = epoll_create1(0);
-       ASSERT_TRUE(epFd != -1);
-
-       timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
-       ASSERT_TRUE(timerFd != -1);
-
-       memset(&ep, 0, sizeof ep);
-       ep.events |= EPOLLIN;
-       ep.data.fd = timerFd;
-       ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
-
-       ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
-
-       memset(&ep, 0, sizeof ep);
-       ep.events |= EPOLLIN;
-       ep.data.fd = tdmFd;
-       ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
+       DestroyBuffers();
 }
 
-void TDMCaptureCommit::TearDown(void)
+void TDMCapture::DumpBuffers(int b, char *test)
 {
-       if (epFd)
-               close(epFd);
-       if (timerFd)
-               close(timerFd);
-
-       for (UtCapture & utCapture : captures) {
-               for (tdm_layer *layer : utCapture.layers)
-                       tdm_layer_unset_buffer(layer);
+       char filename[256];
+       if (test)
+               snprintf(filename, sizeof filename, "%s_%s_%d", typeid(*this).name(), test, b);
+       else
+               snprintf(filename, sizeof filename, "%s_%d", typeid(*this).name(), b);
+       tdm_helper_dump_buffer_str(buffers[b], NULL, filename);
+}
 
-               tdm_output_set_dpms(utCapture.output, TDM_OUTPUT_DPMS_OFF);
+void TDMCapture::DestroyBuffers(void)
+{
+       for (int b = 0; b < 3; b++) {
+               tbm_surface_destroy(buffers[b]);
+               buffers[b] = NULL;
        }
-
-       TDMCapture::TearDown();
 }
 
-void TDMCaptureCommit::UtHandleCaptureEvent()
+bool
+ut_tdm_capture_fill_info(tdm_output *output, tbm_surface_h buffer, tdm_transform transform,
+                                                tdm_capture_type type, int frequency, tdm_info_capture *info)
 {
-       struct itimerspec its;
-       int count;
-       struct epoll_event ep_event[2];
-
-       if (utCaptureDoneHandlerSuccessCounter == (int)captures.size())
-               return;
+       int bw, bh;
 
-       its.it_interval.tv_sec = 0;
-       its.it_interval.tv_nsec = 0;
-       its.it_value.tv_sec = timeLimitSec;
-       its.it_value.tv_nsec = timeLimitNsec;
+       memset(info, 0, sizeof *info);
 
-       ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
+       bw = bh = TDM_UT_INVALID_VALUE;
+       tdm_helper_get_buffer_full_size(buffer, &bw, &bh);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(buffer));
+       TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(buffer));
+       info->dst_config.size.h = bw;
+       info->dst_config.size.v = bh;
+       info->dst_config.pos.x = 0;
+       info->dst_config.pos.y = 0;
+       info->dst_config.pos.w = tbm_surface_get_width(buffer);
+       info->dst_config.pos.h = tbm_surface_get_height(buffer);
+       info->dst_config.format = tbm_surface_get_format(buffer);
 
-       while (1) {
-               count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
-               ASSERT_TRUE(count >= 0);
+       info->transform = transform;
+       info->type = type;
+       info->flags = 0;
 
-               for (int i = 0; i < count; i++) {
-                       if (ep_event[i].data.fd == timerFd) {
-                               return;
-                       } else {
-                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
-                               if (utCaptureDoneHandlerSuccessCounter == (int)captures.size())
-                                       return;
-                       }
-               }
+       if (frequency <= 0) {
+               const tdm_output_mode *mode = NULL;
+               TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_mode(output, &mode) == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(mode != NULL);
+               frequency = mode->vrefresh;
        }
-}
 
-int TDMCaptureCommit::UtPrepareToCapture(double scale, tdm_transform transform, tdm_capture_type type)
-{
-       tdm_error error;
-       tbm_surface_h buffer;
+       info->frequency = frequency;
 
-       for (UtCapture & utCapture : captures) {
-               tdm_info_capture info = {0};
+       TDM_INFO("filling capture info done: dst_config(%dx%d: %d,%d %dx%d: %c%c%c%c) transform(%s) type(%s) freq(%d)",
+                        info->dst_config.size.h, info->dst_config.size.h,
+                        info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h,
+                        FOURCC_STR(info->dst_config.format),
+                        tdm_transform_str(info->transform), tdm_capture_type_str(info->type), info->frequency);
 
-               UtCaptureGetInfo(&utCapture, scale, transform, &info);
-               info.type = type;
+       return true;
+}
 
-               error = tdm_capture_set_done_handler(utCapture.capture, UtCaptureDoneHandler, this);
-               EXPECT_EQ(TDM_ERROR_NONE, error);
-               if (error != TDM_ERROR_NONE)
-                       return -1;
+#ifdef UT_TDM_CAPTURE_ENABLE
 
-               error = tdm_capture_set_info(utCapture.capture, &info);
-               EXPECT_EQ(TDM_ERROR_NONE, error);
-               if (error != TDM_ERROR_NONE)
-                       return -1;
+static tbm_format test_formats[] = {
+       TBM_FORMAT_ARGB8888,
+       TBM_FORMAT_XRGB8888,
+       TBM_FORMAT_YUV420,
+       TBM_FORMAT_YVU420,
+       TBM_FORMAT_NV12,
+       TBM_FORMAT_NV21,
+};
 
-               buffer = UtCaptureCreateBuffer(info.dst_config.size.h,
-                                                                          info.dst_config.size.v,
-                                                                          info.dst_config.format);
-               EXPECT_NE(NULL, buffer);
-               if (!buffer)
-                       return -1;
+#define TEST_FORMAT_CNT (int)(sizeof(test_formats) / sizeof((test_formats)[0]))
 
-               error = tdm_capture_attach(utCapture.capture, buffer);
-               EXPECT_EQ(TDM_ERROR_NONE, error);
-               if (error != TDM_ERROR_NONE)
-                       return -1;
+TEST_P(TDMCapture, CaptureDispalyGetAvaiableFormats)
+{
+       const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
+       int count = TDM_UT_INVALID_VALUE;
+       if (has_capture_cap) {
+               ASSERT_TRUE(tdm_display_get_capture_available_formats(dpy, &formats, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(formats != NULL && formats != (const tbm_format *)TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(count > 0 && count != TDM_UT_INVALID_VALUE);
+       } else {
+               ASSERT_TRUE(tdm_display_get_capture_available_formats(dpy, &formats, &count) == TDM_ERROR_NO_CAPABILITY);
+               ASSERT_TRUE(formats == (const tbm_format *)TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
        }
-
-       return 0;
 }
 
-int TDMCaptureCommit::UtPrepareToCapture()
+TEST_P(TDMCapture, CaptureDispalyGetAvaiableFormatsNullObject)
 {
-       return UtPrepareToCapture(1.0, TDM_TRANSFORM_NORMAL);
+       const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
+       int count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_capture_available_formats(NULL, &formats, &count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(formats == (const tbm_format *)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
 }
 
-int TDMCaptureCommit::UtPrepareToCapture(double scale, tdm_transform transform)
+TEST_P(TDMCapture, CaptureDispalyGetAvaiableFormatsNullOther)
 {
-       return UtPrepareToCapture(1.0, TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT);
+       ASSERT_TRUE(tdm_display_get_capture_available_formats(dpy, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-class TDMCaptureCommitThread : public TDMCaptureCommit {
-protected:
-       void SetEnvs()
-       {
-               TDMCaptureCommit::SetEnvs();
-               setenv("TDM_THREAD", "1", 1);
-       }
-       void UnsetEnvs()
-       {
-               TDMCaptureCommit::UnsetEnvs();
-               unsetenv("TDM_THREAD");
+TEST_P(TDMCapture, CaptureDispalyGetAvaiableSize)
+{
+       int min_w = TDM_UT_INVALID_VALUE;
+       int min_h = TDM_UT_INVALID_VALUE;
+       int max_w = TDM_UT_INVALID_VALUE;
+       int max_h = TDM_UT_INVALID_VALUE;
+       int preferred_align = TDM_UT_INVALID_VALUE;
+       if (has_capture_cap) {
+               ASSERT_TRUE(tdm_display_get_capture_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE);
+               ASSERT_TRUE(min_w != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(min_h != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(max_w != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(max_h != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(preferred_align != TDM_UT_INVALID_VALUE);
+       } else {
+               ASSERT_TRUE(tdm_display_get_capture_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NO_CAPABILITY);
+               ASSERT_TRUE(min_w == TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(min_h == TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(max_w == TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(max_h == TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(preferred_align == TDM_UT_INVALID_VALUE);
        }
-};
+}
 
-TEST_F(TDMCaptureWithoutCreation, DisplayGetCaptureAvailableFormatsSuccessful)
+TEST_P(TDMCapture, CaptureDispalyGetAvaiableSizeNullObject)
 {
-       SKIP_FLAG(has_capture);
-       const tbm_format * formats = nullptr;
-       int count = -42;
-       ASSERT_TRUE(TDM_ERROR_NONE == tdm_display_get_capture_available_formats(dpy, &formats, &count));
-       ASSERT_FALSE(-42 == count);
-       ASSERT_FALSE(nullptr == formats);
+       int min_w = TDM_UT_INVALID_VALUE;
+       int min_h = TDM_UT_INVALID_VALUE;
+       int max_w = TDM_UT_INVALID_VALUE;
+       int max_h = TDM_UT_INVALID_VALUE;
+       int preferred_align = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_capture_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(min_w == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(min_h == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(max_w == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(max_h == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(preferred_align == TDM_UT_INVALID_VALUE);
 }
 
-/* tdm_display_create_pp() */
+TEST_P(TDMCapture, CaptureDispalyGetAvaiableSizeNullOther)
+{
+       if (has_capture_cap)
+               ASSERT_TRUE(tdm_display_get_capture_available_size(dpy, NULL, NULL, NULL, NULL, NULL) == TDM_ERROR_NONE);
+       else
+               ASSERT_TRUE(tdm_display_get_capture_available_size(dpy, NULL, NULL, NULL, NULL, NULL) == TDM_ERROR_NO_CAPABILITY);
+}
 
-TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureNullAll)
+TEST_P(TDMCapture, CaptureDestroy)
 {
-       SKIP_FLAG(has_capture);
-       tdm_capture *capture;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
+
+       ASSERT_TRUE(TestPrepareDefault() == true);
 
-       capture = tdm_output_create_capture(nullptr, nullptr);
-       ASSERT_EQ(nullptr, capture);
+       TestDone();
 }
 
-TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureNullOutput)
+TEST_P(TDMCapture, CaptureDestroyNullObject)
 {
-       SKIP_FLAG(has_capture);
-       tdm_capture *capture;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       capture = tdm_output_create_capture(nullptr, &error);
-       ASSERT_EQ(nullptr, capture);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       tdm_capture_destroy(NULL);
 }
 
-TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureSuccessNullError)
+TEST_P(TDMCapture, CaptureSetInfo)
 {
-       SKIP_FLAG(has_capture);
-       tdm_capture *capture;
-
-       for (tdm_output *output : output_array) {
-               capture = tdm_output_create_capture(output, nullptr);
-               ASSERT_NE(nullptr, capture);
-       }
+       /* tested in CaptureNoScaleNoTransformNoCSC */
 }
 
-TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureSuccess)
+TEST_P(TDMCapture, CaptureSetInfoNullObject)
 {
-       SKIP_FLAG(has_capture);
-       tdm_capture *capture;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       for (tdm_output *output : output_array) {
-               capture = tdm_output_create_capture(output, &error);
-               ASSERT_NE(nullptr, capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+       tdm_info_capture info;
+       memset(&info, 0, sizeof info);
+       ASSERT_TRUE(tdm_capture_set_info(NULL, &info) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-/* tdm_display_get_capture_available_size */
-
-TEST_F(TDMCapture, DisplayGetCaptureAvailableSizeFailNullAll)
+TEST_P(TDMCapture, CaptureSetInfoNullOther)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
+
+       ASSERT_TRUE(TestPrepareDefault() == true);
 
-       error = tdm_display_get_capture_available_size(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_capture_set_info(capture, NULL) == TDM_ERROR_INVALID_PARAMETER);
+
+       TestDone();
 }
 
-TEST_F(TDMCapture, DisplayGetCaptureAvailableSizeSuccess)
+static void
+_ut_tdm_capture_done_cb(tdm_capture *capture, tbm_surface_h buffer, void *user_data)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
-       int min_w;
-       int min_h;
-       int max_w;
-       int max_h;
-       int preferred_align;
-
-       error = tdm_display_get_capture_available_size(dpy, &min_w, &min_h,
-                                                                                                  &max_w, &max_h, &preferred_align);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
 }
 
+TEST_P(TDMCapture, CaptureSetDoneHandler)
+{
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-/* tdm_capture_set_info() */
+       ASSERT_TRUE(TestPrepareDefault() == true);
 
-TEST_F(TDMCapture, CaptureSetInfoFailNullAll)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       ASSERT_TRUE(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb, NULL) == TDM_ERROR_NONE);
 
-       error = tdm_capture_set_info(nullptr, nullptr);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       TestDone();
 }
 
-TEST_F(TDMCapture, CaptureSetInfoFailNullCapture)
+TEST_P(TDMCapture, CaptureSetDoneHandlerNullObject)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
-       tdm_info_capture info;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       error = tdm_capture_set_info(nullptr, &info);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_capture_set_done_handler(NULL, _ut_tdm_capture_done_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMCapture, CaptureSetInfoNullInfo)
+TEST_P(TDMCapture, CaptureSetDoneHandlerNullOther)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_set_info(utCapture.capture, nullptr);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
+       ASSERT_TRUE(TestPrepareDefault() == true);
+
+       ASSERT_TRUE(tdm_capture_set_done_handler(capture, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
+
+       TestDone();
 }
 
-TEST_F(TDMCapture, CaptureSetInfoSuccessStream)
+TEST_P(TDMCapture, CaptureAttach)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
-       tdm_info_capture info;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
+
+       for (int o = 0; o < output_count; o++) {
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_output_set_mode(utCapture.output, utCapture.output_mode);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               for (int f = 0; f < TEST_FORMAT_CNT; f++) {
+                       if (!FindFormat(test_formats[f]))
+                               continue;
 
-               UtCaptureGetInfo(&utCapture, &info);
+                       ASSERT_TRUE(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f],
+                                                                       TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1) == true);
 
-               info.type = TDM_CAPTURE_TYPE_STREAM;
+                       for (int b = 0; b < 3; b++)
+                               ASSERT_TRUE(tdm_capture_attach(capture, buffers[b]) == TDM_ERROR_NONE);
 
-               error = tdm_capture_set_info(utCapture.capture, &info);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+                       TestDone();
+               }
        }
 }
 
-TEST_F(TDMCapture, CaptureSetInfoSuccess)
+TEST_P(TDMCapture, CaptureAttachNullObject)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
-       tdm_info_capture info;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       for (UtCapture & utCapture : captures) {
-               UtCaptureGetInfo(&utCapture, &info);
+       tbm_surface_h buffer = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
 
-               error = tdm_capture_set_info(utCapture.capture, &info);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+       ASSERT_TRUE(tdm_capture_attach(NULL, buffer) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-/* tdm_capture_set_done_handler() */
-
-TEST_F(TDMCapture, CaptureSetDoneHandlerFailNullAll)
+TEST_P(TDMCapture, CaptureAttachNullOther)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       error = tdm_capture_set_done_handler(nullptr, nullptr, nullptr);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-}
+       ASSERT_TRUE(TestPrepareDefault() == true);
 
-TEST_F(TDMCapture, CaptureSetDoneHandlerFailNullCapture)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       ASSERT_TRUE(tdm_capture_attach(capture, NULL) == TDM_ERROR_INVALID_PARAMETER);
 
-       error = tdm_capture_set_done_handler(nullptr, UtCaptureDoneHandler, this);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       TestDone();
 }
 
-TEST_F(TDMCapture, CaptureSetDoneHandlerSuccessNullFailNullFunc)
+TEST_P(TDMCapture, CaptureCommit)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_pp_set_done_handler(utCapture.capture, nullptr, this);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
+       ASSERT_TRUE(TestPrepareDefault() == true);
+
+       ASSERT_TRUE(tdm_capture_commit(capture) == TDM_ERROR_NONE);
+
+       TestDone();
 }
 
-TEST_F(TDMCapture, CaptureSetDoneHandlerSuccessNullData)
+TEST_P(TDMCapture, CaptureCommitNullOBject)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_set_done_handler(utCapture.capture, UtCaptureDoneHandler, this);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+       ASSERT_TRUE(tdm_capture_commit(NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMCapture, CaptureSetDoneHandlerSuccess)
+TEST_P(TDMCapture, CaptureCommitDpmsOff)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_set_done_handler(utCapture.capture, UtCaptureDoneHandler, this);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
-}
+       ASSERT_TRUE(TestPrepareDefault() == true);
 
-/* tdm_capture_attach() */
+       ASSERT_TRUE(ut_tdm_output_unset(dpy, output) == true);
 
-TEST_F(TDMCapture, CaptureAttachFailNullAll)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       ASSERT_TRUE(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
 
-       error = tdm_capture_attach(nullptr, nullptr);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_capture_commit(capture) == TDM_ERROR_BAD_REQUEST);
+
+       TestDone();
 }
 
-TEST_F(TDMCapture, CaptureAttachFailNullCapture)
+TEST_P(TDMCapture, CaptureNoScaleNoTransformNoCSC)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
-       tbm_surface_h buffer;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       buffer = UtCaptureCreateBuffer(&captures[0]);
-       ASSERT_NE(nullptr, buffer);
+       bool done;
 
-       error = tdm_capture_attach(nullptr, buffer);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-}
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *mode = NULL;
 
-TEST_F(TDMCapture, CaptureAttachFailNullBuffer)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_attach(utCapture.capture, nullptr);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
-}
+               ASSERT_TRUE(tdm_output_get_mode(outputs[o], &mode) == TDM_ERROR_NONE);
 
-TEST_F(TDMCapture, CaptureAttachSuccess)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
-       tbm_surface_h buffer;
+               for (int f = 0; f < TEST_FORMAT_CNT; f++) {
+                       char temp[256];
+                       snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(test_formats[f]));
 
-       for (UtCapture & utCapture : captures) {
-               buffer = UtCaptureCreateBuffer(&utCapture);
-               ASSERT_NE(nullptr, buffer);
+                       if (!FindFormat(test_formats[f]))
+                               continue;
 
-               error = tdm_capture_attach(utCapture.capture, buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
-}
+                       ASSERT_TRUE(TestPrepare(o, mode->hdisplay, mode->vdisplay, test_formats[f],
+                                                                       TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1) == true);
 
-/* tdm_pp_commit() */
+                       ASSERT_TRUE(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb, &done) == TDM_ERROR_NONE);
 
-TEST_F(TDMCapture, CaptureCommitFailNullCapture)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+                       for (int b = 0; b < 3; b++) {
+                               done = false;
+                               ASSERT_TRUE(tdm_capture_attach(capture, buffers[b]) == TDM_ERROR_NONE);
+                               ASSERT_TRUE(tdm_capture_commit(capture) == TDM_ERROR_NONE);
 
-       error = tdm_capture_commit(nullptr);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-}
+                               while (!done)
+                                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-TEST_F(TDMCapture, CaptureCommitFailDpmsOff)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+                               DumpBuffers(b, temp);
+                       }
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_NE(TDM_ERROR_NONE, error);
+                       TestDone();
+               }
        }
 }
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccess)
+TEST_P(TDMCapture, CaptureScaleTransformCSC)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       ASSERT_NE(-1, UtPrepareToCapture());
+       bool done;
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *mode = NULL;
 
-       UtHandleCaptureEvent();
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+               ASSERT_TRUE(tdm_output_get_mode(outputs[o], &mode) == TDM_ERROR_NONE);
 
-TEST_F(TDMCaptureCommitThread, CaptureCommitSuccess)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+               for (int f = 0; f < TEST_FORMAT_CNT; f++) {
+                       char temp[256];
+                       snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(test_formats[f]));
 
-       ASSERT_NE(-1, UtPrepareToCapture());
+                       if (!FindFormat(test_formats[f]))
+                               continue;
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+                       ASSERT_TRUE(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f],
+                                                                       TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1) == true);
 
-       UtHandleCaptureEvent();
+                       ASSERT_TRUE(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb, &done) == TDM_ERROR_NONE);
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+                       for (int b = 0; b < 3; b++) {
+                               done = false;
+                               ASSERT_TRUE(tdm_capture_attach(capture, buffers[b]) == TDM_ERROR_NONE);
+                               ASSERT_TRUE(tdm_capture_commit(capture) == TDM_ERROR_NONE);
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScale)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+                               while (!done)
+                                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_NORMAL));
+                               DumpBuffers(b, temp);
+                       }
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+                       TestDone();
+               }
        }
+}
 
-       UtHandleCaptureEvent();
-
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
+static void
+_ut_tdm_capture_done_cb2(tdm_capture *capture, tbm_surface_h buffer, void *user_data)
+{
+       int *done = (int*)user_data;
+       if (done)
+               (*done)++;
 }
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransform)
+TEST_P(TDMCapture, CaptureAttachFewTimesInOneCommit)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_180));
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *mode = NULL;
+               int done = 0;
+               int f = 0;
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       UtHandleCaptureEvent();
+               ASSERT_TRUE(tdm_output_get_mode(outputs[o], &mode) == TDM_ERROR_NONE);
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+               char temp[256];
+               snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(test_formats[f]));
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransform90)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+               if (!FindFormat(test_formats[f]))
+                       continue;
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_90));
+               ASSERT_TRUE(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f],
+                                                               TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1) == true);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               ASSERT_TRUE(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, &done) == TDM_ERROR_NONE);
 
-       UtHandleCaptureEvent();
+               done = 0;
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+               for (int b = 0; b < 3; b++)
+                       ASSERT_TRUE(tdm_capture_attach(capture, buffers[b]) == TDM_ERROR_NONE);
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransform270)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+               ASSERT_TRUE(tdm_capture_commit(capture) == TDM_ERROR_NONE);
+               while (done != 3)
+                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_270));
+               for (int b = 0; b < 3; b++)
+                       DumpBuffers(b, temp);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               TestDone();
        }
-
-       UtHandleCaptureEvent();
-
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
 }
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransformFliped)
+TEST_P(TDMCapture, CaptureDestroyWithoutCommit)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_FLIPPED));
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *mode = NULL;
+               int f = 0;
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       UtHandleCaptureEvent();
+               ASSERT_TRUE(tdm_output_get_mode(outputs[o], &mode) == TDM_ERROR_NONE);
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+               if (!FindFormat(test_formats[f]))
+                       continue;
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransformFliped90)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+               ASSERT_TRUE(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f],
+                                                               TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1) == true);
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_FLIPPED_90));
+               ASSERT_TRUE(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, NULL) == TDM_ERROR_NONE);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               for (int b = 0; b < 3; b++)
+                       ASSERT_TRUE(tdm_capture_attach(capture, buffers[b]) == TDM_ERROR_NONE);
 
-       UtHandleCaptureEvent();
+               tdm_capture_destroy(capture);
+               capture = NULL;
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
+               TestDone();
+       }
 }
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransformFliped180)
+TEST_P(TDMCapture, CaptureDestroyBeforeDone)
 {
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_capture_cap);
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_FLIPPED_180));
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *mode = NULL;
+               int f = 0;
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       UtHandleCaptureEvent();
+               ASSERT_TRUE(tdm_output_get_mode(outputs[o], &mode) == TDM_ERROR_NONE);
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+               if (!FindFormat(test_formats[f]))
+                       continue;
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransformFliped270)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
+               ASSERT_TRUE(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f],
+                                                               TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1) == true);
 
-       ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_FLIPPED_270));
+               ASSERT_TRUE(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, NULL) == TDM_ERROR_NONE);
 
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               for (int b = 0; b < 3; b++)
+                       ASSERT_TRUE(tdm_capture_attach(capture, buffers[b]) == TDM_ERROR_NONE);
 
-       UtHandleCaptureEvent();
+               ASSERT_TRUE(tdm_capture_commit(capture) == TDM_ERROR_NONE);
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+               tdm_capture_destroy(capture);
+               capture = NULL;
 
-TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleStream)
-{
-       SKIP_FLAG(has_capture);
-       tdm_error error;
-
-       ASSERT_NE(-1, UtPrepareToCapture(1.0, TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_STREAM));
-
-       for (UtCapture & utCapture : captures) {
-               error = tdm_capture_commit(utCapture.capture);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               TestDone();
        }
+}
 
-       UtHandleCaptureEvent();
+INSTANTIATE_TEST_CASE_P(TDMCaptureParams,
+                                               TDMCapture,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
 
-       ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
-}
+#endif
index 1b65ed4..b8f5793 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
-#include "ut_tdm.h"
-
-#include <cstring>
-
-#include <sys/eventfd.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <semaphore.h>
 #include <sys/signalfd.h>
 #include <poll.h>
 #include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/timerfd.h>
 
-extern "C"
-{
-#include "tdm.h"
-#include "tdm_config.h"
+#include "ut_tdm.h"
 #include "tdm_client.h"
 
-#include "tbm_surface.h"
+enum {
+       TDM_UT_PIPE_MSG_NONE,
+       TDM_UT_PIPE_MSG_SERVER_READY,
+       TDM_UT_PIPE_MSG_DPMS_ON,
+       TDM_UT_PIPE_MSG_DPMS_OFF,
+       TDM_UT_PIPE_MSG_TERMINATE_SERVER,
+};
 
-#include "wayland-client.h"
-}
+static int _ut_tdm_pipe_read_msg(int fd);
+static bool _ut_tdm_pipe_write_msg(int fd, int msg);
+static pid_t _ut_tdm_client_server_fork(int *pipe_to_parent, int *pipe_to_child);
 
-class tdm_client_test_prepare
+class TDMClient : public TDMEnv
 {
 public:
-       tdm_client_test_prepare()
-       {
-               /* we have to deal with a named semaphore to protect an access to tdm across several instances
-                * of servers */
-               semaphore = sem_open(semaphore_name.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, 1);
-               if (semaphore == SEM_FAILED)
-               {
-                       if (errno == EEXIST)
-                               sem_unlink(semaphore_name.c_str());
-                       else
-                       {
-                               std::cout << "can't create semaphore(1): " << semaphore_name << ", errno: " << errno << ".\n";
-                               exit(EXIT_FAILURE);
-                       }
-               } else {
-                       return;
-               }
+       pid_t server_pid;
 
-               semaphore = sem_open(semaphore_name.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, 1);
-               if (semaphore == SEM_FAILED)
-               {
-                       std::cout << "can't create semaphore(2): " << semaphore_name << ", errno: " << errno << ".\n";
-                       exit(EXIT_FAILURE);
-               }
-       }
+       /* 0: read, 1: write */
+       int pipe_parent[2];
+       int pipe_child[2];
 
-       ~tdm_client_test_prepare()
-       {
-               sem_close(semaphore);
-               sem_unlink(semaphore_name.c_str());
-       }
+       tdm_client *client;
+       tdm_client_output *output;
+       tdm_client_vblank *vblank;
 
-       static sem_t *semaphore;
+       double vrefresh_interval, start, end;
 
-       /* /dev/shm/sem.tdm-client-utests */
-       static const std::string semaphore_name;
+       TDMClient();
+       void SetUp(void);
+       void TearDown(void);
+       bool PrepareClient(void);
+       bool PrepareOutput(void);
+       bool PrepareVblank(void);
 };
 
-sem_t *tdm_client_test_prepare::semaphore;
-const std::string tdm_client_test_prepare::semaphore_name = "/tdm-client-utests";
-
-/* global object is created before main() */
-tdm_client_test_prepare dont_use_it;
-
-/* real mess, sorry... */
-class TDMClientTest : public ::testing::Test
+TDMClient::TDMClient()
 {
-protected:
-       TDMClientTest() : error(TDM_ERROR_NONE), server_pid(0),
-               dsp(nullptr), output(nullptr), layer(nullptr), buffer(nullptr), is_server_stopped(false)
-       {
-               set_env_vars();
-               start_server(); /* as a separate process */
-               wait_till_server_ready();
-       }
-
-       ~TDMClientTest()
-       {
-               stop_server();
-               unset_env_vars();
-       }
+       server_pid = -1;
+       pipe_parent[0] = pipe_parent[1] = -1;
+       pipe_child[0] = pipe_child[1] = -1;
+       client = NULL;
+       output = NULL;
+       vblank = NULL;
+       vrefresh_interval = start = end = 0.0;
+}
 
-       void send_request_to_server(int req)
-       {
-               switch(req)
-               {
-                       case ChangeDPMS:
-                               send_request(ChangeDPMS);
-                       break;
+void TDMClient::SetUp(void)
+{
+       TDMEnv::SetUp();
 
-                       default:
-                       break;
-               }
-       }
+       server_pid = _ut_tdm_client_server_fork(pipe_parent, pipe_child);
+       ASSERT_TRUE(server_pid > 0);
+}
 
-       /* to stop server by user demand */
-       void stop_server(void)
-       {
-               _stop_server();
-               wait_till_serv_is_over();
+void TDMClient::TearDown(void)
+{
+       if (vblank)
+               tdm_client_vblank_destroy(vblank);
+       if (client)
+               tdm_client_destroy(client);
 
-               /* TODO: maybe it makes a sense to use this approach in the dtor too */
+       if (pipe_child[0] >= 0)
+               close(pipe_child[0]);
+       if (pipe_child[1] >= 0) {
+               _ut_tdm_pipe_write_msg(pipe_child[1], TDM_UT_PIPE_MSG_TERMINATE_SERVER);
+               if (server_pid > 0)
+                       waitpid(server_pid, NULL, 0);
+               TDM_INFO("*** server terminated ***");
+               close(pipe_child[1]);
        }
 
-       enum
-       {
-               ChangeDPMS,
-       };
-
-private:
-       void set_env_vars(void)
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-       }
+       if (pipe_parent[0] >= 0)
+               close(pipe_parent[0]);
+       if (pipe_parent[1] >= 0)
+               close(pipe_parent[1]);
 
-       void unset_env_vars(void)
-       {
-               unsetenv("TBM_DISPLAY_SERVER");
-               unsetenv("XDG_RUNTIME_DIR");
-       }
+       TDMEnv::TearDown();
+}
 
-       void start_server(void)
-       {
-               cl_serv_lock_fd = eventfd(0, 0);
-               socketpair(AF_UNIX, SOCK_STREAM, 0, reinterpret_cast<int*>(&socks_pair));
+bool TDMClient::PrepareClient(void)
+{
+       tdm_error ret;
+       client = tdm_client_create(&ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
 
-               server_pid = fork();
+       return true;
+}
 
-               if (server_pid)
-               {
-                       close(socks_pair.server_socket);
-                       return;
-               }
+bool TDMClient::PrepareOutput(void)
+{
+       tdm_error ret;
 
-               close(socks_pair.client_socket);
+       TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
 
-               wait_till_serv_resources_available();
-               run_server();
-       }
+       output = tdm_client_get_output(client, NULL, &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-       void _stop_server(void)
-       {
-               if (is_server_stopped) return;
+       return true;
+}
 
-               close(socks_pair.client_socket);
-               close(cl_serv_lock_fd);
-               kill(server_pid, SIGINT);
+bool TDMClient::PrepareVblank(void)
+{
+       tdm_error ret;
+       unsigned int refresh;
 
-               is_server_stopped = true;
-       }
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-       void wait_till_server_ready(void)
-       {
-               uint64_t val;
+       vblank = tdm_client_output_create_vblank(output, &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(vblank != NULL);
 
-               if (read(cl_serv_lock_fd, &val, sizeof val) < 0)
-                       std::cout << "error while trying to read from cl_serv_lock_fd eventfd object.\n";
-       }
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_client_output_get_refresh_rate(output, &refresh) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(refresh > 0);
 
-       void notify_server_ready(void)
-       {
-               uint64_t val;
+       vrefresh_interval = 1.0 / (double)refresh;
+       TDM_UT_RETURN_FALSE_IF_FAIL(vrefresh_interval > 0);
 
-               val = 1;
+       return true;
+}
 
-               if (write(cl_serv_lock_fd, &val, sizeof val) < 0)
-                       std::cout << "error while trying to write to cl_serv_lock_fd evenfd object.\n";
-       }
+static int
+_ut_tdm_pipe_read_msg(int fd)
+{
+       char buffer[1024];
+       ssize_t len;
+       int *msg;
 
-       void wait_till_serv_resources_available(void)
-       {
-               while (1)
-               {
-                       int ret;
+       do {
+               len = read(fd, buffer, sizeof buffer);
+       } while (len < 0 && errno == EINTR);
 
-                       ret = sem_wait(tdm_client_test_prepare::semaphore);
-                       if (ret < 0 && errno == EINTR)
-                               continue;
-                       else
-                               break;
-               }
-       }
+       if (len <= 0)
+               return TDM_UT_PIPE_MSG_NONE;
 
-       void notify_serv_resources_available(void)
-       {
-               sem_post(tdm_client_test_prepare::semaphore);
+       msg = (int*)buffer;
 
-               sem_close(tdm_client_test_prepare::semaphore);
-               sem_unlink(tdm_client_test_prepare::semaphore_name.c_str());
-       }
+       return *msg;
+}
 
-       void wait_till_serv_is_over(void)
-       {
-               wait_till_serv_resources_available();
-               sem_post(tdm_client_test_prepare::semaphore);
-       }
+static bool
+_ut_tdm_pipe_write_msg(int fd, int msg)
+{
+       ssize_t len = write(fd, &msg, sizeof msg);
+       TDM_UT_RETURN_FALSE_IF_FAIL(len == sizeof msg);
 
-       void send_request(int req)
-       {
-               int count;
+       return true;
+}
 
-               count = send(socks_pair.client_socket, &req, sizeof req, 0);
+static bool
+_ut_tdm_server_set_output_dpms(tdm_display *dpy, int msg)
+{
+       tdm_error ret;
+       tdm_output *output;
 
-               if (count != sizeof req)
-                       std::cout << "error while trying to send request to socks_pair.client_socket.\n";
+       output = tdm_display_find_output(dpy, "primary", &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
+
+       switch (msg) {
+       case TDM_UT_PIPE_MSG_DPMS_ON:
+               TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               break;
+       case TDM_UT_PIPE_MSG_DPMS_OFF:
+               TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+               break;
+       default:
+               break;
        }
 
-       void handle_client_request()
-       {
-               int req;
-               int count;
-
-               count = recv(socks_pair.server_socket, &req, sizeof req, 0);
-
-               if (count != sizeof req) {
-                       std::cout << "error while trying to reserve data from socks_pair.server_socket.\n";
-                       return;
-               }
+       return true;
+}
 
-               switch(req)
-               {
-                       case ChangeDPMS:
-                               change_dpms_request_handler();
-                       break;
+static void
+_ut_tdm_server_run(int *pipe_parent, int *pipe_child)
+{
+       tdm_display *dpy = NULL;
+       tdm_error ret;
+       struct pollfd fds[2];
+       int tdm_fd, err;
+       int output_count = 0;
 
-                       default:
-                               break;
-               }
-       }
+       dpy = tdm_display_init(&ret);
+       TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, done);
+       TDM_UT_GOTO_IF_FAIL(dpy != NULL, done);
 
-       void run_server(void)
-       {
-               sigset_t mask;
-               int signal_fd;
-               int tdm_fd;
-               pollfd work_fds[3];
+       TDM_UT_GOTO_IF_FAIL(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE, done);
 
-               /* ask kernel to notify us about parent's die via SIGHUP signal */
-               prctl(PR_SET_PDEATHSIG, SIGHUP);
+       for (int o = 0; o < output_count; o++) {
+               tdm_output *output = tdm_display_get_output(dpy, o, &ret);
+               TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, done);
+               TDM_UT_GOTO_IF_FAIL(output != NULL, done);
 
-               sigemptyset(&mask);
-               sigaddset(&mask, SIGINT);
-               sigaddset(&mask, SIGHUP);
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
 
-               sigprocmask(SIG_BLOCK, &mask, NULL);
+               TDM_UT_GOTO_IF_FAIL(ut_tdm_output_prepare(dpy, output) == true, done);
+       }
 
-               signal_fd = signalfd(-1, &mask, 0);
+       TDM_UT_GOTO_IF_FAIL(_ut_tdm_pipe_write_msg(pipe_parent[1], TDM_UT_PIPE_MSG_SERVER_READY) == true, done);
 
-               init_tdm();
-               tdm_display_get_fd(dsp, &tdm_fd);
+       TDM_INFO("*** server ready ***");
 
-               std::memset(&work_fds, 0, sizeof work_fds);
+       ret = tdm_display_get_fd(dpy, &tdm_fd);
+       TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, done);
 
-               work_fds[0].fd = signal_fd;
-               work_fds[0].events = POLLIN;
+       fds[0].events = POLLIN;
+       fds[0].fd = tdm_fd;
+       fds[0].revents = 0;
 
-               work_fds[1].fd = tdm_fd;
-               work_fds[1].events = POLLIN;
+       fds[1].events = POLLIN;
+       fds[1].fd = pipe_child[0];
+       fds[1].revents = 0;
 
-               work_fds[2].fd = socks_pair.server_socket;
-               work_fds[2].events = POLLIN;
+       while (1) {
+               /* make sure all events are flushed to clients before falling in sleep */
+               tdm_display_flush(dpy);
 
-               notify_server_ready();
+               err = poll(fds, 2, -1);
+               if (err < 0) {
+                       if (errno == EINTR || errno == EAGAIN) {
+                               continue;
+                       } else {
+                               TDM_ERR("server-process: poll failed: %m\n");
+                               goto done;
+                       }
+               }
 
-               while (1)
-               {
-                       int ret;
+               if (fds[0].revents & POLLIN)
+                       ret = tdm_display_handle_events(dpy);
 
-                       ret = poll(work_fds, 3, -1);
-                       if (ret < 0 && errno == EINTR) continue;
+               if (fds[1].revents & POLLIN) {
+                       int msg = _ut_tdm_pipe_read_msg(pipe_child[0]);
 
-                       if (work_fds[0].revents == POLLIN)
-                       {
-                               signal_hndl();
-                               exit(EXIT_SUCCESS);
+                       switch (msg) {
+                       case TDM_UT_PIPE_MSG_DPMS_ON:
+                       case TDM_UT_PIPE_MSG_DPMS_OFF:
+                               _ut_tdm_server_set_output_dpms(dpy, msg);
+                               break;
+                       case TDM_UT_PIPE_MSG_TERMINATE_SERVER:
+                               goto done;
+                       default:
+                               break;
                        }
-
-                       if(work_fds[1].revents == POLLIN)
-                               tdm_display_handle_events(dsp);
-
-                       if(work_fds[2].revents == POLLIN)
-                               handle_client_request();
                }
        }
 
-       void signal_hndl(void)
-       {
-               close(socks_pair.server_socket);
-               close(cl_serv_lock_fd);
+done:
+       if (dpy)
+               tdm_display_deinit(dpy);
+}
 
-               deinit_tdm();
-               notify_serv_resources_available();
-       }
+static pid_t
+_ut_tdm_client_server_fork(int *pipe_parent, int *pipe_child)
+{
+       pid_t pid;
+       int msg;
 
-       void init_tdm(void);
-       void deinit_tdm(void);
+       TDM_UT_GOTO_IF_FAIL(pipe(pipe_parent) == 0, failed);
+       TDM_UT_GOTO_IF_FAIL(pipe(pipe_child) == 0, failed);
 
-       void set_layer_geometry(int w, int h);
-       void set_image_on_screen(int w, int h);
+       signal(SIGCHLD, SIG_IGN);
+       prctl(PR_SET_PDEATHSIG, SIGHUP);
 
-       void change_dpms_request_handler(void);
+       pid = fork();
+       TDM_UT_GOTO_IF_FAIL(pid >= 0, failed);
 
-       struct sockets_pair
-       {
-               sockets_pair() : server_socket(0), client_socket(0) {}
-               int server_socket;
-               int client_socket;
-       };
+       if (pid == 0) {
+               _ut_tdm_server_run(pipe_parent, pipe_child);
+               close(pipe_child[0]);
+               close(pipe_child[1]);
+               close(pipe_parent[0]);
+               close(pipe_parent[1]);
 
-protected:
-       tdm_error error;
+#ifdef TIZEN_TEST_GCOV
+               __gcov_flush();
+#endif
 
-private:
-       pid_t server_pid;
-       int cl_serv_lock_fd;
-       sockets_pair socks_pair;
+               exit(0);
+       }
 
-       tdm_display *dsp;
-       tdm_output *output;
-       tdm_layer *layer;
+       msg = _ut_tdm_pipe_read_msg(pipe_parent[0]);
+       TDM_UT_GOTO_IF_FAIL(msg == TDM_UT_PIPE_MSG_SERVER_READY, failed);
 
-       tbm_surface_h buffer;
+       TDM_INFO("*** server fork done ***");
 
-       bool is_server_stopped;
-};
+       return pid;
 
-class TDMClientTestClient : public TDMClientTest
-{
-protected:
-       TDMClientTestClient() : TDMClientTest()
-       {
-               tdm_cl = tdm_client_create(nullptr);
-       }
-       ~TDMClientTestClient()
-       {
-               tdm_client_destroy(tdm_cl);
-       }
+failed:
+       return -1;
+}
 
-protected:
-       tdm_client *tdm_cl;
-};
+#ifdef UT_TDM_CLIENT_ENABLE
 
-class TDMClientTestClientOutput : public TDMClientTestClient
+TEST_P(TDMClient, ClientCreate)
 {
-protected:
-       TDMClientTestClientOutput() : TDMClientTestClient()
-       {
-               cl_output = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       }
-       ~TDMClientTestClientOutput()
-       {
-       }
+       tdm_error ret;
 
-protected:
-       tdm_client_output* cl_output;
-};
+       client = tdm_client_create(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(client != NULL);
+}
 
-class TDMClientTestVblank : public TDMClientTestClientOutput
+TEST_P(TDMClient, ClientCreateNullOther)
 {
-protected:
-       TDMClientTestVblank() : TDMClientTestClientOutput()
-       {
-               cl_vblank =  tdm_client_output_create_vblank(cl_output, nullptr);
-       }
-       ~TDMClientTestVblank()
-       {
-               tdm_client_vblank_destroy(cl_vblank);
-       }
-
-protected:
-       tdm_client_vblank* cl_vblank;
-};
-
-typedef TDMClientTest TDMClientTestDeathTest;
-typedef TDMClientTestClient TDMClientTestClientDeathTest;
-typedef TDMClientTestClientOutput TDMClientTestClientOutputDeathTest;
-typedef TDMClientTestVblank TDMClientTestVblankDeathTest;
-
+       client = tdm_client_create(NULL);
+       ASSERT_TRUE(client != NULL);
+}
 
-void TDMClientTest::set_layer_geometry(int w, int h)
+TEST_P(TDMClient, ClientDestroy)
 {
-       tdm_info_layer layer_info;
-
-       std::memset(&layer_info, 0, sizeof(tdm_info_layer));
+       tdm_error ret;
 
-       layer_info.src_config.size.h = w;
-       layer_info.src_config.size.v = h;
-       layer_info.src_config.pos.x = 0;
-       layer_info.src_config.pos.y = 0;
-       layer_info.src_config.pos.w = w;
-       layer_info.src_config.pos.h = h;
-       layer_info.src_config.format = TBM_FORMAT_ARGB8888;
-       layer_info.dst_pos.x = 0;
-       layer_info.dst_pos.y = 0;
-       layer_info.dst_pos.w = w;
-       layer_info.dst_pos.h = h;
-       layer_info.transform = TDM_TRANSFORM_NORMAL;
+       client = tdm_client_create(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(client != NULL);
 
-       tdm_layer_set_info(layer, &layer_info);
+       tdm_client_destroy(client);
+       client = NULL;
 }
 
-void TDMClientTest::set_image_on_screen(int w, int h)
+TEST_P(TDMClient, ClientNullObject)
 {
-       tbm_surface_info_s tbm_surface_info;
-
-       /* to have a hw vblank we have to make at least one tdm_commit */
-       buffer = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
+       tdm_client_destroy(NULL);
+}
 
-       std::memset(&tbm_surface_info, 0, sizeof(tbm_surface_info_s));
+/* tdm_client_get_fd */
+TEST_P(TDMClient, ClientGetFd)
+{
+       int fd = TDM_UT_INVALID_VALUE;
 
-       tbm_surface_map(buffer, TBM_SURF_OPTION_WRITE, &tbm_surface_info);
+       ASSERT_TRUE(PrepareClient() == true);
 
-       int *img = (int *)tbm_surface_info.planes[0].ptr;
+       ASSERT_TRUE(tdm_client_get_fd(client, &fd) == TDM_ERROR_NONE);
+       ASSERT_TRUE(fd >= 0);
+}
 
-       for (uint32_t i = 0; i < tbm_surface_info.height; i++)
-               for (uint32_t j = 0; j < tbm_surface_info.planes[0].stride / 4; j++)
-                       *img++ = 0x0000000;
+TEST_P(TDMClient, ClientGetFdNullObject)
+{
+       int fd = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_client_get_fd(NULL, &fd) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(fd == TDM_UT_INVALID_VALUE);
+}
 
-       tbm_surface_unmap(buffer);
+TEST_P(TDMClient, ClientGetFdNullOther)
+{
+       ASSERT_TRUE(PrepareClient() == true);
 
-       set_layer_geometry(w, h);
-       tdm_layer_set_buffer(layer, buffer);
-       tdm_output_commit(output, 0, nullptr, nullptr);
+       ASSERT_TRUE(tdm_client_get_fd(client, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-void TDMClientTest::init_tdm(void)
+/* tdm_client_handle_events */
+TEST_P(TDMClient, DISABLED_ClientHandleEvent)
 {
-       int outputs_cnt = 0;
-       tdm_output_type tdm_output_type;
-       tdm_error error;
+       ASSERT_TRUE(PrepareClient() == true);
 
-       int output_modes_cnt = 0;
-       const tdm_output_mode* output_modes;
-       const tdm_output_mode* preferred_mode = NULL;
+//     ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+}
 
-       int layers_cnt = 0;
-       tdm_layer_capability tdm_layer_capability;
+TEST_P(TDMClient, ClientHandleEventNullObject)
+{
+       ASSERT_TRUE(tdm_client_handle_events(NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-       dsp = tdm_display_init(nullptr);
+static void
+_ut_tdm_client_vblank_cb(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+       bool *done = (bool *)user_data;
+       if (done)
+               *done = true;
+}
 
-       tdm_display_get_output_count(dsp, &outputs_cnt);
+/* tdm_client_wait_vblank, deprecated */
+TEST_P(TDMClient, ClientWaitVblank)
+{
+       bool done = false;
 
-       /* this part is hardware dependent, how to resolve this issue ? */
-       for (int i = 0; i < outputs_cnt; i++)
-       {
-               output = tdm_display_get_output(dsp, i, nullptr);
-               if (output == NULL) {
-                       std::cout << "tdm_display_get_output faild, server's gonna be stopped.\n";
-                       deinit_tdm();
-                       exit(EXIT_FAILURE);
-               }
-               error = tdm_output_get_output_type(output, &tdm_output_type);
-               if (error != TDM_ERROR_NONE) {
-                       std::cout << "tdm_output_get_output_type faild, server's gonna be stopped.\n";
-                       deinit_tdm();
-                       exit(EXIT_FAILURE);
-               }
+       ASSERT_TRUE(PrepareClient() == true);
 
-               /* we're not interesting about other outputs */
-               if (tdm_output_type != TDM_OUTPUT_TYPE_VIRTUAL &&
-                       tdm_output_type != TDM_OUTPUT_TYPE_HDMIA)
-                       break;
-       }
+       ASSERT_TRUE(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _ut_tdm_client_vblank_cb, &done) == TDM_ERROR_NONE);
+       ASSERT_TRUE(done == false);
 
-       /* get output's preferred mode to obtain width & height we'll use later to create surface */
-       tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt);
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+}
 
-       /* look for output's preferred mode */
-       for (int i = 0; i < output_modes_cnt; i++)
-       {
-               if (output_modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
-               {
-                       preferred_mode = &output_modes[i];
-                       break;
-               }
-       }
+/* tdm_client_get_output */
+TEST_P(TDMClient, ClientGetOutput)
+{
+       tdm_error ret;
 
-       if (!preferred_mode)
-       {
-               std::cout << "no preferred mode, server's gonna be stopped.\n";
+       ASSERT_TRUE(PrepareClient() == true);
 
-               deinit_tdm();
-               exit(EXIT_FAILURE);
-       }
+       output = tdm_client_get_output(client, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(output != NULL);
+}
 
-       tdm_output_set_mode(output, preferred_mode);
+TEST_P(TDMClient, ClientGetOutputPrimary)
+{
+       tdm_error ret;
 
-       tdm_output_get_layer_count(output, &layers_cnt);
+       ASSERT_TRUE(PrepareClient() == true);
 
-       /* it supposed that output always has primary & graphic layer */
-       for (int i = 0; i < layers_cnt; i++)
-       {
-               layer = tdm_output_get_layer(output, i, nullptr);
-               tdm_layer_get_capabilities(layer, &tdm_layer_capability);
+       output = tdm_client_get_output(client, (char*)"primary", &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(output != NULL);
+}
 
-               if ((tdm_layer_capability & TDM_LAYER_CAPABILITY_PRIMARY) &&
-                       (tdm_layer_capability & TDM_LAYER_CAPABILITY_GRAPHIC))
-                       break;
-       }
+TEST_P(TDMClient, ClientGetOutputDefault)
+{
+       tdm_error ret;
 
-       tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
+       ASSERT_TRUE(PrepareClient() == true);
 
-       set_image_on_screen(preferred_mode->hdisplay, preferred_mode->vdisplay);
+       output = tdm_client_get_output(client, (char*)"default", &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(output != NULL);
 }
 
-void TDMClientTest::deinit_tdm(void)
+TEST_P(TDMClient, ClientGetOutputInvalidName)
 {
-       if (layer)
-       {
-               tdm_layer_unset_buffer(layer);
-               tdm_output_commit(output, 1, nullptr, nullptr);
-       }
+       tdm_error ret;
 
-       if (buffer)
-               tbm_surface_internal_unref(buffer);
+       ASSERT_TRUE(PrepareClient() == true);
 
-       if (dsp)
-               tdm_display_deinit(dsp);
+       output = tdm_client_get_output(client, (char*)"invalid", &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(output == NULL);
 }
 
-void TDMClientTest::change_dpms_request_handler(void)
+TEST_P(TDMClient, ClientGetOutputNullObject)
 {
-       std::cout << "tdm_output_set_dpms.\n";
-       tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
+       tdm_error ret;
+
+       output = tdm_client_get_output(NULL, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(output == NULL);
 }
 
-TEST_F(TDMClientTest, TdmClientCreateSuccessfulCheckClient)
+TEST_P(TDMClient, ClientGetOutputNullOther)
 {
-       tdm_client *tdm_cl = tdm_client_create(nullptr);
-       ASSERT_TRUE(nullptr != tdm_cl);
+       ASSERT_TRUE(PrepareClient() == true);
 
-       tdm_client_destroy(tdm_cl);
+       output = tdm_client_get_output(client, NULL, NULL);
+       ASSERT_TRUE(output != NULL);
 }
 
-TEST_F(TDMClientTest, TdmClientCreateSuccessfulCheckError)
+static void
+_ut_tdm_client_output_change_dpms_cb(tdm_client_output *output,
+                                                                        tdm_output_change_type type,
+                                                                        tdm_value value,
+                                                                        void *user_data)
 {
-       tdm_client* tdm_cl = tdm_client_create(&error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool *done = (bool *)user_data;
 
-       tdm_client_destroy(tdm_cl);
+       switch (type) {
+       case TDM_OUTPUT_CHANGE_DPMS:
+               if (done)
+                       *done = true;
+               break;
+       default:
+               break;
+       }
 }
 
-TEST_F(TDMClientTest, TdmClientCreateFailServerStoppedCheckError)
+/* tdm_client_output_add_change_handler */
+TEST_P(TDMClient, ClientOutputAddChangeHandler)
 {
-       stop_server();
+       bool done = false;
+       tdm_output_dpms dpms;
 
-       tdm_client_create(&error);
-       ASSERT_TRUE(TDM_ERROR_OPERATION_FAILED == error);
-}
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-TEST_F(TDMClientTest, TdmClientCreateFailServerStopped)
-{
-       stop_server();
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, &done) == TDM_ERROR_NONE);
+       ASSERT_TRUE(_ut_tdm_pipe_write_msg(pipe_child[1], TDM_UT_PIPE_MSG_DPMS_OFF) == true);
 
-       tdm_client *tdm_cl = tdm_client_create(nullptr);
-       ASSERT_TRUE(nullptr == tdm_cl);
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+
+       ASSERT_TRUE(tdm_client_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpms == TDM_OUTPUT_DPMS_OFF);
 }
 
-TEST_F(TDMClientTestDeathTest, TdmClientDestroySuccessful)
+TEST_P(TDMClient, ClientOutputAddChangeHandlerTwice)
 {
-       ASSERT_EXIT(
-               {
-                       tdm_client_destroy(nullptr);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-                       exit(EXIT_SUCCESS);
-               },
-               ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL) == TDM_ERROR_BAD_REQUEST);
 }
 
-TEST_F(TDMClientTestDeathTest, TdmClientDestroySuccessfulServerStopped)
+TEST_P(TDMClient, ClientOutputAddChangeHandlerNullObject)
 {
-       ASSERT_EXIT(
-               {
-                       tdm_client *tdm_cl = tdm_client_create(nullptr);
-
-                       stop_server();
-
-                       tdm_client_destroy(tdm_cl);
-
-                       exit(EXIT_SUCCESS);
-               },
-               ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_TRUE(tdm_client_output_add_change_handler(NULL, _ut_tdm_client_output_change_dpms_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetFdSuccessful)
+TEST_P(TDMClient, ClientOutputAddChangeHandlerNullOther)
 {
-       int fd;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-       tdm_client_get_fd(tdm_cl, &fd);
-       ASSERT_TRUE(0 < fd);
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetFdSuccessfulCheckError)
+/* tdm_client_output_remove_change_handler */
+TEST_P(TDMClient, ClientOutputRemoveChangeHandler)
 {
-       int fd;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-       error = tdm_client_get_fd(tdm_cl, &fd);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL) == TDM_ERROR_NONE);
+       tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetFdFailNullTdmClient)
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerDifferentData)
 {
-       int fd;
+       bool done = (bool)TDM_UT_INVALID_VALUE;
 
-       error = tdm_client_get_fd(nullptr, &fd);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
-}
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-TEST_F(TDMClientTestClient, TdmClientGetFdFailNullFd)
-{
-       error = tdm_client_get_fd(nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, &done) == TDM_ERROR_NONE);
+       tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL);
 }
 
-TEST_F(TDMClientTestClient, TdmClientHandleEventsSuccessful)
+static void
+_ut_tdm_client_output_change_dpms_cb2(tdm_client_output *output,
+                                                                         tdm_output_change_type type,
+                                                                         tdm_value value,
+                                                                         void *user_data)
 {
-       ASSERT_EXIT(
-       {
-               pollfd work_fds[2];
-               itimerspec times_up;
-
-               std::memset(&work_fds, 0, sizeof work_fds);
-               std::memset(&times_up, 0, sizeof times_up);
+       bool *done = (bool *)user_data;
 
-               tdm_client_get_fd(tdm_cl, &work_fds[0].fd);
-               work_fds[0].events = POLLIN;
+       switch (type) {
+       case TDM_OUTPUT_CHANGE_DPMS:
+               if (done)
+                       *done = true;
+               tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, user_data);
+               break;
+       default:
+               break;
+       }
+}
 
-               work_fds[1].fd = timerfd_create(CLOCK_MONOTONIC, 0);
-               work_fds[1].events = POLLIN;
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerInHandler)
+{
+       bool done;
+       tdm_output_dpms dpms;
 
-               times_up.it_value.tv_nsec = 100000000;  /* 100ms */
-               timerfd_settime(work_fds[1].fd, 0, &times_up, nullptr);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-               while (1)
-               {
-                       int ret;
+       done = false;
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, &done) == TDM_ERROR_NONE);
 
-                       ret = poll(work_fds, 2, -1);
-                       if (ret < 0 && errno == EINTR) continue;
+       ASSERT_TRUE(_ut_tdm_pipe_write_msg(pipe_child[1], TDM_UT_PIPE_MSG_DPMS_OFF) == true);
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpms == TDM_OUTPUT_DPMS_OFF);
 
-                       if (work_fds[0].revents == POLLIN)
-                       {
-                               tdm_client_handle_events(tdm_cl);
-                               std::cout << "ha.\n";
-                       }
+       done = false;
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, &done) == TDM_ERROR_NONE);
+       ASSERT_TRUE(_ut_tdm_pipe_write_msg(pipe_child[1], TDM_UT_PIPE_MSG_DPMS_ON) == true);
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpms == TDM_OUTPUT_DPMS_ON);
 
-                       if(work_fds[1].revents == POLLIN)
-                               exit(EXIT_SUCCESS);
-               }
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       done = false;
+       ASSERT_TRUE(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, &done) == TDM_ERROR_NONE);
+       ASSERT_TRUE(_ut_tdm_pipe_write_msg(pipe_child[1], TDM_UT_PIPE_MSG_DPMS_OFF) == true);
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpms == TDM_OUTPUT_DPMS_OFF);
 }
 
-TEST_F(TDMClientTestClient, TdmClientHandleEventsFailNullTDMClient)
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullObject)
 {
-       error = tdm_client_handle_events(nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_client_output_remove_change_handler(NULL, _ut_tdm_client_output_change_dpms_cb, NULL);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessful)
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullOther)
 {
-       tdm_client_output* cl_output;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-       cl_output = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       ASSERT_TRUE(nullptr != cl_output);
+       tdm_client_output_remove_change_handler(output, NULL, NULL);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulCallTwice)
+/* tdm_client_output_get_refresh_rate */
+TEST_P(TDMClient, ClientOutputGetRefreshRate)
 {
-       tdm_client_output* cl_output_1, *cl_output_2;
+       unsigned int refresh = 0;
 
-       cl_output_1 = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       cl_output_2 = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       ASSERT_TRUE(cl_output_1 == cl_output_2);
-}
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulCheckError)
-{
-       tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), &error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(tdm_client_output_get_refresh_rate(output, &refresh) == TDM_ERROR_NONE);
+       ASSERT_TRUE(refresh > 0);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulNullName)
+TEST_P(TDMClient, ClientOutputGetRefreshRateNullObject)
 {
-       tdm_client_output* cl_output;
+       unsigned int refresh = (unsigned int)TDM_UT_INVALID_VALUE;
 
-       cl_output = tdm_client_get_output(tdm_cl, nullptr, nullptr);
-       ASSERT_TRUE(nullptr != cl_output);
+       ASSERT_TRUE(tdm_client_output_get_refresh_rate(NULL, &refresh) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(refresh == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulNullNameCheckError)
+TEST_P(TDMClient, ClientOutputGetRefreshRateNullOther)
 {
-       tdm_client_get_output(tdm_cl, nullptr, &error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+
+       ASSERT_TRUE(tdm_client_output_get_refresh_rate(output, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputFailNullTdmClient)
+/* tdm_client_output_get_refresh_rate */
+TEST_P(TDMClient, ClientOutputGetConnStatus)
 {
-       tdm_client_output* cl_output;
+       tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-       cl_output = tdm_client_get_output(nullptr, const_cast<char*>("primary"), nullptr);
-       ASSERT_TRUE(nullptr == cl_output);
+       ASSERT_TRUE(tdm_client_output_get_conn_status(output, &status) == TDM_ERROR_NONE);
+       ASSERT_TRUE(status != (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputFailNullTdmClientCheckError)
+TEST_P(TDMClient, ClientOutputGetConnStatusNullObject)
 {
-       tdm_client_get_output(nullptr, const_cast<char*>("primary"), &error);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_client_output_get_conn_status(NULL, &status) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(status == (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerSuccessful)
+TEST_P(TDMClient, ClientOutputGetConnStatusNullOther)
 {
-       static bool got_an_event = false;
-       wl_display *wl_dsp;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-       /* is this function implemented fully? */
-       tdm_client_output_add_change_handler(cl_output, [] (tdm_client_output *output,
-                                                                       tdm_output_change_type type,
-                                                                       tdm_value value,
-                                                                       void *user_data) { got_an_event = true; }, nullptr);
+       ASSERT_TRUE(tdm_client_output_get_conn_status(output, NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-       /* force a requests flush */
-       wl_dsp = wl_display_connect("tdm-socket");
-       ASSERT_TRUE(nullptr != wl_dsp);
-       wl_display_flush(wl_dsp);
-       wl_display_roundtrip(wl_dsp);
-       wl_display_disconnect(wl_dsp);
+/* tdm_client_output_get_dpms */
+TEST_P(TDMClient, ClientOutputGetDpms)
+{
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
 
-       send_request_to_server(TDMClientTest::ChangeDPMS);
-       tdm_client_handle_events(tdm_cl);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-       ASSERT_TRUE(true == got_an_event);
+       ASSERT_TRUE(tdm_client_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpms != (tdm_output_dpms)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerFailNullOutput)
+TEST_P(TDMClient, ClientOutputGetDpmsNullObject)
 {
-       error = tdm_client_output_add_change_handler(nullptr, [] (tdm_client_output *output,
-                                                                       tdm_output_change_type type,
-                                                                       tdm_value value,
-                                                                       void *user_data) {}, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
-}
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerFailNullHandler)
-{
-       error = tdm_client_output_add_change_handler(cl_output, nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(tdm_client_output_get_dpms(NULL, &dpms) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(dpms == (tdm_output_dpms)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerSuccessful)
+TEST_P(TDMClient, ClientOutputGetDpmsNullOther)
 {
-       ASSERT_EXIT(
-       {
-               auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
-                               void *user_data) {};
-
-               tdm_client_output_add_change_handler(cl_output, func, nullptr);
-
-               tdm_client_output_remove_change_handler(cl_output, func, nullptr);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_TRUE(tdm_client_output_get_dpms(output, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerSuccessfulInvalidHandler)
+/* tdm_client_output_create_vblank */
+TEST_P(TDMClient, ClientOutputCreateVblank)
 {
-       ASSERT_EXIT(
-       {
-               auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
-                               void *user_data) {};
+       tdm_error ret;
 
-               tdm_client_output_remove_change_handler(cl_output, func, nullptr);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       vblank = tdm_client_output_create_vblank(output, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(vblank != NULL);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerFailNullOutput)
+TEST_P(TDMClient, ClientOutputCreateVblankNullObject)
 {
-       ASSERT_EXIT(
-       {
-               auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
-                               void *user_data) {};
+       tdm_error ret;
 
-               tdm_client_output_remove_change_handler(nullptr, func, nullptr);
-
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       vblank = tdm_client_output_create_vblank(NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(vblank == NULL);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerFailNullHandler)
+TEST_P(TDMClient, ClientOutputCreateVblankNullOther)
 {
-       ASSERT_EXIT(
-       {
-               tdm_client_output_remove_change_handler(cl_output, nullptr, nullptr);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       vblank = tdm_client_output_create_vblank(output, NULL);
+       ASSERT_TRUE(vblank != NULL);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateSuccessful)
+/* tdm_client_vblank_destroy */
+TEST_P(TDMClient, ClientVblankDestroy)
 {
-       uint32_t refresh_rate;
+       tdm_error ret;
 
-       error = tdm_client_output_get_refresh_rate(cl_output, &refresh_rate);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
-}
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateFailNullOutput)
-{
-       uint32_t refresh_rate;
+       vblank = tdm_client_output_create_vblank(output, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(vblank != NULL);
 
-       error = tdm_client_output_get_refresh_rate(nullptr, &refresh_rate);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_client_vblank_destroy(vblank);
+       vblank = NULL;
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateFailNullRefreshRate)
+TEST_P(TDMClient, ClientVblankDestroyNullObject)
 {
-       error = tdm_client_output_get_refresh_rate(cl_output, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_client_vblank_destroy(NULL);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetConnectionStatusSuccessful)
+/* tdm_client_vblank_set_name */
+TEST_P(TDMClient, ClientVblankSetName)
 {
-       tdm_output_conn_status conn_status;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-       error = tdm_client_output_get_conn_status(cl_output, &conn_status);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetConnectionStatusFailNullOutput)
+TEST_P(TDMClient, ClientVblankSetNameTwice)
 {
-       tdm_output_conn_status conn_status;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-       error = tdm_client_output_get_conn_status(nullptr, &conn_status);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TTdmClientOutputGetConnectionStatusFailNullConnState)
+TEST_P(TDMClient, ClientVblankSetNameNullObject)
 {
-       error = tdm_client_output_get_conn_status(cl_output, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(tdm_client_vblank_set_name(NULL, TDM_UT_VBLANK_NAME) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsSuccessful)
+/* tdm_client_vblank_set_sync */
+TEST_P(TDMClient, ClientVblankSetSync)
 {
-       tdm_output_dpms dpms_val;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-       error = tdm_client_output_get_dpms(cl_output, &dpms_val);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(tdm_client_vblank_set_sync(vblank, 1) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsFailNullOutput)
+TEST_P(TDMClient, ClientVblankSetSyncTwice)
 {
-       tdm_output_dpms dpms_val;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-       error = tdm_client_output_get_dpms(nullptr, &dpms_val);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(tdm_client_vblank_set_sync(vblank, 1) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_vblank_set_sync(vblank, 1) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsFailNullDpmsArg)
+TEST_P(TDMClient, ClientVblankSetSyncNullObject)
 {
-       error = tdm_client_output_get_dpms(cl_output, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(tdm_client_vblank_set_sync(NULL, 1) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankSuccessful)
+/* tdm_client_vblank_set_fps */
+TEST_P(TDMClient, ClientVblankSetFps)
 {
-       tdm_client_vblank* cl_vblank;
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-       cl_vblank = tdm_client_output_create_vblank(cl_output, nullptr);
-       ASSERT_TRUE(nullptr != cl_vblank);
-
-       tdm_client_vblank_destroy(cl_vblank);
+       ASSERT_TRUE(tdm_client_vblank_set_fps(vblank, 30) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankSuccessfulCheckError)
+TEST_P(TDMClient, ClientVblankSetFpsTwice)
 {
-       tdm_client_vblank* cl_vblank;
-
-       cl_vblank = tdm_client_output_create_vblank(cl_output, &error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-       tdm_client_vblank_destroy(cl_vblank);
+       ASSERT_TRUE(tdm_client_vblank_set_fps(vblank, 30) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_vblank_set_fps(vblank, 30) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankFailNullOutput)
+TEST_P(TDMClient, ClientVblankSetFpsNullObject)
 {
-       tdm_client_vblank* cl_vblank;
-
-       cl_vblank = tdm_client_output_create_vblank(nullptr, nullptr);
-       ASSERT_TRUE(nullptr == cl_vblank);
+       ASSERT_TRUE(tdm_client_vblank_set_fps(NULL, 30) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankFailNullOutputCheckError)
+/* tdm_client_vblank_set_offset */
+TEST_P(TDMClient, ClientVblankSetOffset)
 {
-       tdm_client_output_create_vblank(nullptr, &error);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       ASSERT_TRUE(tdm_client_vblank_set_offset(vblank, 10) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientDestroyVblankSuccessful)
+TEST_P(TDMClient, ClientVblankSetOffsetTwice)
 {
-       ASSERT_EXIT(
-       {
-               tdm_client_vblank *cl_vblank = tdm_client_output_create_vblank(cl_output, nullptr);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-               tdm_client_vblank_destroy(cl_vblank);
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_TRUE(tdm_client_vblank_set_offset(vblank, 10) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_vblank_set_offset(vblank, 10) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientDestroyVblankFailNoClientVblankArg)
+TEST_P(TDMClient, ClientVblankSetOffsetNullObject)
 {
-       ASSERT_EXIT(
-       {
-               tdm_client_vblank_destroy(nullptr);
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_TRUE(tdm_client_vblank_set_offset(NULL, 10) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetNameSuccessful)
+/* tdm_client_vblank_set_enable_fake */
+TEST_P(TDMClient, ClientVblankSetEnableFake)
 {
-       error = tdm_client_vblank_set_name(cl_vblank, "wassup");
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
-}
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetNameSuccessfulNoExplicitName)
-{
-       error = tdm_client_vblank_set_name(cl_vblank, nullptr);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(tdm_client_vblank_set_enable_fake(vblank, 1) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetNameFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankSetEnableFakeTwice)
 {
-       error = tdm_client_vblank_set_name(nullptr, "wassup");
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
-}
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetSyncSuccessful)
-{
-       error = tdm_client_vblank_set_sync(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(tdm_client_vblank_set_enable_fake(vblank, 1) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_vblank_set_enable_fake(vblank, 1) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetSyncFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankSetEnableFakeNullObject)
 {
-       error = tdm_client_vblank_set_sync(nullptr, 0);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(tdm_client_vblank_set_enable_fake(NULL, 1) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsSuccessful)
+static void
+_ut_tdm_client_vblank_cb2(tdm_client_vblank *vblank,
+                                                 tdm_error error,
+                                                 unsigned int sequence,
+                                                 unsigned int tv_sec,
+                                                 unsigned int tv_usec,
+                                                 void *user_data)
 {
-       error = tdm_client_vblank_set_fps(cl_vblank, 60);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool *done = (bool *)user_data;
+       if (done)
+               *done = true;
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsSuccessfulSetTwice)
+/* tdm_client_vblank_wait */
+TEST_P(TDMClient, ClientVblankWait)
 {
-       tdm_client_vblank_set_fps(cl_vblank, 60);
-       error = tdm_client_vblank_set_fps(cl_vblank, 60);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
-}
+       bool done;
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsFailNullClientVblank)
-{
-       error = tdm_client_vblank_set_fps(nullptr, 60);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       done = false;
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done) == TDM_ERROR_NONE);
+
+       start = tdm_helper_get_time();
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_TRUE((end - start) < (vrefresh_interval + vrefresh_interval));
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsFailInvalidFpsArg)
+TEST_P(TDMClient, ClientVblankWaitFewTime)
 {
-       error = tdm_client_vblank_set_fps(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       bool done1, done2, done3;
+
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       done1 = done2 = done3 = false;
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done1) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done2) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done3) == TDM_ERROR_NONE);
+
+       start = tdm_helper_get_time();
+       while(!done1 || !done2 || !done3)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_TRUE((end - start) < (vrefresh_interval + vrefresh_interval));
+
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetSuccessful)
+TEST_P(TDMClient, ClientVblankWaitInterval0)
 {
-       error = tdm_client_vblank_set_offset(cl_vblank, 10);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 0, _ut_tdm_client_vblank_cb2, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetSuccessfulSetTwice)
+TEST_P(TDMClient, ClientVblankWaitInterval)
 {
-       tdm_client_vblank_set_offset(cl_vblank, 10);
-       error = tdm_client_vblank_set_offset(cl_vblank, 10);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool done;
+
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       /* start from 1 */
+       for (int t = 1; t < 10; t++) {
+               done = false;
+               ASSERT_TRUE(tdm_client_vblank_wait(vblank, t, _ut_tdm_client_vblank_cb2, &done) == TDM_ERROR_NONE);
+
+               start = tdm_helper_get_time();
+               while (!done)
+                       ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+               end = tdm_helper_get_time();
+
+               /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+               ASSERT_TRUE((end - start) > (vrefresh_interval * (t - 1)));
+               ASSERT_TRUE((end - start) < (vrefresh_interval * t + vrefresh_interval));
+       }
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetFailNullClientVblank)
+static void
+_ut_tdm_client_vblank_cb3(tdm_client_vblank *vblank,
+                                                 tdm_error error,
+                                                 unsigned int sequence,
+                                                 unsigned int tv_sec,
+                                                 unsigned int tv_usec,
+                                                 void *user_data)
 {
-       error = tdm_client_vblank_set_offset(nullptr, 10);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       unsigned int *cur_seq = (unsigned int *)user_data;
+       if (cur_seq)
+               *cur_seq = sequence;
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulEnableFake)
+TEST_P(TDMClient, ClientVblankWaitSeq)
 {
-       error = tdm_client_vblank_set_enable_fake(cl_vblank, 1);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       for (int t = 0; t < 10; t++) {
+               unsigned int cur_seq = 0, temp = 0;
+
+               ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb3, &cur_seq) == TDM_ERROR_NONE);
+               while (cur_seq == 0)
+                       ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+
+               start = tdm_helper_get_time();
+               ASSERT_TRUE(tdm_client_vblank_wait_seq(vblank, cur_seq + 1, _ut_tdm_client_vblank_cb3, &temp) == TDM_ERROR_NONE);
+               while (temp == 0)
+                       ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+               end = tdm_helper_get_time();
+
+               /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+               ASSERT_TRUE((end - start) < (vrefresh_interval + vrefresh_interval));
+       }
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulDisableFake)
+TEST_P(TDMClient, ClientVblankWaitSeqInterval)
 {
-       error = tdm_client_vblank_set_enable_fake(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       /* start from 1 */
+       for (int t = 1; t < 10; t++) {
+               unsigned int cur_seq = 0, temp = 0;
+
+               ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb3, &cur_seq) == TDM_ERROR_NONE);
+               while (cur_seq == 0)
+                       ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+
+               start = tdm_helper_get_time();
+               ASSERT_TRUE(tdm_client_vblank_wait_seq(vblank, cur_seq + t, _ut_tdm_client_vblank_cb3, &temp) == TDM_ERROR_NONE);
+               while (temp == 0)
+                       ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+               end = tdm_helper_get_time();
+
+#if 0
+printf("@@@ %s(%d) cur_seq(%d) t(%d) start(%.6f) end(%.6f) diff(%.6f) (%.6f~%.6f)\n",
+__FUNCTION__, __LINE__, cur_seq, t, start, end, end - start, (interval * (t - 1)), (interval * t + interval));
+#endif
+
+               /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+               ASSERT_TRUE((end - start) > (vrefresh_interval * (t - 1)));
+               ASSERT_TRUE((end - start) < (vrefresh_interval * t + vrefresh_interval));
+       }
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulSetTwice)
+TEST_P(TDMClient, ClientVblankWaitNullObject)
 {
-       tdm_client_vblank_set_enable_fake(cl_vblank, 0);
-       error = tdm_client_vblank_set_enable_fake(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       unsigned int cur_seq = 0;
+
+       ASSERT_TRUE(tdm_client_vblank_wait(NULL, 1, _ut_tdm_client_vblank_cb3, &cur_seq) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankWaitNullOther)
 {
-       error = tdm_client_vblank_set_enable_fake(nullptr, 0);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSuccessful)
+TEST_P(TDMClient, ClientVblankWaitDpmsOff)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-       tdm_client_vblank_set_sync(cl_vblank, 0);
-       tdm_client_vblank_set_enable_fake(cl_vblank, 1);
+       ASSERT_TRUE(_ut_tdm_pipe_write_msg(pipe_child[1], TDM_UT_PIPE_MSG_DPMS_OFF) == true);
+       while (dpms != TDM_OUTPUT_DPMS_OFF)
+               ASSERT_TRUE(tdm_client_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpms == TDM_OUTPUT_DPMS_OFF);
 
-       error = tdm_client_vblank_wait(cl_vblank, 1, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, NULL) == TDM_ERROR_DPMS_OFF);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankWaitSetEnableFakeDpmsOff)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
+       bool done;
 
-       error = tdm_client_vblank_wait(nullptr, 1, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
-}
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailNullHandler)
-{
-       error = tdm_client_vblank_wait(cl_vblank, 1, nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(_ut_tdm_pipe_write_msg(pipe_child[1], TDM_UT_PIPE_MSG_DPMS_OFF) == true);
+       while (dpms != TDM_OUTPUT_DPMS_OFF)
+               ASSERT_TRUE(tdm_client_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+
+       ASSERT_TRUE(tdm_client_vblank_set_enable_fake(vblank, 1) == TDM_ERROR_NONE);
+
+       done = false;
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done) == TDM_ERROR_NONE);
+
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailInvalidInterval)
+TEST_P(TDMClient, ClientVblankWaitSetOffset)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       bool done;
 
-       error = tdm_client_vblank_wait(cl_vblank, 0, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       ASSERT_TRUE(tdm_client_vblank_set_offset(vblank, 100) == TDM_ERROR_NONE);
+
+       done = false;
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done) == TDM_ERROR_NONE);
+
+       start = tdm_helper_get_time();
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_TRUE((end - start) > (0.1));
+       ASSERT_TRUE((end - start) < (vrefresh_interval + vrefresh_interval + 0.1));
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencySuccessful)
+TEST_P(TDMClient, ClientVblankWaitSetFps)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       bool done;
+       double interval;
+       unsigned int fps = 10;
+
+       ASSERT_TRUE(PrepareClient() == true);
+       ASSERT_TRUE(PrepareOutput() == true);
+       ASSERT_TRUE(PrepareVblank() == true);
+
+       ASSERT_TRUE(tdm_client_vblank_set_fps(vblank, fps) == TDM_ERROR_NONE);
+       interval = 1.0 / (double)fps;
+
+       done = false;
+       ASSERT_TRUE(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done) == TDM_ERROR_NONE);
 
-       tdm_client_vblank_set_sync(cl_vblank, 0);
-       tdm_client_vblank_set_enable_fake(cl_vblank, 1);
+       start = tdm_helper_get_time();
+       while (!done)
+               ASSERT_TRUE(tdm_client_handle_events(client) == TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
 
-       error = tdm_client_vblank_wait_seq(cl_vblank, 100, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_TRUE((end - start) > (interval - vrefresh_interval));
+       ASSERT_TRUE((end - start) < (interval + vrefresh_interval));
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencyFailNullClientVblank)
+#if 0
+
+TEST_P(TDMVblank, VblankWaitEnableDisableGlobalFps)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+       double vrefresh_interval;
+       unsigned int cur_seq[3];
+       unsigned int global_fps = 5;
+       double start, end, interval;
+
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks3() == true);
+       ASSERT_TRUE(vblank_count == 3);
+
+       ASSERT_TRUE(tdm_vblank_get_fps(vblanks[0], &fps) == TDM_ERROR_NONE);
+       ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+       vrefresh_interval = 1.0 / (double)fps;
+
+       for (int v = 0; v < 3; v++)
+               ASSERT_TRUE(tdm_vblank_set_fixed_fps(vblanks[v], 10 * (v + 1)) == TDM_ERROR_NONE);
+
+       /* enable test */
+       tdm_vblank_enable_global_fps(1, global_fps);
+       interval = 1.0 / (double)global_fps;
+
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]) == TDM_ERROR_NONE);
+       }
+
+       start = tdm_helper_get_time();
+       while (cur_seq[0] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       ASSERT_TRUE(cur_seq[1] != 0);
+       ASSERT_TRUE(cur_seq[2] != 0);
+
+       /* "+- vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_TRUE((end - start) > (interval - vrefresh_interval));
+       ASSERT_TRUE((end - start) < (interval + vrefresh_interval));
+
+       /* disable test */
+       tdm_vblank_enable_global_fps(0, 0);
+
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]) == TDM_ERROR_NONE);
+       }
 
-       error = tdm_client_vblank_wait_seq(nullptr, 1, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       while (cur_seq[0] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       ASSERT_TRUE(cur_seq[1] == 0);
+       ASSERT_TRUE(cur_seq[2] == 0);
+
+       while (cur_seq[1] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       ASSERT_TRUE(cur_seq[2] == 0);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencyFailNullHandler)
+TEST_P(TDMVblank, VblankWaitIgnoreGlobalFps)
 {
-       error = tdm_client_vblank_wait_seq(cl_vblank, 1, nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+       unsigned int cur_seq[3];
+       unsigned int global_fps = 5;
+       double start, end, interval;
+
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks3() == true);
+       ASSERT_TRUE(vblank_count == 3);
+
+       ASSERT_TRUE(tdm_vblank_get_fps(vblanks[0], &fps) == TDM_ERROR_NONE);
+       ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+       interval = 1.0 / (double)fps;
+
+       /* 2nd vblank will ignore the global fps. */
+       ASSERT_TRUE(tdm_vblank_ignore_global_fps(vblanks[1], 1) == TDM_ERROR_NONE);
+
+       tdm_vblank_enable_global_fps(1, global_fps);
+
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]) == TDM_ERROR_NONE);
+       }
+
+       start = tdm_helper_get_time();
+       while (cur_seq[1] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       ASSERT_TRUE(cur_seq[0] == 0);
+       ASSERT_TRUE(cur_seq[2] == 0);
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_TRUE((end - start) < (interval + interval));
+
+       while (cur_seq[0] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       ASSERT_TRUE(cur_seq[2] != 0);
 }
 
+#endif
+
+INSTANTIATE_TEST_CASE_P(TDMClientParams,
+                                               TDMClient,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
index a80fb47..34903d8 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
-extern "C" {
-#include "tdm.h"
-#include "tdm_config.h"
-#include "tbm_bufmgr.h"
-#include "tbm_drm_helper.h"
-}
-
-class TDMInit : public ::testing::Test {
-protected:
-       int master_fd = -42, tbm_fd = -42;
-       void SetUp(void)
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-       }
-       void TearDown(void)
-       {
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_master_fd > -1)
-                               exit(1);
-                       close(master_fd);
-               }
-               if (tbm_fd > -1) {
-                       int temp_tbm_fd = tbm_drm_helper_get_fd();
-                       EXPECT_EQ(temp_tbm_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_tbm_fd > -1)
-                               exit(1);
-                       close(tbm_fd);
-               }
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
-       }
-};
-
-class TDMDefault : public ::testing::Test {
-protected:
-       tdm_display *dpy = NULL;
-       tbm_bufmgr tbm_bufmgr = NULL;
-       int master_fd = -42, tbm_fd = -42;
-       void SetUp(void)
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-               tbm_bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(tbm_bufmgr == NULL);
-               tdm_error error = TDM_ERROR_NONE;
-               dpy = tdm_display_init(&error);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               ASSERT_FALSE(dpy == NULL);
-               master_fd = tbm_drm_helper_get_master_fd();
-               tbm_fd = tbm_drm_helper_get_fd();
-       }
-       void TearDown(void)
-       {
-               tdm_display_deinit(dpy);
-               tbm_bufmgr_deinit(tbm_bufmgr);
-               tbm_bufmgr = NULL;
-               dpy = NULL;
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_master_fd > -1)
-                               exit(1);
-                       close(master_fd);
-               }
-               if (tbm_fd > -1) {
-                       int temp_tbm_fd = tbm_drm_helper_get_fd();
-                       EXPECT_EQ(temp_tbm_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_tbm_fd > -1)
-                               exit(1);
-                       close(tbm_fd);
-               }
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
-       }
-};
-
+#include "ut_tdm.h"
 
-TEST_F(TDMInit, DisplayInitDeinitSuccessfulWithoutTBM)
+TDMDisplay::TDMDisplay()
 {
-       tdm_error error = TDM_ERROR_NONE;
-       tdm_display *dpy = tdm_display_init(&error);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-       ASSERT_FALSE(dpy == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       tdm_display_deinit(dpy);
        dpy = NULL;
+       bufmgr = NULL;
+       has_pp_cap = false;
+       has_capture_cap = false;
 }
 
-TEST_F(TDMInit, DisplayInitDeinitSuccessfulWithTBM)
+void TDMDisplay::SetUp(void)
 {
-       tbm_bufmgr tbm_bufmgr = NULL;
-       tbm_bufmgr = tbm_bufmgr_init(-1);
-       ASSERT_FALSE(tbm_bufmgr == NULL);
-       tdm_error error = TDM_ERROR_NONE;
-       tdm_display *dpy = tdm_display_init(&error);
-       EXPECT_TRUE(error == TDM_ERROR_NONE);
-       EXPECT_FALSE(dpy == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       if (dpy != NULL && error == TDM_ERROR_NONE)
-               tdm_display_deinit(dpy);
-       dpy = NULL;
-       tbm_bufmgr_deinit(tbm_bufmgr);
-       tbm_bufmgr = NULL;
-}
-
-
-TEST_F(TDMInit, DisplayInitFewTimesSuccessfulWithTBM)
-{
-       tdm_error error = TDM_ERROR_NONE;
-       tdm_display *dpy[20] = {NULL};
-       tbm_bufmgr tbm_bufmgr = NULL;
-       tbm_bufmgr = tbm_bufmgr_init(-1);
-       ASSERT_FALSE(tbm_bufmgr == NULL);
-       dpy[0] = tdm_display_init(&error);
-       EXPECT_TRUE(error == TDM_ERROR_NONE);
-       EXPECT_FALSE(dpy[0] == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       for (int i = 1; i < 20; i++) {
-               dpy[i] = tdm_display_init(&error);
-               EXPECT_TRUE(error == TDM_ERROR_NONE);
-               EXPECT_FALSE(dpy[i] == NULL);
-               EXPECT_EQ(dpy[0], dpy[i]);
-       }
-       for (int i = 19; i > 0; i--) {
-               tdm_display_deinit(dpy[i]);
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_NE(temp_master_fd, -1);
-                       if (temp_master_fd > -1)
-                               close(temp_master_fd);
-               }
-               if (tbm_fd > -1) {
-                       int temp_tbm_fd = tbm_drm_helper_get_fd();
-                       EXPECT_NE(temp_tbm_fd, -1);
-                       if (temp_tbm_fd > -1)
-                               close(temp_tbm_fd);
-               }
-       }
-       tdm_display_deinit(dpy[0]);
-       tbm_bufmgr_deinit(tbm_bufmgr);
-       tbm_bufmgr = NULL;
-}
-
-TEST_F(TDMInit, DisplayInitDeinitSuccessfulNullErrorWithTBM)
-{
-       tbm_bufmgr tbm_bufmgr = NULL;
-       tbm_bufmgr = tbm_bufmgr_init(-1);
-       ASSERT_FALSE(tbm_bufmgr == NULL);
-       tdm_display *dpy = tdm_display_init(NULL);
-       EXPECT_FALSE(dpy == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       if (dpy != NULL)
-               tdm_display_deinit(dpy);
-       dpy = NULL;
-       tbm_bufmgr_deinit(tbm_bufmgr);
-       tbm_bufmgr = NULL;
-}
-
-TEST_F(TDMInit, DisplayInitDeinitSuccessfulFewTimesWithTBM)
-{
-       for (int i = 0; i < 20; ++i) {
-               tbm_bufmgr tbm_bufmgr = NULL;
-               tbm_bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(tbm_bufmgr == NULL);
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_display *dpy = tdm_display_init(&error);
-               EXPECT_TRUE(error == TDM_ERROR_NONE);
-               EXPECT_FALSE(dpy == NULL);
-               master_fd = tbm_drm_helper_get_master_fd();
-               tbm_fd = tbm_drm_helper_get_fd();
-               if (dpy != NULL)
-                       tdm_display_deinit(dpy);
-               dpy = NULL;
-               tbm_bufmgr_deinit(tbm_bufmgr);
-               tbm_bufmgr = NULL;
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_master_fd > -1)
-                               exit(1);
-                       close(master_fd);
-                       master_fd = -1;
-               }
-               if (tbm_fd > -1) {
-                       int temp_tbm_fd = tbm_drm_helper_get_fd();
-                       EXPECT_EQ(temp_tbm_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_tbm_fd > -1)
-                               exit(1);
-                       close(tbm_fd);
-                       tbm_fd = -1;
-               }
-       }
+       tdm_error ret;
+       int count = TDM_UT_INVALID_VALUE;
+       tdm_display_capability capabilities = (tdm_display_capability)TDM_UT_INVALID_VALUE;
+
+       TDMEnv::SetUp();
+
+       dpy = tdm_display_init(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpy != NULL);
+
+       bufmgr = tbm_bufmgr_init(-1);
+       ASSERT_TRUE(bufmgr != NULL);
+
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(count > 0);
+
+       ASSERT_TRUE(tdm_display_get_capabilities(dpy, &capabilities) == TDM_ERROR_NONE);
+       has_pp_cap = capabilities & TDM_DISPLAY_CAPABILITY_PP;
+       has_capture_cap = capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE;
 }
 
-TEST_F(TDMInit, DisplayDeinitSuccessfulNullDpyWithoutTBM)
+void TDMDisplay::TearDown(void)
 {
-       tdm_error error = TDM_ERROR_NONE;
-       tdm_display *dpy = tdm_display_init(&error);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-       ASSERT_FALSE(dpy == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       tdm_display_deinit(NULL);
+       tbm_bufmgr_deinit(bufmgr);
        tdm_display_deinit(dpy);
-       dpy = NULL;
+
+       ASSERT_TRUE(tbm_bufmgr_debug_get_ref_count() == 0);
+
+       TDMEnv::TearDown();
 }
 
-TEST_F(TDMInit, DisplayDeinitFailWrongDpyBadAddress)
+#ifdef UT_TDM_DISPLAY_ENABLE
+
+TEST_P(TDMDisplay, DisplayUpdate)
 {
-       tdm_error error = TDM_ERROR_NONE;
-       tdm_display *dpy = tdm_display_init(&error);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-       ASSERT_FALSE(dpy == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       EXPECT_EXIT({tdm_display *wrong_dpy = (tdm_display *) 0xBEAF;
-                                tdm_display_deinit(wrong_dpy);
-                                exit(0); }, ::testing::ExitedWithCode(0), "");
-       tdm_display_deinit(dpy);
-       dpy = NULL;
+       ASSERT_TRUE(tdm_display_update(dpy) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMInit, DisplayDeinitFailWrongDpyStackAddress)
+TEST_P(TDMDisplay, DisplayUpdateWrongDpy)
 {
-       tdm_error error = TDM_ERROR_NONE;
-       tdm_display *dpy = tdm_display_init(&error);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-       ASSERT_FALSE(dpy == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       EXPECT_EXIT({tdm_display *wrong_dpy = &error;
-                                tdm_display_deinit(wrong_dpy);
-                                exit(0); }, ::testing::ExitedWithCode(0), "");
-       tdm_display_deinit(dpy);
-       dpy = NULL;
+       EXPECT_EXIT({
+               tdm_display *wrong_dpy = (tdm_display *)TDM_UT_INVALID_VALUE;
+               tdm_display_update(wrong_dpy);
+               exit(0);
+       }, ::testing::ExitedWithCode(0), "");
 }
 
-TEST_F(TDMInit, DisplayDeinitFailWrongDpyHeapAddress)
+TEST_P(TDMDisplay, DisplayUpdateNullObject)
 {
-       tdm_error error = TDM_ERROR_NONE;
-       tdm_display *dpy = tdm_display_init(&error);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-       ASSERT_FALSE(dpy == NULL);
-       master_fd = tbm_drm_helper_get_master_fd();
-       tbm_fd = tbm_drm_helper_get_fd();
-       EXPECT_EXIT({tdm_display *wrong_dpy = (tdm_display *) ((unsigned long) sbrk(0) - sizeof(unsigned long));
-                                tdm_display_deinit(wrong_dpy);
-                                exit(0); }, ::testing::ExitedWithCode(0), "");
-       tdm_display_deinit(dpy);
-       dpy = NULL;
+       ASSERT_TRUE(tdm_display_update(NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMInit, DisplayDeinitFailRepeatWithSameDpy)
+TEST_P(TDMDisplay, DisplayGetFDSuccesful)
 {
-       EXPECT_EXIT({tdm_error error = TDM_ERROR_NONE;
-                                tdm_display *dpy = tdm_display_init(&error);
-                                if (error != TDM_ERROR_NONE) exit(1);
-                                tdm_display_deinit(dpy);
-                                if (tbm_drm_helper_get_master_fd() != -1) exit(1);
-                                if (tbm_drm_helper_get_fd() != -1) exit(1);
-                                tdm_display_deinit(dpy);
-                                tdm_display *dpy2 = malloc(2048);
-                                *((unsigned int *)dpy2) = 673282346;
-                                tdm_display_deinit(dpy2);
-                                tdm_display_deinit(dpy);
-                                tdm_display_deinit(dpy2);
-                                free(dpy2);
-                                exit(0); }, ::testing::ExitedWithCode(0), "");
+       int fd = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_fd(dpy, &fd) == TDM_ERROR_NONE);
+       ASSERT_TRUE(fd != TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayUpdateSuccessful)
+TEST_P(TDMDisplay, DisplayGetFDNullObject)
 {
-       ASSERT_TRUE(tdm_display_update(dpy) == TDM_ERROR_NONE);
+       int fd = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_fd(NULL, &fd) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(fd == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayUpdateFailWrongDpy)
+TEST_P(TDMDisplay, DisplayGetFDNullFD)
 {
-       ASSERT_EXIT({tdm_display *wrong_dpy = (tdm_display *)0xBEAF;
-                                tdm_display_update(wrong_dpy);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_display_get_fd(dpy, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMDefault, DisplayUpdateFailNullDpy)
+TEST_P(TDMDisplay, DisplayGetFDWrongDpy)
 {
-       ASSERT_FALSE(tdm_display_update(NULL) == TDM_ERROR_NONE);
+       tdm_display *wrong_dpy = (tdm_display *)TDM_UT_INVALID_VALUE;
+       int fd = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_fd(wrong_dpy, &fd) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(fd == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetFDSuccesful)
+/* DISABLED */
+TEST_P(TDMDisplay, DISABLED_DisplayHandleEvents)
 {
-       int fd = -42;
-       ASSERT_TRUE(tdm_display_get_fd(dpy, &fd) == TDM_ERROR_NONE);
-       ASSERT_FALSE(fd == -42);
+       /* TODO Generate events*/
+       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMDefault, DisplayGetFDFailNullAll)
+TEST_P(TDMDisplay, DisplayFlush)
 {
-       ASSERT_FALSE(tdm_display_get_fd(NULL, NULL) == TDM_ERROR_NONE);
+       tdm_display_flush(dpy);
 }
 
-TEST_F(TDMDefault, DisplayGetFDFailNullFD)
+TEST_P(TDMDisplay, DisplayFlushNullObject)
 {
-       ASSERT_FALSE(tdm_display_get_fd(dpy, NULL) == TDM_ERROR_NONE);
+       tdm_display_flush(NULL);
 }
 
-TEST_F(TDMDefault, DisplayGetFDFailNullDpy)
+TEST_P(TDMDisplay, DisplayGetBackendInfo)
 {
-       int fd = -42;
-       ASSERT_FALSE(tdm_display_get_fd(NULL, &fd) == TDM_ERROR_NONE);
+       const char *name = (const char*)TDM_UT_INVALID_VALUE;
+       const char *vendor = (const char*)TDM_UT_INVALID_VALUE;
+       int major = TDM_UT_INVALID_VALUE, minor = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_backend_info(dpy, &name, &vendor, &major, &minor) == TDM_ERROR_NONE);
+       ASSERT_TRUE(name != (const char*)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(vendor != (const char*)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(major != TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(minor != TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetFDFailWrongDpy)
+TEST_P(TDMDisplay, DisplayGetBackendInfoNullObject)
 {
-       ASSERT_EXIT({tdm_display *wrong_dpy = (tdm_display *) 0xBEAF; int fd = -42;
-                                tdm_display_get_fd(wrong_dpy, &fd);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       const char *name = (const char*)TDM_UT_INVALID_VALUE;
+       const char *vendor = (const char*)TDM_UT_INVALID_VALUE;
+       int major = TDM_UT_INVALID_VALUE, minor = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_backend_info(NULL, &name, &vendor, &major, &minor) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(name == (const char*)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(vendor == (const char*)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(major == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(minor == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DISABLED_DisplayHandleEventsSuccessful)
+TEST_P(TDMDisplay, DisplayGetBackendInfoNullOther)
 {
-       /* TODO Generate events*/
-       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, NULL, NULL) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMDefault, DisplayGetBackendInfoSuccessful)
+TEST_P(TDMDisplay, DisplayGetCapabilities)
 {
-       const char *name = NULL;
-       const char *vendor = NULL;
-       int major = -42, minor = -42;
-       ASSERT_TRUE(tdm_display_get_backend_info(dpy, &name, &vendor, &major, &minor) == TDM_ERROR_NONE);
-       ASSERT_FALSE(name == NULL);
-       ASSERT_FALSE(vendor == NULL);
-       ASSERT_FALSE(major == -42);
-       ASSERT_FALSE(minor == -42);
+       tdm_display_capability capabilities = (tdm_display_capability)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_capabilities(dpy, &capabilities) == TDM_ERROR_NONE);
+       ASSERT_TRUE(capabilities != TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetBackendInfoFailNullAll)
+TEST_P(TDMDisplay, DisplayGetCapabilitiesNullObject)
 {
-       ASSERT_FALSE(tdm_display_get_backend_info(NULL, NULL, NULL, NULL, NULL) == TDM_ERROR_NONE);
+       tdm_display_capability capabilities = (tdm_display_capability)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_capabilities(NULL, &capabilities) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(capabilities == (tdm_display_capability)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetBackendInfoSuccessfulSetOnlyDpy)
+TEST_P(TDMDisplay, DisplayGetCapabilitiesNullOther)
 {
-       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, NULL, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_display_get_capabilities(dpy, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMDefault, DisplayGetBackendInfoSuccessfulSetOnlyName)
+TEST_P(TDMDisplay, DisplayGetPPCapabilities)
 {
-       const char *name = NULL;
-       ASSERT_TRUE(tdm_display_get_backend_info(dpy, &name, NULL, NULL, NULL) == TDM_ERROR_NONE);
-       ASSERT_FALSE(name == NULL);
+       tdm_pp_capability capabilities = (tdm_pp_capability) TDM_UT_INVALID_VALUE;
+       tdm_error ret;
+       if (!has_pp_cap)
+               return;
+       ret = tdm_display_get_pp_capabilities(dpy, &capabilities);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE || ret == TDM_ERROR_NO_CAPABILITY);
+
+       if (ret == TDM_ERROR_NONE)
+               ASSERT_TRUE(capabilities != TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetBackendInfoSuccessfulSetOnlyVendor)
+TEST_P(TDMDisplay, DisplayGetPPCapabilitiesNullObject)
 {
-       const char *vendor = NULL;
-       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, &vendor, NULL, NULL) == TDM_ERROR_NONE);
-       ASSERT_FALSE(vendor == NULL);
+       tdm_pp_capability capabilities = (tdm_pp_capability)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_pp_capabilities(NULL, &capabilities) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(capabilities == (tdm_pp_capability)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetBackendInfoSuccessfulSetOnlyMajor)
+TEST_P(TDMDisplay, DisplayGetPPCapabilitiesNullOther)
 {
-       int major = -42;
-       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, &major, NULL) == TDM_ERROR_NONE);
-       ASSERT_FALSE(major == -42);
+       ASSERT_TRUE(tdm_display_get_pp_capabilities(dpy, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMDefault, DisplayGetBackendInfoSuccessfulSetOnlyMinor)
+TEST_P(TDMDisplay, DisplayGetCaptureCapabilities)
 {
-       int minor = -42;
-       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, NULL, &minor) == TDM_ERROR_NONE);
-       ASSERT_FALSE(minor == -1);
+       tdm_capture_capability capabilities = (tdm_capture_capability)TDM_UT_INVALID_VALUE;
+       tdm_error ret;
+
+       if (!has_capture_cap)
+               return;
+
+       ret = tdm_display_get_capture_capabilities(dpy, &capabilities);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE || ret == TDM_ERROR_NO_CAPABILITY);
+
+       if (ret == TDM_ERROR_NONE)
+               ASSERT_TRUE(capabilities != (tdm_capture_capability)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetCapabilitiesSuccessful)
+TEST_P(TDMDisplay, DisplayGetCaptureCapabilitiesNullObject)
 {
-       tdm_display_capability capabilities = (tdm_display_capability) -42;
-       ASSERT_TRUE(tdm_display_get_capabilities(dpy, &capabilities) == TDM_ERROR_NONE);
-       ASSERT_FALSE(capabilities == -1);
+       tdm_capture_capability capabilities = (tdm_capture_capability)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_capture_capabilities(NULL, &capabilities) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(capabilities == (tdm_capture_capability)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetCapabilitiesFailNullAll)
+TEST_P(TDMDisplay, DisplayGetCaptureCapabilitiesNullOther)
 {
-       ASSERT_FALSE(tdm_display_get_capabilities(NULL, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_display_get_capture_capabilities(dpy, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMDefault, DisplayGetCapabilitiesFailSetOnlyDpy)
+TEST_P(TDMDisplay, DisplayGetMaxLayerCount)
 {
-       ASSERT_FALSE(tdm_display_get_capabilities(dpy, NULL) == TDM_ERROR_NONE);
+       int max_count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_max_layer_count(dpy, &max_count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(max_count != TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetPPCapabilitiesSuccessful)
+TEST_P(TDMDisplay, DisplayGetMaxLayerCountNullObject)
 {
-       tdm_pp_capability capabilities = (tdm_pp_capability) -42;
-       tdm_error error = TDM_ERROR_NONE;
-       error = tdm_display_get_pp_capabilities(dpy, &capabilities);
-       ASSERT_TRUE(error == TDM_ERROR_NONE || error == TDM_ERROR_NO_CAPABILITY);
-       if (error == TDM_ERROR_NONE) {
-               ASSERT_FALSE(capabilities == -42);
-       }
+       int max_count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_max_layer_count(NULL, &max_count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(max_count == TDM_UT_INVALID_VALUE);
+}
+
+TEST_P(TDMDisplay, DisplayGetMaxLayerCountNullOther)
+{
+       ASSERT_TRUE(tdm_display_get_max_layer_count(dpy, NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMDisplay, DisplayGetOutputCount)
+{
+       int count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(count != TDM_UT_INVALID_VALUE);
+}
+
+TEST_P(TDMDisplay, DisplayGetOutputCountNullObject)
+{
+       int count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_display_get_output_count(NULL, &count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMDefault, DisplayGetPPCapabilitiesFailNullAll)
+TEST_P(TDMDisplay, DisplayGetOutputCountNullOther)
 {
-       ASSERT_FALSE(tdm_display_get_pp_capabilities(NULL, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMDefault, DisplayGetCaptureCapabilitiesSuccessful)
+TEST_P(TDMDisplay, DisplayGetOutput)
 {
-       tdm_capture_capability capabilities = (tdm_capture_capability) -42;
-       tdm_error error = TDM_ERROR_NONE;
-       error = tdm_display_get_capture_capabilities(dpy, &capabilities);
-       ASSERT_TRUE(error == TDM_ERROR_NONE || error == TDM_ERROR_NO_CAPABILITY);
-       if (error == TDM_ERROR_NONE) {
-               ASSERT_FALSE(capabilities == -42);
+       tdm_output *output;
+       int o, count = TDM_UT_INVALID_VALUE;
+       tdm_error ret;
+
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(count > 0);
+
+       for (o = 0; o < count; o++) {
+               output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
        }
 }
 
-TEST_F(TDMDefault, DisplayGetCaptureCapabilitiesFailNullAll)
+TEST_P(TDMDisplay, DisplayGetOutputNullAll)
 {
-       ASSERT_FALSE(tdm_display_get_capture_capabilities(NULL, NULL) == TDM_ERROR_NONE);
+       tdm_output *output;
+       int o, count = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(count > 0);
+
+       for (o = 0; o < count; o++) {
+               output = tdm_display_get_output(NULL, o, NULL);
+               ASSERT_TRUE(output == NULL);
+       }
 }
 
-TEST_F(TDMDefault, DisplayGetMaxLayerCountSuccessful)
+TEST_P(TDMDisplay, DisplayGetOutputNullObject)
 {
-       int max_count = -42;
-       ASSERT_TRUE(TDM_ERROR_NONE == tdm_display_get_max_layer_count(dpy, &max_count));
-       ASSERT_NE(max_count, -42);
+       tdm_output *output;
+       tdm_error ret;
+
+       output = tdm_display_get_output(NULL, 0, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(output == NULL);
 }
 
-TEST_F(TDMDefault, DisplayGetMaxLayerCountFailNullAll)
+TEST_P(TDMDisplay, DisplayGetOutputNullOther)
 {
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_display_get_max_layer_count(NULL, NULL));
+       tdm_output *output;
+       int o, count = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(count > 0);
+
+       for (o = 0; o < count; o++) {
+               output = tdm_display_get_output(dpy, o, NULL);
+               ASSERT_TRUE(output != NULL);
+       }
 }
 
-TEST_F(TDMDefault, DisplayGetMaxLayerCountFailSetOnlyDpy)
+TEST_P(TDMDisplay, DisplayGetOutputWrongIndex)
 {
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_display_get_max_layer_count(dpy, NULL));
+       tdm_output *output;
+       tdm_error ret;
+
+       output = tdm_display_get_output(dpy, -1, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(output == NULL);
+
+       output = tdm_display_get_output(dpy, INT_MAX, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(output == NULL);
 }
 
-TEST_F(TDMDefault, DisplayGetOutputCountSuccessful)
+TEST_P(TDMDisplay, DisplayCreatePp)
 {
-       int count = -42;
-       ASSERT_TRUE(TDM_ERROR_NONE == tdm_display_get_output_count(dpy, &count));
-       ASSERT_FALSE(-42 == count);
+       tdm_pp *pp;
+       tdm_error ret;
+
+       if (!has_pp_cap)
+               return;
+
+       pp = tdm_display_create_pp(dpy, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(pp != NULL);
+
+       tdm_pp_destroy(pp);
 }
 
-TEST_F(TDMDefault, DisplayGetOutputCountFailNullALl)
+TEST_P(TDMDisplay, DisplayCreatePpNullObject)
 {
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_display_get_output_count(NULL, NULL));
+       tdm_pp *pp;
+       tdm_error ret;
+
+       if (!has_pp_cap)
+               return;
+
+       pp = tdm_display_create_pp(NULL, &ret);
+       ASSERT_TRUE(ret != TDM_ERROR_NONE);
+       ASSERT_TRUE(pp == NULL);
+}
+
+TEST_P(TDMDisplay, BackendGetInfo)
+{
+       tdm_output *output;
+       int o, count = TDM_UT_INVALID_VALUE;
+       tdm_error ret;
+
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(count > 0);
+
+       for (o = 0; o < count; o++) {
+               tdm_backend *backend;
+               const char *name = (const char *)TDM_UT_INVALID_VALUE;
+               const char *vendor = (const char *)TDM_UT_INVALID_VALUE;
+               int major = TDM_UT_INVALID_VALUE;
+               int minor = TDM_UT_INVALID_VALUE;
+
+               output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
+
+               backend = tdm_output_get_backend(output, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(backend != NULL);
+
+               ASSERT_TRUE(tdm_backend_get_info(backend, &name, &vendor, &major, &minor) == TDM_ERROR_NONE);
+               ASSERT_TRUE(name != (const char *)TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(vendor != (const char *)TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(major != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(minor != TDM_UT_INVALID_VALUE);
+       }
 }
 
-TEST_F(TDMDefault, DisplayGetOutputCountFailSetOnlyDpy)
+TEST_P(TDMDisplay, BackendGetInfoNullObject)
 {
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_display_get_output_count(dpy, NULL));
+       const char *name = (const char *)TDM_UT_INVALID_VALUE;
+       const char *vendor = (const char *)TDM_UT_INVALID_VALUE;
+       int major = TDM_UT_INVALID_VALUE;
+       int minor = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_backend_get_info(NULL, &name, &vendor, &major, &minor) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(name == (const char *)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(vendor == (const char *)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(major == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(minor == TDM_UT_INVALID_VALUE);
 }
+
+TEST_P(TDMDisplay, BackendGetInfoNullOther)
+{
+       tdm_output *output;
+       int o, count = TDM_UT_INVALID_VALUE;
+       tdm_error ret;
+
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(count > 0);
+
+       for (o = 0; o < count; o++) {
+               tdm_backend *backend;
+
+               output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
+
+               backend = tdm_output_get_backend(output, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(backend != NULL);
+
+               ASSERT_TRUE(tdm_backend_get_info(backend, NULL, NULL, NULL, NULL) == TDM_ERROR_NONE);
+       }
+}
+
+INSTANTIATE_TEST_CASE_P(TDMDisplayParams,
+                                               TDMDisplay,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
diff --git a/utests/src/ut_tdm_env.cpp b/utests/src/ut_tdm_env.cpp
new file mode 100644 (file)
index 0000000..f94b77d
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
+ * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ *
+ * 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 "ut_tdm.h"
+
+void TDMEnv::SetUp(void)
+{
+       const char *test_backend;
+
+       TDM_UT_ENTRY();
+
+       setenv("XDG_RUNTIME_DIR", "/run", 1);
+       setenv("TBM_DISPLAY_SERVER", "1", 1);
+
+       tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, ::testing::get<0>(GetParam()));
+       tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, ::testing::get<1>(GetParam()));
+
+       const char *debug = getenv("TDM_DEBUG_MODULE");
+       if (debug && strstr(debug, "1"))
+               tdm_config_set_string(TDM_CONFIG_KEY_DEBUG_MODULE, "buffer,thread,event,vblank,commit,pp,capture");
+
+       test_backend = ::testing::get<2>(GetParam());
+       if (!test_backend)
+               test_backend = TDM_DEFAULT_MODULE;
+       tdm_config_set_string(TDM_CONFIG_KEY_GENERAL_BACKENDS, test_backend);
+}
+
+void TDMEnv::TearDown(void)
+{
+       unsetenv("XDG_RUNTIME_DIR");
+       unsetenv("TBM_DISPLAY_SERVER");
+}
+
+#ifdef UT_TDM_ENV_ENABLE
+
+TEST_P(TDMEnv, DisplayInitDeinit)
+{
+       tdm_display *dpy;
+       tdm_error ret;
+
+       dpy = tdm_display_init(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpy != NULL);
+
+       tdm_display_deinit(dpy);
+}
+
+TEST_P(TDMEnv, DisplayInitDeinitWithoutEnv)
+{
+       tdm_display *dpy;
+       tdm_error ret;
+
+       TDMEnv::TearDown();
+
+       dpy = tdm_display_init(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_OPERATION_FAILED);
+       ASSERT_TRUE(dpy == NULL);
+}
+
+TEST_P(TDMEnv, DisplayInitFewTimes)
+{
+       tdm_display *dpy[10];
+       int d;
+       tdm_error ret;
+
+       for (d = 0; d < 10; d++) {
+               dpy[d] = tdm_display_init(&ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(dpy[d] != NULL);
+       }
+
+       for (d = 0; d < 9; d++)
+               ASSERT_TRUE(dpy[d] == dpy[d + 1]);
+
+       for (d = 0; d < 10; d++)
+               tdm_display_deinit(dpy[d]);
+}
+
+TEST_P(TDMEnv, DisplayInitDeinitWithTBM)
+{
+       tdm_display *dpy;
+       tbm_bufmgr bufmgr;
+       tdm_error ret;
+
+       bufmgr = tbm_bufmgr_init(-1);
+       ASSERT_TRUE(bufmgr != NULL);
+
+       dpy = tdm_display_init(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpy != NULL);
+
+       tdm_display_deinit(dpy);
+       tbm_bufmgr_deinit(bufmgr);
+}
+
+TEST_P(TDMEnv, DisplayInitDeinitWithoutBackends)
+{
+       ASSERT_TRUE(1);
+}
+
+TEST_P(TDMEnv, DisplayInitDeinitWrongDpyBadAddress)
+{
+       tdm_display *dpy;
+       tdm_error ret;
+
+       dpy = tdm_display_init(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpy != NULL);
+
+       EXPECT_EXIT({
+               tdm_display *wrong_dpy = (tdm_display *)TDM_UT_INVALID_VALUE;
+               tdm_display_deinit(wrong_dpy);
+               exit(0);
+       }, ::testing::ExitedWithCode(0), "");
+
+       tdm_display_deinit(dpy);
+}
+
+TEST_P(TDMEnv, DisplayDeinitWithNULL)
+{
+       tdm_display_deinit(NULL);
+}
+
+TEST_P(TDMEnv, DisplayDeinitRepeatWithSameDpy)
+{
+       tdm_display *dpy;
+       tdm_error ret;
+
+       dpy = tdm_display_init(&ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(dpy != NULL);
+
+       EXPECT_EXIT({
+               tdm_display_deinit(dpy);
+               tdm_display_deinit(dpy);
+               exit(0);
+       }, ::testing::ExitedWithCode(0), "");
+
+       tdm_display_deinit(dpy);
+}
+
+INSTANTIATE_TEST_CASE_P(TDMEnvParams,
+                                               TDMEnv,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
index e8ecaaa..58641db 100644 (file)
-#include "gtest/gtest.h"
+/**************************************************************************
+ *
+ * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
+ * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ *
+ * 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 "ut_tdm.h"
-#include "stdint.h"
-#include "fcntl.h"
-
-extern "C" {
-#include "tdm.h"
-#include "tdm_config.h"
-#include "tdm_backend.h"
-#include "tbm_bufmgr.h"
-#include "tbm_surface.h"
-#include "tbm_surface_internal.h"
-#include "tbm_drm_helper.h"
-}
-
-class TDMEventLoop: public ::testing::Test
-{
-protected:
-       static tdm_display *dpy;
-       tdm_error error;
-       tdm_event_loop_source *loop_src;
-       int fd;
-
-       static void SetEnv(void)
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 0);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-       }
-
-       static void UnsetEnv(void)
-       {
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
-       }
-
-       static void SetUpTestCase()
-       {
-               tdm_error error;
-               SetEnv();
-               dpy = tdm_display_init(&error);
-               ASSERT_NE(NULL, dpy);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
-
-       static void TearDownTestCase()
-       {
-               tdm_display_deinit(dpy);
-               UnsetEnv();
-       }
-
-       int GetFd()
-       {
-               if (fd == -1)
-                       fd = tbm_drm_helper_get_master_fd();
-               return fd;
-       }
-
-       void SetUp()
-       {
-               loop_src = NULL;
-               fd = -1;
-       }
-
-       void TearDown()
-       {
-               if (loop_src)
-                       tdm_event_loop_source_remove(loop_src);
-               if (fd >= 0)
-                       close(fd);
-       }
+
+class TDMEventLoop : public TDMDisplay {
+public:
+       TDMEventLoop();
+       void SetUp(void);
+       void TearDown(void);
 };
 
-tdm_display *TDMEventLoop::dpy = NULL;
+TDMEventLoop::TDMEventLoop()
+{
+}
 
-static int handler_is_called = 0;
-static tdm_error timer_handler(void *user_data)
+void TDMEventLoop::SetUp(void)
 {
-       if (user_data == &handler_is_called)
-               handler_is_called = 1;
-       return TDM_ERROR_NONE;
+       TDMDisplay::SetUp();
+       tdm_display_lock(dpy);
 }
 
-static tdm_error fd_handler(int fd, tdm_event_loop_mask mask, void *user_data)
+void TDMEventLoop::TearDown(void)
 {
-       if (user_data == &handler_is_called)
-               handler_is_called = 1;
-       return TDM_ERROR_NONE;
+       tdm_display_unlock(dpy);
+       TDMDisplay::TearDown();
 }
 
-/*void tdm_event_loop_source_remove(tdm_event_loop_source *source); */
-TEST_F(TDMEventLoop, SourceRemoveFailNULL)
+#ifdef UT_TDM_EVENT_LOOP_ENABLE
+
+static tdm_error
+_ut_tdm_event_loop_fd_cb(int fd, tdm_event_loop_mask mask, void *user_data)
 {
-       tdm_event_loop_source_remove(NULL);
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+       return TDM_ERROR_NONE;
 }
 
-/* tdm_event_loop_source* tdm_event_loop_add_timer_handler(tdm_display *dpy,
-                                                                       tdm_event_loop_timer_handler func,
-                                                                       void *user_data, tdm_error *error); */
-TEST_F(TDMEventLoop, AddTimerHandlerFailNULL)
+TEST_P(TDMEventLoop, EventLoopAddFdHandler)
 {
-       loop_src = tdm_event_loop_add_timer_handler(NULL, timer_handler, &handler_is_called, &error);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-       ASSERT_EQ(NULL, loop_src);
+       tdm_error ret;
+       int pipes[2];  /* 0: read, 1: write */
+       tdm_event_loop_source *source;
+       bool done;
+       int len;
+
+       ASSERT_TRUE(pipe(pipes) == 0);
+
+       done = false;
+       source = tdm_event_loop_add_fd_handler(dpy, pipes[0], TDM_EVENT_LOOP_READABLE,
+                                                                                  _ut_tdm_event_loop_fd_cb, &done, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(source != NULL);
+
+       len = write(pipes[1], "hello", 5);
+       ASSERT_TRUE(len == 5);
 
-       loop_src = tdm_event_loop_add_timer_handler(dpy, NULL, &handler_is_called, &error);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-       ASSERT_EQ(NULL, loop_src);
+//TODO
+//     while (!done)
+//             ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       loop_src = tdm_event_loop_add_timer_handler(dpy, NULL, &handler_is_called, NULL);
-       ASSERT_EQ(NULL, loop_src);
+       tdm_event_loop_source_remove(source);
+
+       close(pipes[0]);
+       close(pipes[1]);
 }
 
-TEST_F(TDMEventLoop, AddTimerHandlerSuccessful)
+TEST_P(TDMEventLoop, EventLoopAddFdHandlerNullObject)
 {
-       loop_src = tdm_event_loop_add_timer_handler(dpy, timer_handler, &handler_is_called, &error);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-       ASSERT_NE(NULL, loop_src);
+       tdm_error ret;
+       tdm_event_loop_source *source;
+       source = tdm_event_loop_add_fd_handler(NULL, 0, TDM_EVENT_LOOP_READABLE,
+                                                                                  _ut_tdm_event_loop_fd_cb, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(source == NULL);
 }
 
-/* tdm_error tdm_event_loop_source_timer_update(tdm_event_loop_source *source, unsigned int ms_delay); */
-TEST_F(TDMEventLoop, SourceTimerUpdateFailNULL)
+TEST_P(TDMEventLoop, EventLoopAddFdHandlerNullOther)
 {
-       error = tdm_event_loop_source_timer_update(NULL, 0);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       tdm_error ret;
+       tdm_event_loop_source *source;
+       source = tdm_event_loop_add_fd_handler(NULL, -1, TDM_EVENT_LOOP_READABLE, NULL, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(source == NULL);
 }
-TEST_F(TDMEventLoop, SourceTimerUpdateSuccessful)
+
+TEST_P(TDMEventLoop, EventLoopSourceFdUpdate)
 {
-       loop_src = tdm_event_loop_add_timer_handler(dpy, timer_handler, &handler_is_called, &error);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-       ASSERT_NE(NULL, loop_src);
+       tdm_error ret;
+       int pipes[2];  /* 0: read, 1: write */
+       tdm_event_loop_source *source;
+       bool done;
+       int len;
 
-       error = tdm_event_loop_source_timer_update(loop_src, 10);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-}
+       ASSERT_TRUE(pipe(pipes) == 0);
 
-/* tdm_event_loop_source* tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask,
-                                                         tdm_event_loop_fd_handler func, void *user_data,
-                                                         tdm_error *error); */
-TEST_F(TDMEventLoop, AddFdHandlerFailNULL)
-{
-       loop_src = tdm_event_loop_add_fd_handler(NULL, 0, TDM_EVENT_LOOP_READABLE,
-                                                                                       fd_handler, &handler_is_called, &error);
-       ASSERT_EQ(NULL, loop_src);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       done = false;
+       source = tdm_event_loop_add_fd_handler(dpy, pipes[0], TDM_EVENT_LOOP_WRITABLE,
+                                                                                  _ut_tdm_event_loop_fd_cb, &done, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(source != NULL);
 
-       loop_src = tdm_event_loop_add_fd_handler(dpy, 0, TDM_EVENT_LOOP_READABLE,
-                                                                                       NULL, &handler_is_called, &error);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-       ASSERT_EQ(NULL, loop_src);
+       ASSERT_TRUE(tdm_event_loop_source_fd_update(source, TDM_EVENT_LOOP_READABLE) == TDM_ERROR_NONE);
+
+       len = write(pipes[1], "hello", 5);
+       ASSERT_TRUE(len == 5);
+
+//TODO
+//     while (!done)
+//             ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+
+       tdm_event_loop_source_remove(source);
+
+       close(pipes[0]);
+       close(pipes[1]);
 }
 
-TEST_F(TDMEventLoop, AddFdHandlerFailInvalidFd)
+TEST_P(TDMEventLoop, EventLoopSourceFdUpdateNullObject)
 {
-       loop_src = tdm_event_loop_add_fd_handler(dpy, -1, TDM_EVENT_LOOP_READABLE,
-                                                                                       fd_handler, &handler_is_called, &error);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-       ASSERT_EQ(NULL, loop_src);
+       ASSERT_TRUE(tdm_event_loop_source_fd_update(NULL, TDM_EVENT_LOOP_READABLE) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMEventLoop, AddFdHandlerSuccessful)
+static tdm_error
+_ut_tdm_event_loop_timer_cb(void *user_data)
 {
-       int fd = GetFd();
-       ASSERT_NE(-1, fd);
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+       return TDM_ERROR_NONE;
+}
 
-       loop_src = tdm_event_loop_add_fd_handler(dpy, fd, TDM_EVENT_LOOP_READABLE,
-                                                                                       fd_handler, &handler_is_called, &error);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-       ASSERT_NE(NULL, loop_src);
+TEST_P(TDMEventLoop, EventLoopAddTimerHandler)
+{
+       tdm_error ret;
+       tdm_event_loop_source *source;
+       source = tdm_event_loop_add_timer_handler(dpy, _ut_tdm_event_loop_timer_cb, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(source != NULL);
+       tdm_event_loop_source_remove(source);
 }
 
-/* tdm_error tdm_event_loop_source_fd_update(tdm_event_loop_source *source, tdm_event_loop_mask mask); */
-TEST_F(TDMEventLoop, SourceFdUpdateFailNULL)
+TEST_P(TDMEventLoop, EventLoopAddTimerHandlerNullObject)
 {
-       error = tdm_event_loop_source_fd_update(NULL, TDM_EVENT_LOOP_READABLE);
+       tdm_error ret;
+       tdm_event_loop_source *source;
+       source = tdm_event_loop_add_timer_handler(NULL, _ut_tdm_event_loop_timer_cb, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(source == NULL);
 }
 
-TEST_F(TDMEventLoop, SourceFdUpdateSuccessful)
+
+TEST_P(TDMEventLoop, EventLoopAddTimerHandlerNullOther)
 {
-       int fd;
-       tdm_event_loop_mask flag = TDM_EVENT_LOOP_WRITABLE;
+       tdm_error ret;
+       tdm_event_loop_source *source;
+       source = tdm_event_loop_add_timer_handler(dpy, NULL, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(source == NULL);
+}
 
-       fd = GetFd();
-       ASSERT_NE(-1, fd);
+TEST_P(TDMEventLoop, EventLoopSourceTimerUpdate)
+{
+       tdm_error ret;
+       tdm_event_loop_source *source;
+       source = tdm_event_loop_add_timer_handler(dpy, _ut_tdm_event_loop_timer_cb, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(source != NULL);
+       ASSERT_TRUE(tdm_event_loop_source_timer_update(source, 100) == TDM_ERROR_NONE);
+//TODO
+//     while (!done)
+//             ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       tdm_event_loop_source_remove(source);
+}
 
-       loop_src = tdm_event_loop_add_fd_handler(dpy, fd, flag,
-                                                                                       fd_handler, &handler_is_called, &error);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-       ASSERT_NE(NULL, loop_src);
+TEST_P(TDMEventLoop, EventLoopSourceTimerUpdateNullObject)
+{
+       ASSERT_TRUE(tdm_event_loop_source_timer_update(NULL, 100) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-       error = tdm_event_loop_source_fd_update(loop_src, TDM_EVENT_LOOP_READABLE);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+TEST_P(TDMEventLoop, EventLoopSourceRemoveNullObject)
+{
+       tdm_event_loop_source_remove(NULL);
 }
 
+INSTANTIATE_TEST_CASE_P(TDMEventLoopParams,
+                                               TDMEventLoop,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
index a093ffc..7f2f2e0 100644 (file)
-#include "gtest/gtest.h"
-#include "ut_tdm.h"
-#include "stdint.h"
-#include <stdio.h>
-#include <ftw.h>
-#include <unistd.h>
-
-extern "C" {
-#include "tdm.h"
-#include "tdm_config.h"
-#include "tdm_helper.h"
-#include "tdm_backend.h"
-#include "tbm_bufmgr.h"
-#include "tbm_surface.h"
-#include "tbm_surface_internal.h"
-#include "tbm_drm_helper.h"
-}
-
-#define TMP_PATH_FOR_UTEST "/tmp/tmp_utest_helper"
-#define STR_LEN 8192
-
-class TDMHelper : public ::testing::Test {
-protected:
-       tdm_display *dpy = NULL;
-       tbm_bufmgr bufmgr = NULL;
-       int master_fd = -42;
-       /*list of connected outputs*/
-       int output_count = 0;
-       const tdm_output_mode **preferred_mode_array = NULL;
-       tdm_output **outputs;
-       tdm_error error ;
-       tbm_surface_h surface;
-       virtual void SetEnv()
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1);
-       }
+/**************************************************************************
+ *
+ * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
+ * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ *
+ * 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.
+ *
+**************************************************************************/
 
-       void UnsetEnv()
-       {
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
-       }
+#include "ut_tdm.h"
 
-       void SetUp(void)
-       {
-               const tdm_output_mode *preferred_mode = NULL;
-               tdm_error error = TDM_ERROR_NONE;
-               int all_output_count = 0;
+class TDMHelper : public TDMOutput {
+public:
+       TDMHelper();
+       void SetUp(void);
+       void TearDown(void);
+};
 
-               SetEnv();
+TDMHelper::TDMHelper()
+{
+}
 
-               bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(bufmgr == NULL);
+void TDMHelper::SetUp(void)
+{
+       TDMOutput::SetUp();
+}
 
-               dpy = tdm_display_init(&error);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               ASSERT_FALSE(dpy == NULL);
+void TDMHelper::TearDown(void)
+{
+       TDMOutput::TearDown();
+}
 
-               master_fd = tbm_drm_helper_get_master_fd();
-               ASSERT_TRUE(tdm_display_get_output_count(dpy, &all_output_count) == TDM_ERROR_NONE);
+#ifdef UT_TDM_HELPER_ENABLE
 
-               outputs = (tdm_output **)calloc(all_output_count, sizeof(tdm_output *));
-               ASSERT_FALSE(NULL == outputs);
+TEST_P(TDMHelper, HelperGetTime)
+{
+       ASSERT_TRUE(tdm_helper_get_time() > 0.0);
+}
 
-               preferred_mode_array = (const tdm_output_mode **)calloc(all_output_count, sizeof(tdm_output_mode *));
-               ASSERT_FALSE(NULL == preferred_mode_array);
+TEST_P(TDMHelper, HelperDumpBuffer)
+{
+       tbm_surface_h buffer;
 
-               output_count = 0;
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
 
-               for (int i = 0; i < all_output_count; i++) {
-                       tdm_output *output = tdm_display_get_output(dpy, i, &error);
-                       int output_modes_cnt = 0;
-                       const tdm_output_mode *output_modes;
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-                       if (TDM_ERROR_NONE != error || NULL == output)
-                               continue;
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
 
-                       tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-                       if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status))
-                               continue;
+       tbm_surface_destroy(buffer);
+}
 
-                       if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                               continue;
+TEST_P(TDMHelper, HelperDumpBufferNullObject)
+{
+       char filename[256];
+       tdm_helper_dump_buffer(NULL, (const char*)filename);
+}
 
-                       error = tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt);
-                       if (TDM_ERROR_NONE != error)
-                               continue;
-                       if (output_modes_cnt <= 0) {
-                               continue;
-                       }
+TEST_P(TDMHelper, HelperDumpBufferNullOther)
+{
+       tbm_surface_h buffer = (tbm_surface_h)TDM_UT_INVALID_VALUE;
+       tdm_helper_dump_buffer(buffer, NULL);
+}
 
-                       for(int j = 0; j < output_modes_cnt; j++)
-                               if(output_modes[j].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
-                                       preferred_mode = &output_modes[j];
+TEST_P(TDMHelper, HelperClearBufferPos)
+{
+       tbm_surface_h buffer;
+       tdm_pos pos = {.x = 40, .y = 40, .w = TDM_UT_BUFFER_SIZE - 80, .h = TDM_UT_BUFFER_SIZE - 80};
 
-                       if (!preferred_mode)
-                               continue;
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
 
-                       if (preferred_mode_array)
-                               preferred_mode_array[output_count] = preferred_mode;
-                       if (outputs)
-                               outputs[output_count] = output;
-                       output_count++;
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-                       error = tdm_output_set_mode(output, preferred_mode);
-                       ASSERT_EQ(TDM_ERROR_NONE, error);
-               }
-               surface = tbm_surface_create(256, 256, TBM_FORMAT_ARGB8888);
-               ASSERT_TRUE(surface != NULL);
-       }
+       tdm_helper_clear_buffer_pos(buffer, &pos);
 
-       void TearDown(void)
-       {
-               if (surface) {
-                       while (tbm_surface_internal_is_valid(surface))
-                               tbm_surface_destroy(surface);
-               }
-               tdm_display_deinit(dpy);
-               dpy = NULL;
-               tbm_bufmgr_deinit(bufmgr);
-               bufmgr = NULL;
-               if (outputs)
-                       free(outputs);
-               if (preferred_mode_array)
-                       free(preferred_mode_array);
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_master_fd > -1)
-                               exit(1);
-                       close(master_fd);
-               }
-
-               UnsetEnv();
-       }
-};
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
 
-int remove_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
-{
-       int rv = remove(fpath);
-       if (rv)
-               perror(fpath);
-       return rv;
+       tbm_surface_destroy(buffer);
 }
 
-int rmrf(const char *path)
+TEST_P(TDMHelper, HelperClearBufferColor)
 {
-       return nftw(path, remove_cb, 64, FTW_DEPTH | FTW_PHYS);
+       tbm_surface_h buffer;
+       tdm_pos pos = {.x = 40, .y = 40, .w = TDM_UT_BUFFER_SIZE - 80, .h = TDM_UT_BUFFER_SIZE - 80};
+       unsigned int color = 0xffffff00;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       tdm_helper_clear_buffer_color(buffer, &pos, color);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
 }
 
-class TDMHelperSurface: public TDMHelper
+TEST_P(TDMHelper, HelperClearBufferARGB)
 {
-protected:
+       tbm_surface_h buffer;
 
-       void SetUp()
-       {
-               TDMHelper::SetUp();
-               ASSERT_EQ(0, mkdir(TMP_PATH_FOR_UTEST, 0755)) << "error: " <<  strerror(errno);
-       }
-       void TearDown()
-       {
-
-               rmrf(TMP_PATH_FOR_UTEST);
-               TDMHelper::TearDown();
-       }
-};
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
 
-class TDMHelperDisplay: public TDMHelper {
-};
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-class TDMHelperOutput: public TDMHelper {
-};
+       tdm_helper_clear_buffer(buffer);
 
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
 
-/* double tdm_helper_get_time(void); */
-TEST(TDMHelper, GetTime)
-{
-       double time;
-       time = tdm_helper_get_time();
-       EXPECT_GT(time, 0);
+       tbm_surface_destroy(buffer);
 }
 
-/* void tdm_helper_dump_start(char *dumppath, int *count); */
-TEST(TDMHelper, DumpStartFailNull)
+TEST_P(TDMHelper, HelperClearBufferXRGB)
 {
-       int count = 100;
-       tdm_helper_dump_start(NULL, &count);
+       tbm_surface_h buffer;
 
-       tdm_helper_dump_start((char *)TMP_PATH_FOR_UTEST, NULL);
-}
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_XRGB8888);
+       ASSERT_TRUE(buffer != NULL);
 
-TEST(TDMHelper, DumpStartSuccessful)
-{
-       int count = 100;
-       tdm_helper_dump_start((char *)TMP_PATH_FOR_UTEST, &count);
-}
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-/* void tdm_helper_dump_stop(void); */
-TEST(TDMHelper, DumpStopSuccessful)
-{
-       tdm_helper_dump_stop();
-}
+       tdm_helper_clear_buffer(buffer);
 
-/* void tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file); */
-TEST_F(TDMHelperSurface, DumpBufferFailNull)
-{
-       tdm_helper_dump_buffer(NULL, TMP_PATH_FOR_UTEST "/tmp");
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
 }
 
-TEST_F(TDMHelperSurface, DumpBufferFailInvalidOutput)
+TEST_P(TDMHelper, HelperClearBufferYUV420)
 {
-       int invalid_surface;
-       tdm_helper_dump_buffer((tbm_surface_h)&invalid_surface, TMP_PATH_FOR_UTEST "/xyz.png");
+       tbm_surface_h buffer;
 
-       /* file name mast have an extension ".png" */
-       tdm_helper_dump_buffer(surface, TMP_PATH_FOR_UTEST "/tmp.xyz");
-}
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_YUV420);
+       ASSERT_TRUE(buffer != NULL);
 
-TEST_F(TDMHelperSurface, DumpBufferFailUnknownFormat)
-{
-       tbm_surface_h surf;
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUV444);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_dump_buffer(surface, TMP_PATH_FOR_UTEST "/xyz.png");
-       tbm_surface_destroy(surf);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       tdm_helper_clear_buffer(buffer);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
 }
 
-TEST_F(TDMHelperSurface, DumpBufferSuccessful)
+TEST_P(TDMHelper, HelperClearBufferNV12)
 {
-       tbm_surface_h surf;
+       tbm_surface_h buffer;
 
-       tdm_helper_dump_buffer(surface, TMP_PATH_FOR_UTEST "/rgb.png");
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_NV12);
+       ASSERT_TRUE(buffer != NULL);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUV420);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_dump_buffer(surf, TMP_PATH_FOR_UTEST "/YUV.yuv");
-       tbm_surface_destroy(surf);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_NV12);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_dump_buffer(surf, TMP_PATH_FOR_UTEST "/NV.yuv");
-       tbm_surface_destroy(surf);
+       tdm_helper_clear_buffer(buffer);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUYV);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_dump_buffer(surf, TMP_PATH_FOR_UTEST "/YUYV.yuv");
-       tbm_surface_destroy(surf);
-}
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
 
-/* void tdm_helper_clear_buffer_color(tbm_surface_h buffer, tdm_pos *pos, unsigned int color); */
-TEST_F(TDMHelperSurface, ClearBufferColorFailNull)
-{
-       tdm_pos pos;
-       tdm_helper_clear_buffer_color(NULL, &pos, 0x0F0F0F);
+       tbm_surface_destroy(buffer);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferColorInvalidOutput)
+TEST_P(TDMHelper, HelperClearBufferNV21)
 {
-       int invalid_surface;
-       tdm_pos pos;
-       tdm_helper_clear_buffer_color((tbm_surface_h)&invalid_surface, &pos, 0x0F0F0F);
-}
+       tbm_surface_h buffer;
 
-TEST_F(TDMHelperSurface, ClearBufferColorUnknownFormat)
-{
-       tdm_pos pos = { .x = 0, .y = 0, .w = 10, .h = 10 };
-       tbm_surface_h surf;
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUV444);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_color(surf, &pos, 0x0F0F0F);
-       tbm_surface_destroy(surf);
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_NV21);
+       ASSERT_TRUE(buffer != NULL);
+
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       tdm_helper_clear_buffer(buffer);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferColorSuccessful)
+TEST_P(TDMHelper, HelperClearBufferYUYV)
 {
-       tdm_pos pos = { .x = 0, .y = 0, .w = 10, .h = 10 };
-       tbm_surface_h surf;
+       tbm_surface_h buffer;
 
-       tdm_helper_clear_buffer_color(surface, &pos, 0x0F0F0F);
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_YUYV);
+       ASSERT_TRUE(buffer != NULL);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YVU420);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_color(surf, &pos, 0x0F0F0F);
-       tbm_surface_destroy(surf);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_NV12);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_color(surf, &pos, 0x0F0F0F);
-       tbm_surface_destroy(surf);
+       tdm_helper_clear_buffer(buffer);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUYV);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_color(surf, &pos, 0x0F0F0F);
-       tbm_surface_destroy(surf);
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_UYVY);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_color(surf, &pos, 0x0F0F0F);
-       tbm_surface_destroy(surf);
+       tbm_surface_destroy(buffer);
 }
 
-/* void tdm_helper_clear_buffer_pos(tbm_surface_h buffer, tdm_pos *pos); */
-TEST_F(TDMHelperSurface, ClearBufferPosFailNull)
+TEST_P(TDMHelper, HelperClearBufferUYVY)
 {
-       tdm_pos pos;
-       tdm_helper_clear_buffer_pos(NULL, &pos);
+       tbm_surface_h buffer;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_UYVY);
+       ASSERT_TRUE(buffer != NULL);
+
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       tdm_helper_clear_buffer(buffer);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(buffer, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferPosInvalidOutput)
+TEST_P(TDMHelper, HelperGetBufferFullSize)
 {
-       int invalid_surface;
-       tdm_pos pos;
-       tdm_helper_clear_buffer_pos((tbm_surface_h)&invalid_surface, &pos);
+       tbm_surface_h buffer;
+       int w = TDM_UT_INVALID_VALUE, h = TDM_UT_INVALID_VALUE;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+
+       tdm_helper_get_buffer_full_size(buffer, &w, &h);
+       ASSERT_TRUE(w != TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(w >= tbm_surface_get_width(buffer));
+       ASSERT_TRUE(h != TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(h >= tbm_surface_get_height(buffer));
+
+       tbm_surface_destroy(buffer);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferPosUnknownFormat)
+TEST_P(TDMHelper, HelperConvertBufferRotate0)
 {
-       tdm_pos pos = { .x = 0, .y = 0, .w = 10, .h = 10 };
-       tbm_surface_h surf;
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUV444);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_pos(surf, &pos);
-       tbm_surface_destroy(surf);
+       tbm_surface_h buffer, temp;
+       tdm_pos sp, dp;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       temp = tbm_surface_create(TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(temp != NULL);
+
+       sp.x = sp.y = 0, sp.w = sp.h = TDM_UT_BUFFER_SIZE;
+       dp.x = dp.y = 0, dp.w = dp.h = TDM_UT_BUFFER_SIZE * 2;
+
+       ASSERT_TRUE(tdm_helper_convert_buffer(buffer, temp, &sp, &dp, TDM_TRANSFORM_NORMAL, 0) == TDM_ERROR_NONE);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(temp, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
+       tbm_surface_destroy(temp);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferPosSuccessful)
+TEST_P(TDMHelper, HelperConvertBufferRotate0Flip)
 {
-       tdm_pos pos = { .x = 0, .y = 0, .w = 10, .h = 10 };
-       tbm_surface_h surf;
+       tbm_surface_h buffer, temp;
+       tdm_pos sp, dp;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-       tdm_helper_clear_buffer_pos(surface, &pos);
+       temp = tbm_surface_create(TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(temp != NULL);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YVU420);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_pos(surf, &pos);
-       tbm_surface_destroy(surf);
+       sp.x = sp.y = 0, sp.w = sp.h = TDM_UT_BUFFER_SIZE;
+       dp.x = dp.y = 0, dp.w = dp.h = TDM_UT_BUFFER_SIZE * 2;
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_NV12);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_pos(surf, &pos);
-       tbm_surface_destroy(surf);
+       ASSERT_TRUE(tdm_helper_convert_buffer(buffer, temp, &sp, &dp, TDM_TRANSFORM_FLIPPED, 0) == TDM_ERROR_NONE);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUYV);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_pos(surf, &pos);
-       tbm_surface_destroy(surf);
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(temp, (const char*)filename);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_UYVY);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer_pos(surf, &pos);
-       tbm_surface_destroy(surf);
+       tbm_surface_destroy(buffer);
+       tbm_surface_destroy(temp);
 }
 
-/* void tdm_helper_clear_buffer(tbm_surface_h buffer); */
-TEST_F(TDMHelperSurface, ClearBufferFailNull)
+TEST_P(TDMHelper, HelperConvertBufferRotate90)
 {
-       tdm_helper_clear_buffer(NULL);
+       tbm_surface_h buffer, temp;
+       tdm_pos sp, dp;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       temp = tbm_surface_create(TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(temp != NULL);
+
+       sp.x = sp.y = 0, sp.w = sp.h = TDM_UT_BUFFER_SIZE;
+       dp.x = dp.y = 0, dp.w = dp.h = TDM_UT_BUFFER_SIZE * 2;
+
+       ASSERT_TRUE(tdm_helper_convert_buffer(buffer, temp, &sp, &dp, TDM_TRANSFORM_90, 0) == TDM_ERROR_NONE);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(temp, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
+       tbm_surface_destroy(temp);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferInvalidOutput)
+TEST_P(TDMHelper, HelperConvertBufferRotate180)
 {
-       int invalid_surface;
-       tdm_helper_clear_buffer((tbm_surface_h)&invalid_surface);
+       tbm_surface_h buffer, temp;
+       tdm_pos sp, dp;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       temp = tbm_surface_create(TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(temp != NULL);
+
+       sp.x = sp.y = 0, sp.w = sp.h = TDM_UT_BUFFER_SIZE;
+       dp.x = dp.y = 0, dp.w = dp.h = TDM_UT_BUFFER_SIZE * 2;
+
+       ASSERT_TRUE(tdm_helper_convert_buffer(buffer, temp, &sp, &dp, TDM_TRANSFORM_180, 0) == TDM_ERROR_NONE);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(temp, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
+       tbm_surface_destroy(temp);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferUnknownFormat)
+TEST_P(TDMHelper, HelperConvertBufferRotate270)
 {
-       tbm_surface_h surf;
+       tbm_surface_h buffer, temp;
+       tdm_pos sp, dp;
+
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(buffer != NULL);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+
+       temp = tbm_surface_create(TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, TBM_FORMAT_ARGB8888);
+       ASSERT_TRUE(temp != NULL);
+
+       sp.x = sp.y = 0, sp.w = sp.h = TDM_UT_BUFFER_SIZE;
+       dp.x = dp.y = 0, dp.w = dp.h = TDM_UT_BUFFER_SIZE * 2;
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUV444);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer(surf);
-       tbm_surface_destroy(surf);
+       ASSERT_TRUE(tdm_helper_convert_buffer(buffer, temp, &sp, &dp, TDM_TRANSFORM_270, 0) == TDM_ERROR_NONE);
+
+       char filename[256];
+       snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+       tdm_helper_dump_buffer(temp, (const char*)filename);
+
+       tbm_surface_destroy(buffer);
+       tbm_surface_destroy(temp);
 }
 
-TEST_F(TDMHelperSurface, ClearBufferSuccessful)
+TEST_P(TDMHelper, HelperConvertBufferYUV420)
 {
-       tbm_surface_h surf;
+       tbm_surface_h buffer, temp;
+       tdm_pos sp, dp;
 
-       tdm_helper_clear_buffer(surface);
+       buffer = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_YUV420);
+       ASSERT_TRUE(buffer != NULL);
+       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YVU420);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer(surf);
-       tbm_surface_destroy(surf);
+       temp = tbm_surface_create(TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, TBM_FORMAT_YUV420);
+       ASSERT_TRUE(temp != NULL);
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_NV12);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer(surf);
-       tbm_surface_destroy(surf);
+       sp.x = sp.y = 0, sp.w = sp.h = TDM_UT_BUFFER_SIZE;
+       dp.x = dp.y = 0, dp.w = dp.h = TDM_UT_BUFFER_SIZE * 2;
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_YUYV);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer(surf);
-       tbm_surface_destroy(surf);
+       ASSERT_TRUE(tdm_helper_convert_buffer(buffer, temp, &sp, &dp, TDM_TRANSFORM_NORMAL, 0) == TDM_ERROR_OPERATION_FAILED);
+
+       tbm_surface_destroy(buffer);
+       tbm_surface_destroy(temp);
+}
 
-       surf = tbm_surface_create(256, 256, TBM_FORMAT_UYVY);
-       ASSERT_TRUE(surf != NULL);
-       tdm_helper_clear_buffer(surf);
-       tbm_surface_destroy(surf);
+TEST_P(TDMHelper, HelperGetFD)
+{
+       int fd = tdm_helper_get_fd("TDM_DRM_MASTER_FD");
+       ASSERT_TRUE(fd >= 0);
+       close(fd);
+       fd = tdm_helper_get_fd("BLURBLUR");
+       ASSERT_TRUE(fd == -1);
 }
 
-/* void tdm_helper_get_buffer_full_size(tbm_surface_h buffer, int *buffer_w, int *buffer_h); */
-TEST_F(TDMHelperSurface, GetBufferFullSizeFailNull)
+TEST_P(TDMHelper, HelperSetFD)
 {
-       int buffer_w;
-       int buffer_h;
-       tdm_helper_get_buffer_full_size(NULL, &buffer_w, &buffer_h);
+       tdm_helper_set_fd("TDM_DRM_MASTER_FD", -1);
+       tdm_helper_set_fd("BLURBLUR", -1);
 }
 
-TEST_F(TDMHelperSurface, GetBufferFullSizeFailinvalidBuffer)
+TEST_P(TDMHelper, HelperDumpStart)
 {
-       int invalid_surface;
-       int buffer_w;
-       int buffer_h;
-       tdm_helper_get_buffer_full_size((tbm_surface_h)&invalid_surface, &buffer_w, &buffer_h);
+       char path[256];
+       int count = 0;
+       snprintf(path, sizeof path, "blurblur");
+       tdm_helper_dump_start(path, &count);
+       tdm_helper_dump_stop();
 }
 
-TEST_F(TDMHelperSurface, GetBufferFullSizeSuccessful)
+static void
+_ut_tdm_helper_capture_cb(tbm_surface_h buffer, void *user_data)
 {
-       int buffer_w = 0;
-       int buffer_h = 0;
-       tdm_helper_get_buffer_full_size(surface, &buffer_w, &buffer_h);
-       ASSERT_GE(buffer_w, 0);
-       ASSERT_GE(buffer_h, 0);
 }
 
-/* tdm_error tdm_helper_convert_buffer(tbm_surface_h srcbuf, tbm_surface_h dstbuf,
-                                                 tdm_pos *srcpos, tdm_pos *dstpos,
-                                                 tdm_transform transform, int over); */
-TEST_F(TDMHelperSurface, ConvertBufferFailNull)
+TEST_P(TDMHelper, HelperCaptureOutput)
 {
-       tdm_pos srcpos = { 0, 0, 256, 256 };
-       tdm_pos dstpos = { 0, 0, 256, 256 };
-       tbm_surface_h dstbuf;
-       tdm_error error;
+       tdm_error ret;
+       tdm_output *output;
 
-       dstbuf = tbm_surface_create(256, 256, TBM_FORMAT_ARGB8888);
-       ASSERT_TRUE(dstbuf != NULL);
+       for (int o = 0; o < output_count; o++) {
+               tbm_surface_h dump;
 
-       error = tdm_helper_convert_buffer(NULL, dstbuf, &srcpos, &dstpos, TDM_TRANSFORM_NORMAL, 0);
-       tbm_surface_destroy(dstbuf);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+               output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
 
-       error = tdm_helper_convert_buffer(surface, NULL, &srcpos, &dstpos, TDM_TRANSFORM_NORMAL, 0);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-}
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
 
-TEST_F(TDMHelperSurface, ConvertBufferFailinvalidBuffer)
-{
-       int invalid_surface;
-       tdm_pos srcpos = { 0, 0, 256, 256 };
-       tdm_pos dstpos = { 0, 0, 256, 256 };
-       tbm_surface_h dstbuf;
-       tdm_error error;
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, output) == true);
 
-       dstbuf = tbm_surface_create(256, 256, TBM_FORMAT_ARGB8888);
-       ASSERT_TRUE(dstbuf != NULL);
+               dump = tbm_surface_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, TBM_FORMAT_ARGB8888);
+               ASSERT_TRUE(dump != NULL);
 
-       error = tdm_helper_convert_buffer((tbm_surface_h)&invalid_surface, dstbuf, &srcpos, &dstpos, TDM_TRANSFORM_NORMAL, 0);
-       tbm_surface_destroy(dstbuf);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_helper_capture_output(output, dump, 0, 0, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE,
+                                       _ut_tdm_helper_capture_cb, NULL) == TDM_ERROR_NONE);
 
-       error = tdm_helper_convert_buffer(surface, (tbm_surface_h)&invalid_surface, &srcpos, &dstpos, TDM_TRANSFORM_NORMAL, 0);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+               char filename[256];
+               snprintf(filename, sizeof filename, "%s.png", typeid(*this).name());
+               tdm_helper_dump_buffer(dump, (const char*)filename);
+
+               tbm_surface_destroy(dump);
+       }
 }
 
-TEST_F(TDMHelperSurface, ConvertBufferSuccessful)
-{
-       tdm_pos srcpos = { 0, 0, 256, 256 };
-       tdm_pos dstpos = { 0, 0, 256, 256 };
-       tbm_surface_h dstbuf;
-       tdm_error error;
 
-       dstbuf = tbm_surface_create(256, 256, TBM_FORMAT_ARGB8888);
-       ASSERT_TRUE(dstbuf != NULL);
+TEST_P(TDMHelper, HelperCaptureOutputNullObject)
+{
+       tbm_surface_h dump = (tbm_surface_h)TDM_UT_INVALID_VALUE;
 
-       error = tdm_helper_convert_buffer(surface, dstbuf, &srcpos, &dstpos, TDM_TRANSFORM_NORMAL, 0);
-       tbm_surface_destroy(dstbuf);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_helper_capture_output(NULL, dump, 0, 0, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE,
+                               _ut_tdm_helper_capture_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-
-/* void tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len); */
-TEST_F(TDMHelperDisplay, GetDisplayInformationFailNull)
+TEST_P(TDMHelper, HelperCaptureOutputNullOther)
 {
-       char reply[STR_LEN] = {0};
-       int len = STR_LEN;
-       tdm_helper_get_display_information(NULL, reply, &len);
-       ASSERT_LT(len, STR_LEN);
-       ASSERT_EQ((STR_LEN - len), strlen(reply));
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
+               tdm_output *output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
+               tdm_helper_output_commit_per_vblank_enabled(output);
+       }
 
-       len = STR_LEN;
-       tdm_helper_get_display_information(dpy, NULL, &len);
-       ASSERT_EQ(STR_LEN, len);
+       tbm_surface_h dump = (tbm_surface_h)TDM_UT_INVALID_VALUE;
 
-       reply[0] = '\0';
-       tdm_helper_get_display_information(dpy, reply, NULL);
-       ASSERT_EQ(0, reply[0]);
+       ASSERT_TRUE(tdm_helper_capture_output(NULL, dump, 0, 0, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE,
+                               _ut_tdm_helper_capture_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMHelperDisplay, GetDisplayInformationSuccessful)
+TEST_P(TDMHelper, HelperGetDisplayInformation)
 {
-       char reply[STR_LEN] = {0};
-       int len = STR_LEN;
-       tdm_helper_get_display_information(dpy, reply, &len);
-       ASSERT_LT(len, STR_LEN);
-       ASSERT_EQ((STR_LEN - len), strlen(reply));
-}
-int capture_handler_is_called = 0;
-void capture_handler(tbm_surface_h buffer, void *user_data)
-{
-       if (&capture_handler_is_called == user_data)
-               capture_handler_is_called = 1;
-}
-/* tdm_error tdm_helper_capture_output(...); */
-TEST_F(TDMHelperOutput, CaptureOutputFailNull)
-{
-       int output_count = 0;
-       tdm_output *output = NULL;
-       tdm_error error;
-       tbm_surface_h buffer = NULL;
-
-       error = tdm_display_get_output_count(dpy, &output_count);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-       for (int i = 0; i < output_count; i++) {
-
-               output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_NE(NULL, output);
-
-               error = tdm_helper_capture_output(NULL, buffer, 0, 0, 0, 0, capture_handler, &capture_handler_is_called);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-               error = tdm_helper_capture_output(output, NULL, 0, 0, 0, 0, capture_handler, &capture_handler_is_called);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-               error = tdm_helper_capture_output(output, buffer, 0, 0, 0, 0, NULL, &capture_handler_is_called);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-               error = tdm_helper_capture_output(output, buffer, 0, 0, 0, 0, capture_handler, NULL);
-               ASSERT_NE(TDM_ERROR_NONE, error);
+       char reply[8192];
+       int len = sizeof reply;
+
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
+               tdm_output *output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, output) == true);
        }
+
+       tdm_helper_get_display_information(dpy, reply, &len);
+       TDM_INFO("%s", reply);
 }
 
-TEST_F(TDMHelperOutput, CaptureOutputFailInvalidInputs)
+TEST_P(TDMHelper, HelperGetDisplayInformationNullObject)
 {
-       for (int i = 0; i < output_count; i++) {
-               error = tdm_helper_capture_output(outputs[i], surface, -1, 0, 0, 0, capture_handler, &capture_handler_is_called);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-               error = tdm_helper_capture_output(outputs[i], surface, 0, -1, 0, 0, capture_handler, &capture_handler_is_called);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-               error = tdm_helper_capture_output(outputs[i], surface, 0, 0, -1, 0, capture_handler, &capture_handler_is_called);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-               error = tdm_helper_capture_output(outputs[i], surface, 0, 0, 0, -1, capture_handler, &capture_handler_is_called);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
+       char reply[8192];
+       int len = sizeof reply;
+
+       tdm_helper_get_display_information(NULL, reply, &len);
 }
 
-TEST_F(TDMHelperOutput, CaptureOutputSuccessful)
+TEST_P(TDMHelper, HelperGetDisplayInformationNullOther)
 {
-       for (int i = 0; i < output_count; i++) {
-               error = tdm_helper_capture_output(outputs[i], surface, 0, 0, 255, 255, capture_handler, &capture_handler_is_called);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+       tdm_helper_get_display_information(dpy, NULL, NULL);
 }
 
-/* int tdm_helper_output_commit_per_vblank_enabled(tdm_output *output); */
-TEST_F(TDMHelperOutput, CommitPerVblankEnabledFailNull)
+TEST_P(TDMHelper, HelperCommitPerVblankEnabled)
 {
-       int state;
-       state = tdm_helper_output_commit_per_vblank_enabled(NULL);
-       ASSERT_EQ(-1, state);
+       tdm_helper_commit_per_vblank_enabled(dpy);
 }
 
-TEST_F(TDMHelperOutput, CommitPerVblankEnabledSuccessful)
+TEST_P(TDMHelper, HelperCommitPerVblankEnabledNullOBject)
 {
-       int state;
+       tdm_helper_commit_per_vblank_enabled(NULL);
+}
 
-       for (int i = 0; i < output_count; i++) {
-               state = tdm_helper_output_commit_per_vblank_enabled(outputs[i]);
-               ASSERT_EQ(1, state);
+TEST_P(TDMHelper, HelperOutputCommitPerVblankEnabled)
+{
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
+               tdm_output *output = tdm_display_get_output(dpy, o, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
+               tdm_helper_output_commit_per_vblank_enabled(output);
        }
 }
 
+TEST_P(TDMHelper, HelperOutputCommitPerVblankEnabledNullObject)
+{
+       tdm_helper_output_commit_per_vblank_enabled(NULL);
+}
+
+INSTANTIATE_TEST_CASE_P(TDMHelperParams,
+                                               TDMHelper,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
index aaa5d50..1c16d4e 100644 (file)
  *
 **************************************************************************/
 
-#include <limits.h>
-#include "gtest/gtest.h"
 #include "ut_tdm.h"
-#include "stdint.h"
 
-#include "tdm.h"
-#include "tdm_config.h"
-#include "tdm_backend.h"
-extern "C" {
-#include "tbm_bufmgr.h"
-#include "tbm_drm_helper.h"
-}
+#ifdef UT_TDM_HWC_WINDOW_ENABLE
 
 class TDMOutputHwc : public ::testing::Test {
 protected:
        tdm_display *dpy = NULL;
        tbm_bufmgr tbm_bufmgr = NULL;
-       int master_fd = -42;
+       int master_fd = TDM_UT_INVALID_VALUE;
        /*list of connected outputs*/
        int output_count = 0;
        const tdm_output_mode **preferred_mode_array = NULL;
@@ -59,6 +50,7 @@ protected:
                tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
                tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
                tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1);
+               tdm_config_set_string(TDM_CONFIG_KEY_GENERAL_BACKENDS, "libtdm-default.so");
        }
 
        void UnsetEnv()
@@ -350,7 +342,7 @@ TEST_F(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff)
 */
 
 /* tbm_surface_queue_h tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); */
-TEST_F(TDMOutputHwc, GetTargetBufferQueueFailNullOutput)
+TEST_F(TDMOutputHwc, GetTargetBufferQueueFailNullObject)
 {
        tbm_surface_queue_h queue = NULL;
 
@@ -872,7 +864,7 @@ TEST_F(TDMOutputHwc, GetVideoSupportedFormatsSuccessful)
 /* tdm_hwc_window_video_get_available_properties() */
 TEST_F(TDMHwcWindow, GetAvailablePropertiesFailNullWin)
 {
-       SKIP_FLAG(video_hwc_win != NULL);
+       TDM_UT_SKIP_FLAG(video_hwc_win != NULL);
        const tdm_prop *props;
        int count;
 
@@ -888,7 +880,7 @@ TEST_F(TDMHwcWindow, GetAvailablePropertiesFailNullWin)
 
 TEST_F(TDMHwcWindow, GetAvailablePropertiesSuccess)
 {
-       SKIP_FLAG(video_hwc_win != NULL);
+       TDM_UT_SKIP_FLAG(video_hwc_win != NULL);
 
        const tdm_prop *props;
        int count;
@@ -900,7 +892,7 @@ TEST_F(TDMHwcWindow, GetAvailablePropertiesSuccess)
 /* tdm_hwc_window_video_get_property() */
 TEST_F(TDMHwcWindow, GetPropertyFailNull)
 {
-       SKIP_FLAG(video_hwc_win != NULL);
+       TDM_UT_SKIP_FLAG(video_hwc_win != NULL);
 
        tdm_value value;
        int id = 1;
@@ -914,7 +906,7 @@ TEST_F(TDMHwcWindow, GetPropertyFailNull)
 
 TEST_F(TDMHwcWindow, GetPropertyFailWrongId)
 {
-       SKIP_FLAG(video_hwc_win != NULL);
+       TDM_UT_SKIP_FLAG(video_hwc_win != NULL);
 
        tdm_value value;
        int id = INT_MAX;
@@ -926,7 +918,7 @@ TEST_F(TDMHwcWindow, GetPropertyFailWrongId)
 /* tdm_hwc_window_video_set_property() */
 TEST_F(TDMHwcWindow, SetPropertyFailNull)
 {
-       SKIP_FLAG(video_hwc_win != NULL);
+       TDM_UT_SKIP_FLAG(video_hwc_win != NULL);
        tdm_value value;
        int id = 1;
 
@@ -936,7 +928,7 @@ TEST_F(TDMHwcWindow, SetPropertyFailNull)
 
 TEST_F(TDMHwcWindow, SetPropertyFailWrongId)
 {
-       SKIP_FLAG(video_hwc_win != NULL);
+       TDM_UT_SKIP_FLAG(video_hwc_win != NULL);
 
        tdm_value value;
        int id = INT_MAX;
@@ -945,3 +937,4 @@ TEST_F(TDMHwcWindow, SetPropertyFailWrongId)
        ASSERT_NE(TDM_ERROR_NONE, error);
 }
 
+#endif
index dba3023..a0713be 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
 #include "ut_tdm.h"
-#include <limits.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-
-#include "tdm.h"
-#include "tdm_config.h"
-
-extern "C" {
-#include "tbm_bufmgr.h"
-#include "tbm_drm_helper.h"
-#include "tbm_surface.h"
-#include "tbm_surface_queue.h"
-}
-
-class TDMLayer : public ::testing::Test {
-protected:
-       tdm_display *dpy = NULL;
-       tbm_bufmgr tbm_bufmgr = NULL;
-       int master_fd = -42, tbm_fd = -42, layer_count = 0, output_count = 0;
-       tdm_layer **tdm_layer_array = NULL;
-       tbm_surface_h *tdm_layers_buffer_array = NULL;
-       tbm_surface_queue_h *tdm_layers_buffer_queue_array = NULL;
-       int *tdm_layer_output_idx = NULL;
-       const tdm_output_mode **preferred_mode_array = NULL;
-       bool has_layers = false;
-       virtual void SetEnv()
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1);
-       }
-       void SetUp(void)
-       {
-               const tdm_output_mode *preferred_mode = NULL;
-               tdm_error error = TDM_ERROR_NONE;
-
-               SetEnv();
-
-               /* FIXME: fix the error. If we initialize TBM before TDM we get fail
-                * in the tdm_output_set_dpms */
-#if 0
-               tbm_bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(tbm_bufmgr == NULL);
-#endif
 
-               dpy = tdm_display_init(&error);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               ASSERT_FALSE(dpy == NULL);
+class TDMLayer : public TDMOutput {
+public:
+       bool has_layers;
+       tdm_layer **layers;
+       int layer_count;
 
-               master_fd = tbm_drm_helper_get_master_fd();
-               tbm_fd = tbm_drm_helper_get_fd();
-               ASSERT_TRUE(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE);
+       tbm_surface_h buffers[3];
+       tbm_surface_queue_h buffer_queue;
 
-               preferred_mode_array = (const tdm_output_mode **)calloc(output_count, sizeof(tdm_output_mode *));
-               ASSERT_FALSE(NULL == preferred_mode_array);
-               if (!preferred_mode_array)
-                       return;
+       TDMLayer();
+       void SetUp(void);
+       void TearDown(void);
 
-               for (int i = 0; i < output_count; i++) {
-                       tdm_output *output = tdm_display_get_output(dpy, i, &error);
-                       int output_modes_cnt = 0;
-                       const tdm_output_mode *output_modes;
+       void DestroyBuffers(void);
+};
 
-                       if (TDM_ERROR_NONE != error || NULL == output)
-                               continue;
+TDMLayer::TDMLayer()
+{
+       has_layers = false;
+       layers = NULL;
+       layer_count = TDM_UT_INVALID_VALUE;
 
-                       tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-                       if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status))
-                               continue;
+       for(int b = 0; b < 3; b++)
+               buffers[b] = NULL;
 
-                       if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                               continue;
+       buffer_queue = NULL;
+}
 
-                       error = tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt);
-                       if (TDM_ERROR_NONE != error)
-                               continue;
-                       if (output_modes_cnt <= 0) {
-                               continue;
-                       }
+void TDMLayer::SetUp(void)
+{
+       TDMOutput::SetUp();
 
-                       for(int j = 0; j < output_modes_cnt; j++)
-                               if(output_modes[j].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
-                                       preferred_mode = &output_modes[j];
+       layer_count = 0;
 
-                       if (!preferred_mode)
-                               continue;
+       for (int o = 0; o < output_count; o++) {
+               int old_layer_count = layer_count, count = TDM_UT_INVALID_VALUE;
+               tdm_error ret;
 
-                       int temp_layer_count = 0;
-                       if (TDM_ERROR_NONE != tdm_output_get_layer_count(output, &temp_layer_count))
-                               continue;
-                       if (0 == temp_layer_count)
-                               continue;
-                       tdm_layer_array = (tdm_layer **) realloc(tdm_layer_array,
-                                                                                                        (layer_count + temp_layer_count)*sizeof(tdm_layer *));
+               if (ut_tdm_output_is_hwc_enable(outputs[o]))
+                       continue;
 
-                       ASSERT_FALSE(NULL == tdm_layer_array);
+               ASSERT_TRUE(tdm_output_get_layer_count(outputs[o], &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count > 0);
 
-                       tdm_layer_output_idx = (int *) realloc(tdm_layer_output_idx,
-                                                                                       (layer_count + temp_layer_count)*sizeof(int));
-                       ASSERT_FALSE(NULL == tdm_layer_output_idx);
+               layer_count += count;
+               layers = (tdm_layer**)realloc((void*)layers, sizeof(tdm_layer*) * layer_count);
+               ASSERT_TRUE(layers != NULL);
 
-                       for (int k = layer_count; k < (layer_count + temp_layer_count); k++) {
-                               tdm_layer_array[k] = tdm_output_get_layer(output, k, &error);
-                               tdm_layer_output_idx[k] = i;
-                               ASSERT_TRUE(TDM_ERROR_NONE == error);
-                               ASSERT_FALSE(NULL == tdm_layer_array[k]);
-                       }
-                       layer_count += temp_layer_count;
-                       preferred_mode_array[i] = preferred_mode;
+               for (int l = 0; l < count; l++) {
+                       tdm_layer *layer = tdm_output_get_layer(outputs[o], l, &ret);
+                       ASSERT_TRUE(layer != NULL);
+                       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+                       layers[old_layer_count + l] = layer;
                }
-
-               tdm_layers_buffer_array = (tbm_surface_h *) calloc(layer_count, sizeof(tbm_surface_h));
-               ASSERT_FALSE(NULL == tdm_layers_buffer_array);
-
-               tdm_layers_buffer_queue_array = (tbm_surface_queue_h *) calloc(layer_count, sizeof(tbm_surface_queue_h));
-               ASSERT_FALSE(NULL == tdm_layers_buffer_queue_array);
-
-#ifdef FAIL_ON_UNSUPPORTED
-               ASSERT_GT(layer_count, 0);
-#endif
-               if (layer_count > 0)
-                       has_layers = true;
        }
-       void TearDown(void)
-       {
-               tdm_error error;
 
-               for (int i = 0; i < layer_count; ++i) {
-                       error = tdm_layer_unset_buffer(tdm_layer_array[i]);
-                       EXPECT_TRUE(error == TDM_ERROR_NONE);
+       if (layer_count > 0)
+               has_layers = true;
+}
 
-                       if (tdm_layers_buffer_array[i])
-                               tbm_surface_destroy(tdm_layers_buffer_array[i]);
+void TDMLayer::TearDown(void)
+{
+       free(layers);
 
-                       if (tdm_layers_buffer_queue_array[i])
-                               tbm_surface_queue_destroy(tdm_layers_buffer_queue_array[i]);
+       DestroyBuffers();
 
-                       tdm_layers_buffer_array[i] = NULL;
-                       tdm_layers_buffer_queue_array[i] = NULL;
-               }
+       TDMOutput::TearDown();
+}
 
-               tdm_display_deinit(dpy);
-               dpy = NULL;
-               tbm_bufmgr_deinit(tbm_bufmgr);
-               tbm_bufmgr = NULL;
-               if (tdm_layer_array)
-                       free(tdm_layer_array);
-               if (tdm_layer_output_idx)
-                       free(tdm_layer_output_idx);
-               if (preferred_mode_array)
-                       free(preferred_mode_array);
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_master_fd > -1)
-                               exit(1);
-                       close(master_fd);
-               }
-               if (tbm_fd > -1) {
-                       int temp_tbm_fd = tbm_drm_helper_get_fd();
-                       EXPECT_EQ(temp_tbm_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_tbm_fd > -1)
-                               exit(1);
-                       close(tbm_fd);
+void TDMLayer::DestroyBuffers(void)
+{
+       for(int b = 0; b < 3; b++) {
+               if (buffers[b]) {
+                       tbm_surface_destroy(buffers[b]);
+                       buffers[b] = NULL;
                }
+       }
 
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
+       if (buffer_queue) {
+               tbm_surface_queue_destroy(buffer_queue);
+               buffer_queue = NULL;
        }
+}
 
-       tbm_surface_h UtCreateBufferForLayer(int layer_idx, int width, int height,
-                                                                                int format, int flags)
-       {
-               tbm_surface_h buffer;
+bool
+ut_tdm_layer_is_cursor_layer(tdm_layer *layer)
+{
+       tdm_layer_capability capabilities = (tdm_layer_capability)TDM_UT_INVALID_VALUE;
+       if (tdm_layer_get_capabilities(layer, &capabilities) != TDM_ERROR_NONE)
+               return false;
+       return capabilities & TDM_LAYER_CAPABILITY_CURSOR;
+}
 
-               buffer = tbm_surface_internal_create_with_flags(width, height, format, flags);
+bool
+ut_tdm_layer_is_primary_layer(tdm_layer *layer)
+{
+       tdm_layer_capability capabilities = (tdm_layer_capability)TDM_UT_INVALID_VALUE;
+       if (tdm_layer_get_capabilities(layer, &capabilities) != TDM_ERROR_NONE)
+               return false;
+       return capabilities & TDM_LAYER_CAPABILITY_PRIMARY;
+}
 
-               tdm_layers_buffer_array[layer_idx] = buffer;
+bool
+ut_tdm_layer_is_video_layer(tdm_layer *layer)
+{
+       tdm_layer_capability capabilities = (tdm_layer_capability)TDM_UT_INVALID_VALUE;
+       if (tdm_layer_get_capabilities(layer, &capabilities) != TDM_ERROR_NONE)
+               return false;
+       return capabilities & TDM_LAYER_CAPABILITY_VIDEO;
+}
 
-               return buffer;
-       }
+unsigned int
+ut_tdm_layer_get_output_pipe(tdm_layer *layer)
+{
+       unsigned int pipe = (unsigned int)TDM_UT_INVALID_VALUE;
+       tdm_error ret;
+       tdm_output *output = tdm_layer_get_output(layer, &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-       tbm_surface_queue_h UtCreateBufferQueueForLayer(int layer_idx, int width, int height,
-                                                                                int format, int flags)
-       {
-               tbm_surface_queue_h buffer_queue;
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(pipe != (unsigned int)TDM_UT_INVALID_VALUE);
 
-               buffer_queue = tbm_surface_queue_create(2, width, height, format, flags);
+       return pipe;
+}
 
-               tdm_layers_buffer_queue_array[layer_idx] = buffer_queue;
+tbm_format
+ut_tdm_layer_find_best_format(tdm_layer *layer)
+{
+       const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
+       int count = TDM_UT_INVALID_VALUE;
+       tdm_error ret;
+       ret = tdm_layer_get_available_formats(layer, &formats, &count);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
 
-               return buffer_queue;
-       }
-};
+       for (int f = 0; f < count; f++)
+               if (formats[f] == TBM_FORMAT_ARGB8888)
+                       return TBM_FORMAT_ARGB8888;
+       for (int f = 0; f < count; f++)
+               if (formats[f] == TBM_FORMAT_XRGB8888)
+                       return TBM_FORMAT_XRGB8888;
+       for (int f = 0; f < count; f++)
+               if (formats[f] == TBM_FORMAT_YUV420)
+                       return TBM_FORMAT_YUV420;
+       for (int f = 0; f < count; f++)
+               if (formats[f] == TBM_FORMAT_NV12)
+                       return TBM_FORMAT_NV12;
 
-class TDMLayerCommit : public TDMLayer
-{
-private:
-       int epFd = -1;
-       int timerFd = -1;
-       int tdmFd = -1;
-       static const int timeLimitSec = 0;
-       static const int timeLimitNsec = 100000000;
-
-protected:
-       static int utLayerCommitHandlerCounter;
-       static void UtLayerCommitHandler(tdm_layer *layer, unsigned int sequence,
-                                                                        unsigned int tv_sec, unsigned int tv_usec,
-                                                                        void *user_data)
-       {
-               int *data = (int *)user_data;
-               if (data)
-                       (*data)++;
-
-               utLayerCommitHandlerCounter++;
-       }
+       return 0;
+}
 
-       void SetUp(void)
-       {
-               tdm_error error;
-               tdm_output *output;
-               struct epoll_event ep;
+bool
+ut_tdm_layer_prepare_buffer(tdm_layer *layer, tbm_surface_h *buffers, int buffer_count)
+{
+       tdm_error ret;
+       unsigned int flags = 0;
+       tbm_format format = (tbm_format)0;
+       int w, h;
 
-               utLayerCommitHandlerCounter = 0;
+       /* create buffers */
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_buffer_flags(layer, &flags) == TDM_ERROR_NONE);
 
-               ASSERT_NO_FATAL_FAILURE(TDMLayer::SetUp());
+       format = ut_tdm_layer_find_best_format(layer);
+       TDM_UT_RETURN_FALSE_IF_FAIL(format != 0);
 
-               for (int i = 0; i < output_count; ++i) {
-                       if (!preferred_mode_array[i])
-                               continue;
+       if (ut_tdm_layer_is_primary_layer(layer)) {
+               tdm_output *output;
+               const tdm_output_mode *mode = NULL;
 
-                       output = tdm_display_get_output(dpy, i, &error);
-                       ASSERT_FALSE(output == NULL);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               output = tdm_layer_get_output(layer, &ret);
+               TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-                       error = tdm_output_set_mode(output, preferred_mode_array[i]);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_mode(output, &mode) == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(mode != NULL);
 
-                       error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-               }
+               w = mode->hdisplay;
+               h = mode->vdisplay;
+       } else {
+               w = TDM_UT_BUFFER_SIZE;
+               h = TDM_UT_BUFFER_SIZE;
+       }
 
-               epFd = epoll_create1(0);
-               ASSERT_TRUE(epFd != -1);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(w, h, format, flags | TBM_BO_SCANOUT, true, buffer_count, buffers) == true);
 
-               timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
-               ASSERT_TRUE(timerFd != -1);
+       TDM_INFO("preparing buffers done");
 
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = timerFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
+       return true;
+}
 
-               ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
+bool
+ut_tdm_layer_prepare_buffer_queue(tdm_layer *layer, tbm_surface_queue_h *buffer_queue)
+{
+       tdm_error ret;
+       unsigned int flags = 0;
+       tbm_format format = (tbm_format)0;
+       int w, h;
 
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = tdmFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
-       }
+       /* create buffers */
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_buffer_flags(layer, &flags) == TDM_ERROR_NONE);
 
-       void TearDown(void)
-       {
+       format = ut_tdm_layer_find_best_format(layer);
+       TDM_UT_RETURN_FALSE_IF_FAIL(format != (tbm_format)0);
+
+       if (ut_tdm_layer_is_primary_layer(layer)) {
                tdm_output *output;
-               tdm_error error;
+               const tdm_output_mode *mode = NULL;
+               output = tdm_layer_get_output(layer, &ret);
+               TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
+
+               TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_mode(output, &mode) == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(mode != NULL);
+
+               w = mode->hdisplay;
+               h = mode->vdisplay;
+       } else {
+               w = TDM_UT_BUFFER_SIZE;
+               h = TDM_UT_BUFFER_SIZE;
+       }
 
-               for (int i = 0; i < output_count; ++i) {
-                       if (!preferred_mode_array[i])
-                               continue;
+       *buffer_queue = tbm_surface_queue_create(2, w, h, format, flags | TBM_BO_SCANOUT);
+       TDM_UT_RETURN_FALSE_IF_FAIL((*buffer_queue) != NULL);
 
-                       output = tdm_display_get_output(dpy, i, &error);
-                       EXPECT_FALSE(output == NULL);
-                       EXPECT_TRUE(error == TDM_ERROR_NONE);
+       TDM_INFO("preparing buffers done");
 
-                       error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
-                       EXPECT_TRUE(error == TDM_ERROR_NONE);
-               }
-
-               TDMLayer::TearDown();
-       }
+       return true;
+}
 
-       void UtHandleCommitEvent(int num_waiting_layers)
-       {
-               struct itimerspec its;
-               int count;
-               struct epoll_event ep_event[2];
+bool
+ut_tdm_layer_fill_info(tdm_layer *layer, int w, int h, tbm_format format, tdm_info_layer *info)
+{
+       tdm_error ret;
+       tdm_output *output;
+       const tdm_output_mode *mode = NULL;
+       int count = 0;
+       int zpos = -1;
+       unsigned int pipe = 0;
 
-               if (utLayerCommitHandlerCounter == num_waiting_layers)
-                       return;
+       output = tdm_layer_get_output(layer, &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-               its.it_interval.tv_sec = 0;
-               its.it_interval.tv_nsec = 0;
-               its.it_value.tv_sec = timeLimitSec;
-               its.it_value.tv_nsec = timeLimitNsec;
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_mode(output, &mode) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(mode != NULL);
 
-               ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(count > 0);
 
-               while (1) {
-                       count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
-                       ASSERT_TRUE(count >= 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(layer, &zpos) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(zpos >= 0);
 
-                       for (int i = 0; i < count; i++) {
-                               if (ep_event[i].data.fd == timerFd) {
-                                       return;
-                               } else {
-                                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
-                                       if (utLayerCommitHandlerCounter == num_waiting_layers)
-                                               return;
-                               }
-                       }
-               }
+       if (w == -1 || h == -1 || format == 0) {
+               w = TDM_UT_BUFFER_SIZE;
+               h = TDM_UT_BUFFER_SIZE;
+               format = TBM_FORMAT_ARGB8888;
        }
-};
 
-class TDMLayerCommitThread : public TDMLayerCommit
-{
-protected:
-       void SetEnv()
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1);
+       /* TODO: check min,max,prefered size and avaiable formats */
+       memset(info, 0, sizeof *info);
+       info->src_config.size.h = w;
+       info->src_config.size.v = h;
+       info->src_config.pos.x = 0;
+       info->src_config.pos.y = 0;
+       info->src_config.pos.w = w;
+       info->src_config.pos.h = h;
+       info->src_config.format = format;
+       if (ut_tdm_layer_is_primary_layer(layer)) {
+               info->dst_pos.x = 0;
+               info->dst_pos.y = 0;
+       } else {
+               info->dst_pos.x = (mode->hdisplay - w) / count * zpos;
+               info->dst_pos.y = (mode->vdisplay - h) / count * zpos;
        }
-};
+       info->dst_pos.w = w;
+       info->dst_pos.h = h;
+       info->transform = TDM_TRANSFORM_NORMAL;
 
-class TDMLayerCommitWithDisabledCommitPerVblank : public TDMLayerCommit
-{
-protected:
-       void SetEnv()
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-       }
-};
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE);
 
-int TDMLayerCommit::utLayerCommitHandlerCounter = 0;
+       TDM_INFO("filling output(%d) layer(%d) info done: src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_pos(%d,%d %dx%d) transform(%s)",
+                        pipe, zpos,
+                        info->src_config.size.h, info->src_config.size.h,
+                        info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h,
+                        FOURCC_STR(info->src_config.format),
+                        info->dst_pos.x, info->dst_pos.y, info->dst_pos.w, info->dst_pos.h,
+                        tdm_transform_str(info->transform));
 
-TEST_F(TDMLayer, LayerGetCapabilitiesSuccessful)
-{
-       SKIP_FLAG(has_layers);
-       for (int i = 0; i < layer_count; i++) {
-               tdm_layer_capability capabilities = (tdm_layer_capability) -42;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_layer_get_capabilities(tdm_layer_array[i], &capabilities));
-               ASSERT_NE(capabilities, -42);
-       }
+       return true;
 }
 
-TEST_F(TDMLayer, LayerGetCapabilitiesFailNullAll)
-{
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_layer_get_capabilities(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+#ifdef UT_TDM_LAYER_ENABLE
 
-TEST_F(TDMLayer, LayerGetCapabilitiesFailOnlyLayer)
+TEST_P(TDMLayer, LayerGetOutput)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({for (int i = 0; i < layer_count; i++) {
-                                        if (tdm_layer_get_capabilities(tdm_layer_array[i], NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_layers);
 
-TEST_F(TDMLayer, OutputGetPrimaryIndexSuccessful)
-{
-       SKIP_FLAG(has_layers);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int index = -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_primary_index(output, &index));
-               ASSERT_NE(index, -42);
+       for (int l = 0; l < layer_count; l++) {
+               tdm_error ret;
+               tdm_output *output = tdm_layer_get_output(layers[l], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
        }
 }
 
-TEST_F(TDMLayer, OutputGetPrimaryIndexFailNullAll)
+TEST_P(TDMLayer, LayerGetOutputNullObject)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_output_get_primary_index(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_layers);
 
-TEST_F(TDMLayer, OutputGetPrimaryIndexFailOnlyOutput)
-{
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_primary_index(output, NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       tdm_error ret;
+       tdm_output *output = tdm_layer_get_output(NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(output == NULL);
 }
 
-/* tdm_layer_get_available_formats() */
-
-TEST_F(TDMLayer, LayerGetAvailableFormatsFailNullAll)
+TEST_P(TDMLayer, LayerGetOutputNullParam)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_layer_get_available_formats(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_layers);
+
+       for (int l = 0; l < layer_count; l++) {
+               tdm_output *output = tdm_layer_get_output(layers[l], NULL);
+               ASSERT_TRUE(output != NULL);
+       }
 }
 
-TEST_F(TDMLayer, LayerGetAvailableFormatsFailNullLayer)
+TEST_P(TDMLayer, LayerGetCapabilities)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({const tbm_format *formats;
-                                int count;
-                                if (tdm_layer_get_available_formats(NULL, &formats, &count) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_layers);
+
+       for (int l = 0; l < layer_count; l++) {
+               tdm_layer_capability capabilities = (tdm_layer_capability)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_layer_get_capabilities(layers[l], &capabilities) == TDM_ERROR_NONE);
+               ASSERT_TRUE(capabilities != TDM_UT_INVALID_VALUE);
+       }
 }
 
-TEST_F(TDMLayer, LayerGetAvailableFormatsFailNullFormats)
+TEST_P(TDMLayer, LayerGetCapabilitiesNullObject)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({int count;
-                                for (int i = 0; i < layer_count; i++) {
-                                        if (tdm_layer_get_available_formats(tdm_layer_array[i], NULL, &count) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_layers);
+
+       tdm_layer_capability capabilities = (tdm_layer_capability)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_get_capabilities(NULL, &capabilities) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(capabilities == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMLayer, LayerGetAvailableFormatsFailNullCount)
+TEST_P(TDMLayer, LayerGetCapabilitiesNullOther)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({const tbm_format *formats;
-                                for (int i = 0; i < layer_count; i++) {
-                                        if (tdm_layer_get_available_formats(tdm_layer_array[i], &formats, NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_layers);
+       ASSERT_TRUE(tdm_layer_get_capabilities(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer, LayerGetAvailableFormatsSuccess)
+TEST_P(TDMLayer, LayerGetAvailableFormats)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       const tbm_format *formats;
-       int count;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_get_available_formats(tdm_layer_array[i], &formats, &count);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               ASSERT_NE(NULL, formats);
-               ASSERT_NE(0, count);
+       for (int l = 0; l < layer_count; l++) {
+               const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
+               int count = TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_layer_get_available_formats(layers[l], &formats, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(formats != NULL);
+               ASSERT_TRUE(count > 0);
        }
 }
 
-/* tdm_layer_get_available_properties() */
-
-TEST_F(TDMLayer, LayerGetAvailablePropertiesFailNullAll)
+TEST_P(TDMLayer, LayerGetAvailableFormatsNullObject)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_layer_get_available_properties(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_layers);
 
-TEST_F(TDMLayer, LayerGetAvailablePropertiesFailNullLayer)
-{
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({const tdm_prop *props;
-                                int count;
-                                if (tdm_layer_get_available_properties(NULL, &props, &count) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
+       int count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_get_available_formats(NULL, &formats, &count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(formats == (const tbm_format *)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMLayer, LayerGetAvailablePropertiesFailNullFormats)
+TEST_P(TDMLayer, LayerGetAvailableFormatsNullOther)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({int count;
-                                for (int i = 0; i < layer_count; i++) {
-                                        if (tdm_layer_get_available_properties(tdm_layer_array[i], NULL, &count) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_layers);
 
-TEST_F(TDMLayer, LayerGetAvailablePropertiesFailNullCount)
-{
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({const tdm_prop *props;
-                                for (int i = 0; i < layer_count; i++) {
-                                        if (tdm_layer_get_available_properties(tdm_layer_array[i], &props, NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_layer_get_available_formats(layers[0], NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer, LayerGetAvailablePropertiesSuccess)
+TEST_P(TDMLayer, LayerGetAvailableProperties)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       const tdm_prop *props;
-       int count;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_get_available_properties(tdm_layer_array[i], &props, &count);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+               int count = TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_layer_get_available_properties(layers[l], &props, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count >= 0);
+               if (count > 0)
+                       ASSERT_TRUE(props != NULL && props != (const tdm_prop *)TDM_UT_INVALID_VALUE);
        }
 }
 
-/* tdm_layer_get_zpos() */
-
-TEST_F(TDMLayer, LayerGetZposFailNullAll)
+TEST_P(TDMLayer, LayerGetAvailablePropertiesNullObject)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_layer_get_zpos(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_layers);
 
-TEST_F(TDMLayer,  LayerGetZposFailNullLayer)
-{
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({int zpos;
-                                if (tdm_layer_get_zpos(NULL, &zpos) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+       int count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_get_available_properties(NULL, &props, &count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(props == (const tdm_prop *)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMLayer, LayerGetZposFailNullZpos)
+TEST_P(TDMLayer, LayerGetAvailablePropertiesNullOther)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({for (int i = 0; i < layer_count; i++) {
-                                        if (tdm_layer_get_zpos(tdm_layer_array[i], NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMLayer, LayerGetZposSuccess)
-{
-       SKIP_FLAG(has_layers);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               int zpos = INT_MIN;
-               error = tdm_layer_get_zpos(tdm_layer_array[i], &zpos);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               ASSERT_NE(INT_MIN, zpos);
-       }
+       ASSERT_TRUE(tdm_layer_get_available_properties(layers[0], NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-/* tdm_layer_set_property() */
-
-TEST_F(TDMLayer,  LayerSetPropertyFailNullLayer)
+TEST_P(TDMLayer, LayerGetZpos)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({tdm_value value;
-                                int id = INT_MAX;
-                                if (tdm_layer_set_property(NULL, id, value) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_layers);
 
-TEST_F(TDMLayer,  LayerSetPropertyFailWrongId)
-{
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tdm_value value;
-       int id = INT_MAX;
+       bool *check_table = (bool*)calloc(layer_count, output_count);
+       ASSERT_TRUE(check_table != NULL);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_set_property(tdm_layer_array[i], id, value);
-               ASSERT_NE(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               unsigned int pipe = ut_tdm_layer_get_output_pipe(layers[l]);
+               int zpos = TDM_UT_INVALID_VALUE;
+               EXPECT_TRUE(tdm_layer_get_zpos(layers[l], &zpos) == TDM_ERROR_NONE);
+               EXPECT_TRUE(zpos != TDM_UT_INVALID_VALUE);
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
+               EXPECT_TRUE(zpos >= 0);
+               EXPECT_TRUE(pipe < (unsigned int)output_count);
+               EXPECT_TRUE(*(check_table + pipe * layer_count + zpos) == false);
+               *(check_table + pipe * layer_count + zpos) = true;
        }
-}
 
-/* tdm_layer_get_property() */
-
-TEST_F(TDMLayer,  LayerGetPropertyFailNullLayer)
-{
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({tdm_value value;
-                                int id = INT_MAX;
-                                if (tdm_layer_get_property(NULL, id, &value) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       free(check_table);
 }
 
-TEST_F(TDMLayer,  LayerGetPropertyFailNullValue)
+TEST_P(TDMLayer, LayerGetZposNullObject)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({int id = INT_MAX;
-                                for (int i = 0; i < layer_count; ++i) {
-                                       if (tdm_layer_get_property(tdm_layer_array[i], id, NULL) == TDM_ERROR_NONE) exit(1);
-                                }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMLayer,  LayerGetPropertyFailWrongId)
-{
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tdm_value value;
-       int id = INT_MAX;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_get_property(tdm_layer_array[i], id, &value);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
+       int zpos = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_get_zpos(NULL, &zpos) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(zpos == TDM_UT_INVALID_VALUE);
 }
 
-/* tdm_layer_set_info() */
-
-TEST_F(TDMLayer,  LayerSetInfoFailNullAll)
+TEST_P(TDMLayer, LayerGetZposNullParam)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_layer_set_info(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_layers);
+
+       ASSERT_TRUE(tdm_layer_get_zpos(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer,  LayerSetInfoFailNullLayer)
+TEST_P(TDMLayer, LayerSetProperty)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({tdm_info_layer info = {0};
-                                if (tdm_layer_set_info(NULL, &info) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       for (int l = 0; l < layer_count; l++) {
+               const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+               int count = TDM_UT_INVALID_VALUE;
+               tdm_value value = {.s32 = 0};
 
-TEST_F(TDMLayer,  LayerSetInfoFailNullInfo)
-{
-       SKIP_FLAG(has_layers);
+               ASSERT_TRUE(tdm_layer_get_available_properties(layers[l], &props, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count >= 0);
 
-       ASSERT_EXIT({for (int i = 0; i < layer_count; ++i)
-                                       if (tdm_layer_set_info(tdm_layer_array[i], NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+               if (count > 0)
+                       ASSERT_TRUE(tdm_layer_set_property(layers[l], props[0].id, value) == TDM_ERROR_NONE);
+       }
 }
 
-tdm_error
-_ut_tdm_layer_set_info(tdm_layer *layer, int w, int h)
+TEST_P(TDMLayer, LayerSetPropertyNullObject)
 {
-       tdm_info_layer info = {0};
-
-       info.src_config.size.h = w;
-       info.src_config.size.v = h;
-       info.src_config.pos.x = 0;
-       info.src_config.pos.y = 0;
-       info.src_config.pos.w = w;
-       info.src_config.pos.h = h;
-       info.src_config.format = TBM_FORMAT_ARGB8888;
-       info.dst_pos.x = 0;
-       info.dst_pos.y = 0;
-       info.dst_pos.w = w;
-       info.dst_pos.h = h;
-       info.transform = TDM_TRANSFORM_NORMAL;
+       tdm_value value = {.s32 = 0};
 
-       return tdm_layer_set_info(layer, &info);
+       ASSERT_TRUE(tdm_layer_set_property(NULL, 0, value) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer,  LayerSetInfoSuccess)
+TEST_P(TDMLayer, LayerGetProperty)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], 128, 128);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+               int count = TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_layer_get_available_properties(layers[l], &props, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count >= 0);
+               if (count > 0) {
+                       ASSERT_TRUE(props != NULL && props != (const tdm_prop *)TDM_UT_INVALID_VALUE);
+
+                       for (int i = 0; i < count; i++) {
+                               tdm_value value = {.s32 = TDM_UT_INVALID_VALUE};
+                               ASSERT_TRUE(tdm_layer_get_property(layers[l], props[i].id, &value) == TDM_ERROR_NONE);
+                               ASSERT_TRUE(value.s32 != TDM_UT_INVALID_VALUE);
+                       }
+               }
        }
 }
 
-/* tdm_layer_get_info() */
-
-TEST_F(TDMLayer,  LayerGetInfoFailNullAll)
+TEST_P(TDMLayer, LayerGetPropertyNullObject)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_layer_get_info(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_layers);
+
+       tdm_value value = {.s32 = TDM_UT_INVALID_VALUE};
+       ASSERT_TRUE(tdm_layer_get_property(NULL, 0, &value) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(value.s32 == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMLayer,  LayerGetInfoFailNullLayer)
+TEST_P(TDMLayer, LayerGetPropertyNullOther)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({tdm_info_layer info = {0};
-                                if (tdm_layer_get_info(NULL, &info) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_layer_get_property(layers[0], 0, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer,  LayerGetInfoFailNullInfo)
+static bool
+_ut_tdm_layer_mode_setting_all_output(tdm_display *dpy, tdm_output **outputs, int output_count)
 {
-       SKIP_FLAG(has_layers);
-
-       ASSERT_EXIT({for (int i = 0; i < layer_count; ++i)
-                                       if (tdm_layer_get_info(tdm_layer_array[i], NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_mode_setting(outputs[o]))
+                       return false;
+               if (tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) != TDM_ERROR_NONE)
+                       return false;
+       }
+       return true;
 }
 
-TEST_F(TDMLayer,  LayerGetInfoSuccess)
+TEST_P(TDMLayer, LayerSetInfo)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tdm_info_layer set_info = {0};
-       tdm_info_layer ret_info = {0};
-
-       set_info.src_config.size.h = 128;
-       set_info.src_config.size.v = 128;
-       set_info.src_config.pos.x = 0;
-       set_info.src_config.pos.y = 0;
-       set_info.src_config.pos.w = 128;
-       set_info.src_config.pos.h = 128;
-       set_info.src_config.format = TBM_FORMAT_ARGB8888;
-       set_info.dst_pos.x = 0;
-       set_info.dst_pos.y = 0;
-       set_info.dst_pos.w = 128;
-       set_info.dst_pos.h = 128;
-       set_info.transform = TDM_TRANSFORM_NORMAL;
-
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_get_info(tdm_layer_array[i], &set_info);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = tdm_layer_get_info(tdm_layer_array[i], &ret_info);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               ASSERT_TRUE(!memcmp(&ret_info, &set_info, sizeof(tdm_info_layer)));
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], -1, -1, 0, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
        }
 }
 
-/* tdm_layer_set_buffer() */
-
-TEST_F(TDMLayer, LayerSetBufferFailNullAll)
+TEST_P(TDMLayer, LayerSetInfoNullObject)
 {
-       SKIP_FLAG(has_layers);
-       ASSERT_EXIT({if (tdm_layer_set_buffer(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_layers);
 
-TEST_F(TDMLayer, LayerSetBufferFailNullLayer)
-{
-       SKIP_FLAG(has_layers);
-
-       ASSERT_EXIT({tdm_error error;
-                                tbm_surface_h buffer = UtCreateBufferForLayer(0, 128, 128, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-                                if (!buffer) exit(1);
-                                error = tdm_layer_set_buffer(NULL, buffer);
-                                if (error == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       tdm_info_layer info;
+       memset(&info, 0, sizeof info);
+       ASSERT_TRUE(tdm_layer_set_info(NULL, &info) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer, LayerSetBufferFailNullBuffer)
+TEST_P(TDMLayer, LayerSetInfoNullOther)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({for (int i = 0; i < layer_count; ++i)
-                                       if (tdm_layer_set_buffer(tdm_layer_array[i], NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_layer_set_info(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer, LayerSetBufferSuccess)
+TEST_P(TDMLayer, LayerGetInfo)
 {
-       SKIP_FLAG(has_layers);
-       tbm_surface_h buffer;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               buffer = UtCreateBufferForLayer(i, 128, 128, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info, temp;
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], -1, -1, 0, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_commit(layers[l], NULL, NULL) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_get_info(layers[l], &temp) == TDM_ERROR_NONE);
+               ASSERT_TRUE(memcmp(&info, &temp, sizeof info) == 0);
        }
 }
 
-TEST_F(TDMLayer, LayerSetBufferSuccessTwice)
+TEST_P(TDMLayer, LayerGetInfoNoCommit)
 {
-       SKIP_FLAG(has_layers);
-       tbm_surface_h buffer;
-       tdm_error error;
-
-       for (int i = 0; i < layer_count; ++i) {
-               buffer = UtCreateBufferForLayer(i, 128, 128, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info, temp;
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], -1, -1, 0, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_get_info(layers[l], &temp) == TDM_ERROR_NONE);
+               ASSERT_TRUE(memcmp(&info, &temp, sizeof info) != 0);
        }
 }
 
-/* tdm_layer_unset_buffer() */
-
-TEST_F(TDMLayer, LayerUnsetBufferFailNullLayer)
+TEST_P(TDMLayer, LayerGetInfoNullObject)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
+
+       tdm_info_layer temp;
 
-       ASSERT_EXIT({tdm_error error;
-                                error = tdm_layer_unset_buffer(NULL);
-                                if (error == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_layer_get_info(NULL, &temp) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer, LayerUnsetBufferSuccess)
+TEST_P(TDMLayer, LayerGetInfoNullParam)
 {
-       SKIP_FLAG(has_layers);
-       tbm_surface_h buffer;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               buffer = UtCreateBufferForLayer(i, 128, 128, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+       ASSERT_TRUE(tdm_layer_get_info(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+TEST_P(TDMLayer, LayerGetBufferFlags)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = tdm_layer_unset_buffer(tdm_layer_array[i]);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               unsigned int flags = (unsigned int)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_layer_get_buffer_flags(layers[l], &flags) == TDM_ERROR_NONE);
+               ASSERT_TRUE(flags != (unsigned int)TDM_UT_INVALID_VALUE);
        }
 }
 
-/* tdm_layer_commit() */
-
-TEST_F(TDMLayer, LayerCommitFailNullAll)
+TEST_P(TDMLayer, LayerGetBufferFlagsNullObject)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({tdm_error error;
-                                error = tdm_layer_commit(NULL, NULL, NULL);
-                                if (error == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       unsigned int flags = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_get_buffer_flags(NULL, &flags) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(flags == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMLayer, LayerCommitFailDpmsOff)
+TEST_P(TDMLayer, LayerGetBufferFlagsNullOther)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_commit(tdm_layer_array[i], NULL, NULL);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
+       ASSERT_TRUE(tdm_layer_get_buffer_flags(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayerCommit, LayerCommitSuccess)
+static void
+_ut_tdm_layer_commit_cb(tdm_layer *layer, unsigned int sequence,
+                                               unsigned int tv_sec, unsigned int tv_usec,
+                                               void *user_data)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
-
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
-
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
-
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
-
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
-
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
-
-       UtHandleCommitEvent(layer_count);
-
-       ASSERT_EQ(layer_count, utLayerCommitHandlerCounter);
-       ASSERT_EQ(layer_count, data);
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
 }
 
-TEST_F(TDMLayerCommitThread, LayerCommitSuccess)
+TEST_P(TDMLayer, LayerSetBuffer)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       tdm_error ret;
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               unsigned int usable;
+               tdm_info_layer info;
+               int next_buffer = 0;
+               bool done;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
-
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
+
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+
+               ASSERT_TRUE(tdm_layer_is_usable(layers[l], &usable) == TDM_ERROR_NONE);
+               ASSERT_TRUE(usable == 1);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_is_usable(layers[l], &usable) == TDM_ERROR_NONE);
+               ASSERT_TRUE(usable == 0);
+
+               /* set buffer & commit for 100 times */
+               for (int t = 0; t < 100; t++) {
+                       tbm_surface_h displaying_buffer;
+                       ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer]) == TDM_ERROR_NONE);
+                       done = false;
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done) == TDM_ERROR_NONE);
+                       while (!done)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       displaying_buffer = tdm_layer_get_displaying_buffer(layers[l], &ret);
+                       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+                       ASSERT_TRUE(displaying_buffer == buffers[next_buffer]);
+                       next_buffer++;
+                       if (next_buffer == 3)
+                               next_buffer = 0;
+               }
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_is_usable(layers[l], &usable) == TDM_ERROR_NONE);
+               ASSERT_TRUE(usable == 0);
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_is_usable(layers[l], &usable) == TDM_ERROR_NONE);
+               ASSERT_TRUE(usable == 1);
 
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               DestroyBuffers();
        }
-
-       UtHandleCommitEvent(layer_count);
-
-       ASSERT_EQ(layer_count, utLayerCommitHandlerCounter);
-       ASSERT_EQ(layer_count, data);
 }
 
-TEST_F(TDMLayerCommit, LayerCommitSuccessOnlyPrimaryLayers)
+TEST_P(TDMLayer, LayerSetBufferFewTimeInOneCommit)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
-       int num_waiting_layers = 0;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       tdm_error ret;
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               int next_buffer = 0;
+               bool done;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY))
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
                        continue;
 
-               num_waiting_layers++;
-
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
+
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
+
+               /* set buffer & commit for 10 times */
+               for (int t = 0; t < 10; t++) {
+                       tbm_surface_h displaying_buffer;
+                       ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+                       if (next_buffer == 3)
+                               next_buffer = 0;
+                       ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer]) == TDM_ERROR_NONE);
+                       done = false;
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done) == TDM_ERROR_NONE);
+                       while (!done) {
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       }
+                       displaying_buffer = tdm_layer_get_displaying_buffer(layers[l], &ret);
+                       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+                       ASSERT_TRUE(displaying_buffer == buffers[next_buffer]);
+                       next_buffer++;
+                       if (next_buffer == 3)
+                               next_buffer = 0;
+               }
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
 
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               DestroyBuffers();
        }
-
-       UtHandleCommitEvent(num_waiting_layers);
-
-       ASSERT_EQ(num_waiting_layers, utLayerCommitHandlerCounter);
-       ASSERT_EQ(num_waiting_layers, data);
 }
 
-TEST_F(TDMLayerCommitThread, LayerCommitSuccessOnlyPrimaryLayers)
+TEST_P(TDMLayer, LayerSetBufferNullObject)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
-       int num_waiting_layers = 0;
-
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
-
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY))
-                       continue;
+       tbm_surface_h buffer = (tbm_surface_h)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_set_buffer(NULL, buffer) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-               num_waiting_layers++;
+TEST_P(TDMLayer, LayerSetBufferNullOther)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_layer_set_buffer(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+TEST_P(TDMLayer, LayerUnsetBuffer)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+       for (int l = 0; l < layer_count; l++)
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
+}
 
-       UtHandleCommitEvent(num_waiting_layers);
+TEST_P(TDMLayer, LayerUnsetBufferNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EQ(num_waiting_layers, utLayerCommitHandlerCounter);
-       ASSERT_EQ(num_waiting_layers, data);
+       ASSERT_TRUE(tdm_layer_unset_buffer(NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayerCommitWithDisabledCommitPerVblank, LayerCommitSuccess)
+TEST_P(TDMLayer, LayerUnsetBufferBeforeCommit)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               int next_buffer = 0;
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
+
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
+
+               /* set buffer & commit for 10 times */
+               for (int t = 0; t < 10; t++) {
+                       ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+                       if (next_buffer == 3)
+                               next_buffer = 0;
+                       ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+                       if (next_buffer == 3)
+                               next_buffer = 0;
                }
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               DestroyBuffers();
        }
-
-       UtHandleCommitEvent(layer_count);
-
-       ASSERT_EQ(layer_count, utLayerCommitHandlerCounter);
-       ASSERT_EQ(layer_count, data);
 }
 
-TEST_F(TDMLayerCommitWithDisabledCommitPerVblank, LayerCommitSuccessOnlyPrimaryLayers)
+TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommit)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
-       int num_waiting_layers = 0;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               int next_buffer = 0;
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY))
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
                        continue;
 
-               num_waiting_layers++;
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
 
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               DestroyBuffers();
        }
-
-       UtHandleCommitEvent(num_waiting_layers);
-
-       ASSERT_EQ(num_waiting_layers, utLayerCommitHandlerCounter);
-       ASSERT_EQ(num_waiting_layers, data);
 }
 
-TEST_F(TDMLayerCommit, LayerCommitSuccessUnsetAfterCommit)
+TEST_P(TDMLayer, LayerUnsetBufferAfterTwoCommit)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               int next_buffer = 0;
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_NONE);
 
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_unset_buffer(tdm_layer_array[i]);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               DestroyBuffers();
        }
-
-       UtHandleCommitEvent(layer_count);
-       ASSERT_EQ(0, utLayerCommitHandlerCounter);
-       ASSERT_EQ(0, data);
 }
 
-TEST_F(TDMLayerCommit, LayerCommitSuccessUnsetBeforeCommit_2)
+TEST_P(TDMLayer, LayerUnsetBufferAfterTwoCommitOneSetBuffer)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               int next_buffer = 0;
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_NONE);
 
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer]) == TDM_ERROR_NONE);
 
-       UtHandleCommitEvent(layer_count);
-       ASSERT_EQ(layer_count, utLayerCommitHandlerCounter);
-       ASSERT_EQ(layer_count, data);
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_unset_buffer(tdm_layer_array[i]);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               DestroyBuffers();
        }
 }
 
-/* tdm_layer_is_committing() */
-
-TEST_F(TDMLayer, LayerIsCommittingFailNullAll)
+TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommitOneDone)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({tdm_error error;
-                                error = tdm_layer_is_committing(NULL, NULL);
-                                if (error == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-TEST_F(TDMLayer, LayerIsCommittingFailNullLayer)
-{
-       SKIP_FLAG(has_layers);
-       unsigned int committing;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               int next_buffer = 0;
+               bool done;
 
-       ASSERT_EXIT({tdm_error error;
-                                error = tdm_layer_is_committing(NULL, &committing);
-                                if (error == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-TEST_F(TDMLayer, LayerIsCommittingFailNullCommitting)
-{
-       SKIP_FLAG(has_layers);
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
 
-       ASSERT_EXIT({tdm_error error;
-                                error = tdm_layer_is_committing(tdm_layer_array[0], NULL);
-                                if (error == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
 
-TEST_F(TDMLayer, LayerIsCommittingSuccessWithoutCommit)
-{
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       unsigned int committing;
+               /* set buffer & commit for 10 times */
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+
+               done = false;
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done) == TDM_ERROR_NONE);
+               while (!done) {
+                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_is_committing(tdm_layer_array[0], &committing);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
 
-               ASSERT_EQ(0, committing);
+               DestroyBuffers();
        }
 }
 
-TEST_F(TDMLayerCommit, LayerIsCommittingSuccess)
+TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommitOneDoneOneCommit)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       unsigned int committing;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_info_layer info;
+               int next_buffer = 0;
+               bool done;
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3) == true);
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               /* set info */
+               int bw = tbm_surface_get_width(buffers[0]);
+               int bh = tbm_surface_get_height(buffers[0]);
+               tbm_format bf = tbm_surface_get_format(buffers[0]);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+               /* set buffer & commit for 10 times */
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               done = false;
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done) == TDM_ERROR_NONE);
+               while (!done) {
+                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
 
-               error = tdm_layer_commit(tdm_layer_array[i], NULL, NULL);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]) == TDM_ERROR_NONE);
+               next_buffer = 0;
+               ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done) == TDM_ERROR_NONE);
 
-               error = tdm_layer_is_committing(tdm_layer_array[0], &committing);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_layer_unset_buffer(layers[l]) == TDM_ERROR_NONE);
 
-               ASSERT_EQ(1, committing);
+               DestroyBuffers();
        }
 }
 
-/* tdm_layer_remove_commit_handler() */
-
-TEST_F(TDMLayer, LayerRemoveCommitHandlerFailNullAll)
-{
-       SKIP_FLAG(has_layers);
-
-       ASSERT_EXIT({tdm_error error;
-                                error = tdm_layer_remove_commit_handler(NULL, NULL, NULL);
-                                if (error == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMLayerCommit, LayerRemoveCommitHandlerSuccess)
+TEST_P(TDMLayer, LayerCommit)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
-
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
+               for (int t = 0; t < 10; t++) {
+                       unsigned int committing;
+                       bool done = false;
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_is_committing(layers[l], &committing) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(committing == 1);
+                       while (!done)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_is_committing(layers[l], &committing) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(committing == 0);
                }
-
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
-
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               error = tdm_layer_remove_commit_handler(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
        }
-
-       UtHandleCommitEvent(layer_count);
-       ASSERT_EQ(0, utLayerCommitHandlerCounter);
-       ASSERT_EQ(0, data);
 }
 
-/* tdm_layer_get_displaying_buffer() */
-
-TEST_F(TDMLayerCommit, LayerGetDisplayingBufferFailNullAll)
+TEST_P(TDMLayer, LayerCommitDPMSOff)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_get_displaying_buffer(NULL, NULL) != NULL) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_layer_commit(layers[0], NULL, NULL) == TDM_ERROR_DPMS_OFF);
 }
 
-TEST_F(TDMLayerCommit, LayerGetDisplayingBufferFailWithoutCommit)
+TEST_P(TDMLayer, LayerCommitNullObject)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               ASSERT_EQ(NULL, tdm_layer_get_displaying_buffer(tdm_layer_array[i], &error));
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
+       ASSERT_TRUE(tdm_layer_commit(NULL, _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayerCommit, LayerGetDisplayingBufferSuccess)
+TEST_P(TDMLayer, LayerCommitNullOther)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       int data = 0;
-
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer = NULL;
-               tdm_layer_capability layer_capability;
-
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
-
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
-
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               error = tdm_layer_commit(tdm_layer_array[i], UtLayerCommitHandler, &data);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
-
-       UtHandleCommitEvent(layer_count);
-       ASSERT_EQ(layer_count, utLayerCommitHandlerCounter);
-       ASSERT_EQ(layer_count, data);
-
-       for (int i = 0; i < layer_count; ++i) {
-               ASSERT_EQ(tdm_layers_buffer_array[i], tdm_layer_get_displaying_buffer(tdm_layer_array[i], &error));
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+       ASSERT_TRUE(tdm_layer_commit(layers[0], NULL, NULL) == TDM_ERROR_NONE);
 }
 
-/* tdm_layer_is_usable() */
-
-TEST_F(TDMLayer, LayerIsUsableFailNullAll)
+TEST_P(TDMLayer, LayerCommitFewTimesInOneVblank)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_is_usable(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-TEST_F(TDMLayer, LayerIsUsableFailNullLayer)
-{
-       SKIP_FLAG(has_layers);
-       unsigned int usable;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_error ret;
+               tdm_output *output = tdm_layer_get_output(layers[l], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
 
-       ASSERT_EXIT({if (tdm_layer_is_usable(NULL, &usable) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
+
+               for (int t = 0; t < 10; t++) {
+                       unsigned int committing;
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_is_committing(layers[l], &committing) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(committing == 1);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done3) == TDM_ERROR_NONE);
+                       while (!done1 || !done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_is_committing(layers[l], &committing) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(committing == 0);
+               }
+       }
 }
 
-TEST_F(TDMLayer, LayerIsUsableFailNullUsable)
+TEST_P(TDMLayer, LayerIsCommittingNullObject)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_is_usable(tdm_layer_array[0], NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       unsigned int committing = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_is_committing(NULL, &committing) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(committing == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMLayer, LayerIsUsableSuccessAllUsable)
+TEST_P(TDMLayer, LayerIsCommittingNullOther)
 {
-       SKIP_FLAG(has_layers);
-       unsigned int usable;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_is_usable(tdm_layer_array[i], &usable);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               ASSERT_NE(0, usable);
-       }
+       ASSERT_TRUE(tdm_layer_is_committing(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer, LayerIsUsableSuccessAllUsable_2)
+TEST_P(TDMLayer, LayerRemoveCommitHandler)
 {
-       SKIP_FLAG(has_layers);
-       unsigned int usable;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer;
-
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
-
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               tdm_error ret;
+               tdm_output *output = tdm_layer_get_output(layers[l], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
 
-               error = tdm_layer_unset_buffer(tdm_layer_array[i]);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               error = tdm_layer_is_usable(tdm_layer_array[i], &usable);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               ASSERT_NE(0, usable);
+               for (int t = 0; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done3) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_remove_commit_handler(layers[l], _ut_tdm_layer_commit_cb, &done2) == TDM_ERROR_NONE);
+                       while (!done1 || done2 || !done3) {
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       }
+               }
        }
 }
 
-TEST_F(TDMLayer, LayerIsUsableSuccessAllNoUsable)
+TEST_P(TDMLayer, LayerRemoveCommitHandlerDifferentData)
 {
-       SKIP_FLAG(has_layers);
-       unsigned int usable;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h buffer;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       for (int l = 0; l < layer_count; l++) {
+               tdm_error ret;
+               tdm_output *output = tdm_layer_get_output(layers[l], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
 
-               buffer = UtCreateBufferForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer);
-
-               error = tdm_layer_set_buffer(tdm_layer_array[i], buffer);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               error = tdm_layer_is_usable(tdm_layer_array[i], &usable);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               ASSERT_EQ(0, usable);
+               for (int t = 0; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done3) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_remove_commit_handler(layers[l], _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_NONE);
+                       while (!done1 || !done2 || !done3) {
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       }
+               }
        }
 }
-
-/* tdm_layer_set_video_pos() */
-
-TEST_F(TDMLayer, LayerSetVideoPosFailNullAll)
+static void
+_ut_tdm_layer_commit_cb2(tdm_layer *layer, unsigned int sequence,
+                                                unsigned int tv_sec, unsigned int tv_usec,
+                                                void *user_data)
 {
-       SKIP_FLAG(has_layers);
-
-       ASSERT_EXIT({if (tdm_layer_set_video_pos(NULL, -1) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+       ASSERT_TRUE(tdm_layer_remove_commit_handler(layer, _ut_tdm_layer_commit_cb2, user_data) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMLayer, LayerSetVideoPosFailNoVideoLayers)
+TEST_P(TDMLayer, LayerRemoveCommitHandlerInHandler)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tdm_layer_capability layer_capability;
-
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               if (layer_capability & TDM_LAYER_CAPABILITY_VIDEO)
-                       continue;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_set_video_pos(tdm_layer_array[i], -1);
-               ASSERT_NE(TDM_ERROR_NONE, error);
-       }
-}
+       for (int l = 0; l < layer_count; l++) {
+               tdm_error ret;
+               tdm_output *output = tdm_layer_get_output(layers[l], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(output != NULL);
 
-TEST_F(TDMLayer, LayerSetVideoPosSuccess)
-{
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tdm_layer_capability layer_capability;
-
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_VIDEO))
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
                        continue;
 
-               error = tdm_layer_set_video_pos(tdm_layer_array[i], -1);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               for (int t = 0; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb2, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb2, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb2, &done3) == TDM_ERROR_NONE);
+                       while (!done1 || !done2 || !done3) {
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       }
+               }
        }
 }
 
-/* tdm_layer_create_capture() */
-
-TEST_F(TDMLayer, LayerCreateCaptureNullAll)
+TEST_P(TDMLayer, LayerRemoveCommitHandlerNullObject)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_create_capture(NULL, NULL) != NULL) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_layer_remove_commit_handler(NULL, _ut_tdm_layer_commit_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMLayer, LayerCreateCaptureSuccess)
+TEST_P(TDMLayer, LayerRemoveCommitHandlerNullOther)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tdm_capture *capture;
-
-       for (int i = 0; i < layer_count; ++i) {
-               capture = tdm_layer_create_capture(tdm_layer_array[i], &error);
-               if (error == TDM_ERROR_NO_CAPABILITY)
-                       return;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               ASSERT_NE(NULL, capture);
-       }
+       ASSERT_TRUE(tdm_layer_remove_commit_handler(layers[0], NULL, NULL) == TDM_ERROR_NONE);
 }
 
-/* tdm_layer_get_buffer_flags() */
-
-TEST_F(TDMLayer, LayerGetBufferFlagsNullAll)
+TEST_P(TDMLayer, LayerGetDisplayingBufferNullObject)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_get_buffer_flags(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       tbm_surface_h displaying_buffer;
+       tdm_error ret;
+       displaying_buffer = tdm_layer_get_displaying_buffer(NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(displaying_buffer == NULL);
 }
 
-TEST_F(TDMLayer, LayerGetBufferFlagsNullLayer)
+TEST_P(TDMLayer, LayerGetDisplayingBufferNullOther)
 {
-       SKIP_FLAG(has_layers);
-       unsigned int flags;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_get_buffer_flags(NULL, &flags) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       tbm_surface_h displaying_buffer;
+       displaying_buffer = tdm_layer_get_displaying_buffer(layers[0], NULL);
+       ASSERT_TRUE(displaying_buffer == NULL);
 }
 
-TEST_F(TDMLayer, LayerGetBufferFlagsNullFlags)
+TEST_P(TDMLayer, LayerIsUsableNullObject)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_get_buffer_flags(tdm_layer_array[0], NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       unsigned int usable = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_layer_is_usable(NULL, &usable) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(usable == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMLayer, LayerGetBufferFlagsSuccess)
+TEST_P(TDMLayer, LayerSetBufferQueue)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       unsigned int flags;
-
-       for (int i = 0; i < layer_count; ++i) {
-               error = tdm_layer_get_buffer_flags(tdm_layer_array[i], &flags);
-               if (error == TDM_ERROR_NOT_IMPLEMENTED)
-                       return;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
-}
+       tdm_error ret;
 
-/* tdm_layer_set_buffer_queue() */
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-TEST_F(TDMLayer, LayerSetBufferQueueFailNullAll)
-{
-       SKIP_FLAG(has_layers);
-
-       ASSERT_EXIT({if (tdm_layer_set_buffer_queue(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMLayer, LayerSetBufferQueueFailNullLayer)
-{
-       SKIP_FLAG(has_layers);
-       tbm_surface_queue_h bufer_queue;
+       for (int l = 0; l < layer_count; l++) {
+               unsigned int usable;
+               tdm_info_layer info;
+               tbm_surface_h buffer;
+               tbm_surface_h displaying_buffer;
 
-       bufer_queue = UtCreateBufferQueueForLayer(0, 128, 128, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-       ASSERT_NE(NULL, bufer_queue);
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-       ASSERT_EXIT({if (tdm_layer_set_buffer_queue(NULL, bufer_queue) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+               ASSERT_TRUE(ut_tdm_layer_prepare_buffer_queue(layers[l], &buffer_queue) == true);
+               ASSERT_TRUE(buffer_queue != NULL);
 
-TEST_F(TDMLayer, LayerSetBufferQueueFailNullBufferQueue)
-{
-       SKIP_FLAG(has_layers);
+               /* set info */
+               int bw = tbm_surface_queue_get_width(buffer_queue);
+               int bh = tbm_surface_queue_get_height(buffer_queue);
+               tbm_format bf = tbm_surface_queue_get_format(buffer_queue);
+               ASSERT_TRUE(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info) == true);
 
-       ASSERT_EXIT({if (tdm_layer_set_buffer_queue(tdm_layer_array[0], NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
+               ASSERT_TRUE(tdm_layer_is_usable(layers[l], &usable) == TDM_ERROR_NONE);
+               ASSERT_TRUE(usable == 1);
+               ASSERT_TRUE(tdm_layer_set_info(layers[l], &info) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_layer_is_usable(layers[l], &usable) == TDM_ERROR_NONE);
+               ASSERT_TRUE(usable == 0);
 
-TEST_F(TDMLayer, LayerSetBufferQueueSuccess)
-{
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tbm_surface_queue_h buffer_queue;
-       tdm_layer_capability layer_capability;
+               ASSERT_TRUE(tdm_layer_set_buffer_queue(layers[l], buffer_queue) == TDM_ERROR_NONE);
 
-       for (int i = 0; i < layer_count; ++i) {
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+               ASSERT_TRUE(tdm_layer_commit(layers[l], NULL, NULL) == TDM_ERROR_NONE);
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               for (int t = 0; t < 10; t++) {
+                       ASSERT_TRUE(tbm_surface_queue_dequeue(buffer_queue, &buffer) == TBM_SURFACE_QUEUE_ERROR_NONE);
+                       ASSERT_TRUE(buffer != NULL);
+                       tdm_test_buffer_fill(buffer, PATTERN_SMPTE);
+                       ASSERT_TRUE(tbm_surface_queue_enqueue(buffer_queue, buffer) == TBM_SURFACE_QUEUE_ERROR_NONE);
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
+                       displaying_buffer = NULL;
+                       while (!displaying_buffer) {
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                               displaying_buffer = tdm_layer_get_displaying_buffer(layers[l], &ret);
+                               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+                       }
+                       ASSERT_TRUE(displaying_buffer == buffer);
                }
 
-               buffer_queue = UtCreateBufferQueueForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer_queue);
+               ASSERT_TRUE(tdm_layer_unset_buffer_queue(layers[l]) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer_queue(tdm_layer_array[i], buffer_queue);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               DestroyBuffers();
        }
 }
 
-TEST_F(TDMLayer, LayerSetBufferQueueSuccessTwice)
+TEST_P(TDMLayer, LayerSetBufferQueueTwice)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tbm_surface_queue_h buffer_queue;
-       tdm_layer_capability layer_capability;
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
+       _ut_tdm_layer_mode_setting_all_output(dpy, outputs, output_count);
 
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; l++) {
+               tbm_surface_queue_h buffer_queue1 = NULL;
+               tbm_surface_queue_h buffer_queue2 = NULL;
 
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
+               if (ut_tdm_layer_is_cursor_layer(layers[l]))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               buffer_queue = UtCreateBufferQueueForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer_queue);
+               EXPECT_TRUE(ut_tdm_layer_prepare_buffer_queue(layers[l], &buffer_queue1) == true);
+               EXPECT_TRUE(buffer_queue1 != NULL);
+               EXPECT_TRUE(tdm_layer_set_buffer_queue(layers[l], buffer_queue1) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer_queue(tdm_layer_array[i], buffer_queue);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               EXPECT_TRUE(ut_tdm_layer_prepare_buffer_queue(layers[l], &buffer_queue2) == true);
+               EXPECT_TRUE(buffer_queue2 != NULL);
+               EXPECT_TRUE(tdm_layer_set_buffer_queue(layers[l], buffer_queue2) == TDM_ERROR_NONE);
 
-               error = tdm_layer_set_buffer_queue(tdm_layer_array[i], buffer_queue);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+               if (buffer_queue1)
+                       tbm_surface_queue_destroy(buffer_queue1);
+               if (buffer_queue2)
+                       tbm_surface_queue_destroy(buffer_queue2);
        }
 }
 
-TEST_F(TDMLayerCommitThread, LayerSetBufferQueueSuccessRemoveBufferQueue)
+TEST_P(TDMLayer, LayerSetBufferQueueNullObject)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tbm_surface_queue_error_e tbm_err;
-       tbm_surface_queue_h buffer_queue;
-       tdm_layer_capability layer_capability;
-
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h surface;
-
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
-
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       tbm_surface_queue_h buffer_queue = (tbm_surface_queue_h)TDM_UT_INVALID_VALUE;
 
-               buffer_queue = UtCreateBufferQueueForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer_queue);
+       ASSERT_TRUE(tdm_layer_set_buffer_queue(NULL, buffer_queue) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-               error = tdm_layer_set_buffer_queue(tdm_layer_array[i], buffer_queue);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+TEST_P(TDMLayer, LayerSetBufferQueueNullOther)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               tbm_err = tbm_surface_queue_dequeue(buffer_queue, &surface);
-               ASSERT_EQ(TBM_SURFACE_QUEUE_ERROR_NONE, tbm_err);
+       ASSERT_TRUE(tdm_layer_set_buffer_queue(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-               tdm_layer_commit(tdm_layer_array[i], NULL, NULL);
+TEST_P(TDMLayer, LayerUnsetBufferQueueNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               tbm_err = tbm_surface_queue_enqueue(buffer_queue, surface);
-               ASSERT_EQ(TBM_SURFACE_QUEUE_ERROR_NONE, tbm_err);
-       }
+       ASSERT_TRUE(tdm_layer_unset_buffer_queue(NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-       /* FIXME: use another func. */
-       UtHandleCommitEvent(1);
+TEST_P(TDMLayer, LayerIsUsableNullOther)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       for (int i = 0; i < layer_count; ++i) {
-               ASSERT_NE(NULL, tdm_layer_get_displaying_buffer(tdm_layer_array[i], &error));
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_layer_is_usable(layers[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-               tbm_surface_queue_destroy(tdm_layers_buffer_queue_array[i]);
-               tdm_layers_buffer_queue_array[i] = NULL;
+TEST_P(TDMLayer, LayerSetVideoPos)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               ASSERT_EQ(NULL, tdm_layer_get_displaying_buffer(tdm_layer_array[i], &error));
-               ASSERT_NE(TDM_ERROR_NONE, error);
+       for (int l = 0; l < layer_count; ++l) {
+               if (!ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
+               ASSERT_TRUE(tdm_layer_set_video_pos(layers[l], -1) == TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMLayerCommitWithDisabledCommitPerVblank, LayerSetBufferQueueSuccessRemoveBufferQueue)
+TEST_P(TDMLayer, LayerSetVideoPosNullObject)
 {
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tbm_surface_queue_error_e tbm_err;
-       tbm_surface_queue_h buffer_queue;
-       tdm_layer_capability layer_capability;
-
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h surface;
-
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
-
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
-
-               error = _ut_tdm_layer_set_info(tdm_layer_array[i], w, h);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               buffer_queue = UtCreateBufferQueueForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer_queue);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               error = tdm_layer_set_buffer_queue(tdm_layer_array[i], buffer_queue);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_layer_set_video_pos(NULL, -1) == TDM_ERROR_INVALID_PARAMETER);
+}
 
-               tbm_err = tbm_surface_queue_dequeue(buffer_queue, &surface);
-               ASSERT_EQ(TBM_SURFACE_QUEUE_ERROR_NONE, tbm_err);
+TEST_P(TDMLayer, LayerSetVideoPosNoVideoLayer)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-               tdm_layer_commit(tdm_layer_array[i], NULL, NULL);
+       for (int l = 0; l < layer_count; ++l) {
+               if (ut_tdm_layer_is_video_layer(layers[l]))
+                       continue;
 
-               tbm_err = tbm_surface_queue_enqueue(buffer_queue, surface);
-               ASSERT_EQ(TBM_SURFACE_QUEUE_ERROR_NONE, tbm_err);
+               ASSERT_TRUE(tdm_layer_set_video_pos(layers[l], -1) == TDM_ERROR_BAD_REQUEST);
        }
+}
 
-       /* FIXME: use another func. */
-       UtHandleCommitEvent(1);
-
-       for (int i = 0; i < layer_count; ++i) {
-               tbm_surface_h surface;
-
-               tbm_err = tbm_surface_queue_dequeue(tdm_layers_buffer_queue_array[i], &surface);
-               ASSERT_EQ(TBM_SURFACE_QUEUE_ERROR_NONE, error);
-
-               tbm_err = tbm_surface_queue_enqueue(tdm_layers_buffer_queue_array[i], surface);
-               ASSERT_EQ(TBM_SURFACE_QUEUE_ERROR_NONE, error);
-
-               error = tdm_layer_unset_buffer_queue(tdm_layer_array[i]);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
+TEST_P(TDMLayer, LayerCreateCapture)
+{
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       /* FIXME: use another func. */
-       UtHandleCommitEvent(1);
+       for (int l = 0; l < layer_count; ++l) {
+               tdm_error ret;
+               tdm_capture *capture = tdm_layer_create_capture(layers[l], &ret);
 
-       for (int i = 0; i < layer_count; ++i) {
-               ASSERT_EQ(NULL, tdm_layer_get_displaying_buffer(tdm_layer_array[i], &error));
-               ASSERT_NE(TDM_ERROR_NONE, error);
+               if (ret == TDM_ERROR_NONE)
+                       ASSERT_TRUE(capture != NULL);
        }
 }
 
-/* tdm_layer_unset_buffer_queue() */
-
-TEST_F(TDMLayer, LayerUnsetBufferQueueFailNullAll)
+TEST_P(TDMLayer, LayerCreateCaptureNullObject)
 {
-       SKIP_FLAG(has_layers);
+       TDM_UT_SKIP_FLAG(has_layers);
 
-       ASSERT_EXIT({if (tdm_layer_unset_buffer_queue(NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       tdm_error ret;
+       tdm_capture *capture = tdm_layer_create_capture(NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(capture == NULL);
 }
 
-TEST_F(TDMLayer, LayerUnsetBufferQueueSuccess)
-{
-       SKIP_FLAG(has_layers);
-       tdm_error error;
-       tbm_surface_queue_h buffer_queue;
-       tdm_layer_capability layer_capability;
-
-       for (int i = 0; i < layer_count; ++i) {
-               int w = preferred_mode_array[tdm_layer_output_idx[i]]->hdisplay;
-               int h = preferred_mode_array[tdm_layer_output_idx[i]]->vdisplay;
-
-               error = tdm_layer_get_capabilities(tdm_layer_array[i], &layer_capability);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               if (!(layer_capability & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                       w /= 2;
-                       h /= 2;
-               }
-
-               buffer_queue = UtCreateBufferQueueForLayer(i, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
-               ASSERT_NE(NULL, buffer_queue);
-
-               error = tdm_layer_set_buffer_queue(tdm_layer_array[i], buffer_queue);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
+INSTANTIATE_TEST_CASE_P(TDMLayerParams,
+                                               TDMLayer,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
 
-               error = tdm_layer_unset_buffer_queue(tdm_layer_array[i]);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-       }
-}
+#endif
diff --git a/utests/src/ut_tdm_log.cpp b/utests/src/ut_tdm_log.cpp
new file mode 100644 (file)
index 0000000..2d4e245
--- /dev/null
@@ -0,0 +1,95 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
+ * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ *
+ * 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 "ut_tdm.h"
+
+#ifdef UT_TDM_LOG_ENABLE
+
+TEST(TDMLog, logPrintf)
+{
+       tdm_log_enable_color(1);
+       tdm_log_enable_dlog(0);
+       tdm_log_enable_debug(1);
+       tdm_log_set_debug_level(2);
+       tdm_log_set_path("/tmp/tdm.log");
+       tdm_log_print(TDM_LOG_LEVEL_ERR, "utest\n");
+       tdm_log_print(TDM_LOG_LEVEL_WRN, "utest\n");
+       tdm_log_print(TDM_LOG_LEVEL_INFO, "utest\n");
+       tdm_log_print(TDM_LOG_LEVEL_DBG, "utest\n");
+       tdm_log_set_path(NULL);
+}
+
+TEST(TDMLog, logSetPath)
+{
+       tdm_log_enable_dlog(0);
+       tdm_log_set_path("/tmp/tdm.log");
+       tdm_log_print(TDM_LOG_LEVEL_ERR, "hello\n");
+       tdm_log_set_path(NULL);
+}
+
+TEST(TDMLog, logDlogNone)
+{
+       tdm_log_enable_color(0);
+       tdm_log_enable_dlog(1);
+       tdm_log_enable_debug(0);
+       tdm_log_set_debug_level(0);
+       tdm_log_print(TDM_LOG_LEVEL_ERR, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_WRN, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_INFO, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_DBG, "utest");
+}
+
+TEST(TDMLog, logDlog)
+{
+       tdm_log_enable_dlog(1);
+       tdm_log_enable_debug(1);
+       tdm_log_print(TDM_LOG_LEVEL_ERR, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_WRN, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_INFO, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_DBG, "utest");
+}
+
+TEST(TDMLog, logDlogNormal)
+{
+       tdm_log_enable_dlog(1);
+       tdm_log_enable_debug(0);
+       tdm_log_print(TDM_LOG_LEVEL_ERR, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_WRN, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_INFO, "utest");
+       tdm_log_print(TDM_LOG_LEVEL_DBG, "utest");
+}
+
+TEST(TDMLog, logDlogUnknownLevel)
+{
+       tdm_log_enable_dlog(1);
+       tdm_log_print(TDM_UT_INVALID_VALUE, "utest");
+}
+
+#endif
index 0dbfc72..b4d9f19 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
+#include "ut_tdm.h"
 
-#ifdef TIZEN_TEST_GCOV
-extern "C" void __gcov_flush(void);
-#endif
+int tdm_debug_module;
 
 int main(int argc, char **argv)
 {
-    auto AllTestSuccess = false;
+       auto AllTestSuccess = false;
 
 #ifdef TIZEN_TEST_GCOV
        setenv("GCOV_PREFIX", "/tmp", 1);
@@ -50,13 +48,13 @@ int main(int argc, char **argv)
                exit(EXIT_FAILURE);
        }
 
-    try {
-        AllTestSuccess = RUN_ALL_TESTS() == 0 ? true : false;
-    } catch (const ::testing::internal::GoogleTestFailureException& e) {
-        AllTestSuccess = false;
+       try {
+               AllTestSuccess = RUN_ALL_TESTS() == 0 ? true : false;
+       } catch (const ::testing::internal::GoogleTestFailureException & e) {
+               AllTestSuccess = false;
                std::cout << "GoogleTestFailureException was thrown:"<< e.what() << std::endl;
                std::cout << "\n";
-    }
+       }
 
 #ifdef TIZEN_TEST_GCOV
        __gcov_flush();
index db15445..0ff6ffa 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
 #include "ut_tdm.h"
-#include <climits>
-#include "tdm.h"
-#include "tdm_config.h"
-extern "C" {
-#include "tbm_bufmgr.h"
-#include "tbm_drm_helper.h"
-}
-#include <vector>
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#include <pthread.h>
-
-class TDMOutput : public ::testing::Test {
-protected:
-       tdm_display *dpy = NULL;
-       int output_count = 0, master_fd = -42, tbm_fd = -42;
-       bool has_output = false;
-       tbm_bufmgr tbm_bufmgr = NULL;
-       static unsigned int handle_call;
-       static void tdm_output_change_handler_test_func(tdm_output *output,
-                                                                                                       tdm_output_change_type type,
-                                                                                                       tdm_value value,
-                                                                                                       void *u_data)
-       {
-               if ( ((intptr_t) u_data) < -100) {
-                       TDMOutput::handle_call++;
-               }
-       }
-       virtual void SetEnvs()
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-       }
 
-       virtual void UnsetEnvs()
-       {
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
-       }
+TDMOutput::TDMOutput()
+{
+       has_outputs = false;
+       output_count = TDM_UT_INVALID_VALUE;
+       outputs = NULL;
+}
 
-       void SetUp(void)
-       {
-               SetEnvs();
-
-               tdm_error error = TDM_ERROR_NONE;
-               dpy = tdm_display_init(&error);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               ASSERT_FALSE(dpy == NULL);
-               tbm_bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(tbm_bufmgr == NULL);
-               master_fd = tbm_drm_helper_get_master_fd();
-               tbm_fd = tbm_drm_helper_get_fd();
-               error = tdm_display_get_output_count(dpy, &output_count);
-#ifdef FAIL_ON_UNSUPPORTED
-               ASSERT_GT(output_count, 0);
-#endif
-               if (output_count > 0)
-                       has_output = true;
-               handle_call = 0;
-       }
-       void TearDown(void)
-       {
-               tdm_display_deinit(dpy);
-               dpy = NULL;
-               tbm_bufmgr_deinit(tbm_bufmgr);
-               tbm_bufmgr = NULL;
-               if (master_fd > -1) {
-                       int temp_master_fd = tbm_drm_helper_get_master_fd();
-                       EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_master_fd > -1)
-                               exit(1);
-                       close(master_fd);
-               }
-               if (tbm_fd > -1) {
-                       int temp_tbm_fd = tbm_drm_helper_get_fd();
-                       EXPECT_EQ(temp_tbm_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
-                       if (temp_tbm_fd > -1)
-                               exit(1);
-                       close(tbm_fd);
-               }
+void TDMOutput::SetUp(void)
+{
+       TDMDisplay::SetUp();
 
-               UnsetEnvs();
-       }
-};
+       ASSERT_TRUE(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(output_count >= 0);
 
-class TDMOutputHWC : public TDMOutput {
-       void SetEnvs(void)
-       {
-               TDMOutput::SetEnvs();
-               setenv("TDM_HWC", "1", 1);
-       }
-       void UnsetEnvs(void)
-       {
-               TDMOutput::UnsetEnvs();
-               unsetenv("TDM_HWC");
+       if (output_count > 0) {
+               outputs = (tdm_output**)calloc(output_count, sizeof (tdm_output*));
+               ASSERT_TRUE(outputs != NULL);
+
+               for (int o = 0; o < output_count; o++) {
+                       tdm_error ret;
+                       tdm_output *output = tdm_display_get_output(dpy, o, &ret);
+                       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+                       ASSERT_TRUE(output != NULL);
+                       outputs[o] = output;
+               }
+               has_outputs = true;
+       } else {
+               has_outputs = false;
        }
-};
+}
 
-class TDMOutputThread : public TDMOutput {
-       void SetEnvs(void)
-       {
+void TDMOutput::TearDown(void)
+{
+       free(outputs);
+       TDMDisplay::TearDown();
+}
 
-               TDMOutput::SetEnvs();
-               setenv("TDM_THREAD", "1", 1);
-       }
-       void UnsetEnvs(void)
-       {
-               TDMOutput::UnsetEnvs();
-               unsetenv("TDM_THREAD");
-       }
-};
-
-class TDMOutputCommit : public TDMOutput {
-private:
-       int epFd = -1;
-       int timerFd = -1;
-       int tdmFd = -1;
-       static const int timeLimitSec = 1;
-       static const int timeLimitNsec = 0;
-protected:
-       int conn_output_count = 0;
-       tdm_output ** connected_output_array = NULL;
-       const tdm_output_mode** preferred_mode = NULL;
-       bool has_output = false;
-       std::vector<std::vector<tdm_layer *>> layers_array;
-       std::vector<tbm_surface_h> buffers;
-       static unsigned int utOutputCommitHandlerCounter;
-       static void UtOutputCommitHandler(tdm_output *output, unsigned int sequence,
-                                                          unsigned int tv_sec, unsigned int tv_usec,
-                                                          void *user_data)
-       {
-               utOutputCommitHandlerCounter++;
-       }
+bool
+ut_tdm_output_mode_setting(tdm_output *output)
+{
+       const tdm_output_mode *modes = (const tdm_output_mode *)TDM_UT_INVALID_VALUE;
+       const tdm_output_mode *found = NULL;
+       const tdm_output_mode *best = NULL;
+       int count = TDM_UT_INVALID_VALUE;
+       unsigned int pipe = 0;
+
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_available_modes(output, &modes, &count) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(count > 0);
+       TDM_UT_RETURN_FALSE_IF_FAIL(modes != NULL && modes != (const tdm_output_mode *)TDM_UT_INVALID_VALUE);
 
-       static unsigned int utOutputVblankHandlerCounter;
-       static void UtOutputVblankHandler(tdm_output *output, unsigned int sequence,
-                                                          unsigned int tv_sec, unsigned int tv_usec,
-                                                          void *user_data)
-       {
-               utOutputVblankHandlerCounter++;
+       for (int i = 0; i < count; i++) {
+               if (!best)
+                       best = &modes[i];
+               if (modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
+                       found = &modes[i];
        }
-       friend void *UtOutputRemoveChangeHandlerSuccessfulThread(void *ptr);
+       if (!found && best)
+               found = best;
 
-       void SetUp(void)
-       {
-               struct epoll_event ep;
+       TDM_UT_RETURN_FALSE_IF_FAIL(found != NULL);
 
-               utOutputCommitHandlerCounter = 0;
-               utOutputVblankHandlerCounter = 0;
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_mode(output, found) == TDM_ERROR_NONE);
 
-               ASSERT_NO_FATAL_FAILURE(TDMOutput::SetUp());
-               if (TDMOutput::output_count > 0) {
-                       connected_output_array = (tdm_output **) calloc(TDMOutput::output_count, sizeof(tdm_output *));
-                       ASSERT_FALSE(NULL == connected_output_array);
-                       preferred_mode = (const tdm_output_mode **) calloc(TDMOutput::output_count, sizeof(tdm_output_mode*));
-                       ASSERT_FALSE(NULL == preferred_mode);
-               }
-               conn_output_count = 0;
-               for (int i = 0; i < TDMOutput::output_count; i++) {
-                       tdm_error error = TDM_ERROR_NONE;
-                       int output_modes_cnt = 0;
-                       int layer_count = 0;
-                       const tdm_output_mode* output_modes = NULL;
-                       tdm_output * output = tdm_display_get_output(TDMOutput::dpy, i, &error);
-                       std::vector<tdm_layer *> layers;
-                       if (TDM_ERROR_NONE != error || NULL == output)
-                               continue;
-                       tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-                       if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status))
-                               continue;
-                       if (TDM_OUTPUT_CONN_STATUS_DISCONNECTED == status)
-                               continue;
-                       if (TDM_ERROR_NONE != tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON))
-                               continue;
-                       if(TDM_ERROR_NONE != tdm_output_get_available_modes(output,
-                                                                                                                               &output_modes,
-                                                                                                                               &output_modes_cnt))
-                               continue;
-                       for(int k = 0; k < output_modes_cnt; k++) {
-                               if(output_modes[k].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) {
-                                       preferred_mode[conn_output_count] = &output_modes[k];
-                                       break;
-                               }
-                       }
-                       if (NULL == preferred_mode[conn_output_count])
-                               continue;
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE);
 
-                       if (TDM_ERROR_NONE != tdm_output_get_layer_count(output, &layer_count))
-                               continue;
-                       if (0 == layer_count)
-                               continue;
+       TDM_INFO("setting output(%d) mode done: %dx%d %d", pipe, found->hdisplay, found->vdisplay, found->vrefresh);
 
-                       for (int i = 0; i < layer_count; ++i) {
-                               tdm_layer *layer;
-                               layer = tdm_output_get_layer(output, i, &error);
-                               if (layer == nullptr)
-                                       continue;
-                               layers.push_back(layer);
-                       }
-                       connected_output_array[conn_output_count++] = output;
-                       layers_array.push_back(layers);
-               }
-#ifdef FAIL_ON_UNSUPPORTED
-               ASSERT_GT(conn_output_count, 0);
-#endif
+       return true;
+}
 
-               if (conn_output_count > 0)
-                       has_output = true;
+bool
+ut_tdm_output_is_async_dpms_enable(tdm_output *output)
+{
+       tdm_output_capability capabilities = (tdm_output_capability)TDM_UT_INVALID_VALUE;
+       if (tdm_output_get_capabilities(output, &capabilities) != TDM_ERROR_NONE)
+               return false;
+       return capabilities & TDM_OUTPUT_CAPABILITY_ASYNC_DPMS;
+}
 
-               epFd = epoll_create1(0);
-               ASSERT_TRUE(epFd != -1);
+bool
+ut_tdm_output_is_hwc_enable(tdm_output *output)
+{
+       tdm_output_capability capabilities = (tdm_output_capability)TDM_UT_INVALID_VALUE;
+       if (tdm_output_get_capabilities(output, &capabilities) != TDM_ERROR_NONE)
+               return false;
+       return capabilities & TDM_OUTPUT_CAPABILITY_HWC;
+}
 
-               timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
-               ASSERT_TRUE(timerFd != -1);
+bool
+ut_tdm_output_is_aod_enable(tdm_output *output)
+{
+       tdm_output_capability capabilities = (tdm_output_capability)TDM_UT_INVALID_VALUE;
+       if (tdm_output_get_capabilities(output, &capabilities) != TDM_ERROR_NONE)
+               return false;
+       return capabilities & TDM_OUTPUT_CAPABILITY_EXTENDED_DPMS;
+}
 
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = timerFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
+bool
+ut_tdm_output_is_connected(tdm_output *output)
+{
+       tdm_output_conn_status status;
+       if (tdm_output_get_conn_status(output, &status) != TDM_ERROR_NONE)
+               return false;
+       return (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) ? true : false;
+}
 
-               ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
+static void
+_ut_tdm_output_done_cb(tdm_output *output, unsigned int sequence,
+                                          unsigned int tv_sec, unsigned int tv_usec,
+                                          void *user_data)
+{
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+}
 
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = tdmFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
-       }
-       void TearDown(void)
-       {
-               for (size_t i = 0; i < layers_array.size(); ++i) {
-                       for (tdm_layer *layer : layers_array[i]) {
-                               tdm_layer_unset_buffer(layer);
-                       }
-               }
+bool
+ut_tdm_output_prepare(tdm_display *dpy, tdm_output *output)
+{
+       tbm_surface_h *buffers = NULL;
+       tdm_error ret;
+       int count = 0, commit_buffer_count = 0, display_buffer_count = 0;
+       unsigned int pipe = 0;
 
-               for (tbm_surface_h buffer : buffers) {
-                       tbm_surface_destroy(buffer);
-               }
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_output_is_connected(output) == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_output_mode_setting(output) == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
 
-               for (int i = 0; i < conn_output_count; i++) {
-                       EXPECT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i],
-                                                                                                                         TDM_OUTPUT_DPMS_OFF));
-               }
-               if (connected_output_array)
-                       free(connected_output_array);
-               if (preferred_mode)
-                       free(preferred_mode);
-               ASSERT_NO_FATAL_FAILURE(TDMOutput::TearDown());
-       }
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(count > 0);
+
+       buffers = (tbm_surface_h *)calloc(count, sizeof (tbm_surface_h));
+       TDM_UT_RETURN_FALSE_IF_FAIL(buffers != NULL);
 
-       tbm_surface_h UtCreateBuffer(int width, int height, tbm_format format)
-       {
-               tbm_surface_h buffer;
+       for (int l = 0; l < count; l++) {
+               tdm_info_layer info;
+               tdm_layer *layer = tdm_output_get_layer(output, l, &ret);
+               TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
+               TDM_UT_GOTO_IF_FAIL(layer != NULL, failed);
+
+               if (ut_tdm_layer_is_cursor_layer(layer))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layer))
+                       continue;
 
-               buffer = tbm_surface_internal_create_with_flags(width, height, format, TBM_BO_SCANOUT);
+               TDM_UT_GOTO_IF_FAIL(ut_tdm_layer_prepare_buffer(layer, &buffers[l], 1) == true, failed);
+               TDM_UT_GOTO_IF_FAIL(buffers[l] != NULL, failed);
 
-               if (buffer)
-                       buffers.push_back(buffer);
+               int bw = tbm_surface_get_width(buffers[l]);
+               int bh = tbm_surface_get_height(buffers[l]);
+               tbm_format bf = tbm_surface_get_format(buffers[l]);
+               TDM_UT_GOTO_IF_FAIL(ut_tdm_layer_fill_info(layer, bw, bh, bf, &info) == true, failed);
 
-               return buffer;
+               TDM_UT_GOTO_IF_FAIL(tdm_layer_set_info(layer, &info) == TDM_ERROR_NONE, failed);
+               TDM_UT_GOTO_IF_FAIL(tdm_layer_set_buffer(layer, buffers[l]) == TDM_ERROR_NONE, failed);
+               TDM_UT_GOTO_IF_FAIL(tdm_layer_commit(layer, NULL, NULL) == TDM_ERROR_NONE, failed);
+               commit_buffer_count++;
        }
 
-       void UtPrepareToCommit()
-       {
-               for (size_t i = 0; i < layers_array.size(); ++i) {
-                       for (tdm_layer *layer : layers_array[i]) {
-                               int w, h;
-                               tdm_error error;
-                               tdm_layer_capability lcapabilities;
-                               tbm_surface_h buffer;
-                               tdm_info_layer layer_info = {0};
-
-                               w = preferred_mode[i]->hdisplay;
-                               h = preferred_mode[i]->vdisplay;
-
-                               error = tdm_output_set_mode(connected_output_array[i], preferred_mode[i]);
-                               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-                               error = tdm_layer_get_capabilities(layer, &lcapabilities);
-                               ASSERT_EQ(TDM_ERROR_NONE, error);
-                               if (!(lcapabilities & TDM_LAYER_CAPABILITY_PRIMARY)) {
-                                       w = w / 2;
-                                       h = h / 2;
-                               }
-
-                               buffer = UtCreateBuffer(w, h, TBM_FORMAT_ARGB8888);
-                               ASSERT_NE(nullptr, buffer);
-
-                               layer_info.src_config.size.h = w;
-                               layer_info.src_config.size.v = h;
-                               layer_info.src_config.pos.x = 0;
-                               layer_info.src_config.pos.y = 0;
-                               layer_info.src_config.pos.w = w;
-                               layer_info.src_config.pos.h = h;
-                               layer_info.src_config.format = TBM_FORMAT_ARGB8888;
-                               layer_info.dst_pos.x = 0;
-                               layer_info.dst_pos.y = 0;
-                               layer_info.dst_pos.w = w;
-                               layer_info.dst_pos.h = h;
-                               layer_info.transform = TDM_TRANSFORM_NORMAL;
-
-                               error = tdm_layer_set_info(layer, &layer_info);
-                               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-                               error = tdm_layer_set_buffer(layer, buffer);
-                               ASSERT_EQ(TDM_ERROR_NONE, error);
+       while (commit_buffer_count != display_buffer_count) {
+               TDM_UT_GOTO_IF_FAIL(tdm_output_wait_vblank(output, 1, 0, _ut_tdm_output_done_cb, NULL) == TDM_ERROR_NONE, failed);
+               TDM_UT_GOTO_IF_FAIL(tdm_display_handle_events(dpy) == TDM_ERROR_NONE, failed);
+
+               display_buffer_count = 0;
+               for (int l = 0; l < count; l++) {
+                       tbm_surface_h displaying_buffer;
+                       tdm_layer *layer = tdm_output_get_layer(output, l, &ret);
+                       TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
+                       TDM_UT_GOTO_IF_FAIL(layer != NULL, failed);
+
+                       if (ut_tdm_layer_is_cursor_layer(layer))
+                               continue;
+                       if (ut_tdm_layer_is_video_layer(layer))
+                               continue;
+
+                       displaying_buffer = tdm_layer_get_displaying_buffer(layer, &ret);
+                       if (displaying_buffer) {
+                               TDM_UT_GOTO_IF_FAIL(displaying_buffer == buffers[l], failed);
+                               display_buffer_count++;
                        }
                }
        }
 
-       void UtHandleEvent(unsigned int & wait_var, unsigned int num)
-       {
-               struct itimerspec its;
-               int count;
-               struct epoll_event ep_event[2];
+       for (int l = 0; l < count; l++)
+               tbm_surface_destroy(buffers[l]);
 
-               if (wait_var == num)
-                       return;
+       free(buffers);
 
-               its.it_interval.tv_sec = 0;
-               its.it_interval.tv_nsec = 0;
-               its.it_value.tv_sec = timeLimitSec;
-               its.it_value.tv_nsec = timeLimitNsec;
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE);
 
-               ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
+       TDM_INFO("preparing output(%d) done", pipe);
 
-               while (1) {
-                       count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
-                       ASSERT_TRUE(count >= 0);
+       return true;
+failed:
+       for (int l = 0; l < count; l++)
+               tbm_surface_destroy(buffers[l]);
+       free(buffers);
+       return false;
+}
 
-                       for (int i = 0; i < count; i++) {
-                               if (ep_event[i].data.fd == timerFd) {
-                                       return;
-                               } else {
-                                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
-                                       if (wait_var == num)
-                                               return;
-                               }
-                       }
-               }
-       }
+bool
+ut_tdm_output_unset(tdm_display *dpy, tdm_output *output)
+{
+       tdm_error ret;
+       int count = 0;
+       unsigned int pipe = 0;
 
-       void UtHandleCommitEvent()
-       {
-               UtHandleEvent(utOutputCommitHandlerCounter, (unsigned int)conn_output_count);
-       }
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(count > 0);
 
-       void UtHandleVblankEvent()
-       {
-               UtHandleEvent(utOutputVblankHandlerCounter, conn_output_count);
-       }
-};
+       for (int l = 0; l < count; l++) {
+               tdm_layer *layer = tdm_output_get_layer(output, l, &ret);
+               TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+               TDM_UT_RETURN_FALSE_IF_FAIL(layer != NULL);
 
-class TDMOutputCommitPerVblankEnabled : public TDMOutputCommit {
-       void SetEnvs(void)
-       {
+               if (ut_tdm_layer_is_cursor_layer(layer))
+                       continue;
+               if (ut_tdm_layer_is_video_layer(layer))
+                       continue;
 
-               TDMOutputCommit::SetEnvs();
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1);
+               TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_unset_buffer(layer) == TDM_ERROR_NONE);
        }
-       void UnsetEnvs(void)
-       {
-               TDMOutputCommit::UnsetEnvs();
-       }
-};
 
-class TDMOutputCommitThread : public TDMOutputCommit {
-       void SetEnvs(void)
-       {
-               TDMOutputCommit::SetEnvs();
-               setenv("TDM_THREAD", "1", 1);
-       }
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE);
 
-       void UnsetEnvs(void)
-       {
-               TDMOutputCommit::UnsetEnvs();
-               unsetenv("TDM_THREAD");
-       }
-};
+       TDM_INFO("unsetting output(%d) done", pipe);
 
-unsigned int TDMOutput::handle_call = 0;
-unsigned int TDMOutputCommit::utOutputCommitHandlerCounter = 0;
-unsigned int TDMOutputCommit::utOutputVblankHandlerCounter = 0;
+       return true;
+}
 
-TEST_F(TDMOutput, DisplayGetOutputSuccessful)
+/* msec */
+double
+ut_tdm_output_get_vblank_interval_time(tdm_output *output)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               ASSERT_FALSE(NULL == tdm_display_get_output(dpy, i, &error));
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-       }
+       const tdm_output_mode *mode = (const tdm_output_mode *)TDM_UT_INVALID_VALUE;
+       tdm_error ret = tdm_output_get_mode(output, &mode);
+
+       assert(ret == TDM_ERROR_NONE);
+       assert(mode != NULL);
+       assert(mode->vrefresh > 0);
+
+       return (double)1.0 / (double)mode->vrefresh;
 }
 
-TEST_F(TDMOutput, DisplayGetOutputSuccessfulWrongIndex)
+#ifdef UT_TDM_OUTPUT_ENABLE
+
+TEST_P(TDMOutput, OutputGetBackend)
 {
-       SKIP_FLAG(has_output);
-       tdm_error error = TDM_ERROR_NONE;
-       ASSERT_TRUE(NULL == tdm_display_get_output(dpy, -1, &error));
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret = (tdm_error)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_backend(outputs[o], &ret) != NULL);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMOutput, DisplayGetOutputSuccessfulBigIndex)
+TEST_P(TDMOutput, OutputGetBackendNullOBject)
 {
-       SKIP_FLAG(has_output);
-       tdm_error error = TDM_ERROR_NONE;
-       ASSERT_TRUE(NULL == tdm_display_get_output(dpy, INT_MAX, &error));
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_error ret = (tdm_error)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_backend(NULL, &ret) == NULL);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, DisplayGetOutputSuccessfulSmallIndex)
+TEST_P(TDMOutput, OutputGetBackendNullOther)
 {
-       SKIP_FLAG(has_output);
-       tdm_error error = TDM_ERROR_NONE;
-       ASSERT_TRUE(NULL == tdm_display_get_output(dpy, INT_MIN, &error));
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               ASSERT_TRUE(tdm_output_get_backend(outputs[o], NULL) != NULL);
+       }
 }
 
-TEST_F(TDMOutput, DisplayGetOutputSuccessfulErrorNull)
+TEST_P(TDMOutput, OutputGetCapabilities)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_FALSE(NULL == tdm_display_get_output(dpy, 0, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               tdm_output_capability capabilities = (tdm_output_capability)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_capabilities(outputs[o], &capabilities) == TDM_ERROR_NONE);
+               ASSERT_TRUE(capabilities != TDM_UT_INVALID_VALUE);
+       }
 }
 
-TEST_F(TDMOutput, DisplayOutputGetCapabilitiesSuccessful)
+TEST_P(TDMOutput, OutputGetCapabilitiesNullObject)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output_capability capabilities = (tdm_output_capability) -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_capabilities(output, &capabilities));
-               ASSERT_FALSE(-42 == capabilities);
-       }
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_output_capability capabilities = (tdm_output_capability)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_capabilities(NULL, &capabilities) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(capabilities == (tdm_output_capability)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, DisplayOutputGetCapabilitiesFailAllNull)
+TEST_P(TDMOutput, OutputGetCapabilitiesNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_capabilities(NULL, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_capabilities(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, DisplayOutputGetCapabilitiesFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetModelInfo)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_capabilities(output, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               const char *maker = NULL, *model = NULL, *name = NULL;
+               ASSERT_TRUE(tdm_output_get_model_info(outputs[o], &maker, &model, &name) == TDM_ERROR_NONE);
+               ASSERT_TRUE(maker != NULL);
+               ASSERT_TRUE(model != NULL);
+               ASSERT_TRUE(name != NULL);
        }
 }
 
-TEST_F(TDMOutput, OutputGetModelInfoSuccessful)
+TEST_P(TDMOutput, OutputGetModelInfoNullObject)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               const char * maker = NULL, * model = NULL, * name = NULL;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_model_info(output, &maker, &model, &name));
-               ASSERT_FALSE(NULL == maker);
-               ASSERT_FALSE(NULL == model);
-               ASSERT_FALSE(NULL == name);
-       }
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       const char *maker = (const char*)TDM_UT_INVALID_VALUE;
+       const char *model = (const char*)TDM_UT_INVALID_VALUE;
+       const char *name = (const char*)TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_output_get_model_info(NULL, &maker, &model, &name) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(maker == (const char*)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(model == (const char*)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(name == (const char*)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputGetModelInfoFailAllNull)
+TEST_P(TDMOutput, OutputGetModelInfoNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_model_info(NULL, NULL, NULL, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_model_info(outputs[0], NULL, NULL, NULL) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMOutput, OutputGetModelInfoSuccessfulOnlyOutput)
+TEST_P(TDMOutput, OutputGetConnStatus)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_model_info(output, NULL, NULL, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_conn_status(outputs[o], &status) == TDM_ERROR_NONE);
+               ASSERT_TRUE(status != TDM_UT_INVALID_VALUE);
        }
 }
 
-TEST_F(TDMOutput, OutputGetConnStatusSuccessful)
+TEST_P(TDMOutput, OutputGetConnStatusNullObject)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output_conn_status status = (tdm_output_conn_status) -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
-               ASSERT_FALSE(-42 == status);
-       }
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_output_get_conn_status(NULL, &status) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(status == (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputGetConnStatusFailAllNull)
+TEST_P(TDMOutput, OutputGetConnStatusNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_conn_status(NULL, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_conn_status(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputGetConnStatusFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetOutputType)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               tdm_output_type type = (tdm_output_type)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_output_type(outputs[o], &type) == TDM_ERROR_NONE);
+               ASSERT_TRUE(type != TDM_UT_INVALID_VALUE);
        }
 }
 
-TEST_F(TDMOutput, OutputSetDPMSSuccessful)
+TEST_P(TDMOutput, OutputGetOutputTypeNullObject)
 {
-       SKIP_FLAG(has_output);
-       bool checked = false;
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output_conn_status status;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
-               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                       continue;
-               checked = true;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_STANDBY));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_SUSPEND));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
-       }
-       if (false == checked) {
-               FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
-       }
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_output_type type = (tdm_output_type)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_output_type(NULL, &type) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(type == (tdm_output_type)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputAddChangeHandlerSuccessful)
+TEST_P(TDMOutput, OutputGetOutputTypeNullOther)
 {
-       SKIP_FLAG(has_output);
-       bool checked = false;
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               tdm_output_conn_status status;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
-               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                       continue;
-               checked = true;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
-                                                                                                                                       tdm_output_change_handler_test_func,
-                                                                                                                                       (void *) -101));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
-               ASSERT_GT(handle_call, 0);
-       }
-       if (false == checked) {
-               FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
-       }
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_output_type(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputAddChangeHandlerSuccessfulFewFuncs)
+TEST_P(TDMOutput, OutputGetLayerCount)
 {
-       SKIP_FLAG(has_output);
-       bool checked = false;
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               tdm_output_conn_status status;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
-               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                       continue;
-               checked = true;
-               for (intptr_t k = 0; k < 20; k++) {
-                       ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
-                                                                                                                                               tdm_output_change_handler_test_func,
-                                                                                                                                               (void *) (-101-k)));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               int count = TDM_UT_INVALID_VALUE;
+               if (ut_tdm_output_is_hwc_enable(outputs[o])) {
+                       ASSERT_TRUE(tdm_output_get_layer_count(outputs[o], &count) == TDM_ERROR_BAD_REQUEST);
+                       ASSERT_TRUE(count == 0);
+               } else {
+                       ASSERT_TRUE(tdm_output_get_layer_count(outputs[o], &count) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(count > 0);
                }
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
-               ASSERT_GT(handle_call, 20);
-       }
-       if (false == checked) {
-               FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
        }
 }
 
+TEST_P(TDMOutput, OutputGetLayerCountNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       int count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_layer_count(NULL, &count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
+}
 
-TEST_F(TDMOutput, OutputAddChangeHandlerFailAllNull)
+TEST_P(TDMOutput, OutputGetLayerCountNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_add_change_handler(NULL, NULL, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_layer_count(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputAddChangeHandlerFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetLayer)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_add_change_handler(output, NULL, NULL));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
+               tdm_layer *layer;
+               int layer_count = TDM_UT_INVALID_VALUE;
+
+               if (ut_tdm_output_is_hwc_enable(outputs[o])) {
+                       ASSERT_TRUE(tdm_output_get_layer_count(outputs[o], &layer_count) == TDM_ERROR_BAD_REQUEST);
+                       ASSERT_TRUE(layer_count == 0);
+
+                       layer = tdm_output_get_layer(outputs[o], 0, &ret);
+                       ASSERT_TRUE(ret == TDM_ERROR_BAD_REQUEST);
+                       ASSERT_TRUE(layer == NULL);
+               } else {
+                       ASSERT_TRUE(tdm_output_get_layer_count(outputs[o], &layer_count) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(layer_count > 0);
+
+                       for (int l = 0; l < layer_count; l++) {
+                               tdm_layer *layer = tdm_output_get_layer(outputs[o], l, &ret);
+                               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+                               ASSERT_TRUE(layer != NULL);
+                       }
+               }
        }
 }
 
-TEST_F(TDMOutput, OutputAddChangeHandlerFailWrongOutput)
+TEST_P(TDMOutput, OutputGetLayerNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({tdm_output *output = (tdm_output *) 0xBEAF;
-                                tdm_output_add_change_handler(output,
-                                                                                          tdm_output_change_handler_test_func,
-                                                                                          (void *) -101);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_error ret;
+       tdm_layer *layer = tdm_output_get_layer(NULL, 0, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(layer == NULL);
 }
 
-TEST_F(TDMOutput, OutputRemoveChangeHandlerSuccessful)
+TEST_P(TDMOutput, OutputGetLayerNullOther)
 {
-       SKIP_FLAG(has_output);
-       bool checked = false;
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               tdm_output_conn_status status;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
-               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                       continue;
-               checked = true;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
-                                                                                                                                       tdm_output_change_handler_test_func,
-                                                                                                                                       (void *) -101));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
-               ASSERT_GT(handle_call, 0);
-               handle_call = 0;
-               tdm_output_remove_change_handler(output, tdm_output_change_handler_test_func, (void *) -101);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
-               ASSERT_EQ(handle_call, 0);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_layer *layer;
+       if (ut_tdm_output_is_hwc_enable(outputs[0])) {
+               layer = tdm_output_get_layer(outputs[0], 0, NULL);
+               ASSERT_TRUE(layer == NULL);
+       } else {
+               layer = tdm_output_get_layer(outputs[0], 0, NULL);
+               ASSERT_TRUE(layer != NULL);
        }
-       if (false == checked) {
-               FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
+}
+
+TEST_P(TDMOutput, OutputGetAvailableProperties)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               int count = TDM_UT_INVALID_VALUE;
+               const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_available_properties(outputs[o], &props, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count >= 0);
+               if (count > 0)
+                       ASSERT_TRUE(props != NULL && props != (const tdm_prop *)TDM_UT_INVALID_VALUE);
        }
 }
 
-void *UtOutputRemoveChangeHandlerSuccessfulThread(void *ptr)
+TEST_P(TDMOutput, OutputGetAvailablePropertiesNullObject)
 {
-       TDMOutputCommitThread *FTDMOutput = (TDMOutputCommitThread *)ptr;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       bool checked = false;
-       for (int i = 0; i < FTDMOutput->output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(FTDMOutput->dpy, i, &error);
-               if (NULL == output || TDM_ERROR_NONE != error)
-                       return (void *)1;
-               tdm_output_conn_status status;
-               error = tdm_output_get_conn_status(output, &status);
-               if (TDM_ERROR_NONE != error)
-                       return (void *)2;
-               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                       continue;
-               checked = true;
-               error = tdm_output_add_change_handler(output,
-                                                                                               FTDMOutput->tdm_output_change_handler_test_func,
-                                                                                               (void *) -101);
-               if (TDM_ERROR_NONE != error)
-                       return (void *)3;
-               error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
-               if (TDM_ERROR_NONE != error)
-                       return (void *)4;
-               error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
-               if (TDM_ERROR_NONE != error)
-                       return (void *)5;
-               FTDMOutput->UtHandleEvent(FTDMOutput->handle_call, 1);
-               if (FTDMOutput->handle_call <= 0)
-                       return (void *)6;
-               FTDMOutput->handle_call = 0;
-               tdm_output_remove_change_handler(output, FTDMOutput->tdm_output_change_handler_test_func, (void *) -101);
-               error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
-               if (TDM_ERROR_NONE != error)
-                       return (void *)7;
-               error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
-               if (TDM_ERROR_NONE != error)
-                       return (void *)8;
-               FTDMOutput->UtHandleEvent(FTDMOutput->handle_call, 1);
-               if (FTDMOutput->handle_call != 0)
-                       return (void *)9;
+       const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+       int count = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_available_properties(NULL, &props, &count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(props == (const tdm_prop *)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
+}
+
+TEST_P(TDMOutput, OutputGetAvailablePropertiesNullOther)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_available_properties(outputs[0], NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputGetAvailableModes)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               int count = TDM_UT_INVALID_VALUE;
+               const tdm_output_mode *modes_array = (const tdm_output_mode *) TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_available_modes(outputs[o], &modes_array, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count > 0);
+               ASSERT_TRUE(modes_array != NULL && modes_array != (const tdm_output_mode *)TDM_UT_INVALID_VALUE);
        }
-       if (false == checked) {
-               return (void *)10;
+}
+
+TEST_P(TDMOutput, OutputGetAvailableModesNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       int count = TDM_UT_INVALID_VALUE;
+       const tdm_output_mode *modes_array = (const tdm_output_mode *) TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_available_modes(NULL, &modes_array, &count) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(modes_array == (const tdm_output_mode *) TDM_UT_INVALID_VALUE);
+}
+
+TEST_P(TDMOutput, OutputGetAvailableModesNullOther)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_available_modes(outputs[0], NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputGetAvailableSize)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               int min_w = TDM_UT_INVALID_VALUE, min_h = TDM_UT_INVALID_VALUE;
+               int max_w = TDM_UT_INVALID_VALUE, max_h = TDM_UT_INVALID_VALUE;
+               int preferred_align = TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_available_size(outputs[o], &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE);
+               ASSERT_TRUE(min_w != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(min_h != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(max_w != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(max_h != TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(preferred_align != TDM_UT_INVALID_VALUE);
        }
+}
+
+TEST_P(TDMOutput, OutputGetAvailableSizeNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       return nullptr;
+       int min_w = TDM_UT_INVALID_VALUE, min_h = TDM_UT_INVALID_VALUE;
+       int max_w = TDM_UT_INVALID_VALUE, max_h = TDM_UT_INVALID_VALUE;
+       int preferred_align = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(min_w == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(min_h == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(max_w == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(max_h == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(preferred_align == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutputCommitThread, OutputRemoveChangeHandlerSuccessfulThread)
+TEST_P(TDMOutput, OutputGetAvailableSizeNullOther)
 {
-       SKIP_FLAG(has_output);
-       pthread_t thread = 0;
-       int *status = nullptr;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_FALSE(pthread_create(&thread, NULL, UtOutputRemoveChangeHandlerSuccessfulThread, this));
+       ASSERT_TRUE(tdm_output_get_available_size(outputs[0], NULL, NULL, NULL, NULL, NULL) == TDM_ERROR_NONE);
+}
+
+TEST_P(TDMOutput, OutputGetCursorAvailableSize)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_FALSE(pthread_join(thread, (void **)&status));
+       int major = TDM_UT_INVALID_VALUE;
+       int minor = TDM_UT_INVALID_VALUE;
 
-       ASSERT_EQ(nullptr, status);
+       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, &major, &minor) == TDM_ERROR_NONE);
+       if (major > 1 || (major >= 1 && minor >= 5)) {
+               for (int o = 0; o < output_count; o++) {
+                       int min_w = TDM_UT_INVALID_VALUE, min_h = TDM_UT_INVALID_VALUE;
+                       int max_w = TDM_UT_INVALID_VALUE, max_h = TDM_UT_INVALID_VALUE;
+                       int preferred_align = TDM_UT_INVALID_VALUE;
+                       ASSERT_TRUE(tdm_output_get_cursor_available_size(outputs[o], &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(min_w != TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(min_h != TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(max_w != TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(max_h != TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(preferred_align != TDM_UT_INVALID_VALUE);
+               }
+       }
 }
 
-TEST_F(TDMOutput, OutputRemoveChangeHandlerSuccessfulFewFuncs)
+TEST_P(TDMOutput, OutputGetCursorAvailableSizeNullObject)
 {
-       SKIP_FLAG(has_output);
-       bool checked = false;
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               tdm_output_conn_status status;
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
-               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                       continue;
-               checked = true;
-               for (intptr_t k = 0; k < 20; k++) {
-                       ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
-                                                                                                                                               tdm_output_change_handler_test_func,
-                                                                                                                                               (void *) (-101-k)));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       int major = TDM_UT_INVALID_VALUE;
+       int minor = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, &major, &minor) == TDM_ERROR_NONE);
+       if (major > 1 || (major >= 1 && minor >= 5)) {
+               for (int o = 0; o < output_count; o++) {
+                       int min_w = TDM_UT_INVALID_VALUE, min_h = TDM_UT_INVALID_VALUE;
+                       int max_w = TDM_UT_INVALID_VALUE, max_h = TDM_UT_INVALID_VALUE;
+                       int preferred_align = TDM_UT_INVALID_VALUE;
+                       ASSERT_TRUE(tdm_output_get_cursor_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_INVALID_PARAMETER);
+                       ASSERT_TRUE(min_w == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(min_h == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(max_w == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(max_h == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(preferred_align == TDM_UT_INVALID_VALUE);
                }
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
-               ASSERT_GT(handle_call, 20);
-               handle_call = 0;
-               for (intptr_t k = 0; k < 20; k++) {
-                       tdm_output_remove_change_handler(output, tdm_output_change_handler_test_func, (void *) (-101-k));
+       }
+}
+
+TEST_P(TDMOutput, OutputGetCursorAvailableSizeNullOther)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       int major = TDM_UT_INVALID_VALUE;
+       int minor = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, &major, &minor) == TDM_ERROR_NONE);
+       if (major > 1 || (major >= 1 && minor >= 5))
+               ASSERT_TRUE(tdm_output_get_cursor_available_size(outputs[0], NULL, NULL, NULL, NULL, NULL) == TDM_ERROR_NONE);
+}
+
+TEST_P(TDMOutput, OutputGetCursorAvailableSizeNoMatchVersion)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       int major = TDM_UT_INVALID_VALUE;
+       int minor = TDM_UT_INVALID_VALUE;
+
+       ASSERT_TRUE(tdm_display_get_backend_info(dpy, NULL, NULL, &major, &minor) == TDM_ERROR_NONE);
+       if (major <= 1 && minor < 5) {
+               for (int o = 0; o < output_count; o++) {
+                       int min_w = TDM_UT_INVALID_VALUE, min_h = TDM_UT_INVALID_VALUE;
+                       int max_w = TDM_UT_INVALID_VALUE, max_h = TDM_UT_INVALID_VALUE;
+                       int preferred_align = TDM_UT_INVALID_VALUE;
+                       ASSERT_TRUE(tdm_output_get_cursor_available_size(outputs[o], &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_BAD_REQUEST);
+                       ASSERT_TRUE(min_w == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(min_h == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(max_w == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(max_h == TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(preferred_align == TDM_UT_INVALID_VALUE);
                }
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
-               ASSERT_EQ(handle_call, 0);
        }
-       if (false == checked) {
-               FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
+}
+
+TEST_P(TDMOutput, OutputGetPhysicalSize)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               unsigned int mmWidth = (unsigned int)TDM_UT_INVALID_VALUE;
+               unsigned int mmHeight = (unsigned int)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_physical_size(outputs[o], &mmWidth, &mmHeight) == TDM_ERROR_NONE);
+               ASSERT_TRUE(mmWidth != (unsigned int)TDM_UT_INVALID_VALUE);
+               ASSERT_TRUE(mmHeight != (unsigned int)TDM_UT_INVALID_VALUE);
        }
 }
 
-TEST_F(TDMOutput, OutputRemoveChangeHandlerFailAllNull)
+TEST_P(TDMOutput, OutputGetPhysicalSizeNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       unsigned int mmWidth = (unsigned int)TDM_UT_INVALID_VALUE;
+       unsigned int mmHeight = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_physical_size(NULL, &mmWidth, &mmHeight) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(mmWidth == (unsigned int)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(mmHeight == (unsigned int)TDM_UT_INVALID_VALUE);
+}
+
+TEST_P(TDMOutput, OutputGetPhysicalSizeNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({tdm_output_remove_change_handler(NULL, NULL, NULL);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_physical_size(outputs[0], NULL, NULL) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMOutput, OutputRemoveChangeHandlerFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetSubpixel)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        tdm_output_remove_change_handler(output, NULL, NULL);
-                                } exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               unsigned int subpixel = (unsigned int)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_subpixel(outputs[o], &subpixel) == TDM_ERROR_NONE);
+               ASSERT_TRUE(subpixel != (unsigned int)TDM_UT_INVALID_VALUE);
+       }
 }
 
-TEST_F(TDMOutput, OutputRemoveChangeHandlerFailWrongOutput)
+TEST_P(TDMOutput, OutputGetSubpixelNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({tdm_output *output = (tdm_output *) 0xBEAF;
-                                tdm_output_remove_change_handler(output,
-                                                                                          tdm_output_change_handler_test_func,
-                                                                                          (void *) -101);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       unsigned int subpixel = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_subpixel(NULL, &subpixel) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(subpixel == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputGetOutputTypeSuccessful)
+TEST_P(TDMOutput, OutputGetSubpixelNullOther)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output_type type = (tdm_output_type) -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_output_type(output, &type));
-               ASSERT_NE(type, -42);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_subpixel(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputGetPipe)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               unsigned int pipe = (unsigned int)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_pipe(outputs[o], &pipe) == TDM_ERROR_NONE);
+               ASSERT_TRUE(pipe != (unsigned int)TDM_UT_INVALID_VALUE);
        }
 }
 
-TEST_F(TDMOutput, OutputGetOutputTypeFailNullAll)
+TEST_P(TDMOutput, OutputGetPipeNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_output_type(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       unsigned int pipe = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_pipe(NULL, &pipe) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(pipe == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputGetOutputTypeFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetPipeNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_output_type(output, NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_pipe(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputGetLayerCountSuccessful)
+TEST_P(TDMOutput, OutputGetPrimaryIndex)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int count = -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_layer_count(output, &count));
-               ASSERT_NE(count, -42);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               int primary_index = TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_primary_index(outputs[o], &primary_index) == TDM_ERROR_NONE);
+               ASSERT_TRUE(primary_index != TDM_UT_INVALID_VALUE);
        }
 }
 
-int is_hwc_ennable(tdm_output * output)
+TEST_P(TDMOutput, OutputGetPrimaryIndexNullObject)
 {
-       tdm_output_capability capabilities = (tdm_output_capability)0;
-       tdm_output_get_capabilities(output, &capabilities);
-       return capabilities & TDM_OUTPUT_CAPABILITY_HWC;
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       int primary_index = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_primary_index(NULL, &primary_index) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(primary_index == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutputHWC, OutputGetLayerCountFailHWC)
+TEST_P(TDMOutput, OutputGetPrimaryIndexNullOther)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int count = -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               if (is_hwc_ennable(output))
-                       ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_get_layer_count(output, &count));
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_primary_index(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputSetProperty)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+               int count = TDM_UT_INVALID_VALUE;
+               tdm_value value = {.s32 = 0};
+
+               ASSERT_TRUE(tdm_output_get_available_properties(outputs[o], &props, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count >= 0);
+               if (count > 0) {
+                       ASSERT_TRUE(props != NULL && props != (const tdm_prop *)TDM_UT_INVALID_VALUE);
+                       ASSERT_TRUE(tdm_output_set_property(outputs[o], props[0].id, value) == TDM_ERROR_NONE);
+               }
        }
 }
 
-TEST_F(TDMOutputHWC, OutputGetLayerFailHWC)
+TEST_P(TDMOutput, OutputSetPropertyNullObject)
+{
+       tdm_value value = {.s32 = 0};
+
+       ASSERT_TRUE(tdm_output_set_property(NULL, 0, value) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputGetProperty)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               if (is_hwc_ennable(output)) {
-                       ASSERT_TRUE(nullptr == tdm_output_get_layer(output, 0, &error));
-                       ASSERT_TRUE(TDM_ERROR_NONE != error);
+       for (int o = 0; o < output_count; o++) {
+               int count = TDM_UT_INVALID_VALUE;
+               const tdm_prop *props = (const tdm_prop *)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_output_get_available_properties(outputs[o], &props, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(count >= 0);
+               if (count > 0) {
+                       ASSERT_TRUE(props != NULL && props != (const tdm_prop *)TDM_UT_INVALID_VALUE);
+
+                       for (int i = 0; i < count; i++) {
+                               tdm_value value = {.s32 = TDM_UT_INVALID_VALUE};
+                               ASSERT_TRUE(tdm_output_get_property(outputs[o], props[i].id, &value) == TDM_ERROR_NONE);
+                               ASSERT_TRUE(value.s32 != TDM_UT_INVALID_VALUE);
+                       }
                }
        }
 }
 
-TEST_F(TDMOutput, OutputGetLayerCountFailNullAll)
+TEST_P(TDMOutput, OutputGetPropertyNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_layer_count(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_value value = {.s32 = TDM_UT_INVALID_VALUE};
+       ASSERT_TRUE(tdm_output_get_property(NULL, 0, &value) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(value.s32 == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputGetLayerCountFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetPropertyNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (TDM_ERROR_NONE == tdm_output_get_layer_count(output, NULL)) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_property(outputs[0], 0, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputGetAvailablePropertiesSuccessful)
+static void
+_ut_tdm_output_change_cb(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int count = -42;
-               const tdm_prop *tdm_prop_array = (const tdm_prop *) 0xBEAF;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_properties(output,
-                                                                                                                                                 &tdm_prop_array,
-                                                                                                                                                 &count));
-               ASSERT_NE(count, -42);
-               ASSERT_NE(tdm_prop_array, 0xBEAF);
+       bool *done = (bool *)user_data;
+       if (done)
+               *done = true;
+}
+
+TEST_P(TDMOutput, OutputAddChangeHandler)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       bool done;
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+
+               done = false;
+               ASSERT_TRUE(tdm_output_add_change_handler(outputs[o], _ut_tdm_output_change_cb, &done) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               ASSERT_TRUE(done == true);
        }
 }
 
-TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullAll)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_available_properties(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailablePropertiesFailOnlyOutput)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (TDM_ERROR_NONE == tdm_output_get_available_properties(output, NULL, NULL)) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullCount)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        const tdm_prop *tdm_prop_array = NULL;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (TDM_ERROR_NONE == tdm_output_get_available_properties(output,
-                                                                                                                                                          &tdm_prop_array,
-                                                                                                                                                          NULL)) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullProperty)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        int count = -42;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (TDM_ERROR_NONE == tdm_output_get_available_properties(output,
-                                                                                                                                                          NULL,
-                                                                                                                                                          &count)) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailableModesSuccessful)
-{
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int count = -42;
-               const tdm_output_mode *modes_array = (const tdm_output_mode *) 0xBEAF;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_modes(output,
-                                                                                                                                        &modes_array,
-                                                                                                                                        &count));
-               ASSERT_NE(count, -42);
-               ASSERT_NE(modes_array, 0xBEAF);
+TEST_P(TDMOutput, OutputAddChangeHandlerTwice)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_add_change_handler(outputs[0], _ut_tdm_output_change_cb, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_output_add_change_handler(outputs[0], _ut_tdm_output_change_cb, NULL) == TDM_ERROR_BAD_REQUEST);
+}
+
+TEST_P(TDMOutput, OutputAddChangeHandlerNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_add_change_handler(NULL, _ut_tdm_output_change_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputAddChangeHandlerNullOther)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_add_change_handler(outputs[0], NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputRemoveChangeHandler)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               for (int t = 0; t < 100; t++) {
+                       ASSERT_TRUE(tdm_output_add_change_handler(outputs[o], _ut_tdm_output_change_cb, NULL) == TDM_ERROR_NONE);
+                       tdm_output_remove_change_handler(outputs[o], _ut_tdm_output_change_cb, NULL);
+               }
        }
 }
 
-TEST_F(TDMOutput, OutputGetAvailableModesFailNullAll)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_available_modes(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailableModesFailOnlyOutput)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (TDM_ERROR_NONE == tdm_output_get_available_modes(output, NULL, NULL)) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailableModesFailNullCount)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        const tdm_output_mode *modes_array = NULL;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (TDM_ERROR_NONE == tdm_output_get_available_modes(output,
-                                                                                                                                                 &modes_array,
-                                                                                                                                                 NULL)) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailableModesFailNullModes)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        int count = -42;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (TDM_ERROR_NONE == tdm_output_get_available_modes(output,
-                                                                                                                                                 NULL,
-                                                                                                                                                 &count)) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailableSizeSuccessful)
-{
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int min_w = -42, min_h = -42, max_w = -42, max_h = -42, preferred_align = -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_size(output, &min_w, &min_h,
-                                                                                                                                       &max_w, &max_h, &preferred_align));
-               ASSERT_NE(min_w, -42);
-               ASSERT_NE(min_h, -42);
-               ASSERT_NE(max_w, -42);
-               ASSERT_NE(max_h, -42);
-               ASSERT_NE(preferred_align, -42);
+TEST_P(TDMOutput, OutputRemoveChangeHandlerDifferentData)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       bool done;
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+
+               done = false;
+               ASSERT_TRUE(tdm_output_add_change_handler(outputs[o], _ut_tdm_output_change_cb, &done) == TDM_ERROR_NONE);
+               tdm_output_remove_change_handler(outputs[o], _ut_tdm_output_change_cb, NULL);
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               ASSERT_TRUE(done == true);
        }
 }
 
-TEST_F(TDMOutput, OutputGetAvailableSizeFailNullAll)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_available_size(NULL, NULL, NULL,
-                                                                                                  NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMOutput, OutputGetAvailableSizeSuccessfulOnlyOutput)
-{
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_available_size(output, NULL, NULL,
-                                                                                                               NULL, NULL, NULL) != TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
-}
-
-/*TODO: this test has to be fixed in the backends by increase the ABI version upper than 1.5*/
-TEST_F(TDMOutput, DISABLED_OutputGetCursorAvailableSizeSuccessful)
-{
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int min_w = -42, min_h = -42, max_w = -42, max_h = -42, preferred_align = -42;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_cursor_available_size(output, &min_w, &min_h,
-                                                                                                                                                  &max_w, &max_h, &preferred_align));
-               ASSERT_NE(min_w, -42);
-               ASSERT_NE(min_h, -42);
-               ASSERT_NE(max_w, -42);
-               ASSERT_NE(max_h, -42);
-               ASSERT_NE(preferred_align, -42);
+static void
+_ut_tdm_output_change_cb2(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data)
+{
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+       tdm_output_remove_change_handler(output, _ut_tdm_output_change_cb2, user_data);
+}
+
+TEST_P(TDMOutput, OutputRemoveChangeHandlerInHandler)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       bool done1, done2, done3;
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+
+               done1 = false;
+               ASSERT_TRUE(tdm_output_add_change_handler(outputs[o], _ut_tdm_output_change_cb2, &done1) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               ASSERT_TRUE(done1 == true);
+
+               done2 = false;
+               ASSERT_TRUE(tdm_output_add_change_handler(outputs[o], _ut_tdm_output_change_cb, &done2) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+               ASSERT_TRUE(done2 == true);
+
+               done3 = false;
+               ASSERT_TRUE(tdm_output_add_change_handler(outputs[o], _ut_tdm_output_change_cb2, &done3) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               ASSERT_TRUE(done3 == true);
        }
 }
 
-TEST_F(TDMOutput, OutputGetCursorAvailableSizeFailNullAll)
+TEST_P(TDMOutput, OutputRemoveChangeHandlerNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_cursor_available_size(NULL, NULL, NULL,
-                                                                                                                 NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_output_remove_change_handler(NULL, _ut_tdm_output_change_cb, NULL);
 }
 
-/*TODO: this test has to be fixed in the backends by increase the ABI version upper than 1.5*/
-TEST_F(TDMOutput, DISABLED_OutputGetCursorAvailableSizeSuccessfulOnlyOutput)
+TEST_P(TDMOutput, OutputRemoveChangeHandlerNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_cursor_available_size(output, NULL, NULL,
-                                                                                                                         NULL, NULL, NULL) != TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_output_remove_change_handler(outputs[0], NULL, NULL);
 }
 
-TEST_F(TDMOutput, OutputGetPhysicalSizeSuccessful)
+TEST_P(TDMOutput, OutputSetMode)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               unsigned int mmWidth = UINT_MAX, mmHeight = UINT_MAX;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_physical_size(output, &mmWidth, &mmHeight));
-               ASSERT_NE(mmWidth, UINT_MAX);
-               ASSERT_NE(mmHeight, UINT_MAX);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *modes;
+               int count;
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_get_available_modes(outputs[o], &modes, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(modes != NULL);
+               ASSERT_TRUE(count > 0);
+
+               for (int m = 0; m < count; m++)
+                       ASSERT_TRUE(tdm_output_set_mode(outputs[o], modes + m) == TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMOutput, OutputGetPhysicalSizeFailNullAll)
+TEST_P(TDMOutput, OutputSetModeNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_physical_size(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       const tdm_output_mode *mode = (const tdm_output_mode *)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_set_mode(NULL, mode) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputGetPhysicalSuccessfulOnlyOutput)
+TEST_P(TDMOutput, OutputSetModeNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_physical_size(output, NULL, NULL) != TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_set_mode(outputs[o], NULL) == TDM_ERROR_INVALID_PARAMETER);
+       }
 }
 
-TEST_F(TDMOutput, OutputGetSubpixelSuccessful)
+TEST_P(TDMOutput, OutputGetMode)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               unsigned int subpixel = UINT_MAX;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_subpixel(output, &subpixel));
-               ASSERT_NE(subpixel, UINT_MAX);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *modes;
+               int count;
+
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_get_available_modes(outputs[o], &modes, &count) == TDM_ERROR_NONE);
+               ASSERT_TRUE(modes != NULL);
+               ASSERT_TRUE(count > 0);
+
+               for (int m = 0; m < count; m++) {
+                       const tdm_output_mode *current_mode;
+                       ASSERT_TRUE(tdm_output_set_mode(outputs[o], modes + m) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_get_mode(outputs[o], &current_mode) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(current_mode == modes + m);
+               }
        }
 }
 
-TEST_F(TDMOutput, OutputGetSubpixelFailNullAll)
+TEST_P(TDMOutput, OutputGetModeNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_subpixel(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       const tdm_output_mode *current_mode = (const tdm_output_mode *)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_mode(NULL, &current_mode) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(current_mode == (const tdm_output_mode *)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputGetSubpixelFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetModeNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_subpixel(output, NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_mode(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputGetPipeSuccessful)
+TEST_P(TDMOutput, OutputGetModeNoSet)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               unsigned int pipe = UINT_MAX;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_pipe(output, &pipe));
-               ASSERT_NE(pipe, UINT_MAX);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               const tdm_output_mode *mode;
+               ASSERT_TRUE(tdm_output_get_mode(outputs[o], &mode) == TDM_ERROR_NONE);
+               ASSERT_TRUE(mode == NULL);
        }
 }
 
-TEST_F(TDMOutput, OutputGetPipeFailNullAll)
+TEST_P(TDMOutput, OutputSetDPMS)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_STANDBY) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_SUSPEND) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               if (ut_tdm_output_is_aod_enable(outputs[o])) {
+                       ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_AOD) == TDM_ERROR_NONE);
+               } else {
+                       ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_AOD) == TDM_ERROR_BAD_REQUEST);
+               }
+       }
+}
+
+TEST_P(TDMOutput, OutputSetDPMSNullObject)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_set_dpms(NULL, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMOutput, OutputSetDPMSNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_pipe(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_set_dpms(outputs[0], (tdm_output_dpms)-1) == TDM_ERROR_BAD_REQUEST);
+       ASSERT_TRUE(tdm_output_set_dpms(outputs[0], (tdm_output_dpms)INT_MAX) == TDM_ERROR_BAD_REQUEST);
 }
 
-TEST_F(TDMOutput, OutputGetPipeFailOnlyOutput)
+TEST_P(TDMOutput, OutputSetDPMSAsync)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_pipe(output, NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               bool done = false;
+
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+               if (!ut_tdm_output_is_async_dpms_enable(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_add_change_handler(outputs[o], _ut_tdm_output_change_cb, &done) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms_async(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               while(!done)
+                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               tdm_output_remove_change_handler(outputs[o], _ut_tdm_output_change_cb, &done);
+       }
 }
 
-TEST_F(TDMOutput, OutputGetPrimaryIndexSuccessful)
+TEST_P(TDMOutput, OutputGetDPMS)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               int primary_index = INT_MAX;
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_primary_index(output, &primary_index));
-               ASSERT_NE(primary_index, INT_MAX);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               tdm_output_dpms dpms_value;
+
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_get_dpms(outputs[o], &dpms_value) == TDM_ERROR_NONE);
+               ASSERT_TRUE(dpms_value == TDM_OUTPUT_DPMS_OFF);
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_STANDBY) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_get_dpms(outputs[o], &dpms_value) == TDM_ERROR_NONE);
+               ASSERT_TRUE(dpms_value == TDM_OUTPUT_DPMS_STANDBY);
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_SUSPEND) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_get_dpms(outputs[o], &dpms_value) == TDM_ERROR_NONE);
+               ASSERT_TRUE(dpms_value == TDM_OUTPUT_DPMS_SUSPEND);
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_get_dpms(outputs[o], &dpms_value) == TDM_ERROR_NONE);
+               ASSERT_TRUE(dpms_value == TDM_OUTPUT_DPMS_ON);
+
+               if (ut_tdm_output_is_aod_enable(outputs[o])) {
+                       ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_AOD) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_get_dpms(outputs[o], &dpms_value) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(dpms_value == TDM_OUTPUT_DPMS_AOD);
+               } else {
+                       ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_AOD) == TDM_ERROR_BAD_REQUEST);
+               }
        }
 }
 
-TEST_F(TDMOutput, OutputGetPrimaryIndexFailNullAll)
+TEST_P(TDMOutput, OutputGetDPMSNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({if (tdm_output_get_primary_index(NULL, NULL) == TDM_ERROR_NONE) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       tdm_output_dpms dpms_value = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_output_get_dpms(NULL, &dpms_value) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(dpms_value == (tdm_output_dpms)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMOutput, OutputGetPrimaryIndexFailOnlyOutput)
+TEST_P(TDMOutput, OutputGetDPMSNullOther)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
-                                        tdm_error error = TDM_ERROR_NONE;
-                                        tdm_output * output = tdm_display_get_output(dpy, i, &error);
-                                        if (NULL == output) exit(1);
-                                        if (TDM_ERROR_NONE != error) exit(1);
-                                        if (tdm_output_get_primary_index(output, NULL) == TDM_ERROR_NONE) exit(1);
-                               }
-                               exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_get_dpms(outputs[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputSetPropertySuccessful)
+TEST_P(TDMOutput, OutputWaitVblank)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_value value = {.u32 = 0};
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               error = tdm_output_set_property(output, UINT_MAX, value);
-               ASSERT_TRUE(error == TDM_ERROR_NOT_IMPLEMENTED || error == TDM_ERROR_OPERATION_FAILED);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               for (int t = 0; t < 10; t++) {
+                       bool done = false;
+                       double start, end, interval;
+
+                       interval = ut_tdm_output_get_vblank_interval_time(outputs[o]);
+
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], 1, 0, _ut_tdm_output_done_cb, &done) == TDM_ERROR_NONE);
+                       while(!done)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
+
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) < (interval + interval));
+               }
        }
 }
 
-TEST_F(TDMOutput, OutputSetPropertyFailNullAll)
+TEST_P(TDMOutput, OutputWaitVblankNullObject)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({tdm_error error = TDM_ERROR_NONE;
-                                tdm_value value = {.u32 = 0};
-                                error = tdm_output_set_property(NULL, 0, value);
-                                if (error == TDM_ERROR_NONE || error == TDM_ERROR_NOT_IMPLEMENTED ||
-                                       error == TDM_ERROR_OPERATION_FAILED) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_TRUE(tdm_output_wait_vblank(NULL, 1, 0, _ut_tdm_output_done_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutput, OutputGetPropertySuccessful)
+TEST_P(TDMOutput, OutputWaitVblankNullOther)
 {
-       SKIP_FLAG(has_output);
-       for (int i = 0; i < output_count; i++) {
-               tdm_error error = TDM_ERROR_NONE;
-               tdm_value value = {.u32 = 0};
-               tdm_output * output = tdm_display_get_output(dpy, i, &error);
-               ASSERT_FALSE(NULL == output);
-               ASSERT_TRUE(TDM_ERROR_NONE == error);
-               error = tdm_output_get_property(output, UINT_MAX, &value);
-               ASSERT_TRUE(error == TDM_ERROR_NOT_IMPLEMENTED || error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], 1, 0, NULL, NULL) == TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMOutput, OutputGetPropertyFailNullAll)
+TEST_P(TDMOutput, OutputWaitVblankTimeout)
 {
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({tdm_error error = TDM_ERROR_NONE;
-                                error = tdm_output_get_property(NULL, 0, NULL);
-                                if (error == TDM_ERROR_NONE || error == TDM_ERROR_NOT_IMPLEMENTED ||
-                                        error == TDM_ERROR_OPERATION_FAILED) exit(1);
-                                exit(0);}, ::testing::ExitedWithCode(0), "");
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], 1, 0, _ut_tdm_output_done_cb, NULL) == TDM_ERROR_NONE);
+
+               usleep(1100000);
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+
+               ASSERT_TRUE(tdm_helper_output_vblank_timer_expired(outputs[o]) > 0);
+       }
 }
 
-TEST_F(TDMOutputCommit, OutputCommitFailNullAll)
+TEST_P(TDMOutput, OutputWaitVblankInterval0)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(NULL, 0, NULL, NULL));
+       ASSERT_TRUE(tdm_output_wait_vblank(outputs[0], 0, 0, _ut_tdm_output_done_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutputCommit, OutputCommit)
+TEST_P(TDMOutput, OutputWaitVblankInterval)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       bool done = false;
+                       double start, end, interval;
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+                       interval = ut_tdm_output_get_vblank_interval_time(outputs[o]);
 
-       UtHandleCommitEvent();
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done) == TDM_ERROR_NONE);
+                       while(!done)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) > (interval * (t - 1)));
+                       ASSERT_TRUE((end - start) < (interval * t + interval));
+               }
+       }
 }
 
-TEST_F(TDMOutputCommitThread, OutputCommit)
+TEST_P(TDMOutput, OutputWaitVblankFewTimesInOneVblank)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       double start, end, interval;
+
+                       interval = ut_tdm_output_get_vblank_interval_time(outputs[o]);
+
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done3) == TDM_ERROR_NONE);
+                       while(!done1 || !done2 || !done3) {
+                               start = tdm_helper_get_time();
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                               end = tdm_helper_get_time();
+
+                               /* "+ interval" consider the delay of socket communication between kernel and platform */
+                               ASSERT_TRUE((end - start) > (interval * (t - 1)));
+                               ASSERT_TRUE((end - start) < (interval * t + interval));
+                       }
+               }
+       }
+}
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+TEST_P(TDMOutput, OutputRemoveVblankHandler)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       UtHandleCommitEvent();
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done3) == TDM_ERROR_NONE);
+                       tdm_output_remove_vblank_handler(outputs[o], _ut_tdm_output_done_cb, &done2);
+                       while(!done1 || done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
+       }
 }
 
-TEST_F(TDMOutputCommitPerVblankEnabled, OutputCommitFailLayerCommit)
+TEST_P(TDMOutput, OutputRemoveVblankHandlerDifferentData)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       for (size_t i = 0; i < layers_array.size(); ++i) {
-               for (tdm_layer *layer : layers_array[i]) {
-                       tdm_layer_commit(layer, NULL, NULL);
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done3) == TDM_ERROR_NONE);
+                       tdm_output_remove_vblank_handler(outputs[o], _ut_tdm_output_done_cb, NULL);
+                       while(!done1 || !done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
                }
        }
+}
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+static void
+_ut_tdm_output_done_cb2(tdm_output *output, unsigned int sequence,
+                                               unsigned int tv_sec, unsigned int tv_usec,
+                                               void *user_data)
+{
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
+       tdm_output_remove_commit_handler(output, _ut_tdm_output_done_cb2, user_data);
 }
 
-TEST_F(TDMOutputCommitPerVblankEnabled, OutputCommitFailCommitPerVblankEnabled)
+TEST_P(TDMOutput, OutputRemoveVblankHandlerInHandler)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], t, 0, _ut_tdm_output_done_cb, &done3) == TDM_ERROR_NONE);
+                       while(!done1 || !done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
+       }
 }
 
-TEST_F(TDMOutputCommit, OutputCommitFailDpmsOff)
+TEST_P(TDMOutput, OutputCommit)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
+
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               for (int t = 0; t < 10; t++) {
+                       bool done = false;
+                       double start, end, interval;
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+                       interval = ut_tdm_output_get_vblank_interval_time(outputs[o]);
 
-       for (int i = 0; i < conn_output_count; i++) {
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i], TDM_OUTPUT_DPMS_OFF));
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done) == TDM_ERROR_NONE);
+                       while(!done)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-               ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) < (interval + interval));
+               }
        }
 }
 
-TEST_F(TDMOutputCommit, OutputWaitVBlankFailNullAll)
+TEST_P(TDMOutput, OutputCommitNullObject)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_wait_vblank(nullptr, 1, 0, nullptr, nullptr));
+       ASSERT_TRUE(tdm_output_commit(NULL, 0, _ut_tdm_output_done_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMOutputCommit, OutputWaitVBlankFailDpmsOff)
+TEST_P(TDMOutput, OutputCommitNullOther)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
 
-       for (int i = 0; i < conn_output_count; i++) {
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i], TDM_OUTPUT_DPMS_OFF));
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-               for (int i = 0; i < conn_output_count; i++)
-                       ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, nullptr));
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_commit(outputs[o], 0, NULL, NULL) == TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMOutputCommit, OutputWaitVBlank)
+TEST_P(TDMOutput, OutputCommitDpmsSuspend)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
+
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, nullptr));
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_SUSPEND) == TDM_ERROR_NONE);
 
-       UtHandleCommitEvent();
+               ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, NULL) == TDM_ERROR_DPMS_OFF);
+       }
+}
 
-       ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+TEST_P(TDMOutput, OutputCommitDpmsOff)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, nullptr));
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
+
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       UtHandleVblankEvent();
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
 
-       ASSERT_EQ(conn_output_count, utOutputVblankHandlerCounter);
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+
+               ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, NULL) == TDM_ERROR_DPMS_OFF);
+       }
 }
 
-TEST_F(TDMOutputCommitThread, OutputWaitVBlank)
+TEST_P(TDMOutput, OutputCommitDpmsAOD)
 {
-       SKIP_FLAG(has_output);
-
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
 
-       UtHandleCommitEvent();
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+               if (!ut_tdm_output_is_aod_enable(outputs[o]))
+                       continue;
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, NULL));
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
 
-       UtHandleVblankEvent();
+               ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_AOD) == TDM_ERROR_NONE);
 
-       ASSERT_EQ(conn_output_count, utOutputVblankHandlerCounter);
+               for (int t = 0; t < 10; t++) {
+                       bool done = false;
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done) == TDM_ERROR_NONE);
+                       while(!done)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
+       }
 }
 
-TEST_F(TDMOutputCommit, OutputRemoveVblankHandlerFailNullAll)
+TEST_P(TDMOutput, OutputCommitAfterLayerCommit)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               int index = TDM_UT_INVALID_VALUE;
+               tdm_layer *layer;
+               tdm_error ret;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               ASSERT_TRUE(tdm_output_get_primary_index(outputs[o], &index) == TDM_ERROR_NONE);
+               ASSERT_TRUE(index != TDM_UT_INVALID_VALUE);
+
+               layer = tdm_output_get_layer(outputs[o], index, &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(layer != NULL);
+
+               ASSERT_TRUE(tdm_layer_commit(layer, NULL, NULL) == TDM_ERROR_NONE);
 
-       ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_remove_vblank_handler(nullptr, nullptr, nullptr));
+               if (!tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, NULL, NULL) == TDM_ERROR_NONE);
+               else
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, NULL, NULL) == TDM_ERROR_BAD_REQUEST);
+       }
 }
 
-TEST_F(TDMOutputCommitThread, OutputRemoveVblankHandlerSuccess)
+TEST_P(TDMOutput, OutputCommitMismatchCommitType)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+       for (int o = 0; o < output_count; o++) {
+               if (!tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
+               ASSERT_TRUE(tdm_output_commit(outputs[o], 0, NULL, NULL) == TDM_ERROR_BAD_REQUEST);
+       }
+}
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+TEST_P(TDMOutput, OutputCommitFewTimesInOneVblank)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       UtHandleCommitEvent();
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
 
-       ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 2, 0, UtOutputVblankHandler, NULL));
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
 
-       for (int i = 0; i < conn_output_count; i++) {
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_remove_vblank_handler(connected_output_array[i], UtOutputVblankHandler, NULL));
+               for (int t = 0; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done3) == TDM_ERROR_NONE);
+                       while(!done1 || !done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
        }
+}
 
-       UtHandleVblankEvent();
+TEST_P(TDMOutput, OutputRemoveCommitHandler)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_EQ(0, utOutputVblankHandlerCounter);
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
+
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               for (int t = 0; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done3) == TDM_ERROR_NONE);
+                       tdm_output_remove_commit_handler(outputs[o], _ut_tdm_output_done_cb, &done2);
+                       while(!done1 || done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
+       }
 }
 
-TEST_F(TDMOutputCommit, OutputRemoveCommitHandlerFailNullAll)
+TEST_P(TDMOutput, OutputRemoveCommitHandlerDifferentData)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
 
-       ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_remove_commit_handler(nullptr, nullptr, nullptr));
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+
+               for (int t = 0; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb, &done3) == TDM_ERROR_NONE);
+                       tdm_output_remove_commit_handler(outputs[o], _ut_tdm_output_done_cb, NULL);
+                       while(!done1 || !done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
+       }
 }
 
-TEST_F(TDMOutputCommitThread, OutputRemoveCommitHandlerSuccess)
+TEST_P(TDMOutput, OutputRemoveCommitHandlerInHandler)
 {
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+       for (int o = 0; o < output_count; o++) {
+               /* if true, have to use tdm_layer_commit. so skip */
+               if (tdm_helper_output_commit_per_vblank_enabled(outputs[o]))
+                       continue;
 
-       for (int i = 0; i < conn_output_count; i++)
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-       for (int i = 0; i < conn_output_count; i++) {
-               ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_remove_commit_handler(connected_output_array[i], UtOutputCommitHandler, NULL));
-       }
+               ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true);
 
-       UtHandleCommitEvent();
+               for (int t = 0; t < 10; t++) {
+                       bool done1 = false, done2 = false, done3 = false;
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb2, &done1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb2, &done2) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_output_commit(outputs[o], 0, _ut_tdm_output_done_cb2, &done3) == TDM_ERROR_NONE);
+                       while(!done1 || !done2 || !done3)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+               }
+       }
 }
+
+INSTANTIATE_TEST_CASE_P(TDMOutputParams,
+                                               TDMOutput,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
index dd26f0e..a2d1b65 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
 #include "ut_tdm.h"
-#include "tdm.h"
-#include "tdm_config.h"
-extern "C" {
-#include "tbm_bufmgr.h"
-#include "tbm_drm_helper.h"
-}
-
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#include <list>
-#include <limits.h>
-
-#define SIZE_ALIGN(value, base) (((value) + ((base) - 1)) & ~((base) - 1))
-
-class TDMPPWithoutCreation : public testing::Test {
-protected:
-       tdm_display *dpy = NULL;
-       tbm_bufmgr bufmgr;
-       tdm_display_capability display_capability = (tdm_display_capability)0;
-       bool has_pp = false;
-       std::list<tbm_surface_h> buffers_list;
-
-       virtual void SetEnvs()
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-       }
-
-       virtual void UnsetEnvs()
-       {
-               unsetenv("XDG_RUNTIME_DIR");
-               unsetenv("TBM_DISPLAY_SERVER");
-       }
-
-       void SetUp(void)
-       {
-               tdm_error error = TDM_ERROR_NONE;
-
-               SetEnvs();
-
-               bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(bufmgr == NULL);
-
-               dpy = tdm_display_init(&error);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               ASSERT_FALSE(dpy == NULL);
-
-               error = tdm_display_get_capabilities(dpy, &display_capability);
-#ifdef FAIL_ON_UNSUPPORTED
-               ASSERT_TRUE(display_capability & TDM_DISPLAY_CAPABILITY_PP);
-#endif
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               if (display_capability & TDM_DISPLAY_CAPABILITY_PP)
-                       has_pp = true;
-       }
-
-       void TearDown(void)
-       {
-               if (dpy)
-                       tdm_display_deinit(dpy);
-               if (bufmgr)
-                       tbm_bufmgr_deinit(bufmgr);
-
-               UnsetEnvs();
-       }
-};
-
-class TDMPP : public TDMPPWithoutCreation {
-protected:
-       tdm_pp *pp = NULL;
-       const tbm_format *formats = NULL;
-       int format_count = 0;
-       int min_w = 0;
-       int min_h = 0;
-       int max_w = 0;
-       int max_h = 0;
-       int preferred_align = 0;
-       int default_src_w = 128;
-       int default_src_h = 256;
-       int default_dst_w = 512;
-       int default_dst_h = 1024;
-
-       void SetUp(void)
-       {
-               tdm_error error;
-
-               ASSERT_NO_FATAL_FAILURE(TDMPPWithoutCreation::SetUp());
-
-               if (!has_pp)
-                       return;
-
-               pp = tdm_display_create_pp(dpy, &error);
-               ASSERT_NE(NULL, pp);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-
-               error =
-                       tdm_display_get_pp_available_formats(dpy, &formats, &format_count);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               ASSERT_NE(NULL, formats);
-               ASSERT_GE(format_count, 0);
-
-               error =
-                               tdm_display_get_pp_available_size(dpy, &min_w, &min_h,
-                                                                                                 &max_w, &max_h, &preferred_align);
-               ASSERT_EQ(TDM_ERROR_NONE, error);
-               if (preferred_align > 0) {
-                       default_src_w = SIZE_ALIGN(default_src_w, preferred_align);
-                       default_src_h = SIZE_ALIGN(default_src_h, preferred_align);
-                       default_dst_w = SIZE_ALIGN(default_dst_w, preferred_align);
-                       default_dst_h = SIZE_ALIGN(default_dst_h, preferred_align);
-               }
-               if (min_w > default_src_w)
-                       default_src_w = min_w;
-               if (min_h > default_src_h)
-                       default_src_h = min_h;
-               if (max_w > 0 && max_w < default_dst_w)
-                       default_dst_w = max_w;
-               if (max_h > 0 && max_h < default_dst_h)
-                       default_dst_h = max_h;
-       }
-
-       void TearDown(void)
-       {
-               if (pp)
-                       tdm_pp_destroy(pp);
-
-               for (auto it = buffers_list.begin(); it != buffers_list.end(); ++it) {
-                       tbm_surface_destroy(*it);
-               }
-
-               buffers_list.clear();
-
-               TDMPPWithoutCreation::TearDown();
-       }
-
-       void UtGetPPInfoWithScale(tdm_info_pp *info)
-       {
-               memset((void *)info, 0, sizeof(tdm_info_pp));
-
-               info->src_config.size.h = default_src_w;
-               info->src_config.size.v = default_src_h;
-               info->src_config.pos.x = 0;
-               info->src_config.pos.y = 0;
-               info->src_config.pos.w = default_src_w;
-               info->src_config.pos.h = default_src_h;
-               info->src_config.format = formats[0];
-               info->dst_config.size.h = default_dst_w;
-               info->dst_config.size.v = default_dst_h;
-               info->dst_config.pos.x = 0;
-               info->dst_config.pos.y = 0;
-               info->dst_config.pos.w = default_dst_w;
-               info->dst_config.pos.h = default_dst_h;
-               info->dst_config.format = formats[0];
-       }
-
-       void UtGetPPInfoWithScaleAndTransform(tdm_info_pp *info)
-       {
-               UtGetPPInfoWithScale(info);
-
-               info->transform = TDM_TRANSFORM_180;
-       }
-
-       void UtGetPPInfoWithWrongInfo(tdm_info_pp *info)
-       {
-               info->src_config.size.h = UINT_MAX;
-               info->src_config.size.v = UINT_MAX;
-               info->src_config.pos.x = 0;
-               info->src_config.pos.y = 0;
-               info->src_config.pos.w = UINT_MAX;
-               info->src_config.pos.h = UINT_MAX;
-               info->src_config.format = INT_MAX;
-               info->dst_config.size.h = UINT_MAX;
-               info->dst_config.size.v = UINT_MAX;
-               info->dst_config.pos.x = 0;
-               info->dst_config.pos.y = 0;
-               info->dst_config.pos.w = UINT_MAX;
-               info->dst_config.pos.h = UINT_MAX;
-               info->dst_config.format = INT_MAX;
-       }
-
-       tbm_surface_h
-       UtCreateBuffer(int w, int h, tbm_format format)
-       {
-               tbm_surface_h buffer;
-
-               buffer = tbm_surface_create(w, h, format);
-               if (buffer)
-                       buffers_list.push_back(buffer);
-
-               return buffer;
-       }
-};
 
-void UtPpDoneHandler(tdm_pp *pp, tbm_surface_h src,
-                                                       tbm_surface_h dst, void *user_data);
-
-class TDMPPCommit : public TDMPP {
+class TDMPP : public TDMDisplay {
 public:
-       friend void UtPpDoneHandler(tdm_pp *pp, tbm_surface_h src,
-                                                               tbm_surface_h dst, void *user_data);
-private:
-       int epFd = -1;
-       int timerFd = -1;
-       int tdmFd = -1;
-       static const int timeLimitSec = 0;
-       static const int timeLimitNsec = 100000000;
-protected:
-       int utPpDoneHandlerSuccessCounter = 0;
-
-       void SetUp(void)
-       {
-               struct epoll_event ep;
-
-               ASSERT_NO_FATAL_FAILURE(TDMPP::SetUp());
-
-               epFd = epoll_create1(0);
-               ASSERT_TRUE(epFd != -1);
-
-               timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
-               ASSERT_TRUE(timerFd != -1);
-
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = timerFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
-
-               ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
-
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = tdmFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
-       }
-
-       void TearDown(void)
-       {
-               if (epFd)
-                       close(epFd);
-               if (timerFd)
-                       close(timerFd);
-
-               TDMPP::TearDown();
-       }
-
-       void UtHandlePPEvent(int num_attached_buffers)
-       {
-               struct itimerspec its;
-               int count;
-               struct epoll_event ep_event[2];
-
-               if (utPpDoneHandlerSuccessCounter == num_attached_buffers)
-                       return;
-
-               its.it_interval.tv_sec = 0;
-               its.it_interval.tv_nsec = 0;
-               its.it_value.tv_sec = timeLimitSec;
-               its.it_value.tv_nsec = timeLimitNsec;
-
-               ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
-
-               while (1) {
-                       count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
-                       ASSERT_TRUE(count >= 0);
-
-                       for (int i = 0; i < count; i++) {
-                               if (ep_event[i].data.fd == timerFd) {
-                                       return;
-                               } else {
-                                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
-                                       if (utPpDoneHandlerSuccessCounter == num_attached_buffers)
-                                               return;
-                               }
-                       }
-               }
-       }
+       tdm_pp *pp;
+       tdm_pp_capability capabilities;
+       const tbm_format *formats;
+       int format_count;
+       int min_w;
+       int min_h;
+       int max_w;
+       int max_h;
+       int preferred_align;
+
+       tbm_surface_h srcbuf[3];
+       tbm_surface_h dstbuf[3];
 
-       int UtPrepareToPP(tdm_info_pp *info)
-       {
-               tdm_error error;
-               tbm_surface_h src_buf, dst_buf;
-
-               error = tdm_pp_set_done_handler(pp, UtPpDoneHandler, this);
-               EXPECT_EQ(TDM_ERROR_NONE, error);
-               if (error != TDM_ERROR_NONE)
-                       return -1;
-
-               error = tdm_pp_set_info(pp, info);
-               EXPECT_EQ(TDM_ERROR_NONE, error);
-               if (error != TDM_ERROR_NONE)
-                       return -1;
-
-               src_buf = UtCreateBuffer(info->src_config.pos.w, info->src_config.pos.h,
-                                                                info->src_config.format);
-               EXPECT_NE(NULL, src_buf);
-               if (!src_buf)
-                       return -1;
-
-               dst_buf = UtCreateBuffer(info->dst_config.pos.w, info->dst_config.pos.h,
-                                                                info->dst_config.format);
-               EXPECT_NE(NULL, dst_buf);
-               if (!dst_buf)
-                       return -1;
-
-               error = tdm_pp_attach(pp, src_buf, dst_buf);
-               EXPECT_EQ(TDM_ERROR_NONE, error);
-               if (error != TDM_ERROR_NONE)
-                       return -1;
-
-               return 0;
-       }
+       tdm_info_pp info;
 
-       int UtPrepareToPPWithScale()
-       {
-               tdm_info_pp info = {0};
+       TDMPP();
+       void SetUp(void);
+       void TearDown(void);
 
-               UtGetPPInfoWithScale(&info);
+       bool TestPrepare(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t);
+       void DumpBuffers(int b, char *test);
+       void DestroyBuffers(void);
+};
 
-               return UtPrepareToPP(&info);
-       }
+TDMPP::TDMPP()
+{
+       pp = NULL;
+       capabilities = (tdm_pp_capability)0;
+       formats = NULL;
+       format_count = 0;
+       min_w = min_h = max_w = max_h = preferred_align = -1;
+
+       for (int b = 0; b < 3; b++)
+               srcbuf[b] = dstbuf[b] = NULL;
+       memset(&info, 0, sizeof info);
+}
 
-       int UtPrepareToPPWithScaleAndTransform()
-       {
-               tdm_info_pp info = {0};
+void TDMPP::SetUp(void)
+{
+       TDMDisplay::SetUp();
 
-               UtGetPPInfoWithScaleAndTransform(&info);
+       if (!has_pp_cap)
+               return;
 
-               return UtPrepareToPP(&info);
-       }
+       tdm_error ret;
+       pp = tdm_display_create_pp(dpy, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       ASSERT_TRUE(pp != NULL);
+       ASSERT_TRUE(tdm_display_get_pp_capabilities(dpy, &capabilities) == TDM_ERROR_NONE);
+       ASSERT_TRUE(capabilities > 0);
+       ASSERT_TRUE(tdm_display_get_pp_available_formats(dpy, &formats, &format_count) == TDM_ERROR_NONE);
+       ASSERT_TRUE(formats != NULL);
+       ASSERT_TRUE(format_count > 0);
+       ASSERT_TRUE(tdm_display_get_pp_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE);
+       ASSERT_TRUE(min_w == -1 || min_w > 0);
+       ASSERT_TRUE(min_h == -1 || min_h > 0);
+       ASSERT_TRUE(max_w == -1 || max_w > 0);
+       ASSERT_TRUE(max_h == -1 || max_h > 0);
+       ASSERT_TRUE(preferred_align == -1 || preferred_align > 0);
+}
 
-       int UtPrepareToPPWithWrongInfo()
-       {
-               tdm_info_pp info = {0};
-               tdm_error error;
-               int ret;
+void TDMPP::TearDown(void)
+{
+       if (pp)
+               tdm_pp_destroy(pp);
 
-               UtGetPPInfoWithScale(&info);
+       DestroyBuffers();
 
-               ret = UtPrepareToPP(&info);
-               if (ret < 0)
-                       return ret;
+       TDMDisplay::TearDown();
+}
 
-               UtGetPPInfoWithWrongInfo(&info);
+bool TDMPP::TestPrepare(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t)
+{
+       int flags = 0;
 
-               error = tdm_pp_set_info(pp, &info);
-               EXPECT_EQ(TDM_ERROR_NONE, error);
-               if (error != TDM_ERROR_NONE)
-                       return -1;
+       sw = TDM_UT_SIZE_ALIGN(sw, preferred_align);
+       dw = TDM_UT_SIZE_ALIGN(dw, preferred_align);
 
-               return 0;
-       }
+       if (capabilities & TDM_PP_CAPABILITY_SCANOUT)
+               flags = TBM_BO_SCANOUT;
 
-};
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(sw, sh, sf, flags, true, 3, srcbuf) == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(dw, dh, df, flags, false, 3, dstbuf) == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_pp_fill_info(srcbuf[0], dstbuf[0], t, &info) == true);
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_pp_set_info(pp, &info) == TDM_ERROR_NONE);
 
-class TDMPPCommitThread : public TDMPPCommit {
-protected:
-       void SetEnvs()
-       {
-               TDMPPCommit::SetEnvs();
-               setenv("TDM_THREAD", "1", 1);
-       }
-       void UnsetEnvs()
-       {
-               TDMPPCommit::UnsetEnvs();
-               unsetenv("TDM_THREAD");
-       }
-};
+       return true;
+}
 
-void UtPpDoneHandler(tdm_pp *pp, tbm_surface_h src,
-                                                       tbm_surface_h dst, void *user_data)
+void TDMPP::DumpBuffers(int b, char *test)
 {
-       TDMPPCommit *pp_commit = (TDMPPCommit *)user_data;
-       bool src_valid = false, dst_valid = false;
-
-       if (!pp_commit)
-               return;
+       char filename[256];
+       if (test)
+               snprintf(filename, sizeof filename, "%s_%s_src_%d", typeid(*this).name(), test, b);
+       else
+               snprintf(filename, sizeof filename, "%s_src_%d", typeid(*this).name(), b);
+       tdm_helper_dump_buffer_str(srcbuf[b], NULL, filename);
+       if (test)
+               snprintf(filename, sizeof filename, "%s_%s_dst_%d", typeid(*this).name(), test, b);
+       else
+               snprintf(filename, sizeof filename, "%s_dst_%d", typeid(*this).name(), b);
+       tdm_helper_dump_buffer_str(dstbuf[b], NULL, filename);
+}
 
-       for (auto it = pp_commit->buffers_list.begin(); it != pp_commit->buffers_list.end(); ++it) {
-               if (*it == src)
-                       src_valid = true;
-               if (*it == dst)
-                       dst_valid = true;
+void TDMPP::DestroyBuffers(void)
+{
+       for (int b = 0; b < 3; b++) {
+               tbm_surface_destroy(srcbuf[b]);
+               tbm_surface_destroy(dstbuf[b]);
+               srcbuf[b] = dstbuf[b] = NULL;
        }
-
-       if (src_valid && dst_valid)
-               pp_commit->utPpDoneHandlerSuccessCounter++;
 }
 
-TEST_F(TDMPPWithoutCreation, DisplayGetPPAvailableFormatsSuccessful)
+bool
+ut_tdm_pp_fill_info(tbm_surface_h srcbuf, tbm_surface_h dstbuf, tdm_transform transform, tdm_info_pp *info)
 {
-       SKIP_FLAG(has_pp);
-       const tbm_format *formats = NULL;
-       int count = -42;
-       ASSERT_TRUE(TDM_ERROR_NONE == tdm_display_get_pp_available_formats(dpy, &formats, &count));
-       ASSERT_FALSE(-42 == count);
-       ASSERT_FALSE(NULL == formats);
+       int bw, bh;
+
+       memset(info, 0, sizeof *info);
+
+       bw = bh = TDM_UT_INVALID_VALUE;
+       tdm_helper_get_buffer_full_size(srcbuf, &bw, &bh);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(srcbuf));
+       TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(srcbuf));
+       info->src_config.size.h = bw;
+       info->src_config.size.v = bh;
+       info->src_config.pos.x = 0;
+       info->src_config.pos.y = 0;
+       info->src_config.pos.w = tbm_surface_get_width(srcbuf);
+       info->src_config.pos.h = tbm_surface_get_height(srcbuf);
+       info->src_config.format = tbm_surface_get_format(srcbuf);
+
+       bw = bh = TDM_UT_INVALID_VALUE;
+       tdm_helper_get_buffer_full_size(dstbuf, &bw, &bh);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(dstbuf));
+       TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(dstbuf));
+       info->dst_config.size.h = bw;
+       info->dst_config.size.v = bh;
+       info->dst_config.pos.x = 0;
+       info->dst_config.pos.y = 0;
+       info->dst_config.pos.w = tbm_surface_get_width(dstbuf);
+       info->dst_config.pos.h = tbm_surface_get_height(dstbuf);
+       info->dst_config.format = tbm_surface_get_format(dstbuf);
+
+       info->transform = transform;
+       info->sync = 0;
+       info->flags = 0;
+
+       TDM_INFO("src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_config(%dx%d: %d,%d %dx%d: %c%c%c%c) transform(%s) sync(%d) info->flags(%x)",
+                        info->src_config.size.h, info->src_config.size.h,
+                        info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h,
+                        FOURCC_STR(info->src_config.format),
+                        info->dst_config.size.h, info->dst_config.size.h,
+                        info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h,
+                        FOURCC_STR(info->dst_config.format),
+                        tdm_transform_str(transform), info->sync, info->flags);
+
+       return true;
 }
 
-/* tdm_display_create_pp() */
+#ifdef UT_TDM_PP_ENABLE
 
-TEST_F(TDMPPWithoutCreation, DisplayCreatePPNullAll)
+TEST_P(TDMPP, PPDispalyGetAvaiableFormatsNullObject)
 {
-       SKIP_FLAG(has_pp);
-       tdm_pp *pp;
-
-       pp = tdm_display_create_pp(NULL, NULL);
-       ASSERT_EQ(NULL, pp);
+       const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE;
+       int count = TDM_UT_INVALID_VALUE;
+       if (has_pp_cap)
+               ASSERT_TRUE(tdm_display_get_pp_available_formats(NULL, &formats, &count) == TDM_ERROR_INVALID_PARAMETER);
+       else
+               ASSERT_TRUE(tdm_display_get_pp_available_formats(NULL, &formats, &count) == TDM_ERROR_NO_CAPABILITY);
+       ASSERT_TRUE(formats == (const tbm_format *)TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(count == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMPPWithoutCreation, DisplayCreatePPNullDpy)
+TEST_P(TDMPP, PPDispalyGetAvaiableFormatsNullOther)
 {
-       SKIP_FLAG(has_pp);
-       tdm_pp *pp;
-       tdm_error error;
-
-       pp = tdm_display_create_pp(NULL, &error);
-       ASSERT_EQ(NULL, pp);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       if (has_pp_cap)
+               ASSERT_TRUE(tdm_display_get_pp_available_formats(pp, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
+       else
+               ASSERT_TRUE(tdm_display_get_pp_available_formats(pp, NULL, NULL) == TDM_ERROR_NO_CAPABILITY);
 }
 
-TEST_F(TDMPPWithoutCreation, DisplayCreatePPSuccessNullError)
+TEST_P(TDMPP, PPDispalyGetAvaiableSizeNullObject)
 {
-       SKIP_FLAG(has_pp);
-       tdm_pp *pp;
-
-       pp = tdm_display_create_pp(dpy, NULL);
-       ASSERT_NE(NULL, pp);
+       int min_w = TDM_UT_INVALID_VALUE;
+       int min_h = TDM_UT_INVALID_VALUE;
+       int max_w = TDM_UT_INVALID_VALUE;
+       int max_h = TDM_UT_INVALID_VALUE;
+       int preferred_align = TDM_UT_INVALID_VALUE;
+       if (has_pp_cap)
+               ASSERT_TRUE(tdm_display_get_pp_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_INVALID_PARAMETER);
+       else
+               ASSERT_TRUE(tdm_display_get_pp_available_size(NULL, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NO_CAPABILITY);
+       ASSERT_TRUE(min_w == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(min_h == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(max_w == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(max_h == TDM_UT_INVALID_VALUE);
+       ASSERT_TRUE(preferred_align == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMPPWithoutCreation, DisplayCreatePPSuccess)
+TEST_P(TDMPP, PPDispalyGetAvaiableSizeNullOther)
 {
-       SKIP_FLAG(has_pp);
-       tdm_pp *pp;
-       tdm_error error;
-
-       pp = tdm_display_create_pp(dpy, &error);
-       ASSERT_NE(NULL, pp);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       if (has_pp_cap)
+               ASSERT_TRUE(tdm_display_get_pp_available_size(pp, NULL, NULL, NULL, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
+       else
+               ASSERT_TRUE(tdm_display_get_pp_available_size(pp, NULL, NULL, NULL, NULL, NULL) == TDM_ERROR_NO_CAPABILITY);
 }
 
-/* tdm_pp_set_info() */
-
-TEST_F(TDMPP, PpSetInfoNullAll)
+TEST_P(TDMPP, PPDestroy)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_set_info(NULL, NULL);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       tdm_pp_destroy(pp);
+       pp = NULL;
 }
 
-TEST_F(TDMPP, PpSetInfoNullPP)
+TEST_P(TDMPP, PPDestroyNullObject)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       tdm_info_pp info;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_set_info(NULL, &info);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       tdm_pp_destroy(NULL);
 }
 
-TEST_F(TDMPP, PpSetInfoNullInfo)
+TEST_P(TDMPP, PPSetInfo)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-
-       error = tdm_pp_set_info(pp, NULL);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       /* tested in PPNoScaleNoTransformNoCSC */
 }
 
-TEST_F(TDMPP, PpSetInfoSuccess)
+TEST_P(TDMPP, PPSetInfoNullObject)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       tdm_info_pp info;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       UtGetPPInfoWithScale(&info);
-
-       error = tdm_pp_set_info(pp, &info);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       tdm_info_pp info;
+       memset(&info, 0, sizeof info);
+       ASSERT_TRUE(tdm_pp_set_info(NULL, &info) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-/* tdm_pp_set_done_handler() */
-
-TEST_F(TDMPP, PpSetDoneHandlerFailNullAll)
+TEST_P(TDMPP, PPSetInfoNullOther)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_set_done_handler(NULL, NULL, NULL);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_set_info(pp, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMPP, PpSetDoneHandlerFailNullPP)
+static void
+_ut_tdm_pp_done_cb(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-
-       error = tdm_pp_set_done_handler(NULL, UtPpDoneHandler, this);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       bool *done = (bool*)user_data;
+       if (done)
+               *done = true;
 }
 
-TEST_F(TDMPP, PpSetDoneHandlerSuccessNullFailNullFunc)
+TEST_P(TDMPP, PPSetDoneHandler)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       int data;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_set_done_handler(pp, NULL, &data);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, NULL) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMPP, PpSetDoneHandlerSuccessNullData)
+TEST_P(TDMPP, PPSetDoneHandlerNullObject)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_set_done_handler(pp, UtPpDoneHandler, this);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_set_done_handler(NULL, _ut_tdm_pp_done_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMPP, PpSetDoneHandlerSuccess)
+TEST_P(TDMPP, PPSetDoneHandlerNullOther)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_set_done_handler(pp, UtPpDoneHandler, this);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_set_done_handler(pp, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-/* tdm_pp_attach() */
-
-TEST_F(TDMPP, PpAttachFailNullAll)
+TEST_P(TDMPP, PPAttach)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
+
+       for (int f = 0; f < format_count; f++) {
+               ASSERT_TRUE(TestPrepare(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                               TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                               TDM_TRANSFORM_NORMAL) == true);
 
-       error = tdm_pp_attach(NULL, NULL, NULL);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+               for (int b = 0; b < 3; b++)
+                       ASSERT_TRUE(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]) == TDM_ERROR_NONE);
+
+               DestroyBuffers();
+       }
 }
 
-TEST_F(TDMPP, PpAttachFailNullPp)
+TEST_P(TDMPP, PPAttachNullObject)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       tbm_surface_h dst_buf, src_buf;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       src_buf = UtCreateBuffer(default_src_w, default_src_h, formats[0]);
-       ASSERT_NE(NULL, src_buf);
+       tbm_surface_h srcbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
+       tbm_surface_h dstbuf = (tbm_surface_h)TDM_UT_BUFFER_SIZE;
 
-       dst_buf = UtCreateBuffer(default_dst_w, default_dst_h, formats[0]);
-       ASSERT_NE(NULL, dst_buf);
-
-       error = tdm_pp_attach(NULL, src_buf, dst_buf);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_attach(NULL, srcbuf, dstbuf) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMPP, PpAttachFailNullSrc)
+TEST_P(TDMPP, PPAttachNullOther)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       tbm_surface_h dst_buf;
-
-       dst_buf = UtCreateBuffer(default_dst_w, default_dst_h, formats[0]);
-       ASSERT_NE(NULL, dst_buf);
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_attach(pp, NULL, dst_buf);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_attach(pp, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMPP, PpAttachFailNullDst)
+TEST_P(TDMPP, PPCommit)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       tbm_surface_h src_buf;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       src_buf = UtCreateBuffer(default_src_w, default_src_h, formats[0]);
-       ASSERT_NE(NULL, src_buf);
+       ASSERT_TRUE(tdm_pp_commit(pp) == TDM_ERROR_NONE);
+}
+
+TEST_P(TDMPP, PPCommitNullOBject)
+{
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       error = tdm_pp_attach(pp, src_buf, NULL);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_commit(NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMPP, PpAttachSuccess)
+TEST_P(TDMPP, PPNoScaleNoTransformNoCSC)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       tbm_surface_h dst_buf, src_buf;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       src_buf = UtCreateBuffer(default_src_w, default_src_h, formats[0]);
-       ASSERT_NE(NULL, src_buf);
+       bool done;
 
-       dst_buf = UtCreateBuffer(default_dst_w, default_dst_h, formats[0]);
-       ASSERT_NE(NULL, dst_buf);
+       for (int f = 0; f < format_count; f++) {
+               char temp[256];
+               snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(formats[f]));
 
-       error = tdm_pp_attach(pp, src_buf, dst_buf);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
-}
+               TDM_INFO("---- format(%c%c%c%c)", FOURCC_STR(formats[f]));
 
-/* tdm_pp_commit() */
+               ASSERT_TRUE(TestPrepare(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[2],
+                                                               TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[0],
+                                                               TDM_TRANSFORM_NORMAL) == true);
 
-TEST_F(TDMPP, PpCommitFailNullPP)
-{
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+               ASSERT_TRUE(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done) == TDM_ERROR_NONE);
 
-       error = tdm_pp_commit(NULL);
-       ASSERT_NE(TDM_ERROR_NONE, error);
-}
+               for (int b = 0; b < 3; b++) {
+                       done = false;
 
-TEST_F(TDMPPCommit, PpCommitFailWrongInfo)
-{
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+                       ASSERT_TRUE(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_pp_commit(pp) == TDM_ERROR_NONE);
+
+                       while (!done)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       ASSERT_NE(-1, UtPrepareToPPWithWrongInfo());
+                       DumpBuffers(b, temp);
+               }
 
-       error = tdm_pp_commit(pp);
-       ASSERT_NE(TDM_ERROR_NONE, error);
+               DestroyBuffers();
+       }
 }
 
-TEST_F(TDMPPCommit, PpCommitSuccessScale)
+TEST_P(TDMPP, PPScaleTransformCSC)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       ASSERT_NE(-1, UtPrepareToPPWithScale());
+       bool done;
+       tbm_format format1, format2;
 
-       error = tdm_pp_commit(pp);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       format1 = formats[0];
+       if (format_count > 1)
+               format2 = formats[1];
+       else
+               format2 = formats[0];
 
-       UtHandlePPEvent(1);
+       TDM_INFO("format(%c%c%c%c) ------> format(%c%c%c%c)", format1, format2);
 
-       ASSERT_EQ(1, utPpDoneHandlerSuccessCounter);
-}
+       ASSERT_TRUE(TestPrepare(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, format1,
+                                                       TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, format2,
+                                                       TDM_TRANSFORM_NORMAL) == true);
 
-TEST_F(TDMPPCommit, PpCommitSuccessScaleAndTransform)
-{
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       ASSERT_TRUE(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done) == TDM_ERROR_NONE);
 
-       ASSERT_NE(-1, UtPrepareToPPWithScale());
+       for (int b = 0; b < 3; b++) {
+               done = false;
 
-       error = tdm_pp_commit(pp);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+               ASSERT_TRUE(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_pp_commit(pp) == TDM_ERROR_NONE);
 
-       UtHandlePPEvent(1);
+               while (!done)
+                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       ASSERT_EQ(1, utPpDoneHandlerSuccessCounter);
+               DumpBuffers(b, NULL);
+       }
+
+       DestroyBuffers();
 }
 
-TEST_F(TDMPPCommitThread, PpCommitSuccessScale)
+static void
+_ut_tdm_pp_done_cb2(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-
-       ASSERT_NE(-1, UtPrepareToPPWithScale());
+       int *done = (int*)user_data;
+       if (done)
+               (*done)++;
+}
 
-       error = tdm_pp_commit(pp);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+TEST_P(TDMPP, PPAttachFewTimesInOneCommit)
+{
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       UtHandlePPEvent(1);
+       int done = 0;
+       int f = 0;
+       char temp[256];
+       snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(formats[f]));
 
-       ASSERT_EQ(1, utPpDoneHandlerSuccessCounter);
-}
+       ASSERT_TRUE(TestPrepare(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                       TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                       TDM_TRANSFORM_NORMAL) == true);
 
-TEST_F(TDMPPCommitThread, PpCommitSuccessScaleAndTransform)
-{
-       SKIP_FLAG(has_pp);
-       tdm_error error;
+       ASSERT_TRUE(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb2, &done) == TDM_ERROR_NONE);
+       for (int b = 0; b < 3; b++)
+               ASSERT_TRUE(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]) == TDM_ERROR_NONE);
 
-       ASSERT_NE(-1, UtPrepareToPPWithScale());
+       ASSERT_TRUE(tdm_pp_commit(pp) == TDM_ERROR_NONE);
 
-       error = tdm_pp_commit(pp);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       while (done != 3)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       UtHandlePPEvent(1);
+       for (int b = 0; b < 3; b++)
+               DumpBuffers(b, temp);
 
-       ASSERT_EQ(1, utPpDoneHandlerSuccessCounter);
+       DestroyBuffers();
 }
 
-/* tdm_pp_destroy() */
-
-void UtBufferReleaseHandler(tbm_surface_h buffer,
-                                                          void *user_data)
+TEST_P(TDMPP, PPDestroyWithoutCommit)
 {
-       int *data = (int *)user_data;
-       if (!data)
-               return;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
+
+       int f = 0;
+
+       ASSERT_TRUE(TestPrepare(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                       TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                       TDM_TRANSFORM_NORMAL) == true);
+
+       ASSERT_TRUE(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb2, NULL) == TDM_ERROR_NONE);
+       for (int b = 0; b < 3; b++)
+               ASSERT_TRUE(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]) == TDM_ERROR_NONE);
 
-       (*data)++;
+       tdm_pp_destroy(pp);
+       pp = NULL;
+
+       DestroyBuffers();
 }
 
-TEST_F(TDMPPCommit, PPDestroySuccessAfterCommit)
+TEST_P(TDMPP, PPDestroyBeforeDone)
 {
-       SKIP_FLAG(has_pp);
-       tdm_error error;
-       int release_data = 0;
+       TDM_UT_SKIP_FLAG(has_pp_cap);
 
-       ASSERT_NE(-1, UtPrepareToPPWithScale());
+       int f = 0;
 
-       for (auto it = buffers_list.begin(); it != buffers_list.end(); ++it) {
-               tdm_buffer_add_release_handler((tbm_surface_h)*it, UtBufferReleaseHandler, &release_data);
-       }
+       ASSERT_TRUE(TestPrepare(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                       TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f],
+                                                       TDM_TRANSFORM_NORMAL) == true);
 
-       error = tdm_pp_commit(pp);
-       ASSERT_EQ(TDM_ERROR_NONE, error);
+       ASSERT_TRUE(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb2, NULL) == TDM_ERROR_NONE);
+       for (int b = 0; b < 3; b++)
+               ASSERT_TRUE(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]) == TDM_ERROR_NONE);
+
+       ASSERT_TRUE(tdm_pp_commit(pp) == TDM_ERROR_NONE);
 
        tdm_pp_destroy(pp);
        pp = NULL;
 
-       ASSERT_EQ(2, release_data);
+       DestroyBuffers();
 }
+
+INSTANTIATE_TEST_CASE_P(TDMPPParams,
+                                               TDMPP,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+
+#endif
index a1cdc4d..5c18a10 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
-#include "tdm.h"
-#include "tdm_config.h"
-#include "tbm_bufmgr.h"
 #include "ut_tdm.h"
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#include <pthread.h>
-
-class TDMVblankWithoutCreating: public ::testing::Test {
-protected:
-       tbm_bufmgr bufmgr = NULL;
-       tdm_display *dpy = NULL;
-       int output_count = 0;
-       bool has_output = 0;
-       tdm_output *connected_output = NULL;
-       const tdm_output_mode *preferred_mode = NULL;
-       tdm_output *disconnected_output = NULL;
-       tdm_output *default_output = NULL;
-
-       void SetUp(void) {
-               tdm_output *output;
-               tdm_output_conn_status status;
-               tdm_error error = TDM_ERROR_NONE;
-
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 0);
-               tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0);
-               tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_LOG_LEVEL, 4);
-               tdm_config_set_string(TDM_CONFIG_KEY_DEBUG_MODULE, "vblank,thread");
-
-               /* FIXME: fix the error. If we initialize TBM before TDM we get fail
-                * in the tdm_output_set_dpms */
-#if 0
-               bufmgr = tbm_bufmgr_init(-1);
-               ASSERT_FALSE(bufmgr == NULL);
-#endif
-
-               dpy = tdm_display_init(&error);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               ASSERT_FALSE(dpy == NULL);
-
-               error = tdm_display_get_output_count(dpy, &output_count);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-               if (output_count > 0)
-                       has_output = true;
-               else
-                       has_output = false;
-
-               for(int i = 0; i < output_count; i++) {
-                       output = tdm_display_get_output(dpy, i, &error);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-                       ASSERT_FALSE(dpy == NULL);
 
-                       error = tdm_output_get_conn_status(output, &status);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-                       if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
-                               connected_output = output;
-                       else
-                               disconnected_output = output;
-               }
-
-               default_output = disconnected_output;
-
-               if (connected_output) {
-                       int output_modes_cnt = 0;
-                       const tdm_output_mode* output_modes;
+class TDMVblank : public TDMOutput
+{
+public:
+       bool has_vblanks;
 
-                       error = tdm_output_get_available_modes(connected_output, &output_modes, &output_modes_cnt);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-                       if (output_modes_cnt <= 0) {
-                               connected_output = NULL;
-                               return;
-                       }
+       tdm_vblank **vblanks;
+       int vblank_count;
 
-                       for(int i = 0; i < output_modes_cnt; i++) {
-                               if(output_modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) {
-                                       preferred_mode = &output_modes[i];
+       bool done;
 
-                                       default_output = connected_output;
+       TDMVblank();
+       void SetUp(void);
+       void TearDown(void);
 
-                                       return;
-                               }
-                       }
-               }
+       bool TestCreateVblanks(void);
+       bool TestCreateVblanks3(void);
+       void TestDestroyVblanks(void);
 
-               connected_output = NULL;
-       }
-       void TearDown(void)
-       {
-               if (connected_output)
-                       tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
-               if (bufmgr)
-                       tbm_bufmgr_deinit(bufmgr);
-               if (dpy)
-                       tdm_display_deinit(dpy);
-
-               bufmgr = NULL;
-               dpy = NULL;
-       }
+       bool TestPrepareOutput(void);
 };
 
-class TDMVblank: public TDMVblankWithoutCreating {
-protected:
-       tdm_vblank *con_output_vblank = NULL;
-       tdm_vblank *discon_output_vblank = NULL;
-       tdm_output *default_vblank = NULL;
-       int setModeAndDpms = 0;
-       tbm_surface_h buffer = NULL;
-       tdm_layer *layer = NULL;
-
-       void SetUp(void)
-       {
-               tdm_error error;
-
-               ASSERT_NO_FATAL_FAILURE(TDMVblankWithoutCreating::SetUp());
-
-               if (connected_output && setModeAndDpms) {
-                       int primary_index;
-                       tdm_info_layer info = {0};
-
-                       error = tdm_output_set_mode(connected_output, preferred_mode);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-                       error = tdm_output_get_primary_index(connected_output, &primary_index);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-                       layer = tdm_output_get_layer(connected_output, primary_index, &error);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-                       ASSERT_TRUE(layer != NULL);
-
-                       info.src_config.size.h = preferred_mode->hdisplay;
-                       info.src_config.size.v = preferred_mode->vdisplay;
-                       info.src_config.pos.x = 0;
-                       info.src_config.pos.y = 0;
-                       info.src_config.pos.w = preferred_mode->hdisplay;
-                       info.src_config.pos.h = preferred_mode->vdisplay;
-                       info.src_config.format = TBM_FORMAT_ARGB8888;
-                       info.dst_pos.x = 0;
-                       info.dst_pos.y = 0;
-                       info.dst_pos.w = preferred_mode->hdisplay;
-                       info.dst_pos.h = preferred_mode->vdisplay;
-                       info.transform = TDM_TRANSFORM_NORMAL;
-
-                       error = tdm_layer_set_info(layer, &info);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-                       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_ON);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-                       buffer = tbm_surface_internal_create_with_flags(preferred_mode->hdisplay,
-                                                                                                                       preferred_mode->vdisplay,
-                                                                                                                       TBM_FORMAT_ARGB8888,
-                                                                                                                       TBM_BO_SCANOUT);
-                       ASSERT_TRUE(buffer != NULL);
-
-                       error = tdm_layer_set_buffer(layer, buffer);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-                       error = tdm_output_commit(connected_output, 0, NULL, NULL);
-                       ASSERT_TRUE(error == TDM_ERROR_NONE);
-                       /* TODO: use a commit handler instead of an usleep to wait when
-                        * commit will be applied */
-                       usleep(20000);
-               }
+TDMVblank::TDMVblank()
+{
+       has_vblanks = false;
+       vblanks = NULL;
+       vblank_count = 0;
+       done = false;
+}
 
-               if (disconnected_output) {
-                       discon_output_vblank = tdm_vblank_create(dpy, disconnected_output, &error);
-                       EXPECT_TRUE(discon_output_vblank != NULL);
-                       EXPECT_TRUE(error == TDM_ERROR_NONE);
-                       default_vblank = discon_output_vblank;
-               }
+void TDMVblank::SetUp(void)
+{
+       TDMOutput::SetUp();
+}
 
-               if (connected_output) {
-                       con_output_vblank = tdm_vblank_create(dpy, connected_output, &error);
-                       EXPECT_TRUE(con_output_vblank != NULL);
-                       EXPECT_TRUE(error == TDM_ERROR_NONE);
-                       default_vblank = con_output_vblank;
-               }
+void TDMVblank::TearDown(void)
+{
+       TestDestroyVblanks();
 
-               ASSERT_TRUE(default_vblank != NULL);
-       }
+       tdm_vblank_enable_global_fps(0, 0);
 
-       void TearDown(void)
-       {
-               if (buffer) {
-                       tdm_layer_unset_buffer(layer);
-                       tdm_output_commit(connected_output, 0, NULL, NULL);
-                       tbm_surface_destroy(buffer);
-               }
+       TDMOutput::TearDown();
+}
 
-               TDMVblankWithoutCreating::TearDown();
-       }
-};
+bool TDMVblank::TestCreateVblanks(void)
+{
+       TDM_UT_GOTO_IF_FAIL(output_count > 0, failed);
 
-class TDMVblankWait : public TDMVblank {
-public:
-       static int utVblankHandlerIsCalled;
-       static void UtVblankHandler(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
-                                                               unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-        {
-               int *data = (int *)user_data;
+       vblanks = (tdm_vblank**)calloc(output_count, sizeof(tdm_vblank*));
+       TDM_UT_GOTO_IF_FAIL(vblanks != NULL, failed);
 
-               if (data)
-                       *data = 1;
+       vblank_count = output_count;
+       has_vblanks = true;
 
-               utVblankHandlerIsCalled = 1;
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               vblanks[v] = tdm_vblank_create(dpy, outputs[v], &ret);
+               TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
+               TDM_UT_GOTO_IF_FAIL(vblanks[v] != NULL, failed);
        }
-       int utWaitVblankThreadHndlResult = -1;
-       friend void *UtWaitVblankThreadHndl(void *ptr);
-       int utWaitVblankSeqThreadHndlResult = -1;
-       friend void *UtWaitVblankSeqThreadHndl(void *ptr);
 
-private:
-       int epFd = -1;
-       int timerFd = -1;
-       int tdmFd = -1;
-       static const int timeLimitSec = 1;
-
-protected:
-       void SetUp(void)
-        {
-               struct epoll_event ep;
-
-               utVblankHandlerIsCalled = 0;
-
-               setModeAndDpms = 1;
+       return true;
+failed:
+       TestDestroyVblanks();
+       has_vblanks = false;
+       return false;
+}
 
-               ASSERT_NO_FATAL_FAILURE(TDMVblank::SetUp());
+bool TDMVblank::TestCreateVblanks3(void)
+{
+       TDM_UT_GOTO_IF_FAIL(output_count > 0, failed);
 
-               epFd = epoll_create1(0);
-               ASSERT_TRUE(epFd != -1);
+       tdm_error ret;
 
-               timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
-               ASSERT_TRUE(timerFd != -1);
+       vblank_count = 0;
 
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = timerFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
 
-               ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
+               vblank_count = 3;
+               has_vblanks = true;
 
-               memset(&ep, 0, sizeof ep);
-               ep.events |= EPOLLIN;
-               ep.data.fd = tdmFd;
-               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
-       }
+               vblanks = (tdm_vblank**)calloc(vblank_count, sizeof(tdm_vblank*));
+               TDM_UT_GOTO_IF_FAIL(vblanks != NULL, failed);
 
-       void UtHandleVblankEvent()
-       {
-               struct itimerspec its;
-               int count;
-               struct epoll_event ep_event[2];
-
-               if (utVblankHandlerIsCalled)
-                       return;
-
-               its.it_interval.tv_sec = 0;
-               its.it_interval.tv_nsec = 0;
-               its.it_value.tv_sec = timeLimitSec;
-               its.it_value.tv_nsec = 0;
-
-               ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
-
-               while (1) {
-                       count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
-                       ASSERT_TRUE(count >= 0);
-
-                       for (int i = 0; i < count; i++) {
-                               if (ep_event[i].data.fd == timerFd) {
-                                       return;
-                               } else {
-                                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
-                                       if (utVblankHandlerIsCalled)
-                                               return;
-                               }
-                       }
+               for (int v = 0; v < vblank_count; v++) {
+                       vblanks[v] = tdm_vblank_create(dpy, outputs[o], &ret);
+                       TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
+                       TDM_UT_GOTO_IF_FAIL(vblanks[v] != NULL, failed);
                }
-       }
-};
 
-class TDMVblankWaitThread : public TDMVblankWait {
-protected:
-       void SetUp(void)
-       {
-               setenv("TDM_THREAD", "1", 1);
-               ASSERT_NO_FATAL_FAILURE(TDMVblankWait::SetUp());
+               break;
        }
-};
-
-int TDMVblankWait::utVblankHandlerIsCalled = 0;
-
-/* tdm_vblank_enable_global_fps() */
 
-TEST_F(TDMVblankWithoutCreating, VblankEnableGlobalFpFailFpsNull)
-{
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({error = tdm_vblank_enable_global_fps(1, 0);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       return true;
+failed:
+       TestDestroyVblanks();
+       has_vblanks = false;
+       return false;
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankEnableGlobalFpsSuccessEnable)
+void TDMVblank::TestDestroyVblanks(void)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+       if (vblanks) {
+               for (int v = 0; v < vblank_count; v++)
+                       tdm_vblank_destroy(vblanks[v]);
+               free(vblanks);
+               vblanks = NULL;
+       }
+       vblank_count = 0;
 
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({error = tdm_vblank_enable_global_fps(1, 60);
-                               if (error != TDM_ERROR_NONE)
-                                       exit(1);
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankEnableGlobalFpsSuccessDisable)
+bool TDMVblank::TestPrepareOutput(void)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+       for (int o = 0; o < output_count; o++) {
+               if (!ut_tdm_output_is_connected(outputs[o]))
+                       continue;
+
+               TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_output_prepare(dpy, outputs[o]) == true);
+       }
 
-       SKIP_FLAG(has_output);
-       ASSERT_EXIT({error = tdm_vblank_enable_global_fps(0, 0);
-                               if (error != TDM_ERROR_NONE)
-                                       exit(1);
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       return true;
 }
 
-/* tdm_vblank_create() */
+#ifdef UT_TDM_VBLANK_ENABLE
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullAll)
+/* tdm_vblank_set_client_vblank_fps */
+TEST_P(TDMVblank, DISABLED_VblankSetClientVblankFps)
 {
-       tdm_vblank *ret_vblank;
-
-       SKIP_FLAG(has_output);
-
-       ret_vblank = tdm_vblank_create(NULL, NULL, NULL);
-       ASSERT_TRUE(ret_vblank == NULL);
+       /* tested in ut_tdm_client.c */
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullDpy)
+TEST_P(TDMVblank, VblankSetClientVblankFpsNullObject)
 {
-       tdm_vblank *ret_vblank;
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       ret_vblank = tdm_vblank_create(NULL, default_output, &error);
-       ASSERT_TRUE(ret_vblank == NULL);
-       ASSERT_TRUE(error == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(tdm_vblank_set_client_vblank_fps(0, NULL, 60) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(tdm_vblank_set_client_vblank_fps(123, NULL, 0) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullOutput)
+/* tdm_vblank_set_client_vblank_fps */
+TEST_P(TDMVblank, DISABLED_VblankSetClientIgnoreGlobalFps)
 {
-       tdm_vblank *ret_vblank;
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+       /* tested in ut_tdm_client.c */
+}
 
-       ret_vblank = tdm_vblank_create(dpy, NULL, &error);
-       ASSERT_TRUE(ret_vblank == NULL);
-       ASSERT_TRUE(error == TDM_ERROR_INVALID_PARAMETER);
+TEST_P(TDMVblank, VblankSetClientIgnoreGlobalFpsNullObject)
+{
+       ASSERT_TRUE(tdm_vblank_set_client_ignore_global_fps(0, NULL, 0) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(tdm_vblank_set_client_ignore_global_fps(0, NULL, 1) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailWrongDpy)
+/* tdm_vblank_create() */
+TEST_P(TDMVblank, VblankCreateDestroy)
 {
-       tdm_vblank *ret_vblank = NULL;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(vblank != NULL);
 
-       ASSERT_EXIT({ret_vblank = tdm_vblank_create((tdm_display *)0xFFFFFFFF, default_output, &error);
-                               if (ret_vblank || error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailWrongOutput)
+TEST_P(TDMVblank, VblankCreateNullDpy)
 {
-       tdm_vblank *ret_vblank = NULL;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       tdm_error ret;
 
-       ASSERT_EXIT({ret_vblank = tdm_vblank_create(dpy, (tdm_output *)0xFFFFFFFF, &error);
-                               if (ret_vblank || error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       tdm_vblank *vblank = tdm_vblank_create(NULL, outputs[0], &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(vblank == NULL);
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateSuccessForConnectedOutput)
+TEST_P(TDMVblank, VblankCreateNullOutput)
 {
-       tdm_vblank *ret_vblank;
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       if (!connected_output)
-               return;
+       tdm_error ret;
 
-       ret_vblank = tdm_vblank_create(dpy, connected_output, &error);
-       ASSERT_TRUE(ret_vblank != NULL);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       tdm_vblank *vblank = tdm_vblank_create(dpy, NULL, &ret);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(vblank == NULL);
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateSuccessForDisconnectedOutput)
+TEST_P(TDMVblank, VblankCreateNullOther)
 {
-       tdm_vblank *ret_vblank;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[0], NULL);
+       ASSERT_TRUE(vblank != NULL);
 
-       if (!disconnected_output)
-               return;
-
-       ret_vblank = tdm_vblank_create(dpy, disconnected_output, &error);
-       ASSERT_TRUE(ret_vblank != NULL);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       tdm_vblank_destroy(vblank);
 }
 
 /* tdm_vblank_destroy() */
-
-TEST_F(TDMVblank, VblankDestroyWrongVblankPtr)
+TEST_P(TDMVblank, VblankDestroyNullObject)
 {
-       SKIP_FLAG(has_output);
-
-       ASSERT_EXIT({tdm_vblank_destroy((tdm_vblank *)0xFFFFFFFF); exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       tdm_vblank_destroy(NULL);
 }
 
-TEST_F(TDMVblank, VblankDestroySuccess)
+static void
+_ut_tdm_vblank_create_cb(tdm_vblank *vblank, void *user_data)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       tdm_vblank_destroy(con_output_vblank);
-
-       error = tdm_vblank_set_enable_fake(default_vblank, 1);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       TDMVblank *test_vblank = (TDMVblank*)user_data;
+       if (test_vblank)
+               test_vblank->done = true;
 }
 
-/* tdm_vblank_set_name() */
-
-TEST_F(TDMVblank, VblankSetNameFailNullAll)
+/* tdm_vblank_add_create_handler */
+TEST_P(TDMVblank, VblankAddCreateHandler)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_name(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-TEST_F(TDMVblank, VblankSetNameFailWrongVblankPtr)
-{
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, this) == TDM_ERROR_NONE);
 
-       SKIP_FLAG(has_output);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       ASSERT_EXIT({error = tdm_vblank_set_name((tdm_vblank *)0xFFFFFFFF, "ut_vblank");
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
-}
+               done = false;
 
-TEST_F(TDMVblank, VblankSetNameSuccess)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(vblank != NULL);
+               ASSERT_TRUE(done == true);
 
-       error = tdm_vblank_set_name(default_vblank, "ut_vblank");
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankSetNameSuccessNullName)
+TEST_P(TDMVblank, VblankAddCreateHandlerTwice)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_name(default_vblank, NULL);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, NULL) == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, NULL) == TDM_ERROR_BAD_REQUEST);
 }
 
-/* tdm_vblank_get_name() */
-
-TEST_F(TDMVblank, VblankGetNameFailNullAll)
+TEST_P(TDMVblank, VblankAddCreateHandlerNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_name(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_add_create_handler(NULL, _ut_tdm_vblank_create_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetNameFailNullVblank)
+TEST_P(TDMVblank, VblankAddCreateHandlerNullOther)
 {
-       tdm_error error;
-       const char *ret_name;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_name(NULL, &ret_name);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetNameFailWrongVblankPtr)
+/* tdm_vblank_remove_create_handler */
+TEST_P(TDMVblank, VblankRemoveCreateHandler)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       const char *ret_name;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, this) == TDM_ERROR_NONE);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, this);
 
-       ASSERT_EXIT({error = tdm_vblank_get_name((tdm_vblank *)0xFFFFFFFF, &ret_name);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
-}
-
-TEST_F(TDMVblank, VblankGetNameFailNullName)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       error = tdm_vblank_get_name(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+               done = false;
 
-TEST_F(TDMVblank, VblankGetNameSuccessWhithoutSetName)
-{
-       tdm_error error;
-       const char *ret_name;
-       SKIP_FLAG(has_output);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(vblank != NULL);
+               ASSERT_TRUE(done == false);
 
-       error = tdm_vblank_get_name(default_vblank, &ret_name);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetNameSuccess)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerFewTimes)
 {
-       tdm_error error;
-       const char *ret_name;
-       SKIP_FLAG(has_output);
-       const char *set_name = "ut_vblank";
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_name(default_vblank, set_name);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, this) == TDM_ERROR_NONE);
 
-       error = tdm_vblank_get_name(default_vblank, &ret_name);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, this);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, this);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, this);
 
-       ASSERT_STREQ(set_name, ret_name);
-}
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-/* tdm_vblank_set_fps() */
+               done = false;
 
-TEST_F(TDMVblank, VblankSetFpsFailNullVblank)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(vblank != NULL);
+               ASSERT_TRUE(done == false);
 
-       error = tdm_vblank_set_fps(NULL, 10);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankSetFpsFailFpsNull)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerDifferentData)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_fps(default_vblank, 0);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, this) == TDM_ERROR_NONE);
 
-TEST_F(TDMVblank, VblankSetFpsFailWrongVblankPtr)
-{
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, NULL);
 
-       SKIP_FLAG(has_output);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       ASSERT_EXIT({error = tdm_vblank_set_fps((tdm_vblank *)0xFFFFFFFF, 60);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
-}
+               done = false;
 
-TEST_F(TDMVblank, VblankSetFpsSuccess)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(vblank != NULL);
+               ASSERT_TRUE(done == true);
 
-       error = tdm_vblank_set_fps(default_vblank, 60);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankSetFpsSuccessSetTwice)
+static void
+_ut_tdm_vblank_create_cb2(tdm_vblank *vblank, void *user_data)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_fps(default_vblank, 60);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(default_vblank, 60);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDMVblank *test_vblank = (TDMVblank*)user_data;
+       test_vblank->done = true;
+       tdm_vblank_remove_create_handler(test_vblank->dpy, _ut_tdm_vblank_create_cb2, user_data);
 }
 
-/* tdm_vblank_get_fps() */
-
-TEST_F(TDMVblank, VblankGetFpsFailNullAll)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerInHandler)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_fps(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       ASSERT_TRUE(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb2, this) == TDM_ERROR_NONE);
 
-TEST_F(TDMVblank, VblankGetFpsFailNullVblank)
-{
-       tdm_error error;
-       unsigned int ret_fps;
-       SKIP_FLAG(has_output);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       error = tdm_vblank_get_fps(NULL, &ret_fps);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+               done = false;
 
-TEST_F(TDMVblank, VblankGetFpsFailNullFps)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+               ASSERT_TRUE(vblank != NULL);
+               if (o == 0)
+                       ASSERT_TRUE(done == true);
+               else
+                       ASSERT_TRUE(done == false);
 
-       error = tdm_vblank_get_fps(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetFpsFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerNullObject)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       unsigned int ret_fps;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_EXIT({error = tdm_vblank_get_fps((tdm_vblank *)0xFFFFFFFF, &ret_fps);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       tdm_vblank_remove_create_handler(NULL, _ut_tdm_vblank_create_cb, NULL);
 }
 
-TEST_F(TDMVblank, VblankGetNameSuccessWhithoutSetFps)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerNullOther)
 {
-       tdm_error error;
-       unsigned int ret_fps;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_fps(default_vblank, &ret_fps);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       tdm_vblank_remove_create_handler(dpy, NULL, NULL);
 }
 
-TEST_F(TDMVblank, VblankGetFpsSuccess)
+/* tdm_vblank_get_output() */
+TEST_P(TDMVblank, VblankGetOutput)
 {
-       tdm_error error;
-       unsigned int ret_fps = 10;
-       SKIP_FLAG(has_output);
-       unsigned int set_fps = 50;
-
-       error = tdm_vblank_set_fps(default_vblank, set_fps);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_fps(default_vblank, &ret_fps);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       ASSERT_TRUE(set_fps == ret_fps);
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               ASSERT_TRUE(tdm_vblank_get_output(vblanks[v], &ret) != NULL);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
+       }
 }
 
-/* tdm_vblank_ignore_global_fps() */
-
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsFailNullVblank)
+TEST_P(TDMVblank, VblankGetOutputNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_ignore_global_fps(NULL, 1);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       tdm_error ret;
+       ASSERT_TRUE(tdm_vblank_get_output(NULL, &ret) == NULL);
+       ASSERT_TRUE(ret == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankGetOutputNullOther)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-
-       SKIP_FLAG(has_output);
-
-       ASSERT_EXIT({error = tdm_vblank_ignore_global_fps((tdm_vblank *)0xFFFFFFFF, 1);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessUnset)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_get_output(vblanks[0], NULL) != NULL);
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessUnsetTwice)
+/* tdm_vblank_get_client_pid() */
+TEST_P(TDMVblank, VblankGetClientPid)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               pid_t pid = (pid_t)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_vblank_get_client_pid(vblanks[v], &pid) == TDM_ERROR_NONE);
+               /* client pid should be 0 in case vblank is created in server side */
+               ASSERT_TRUE(pid == 0);
+       }
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessSet)
+TEST_P(TDMVblank, VblankGetClientPidNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_ignore_global_fps(default_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       pid_t pid = (pid_t)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_vblank_get_client_pid(NULL, &pid) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(pid == (pid_t)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessSetTwice)
+TEST_P(TDMVblank, VblankGetClientPidNullOther)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_ignore_global_fps(default_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_ignore_global_fps(default_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-}
-
-/* tdm_vblank_set_offset() */
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-TEST_F(TDMVblank, VblankSetOffsetFailNullVblank)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_offset(NULL, 10);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_get_client_pid(vblanks[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankSetOffsetFailFailWrongVblankPtr)
+/* tdm_vblank_set_name() */
+TEST_P(TDMVblank, VblankSetName)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       ASSERT_EXIT({error = tdm_vblank_set_offset((tdm_vblank *)0xFFFFFFFF, 10);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_set_name(vblanks[v], TDM_UT_VBLANK_NAME) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblank, VblankSetOffsetSuccess)
+TEST_P(TDMVblank, VblankSetNameNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_offset(default_vblank, 50);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_set_name(NULL, TDM_UT_VBLANK_NAME) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankSetOffsetSuccessSuccessSetTwice)
+TEST_P(TDMVblank, VblankSetNameNullOther)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_offset(default_vblank, 50);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_offset(default_vblank, 50);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_set_name(vblanks[v], NULL) == TDM_ERROR_NONE);
 }
 
-/* tdm_vblank_get_offset() */
-
-TEST_F(TDMVblank, VblankGetOffsetFailNullAll)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_offset(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
-
-TEST_F(TDMVblank, VblankGetOffsetFailNullVblank)
+/* tdm_vblank_get_name() */
+TEST_P(TDMVblank, VblankGetName)
 {
-       tdm_error error;
-       int offset;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_offset(NULL, &offset);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-TEST_F(TDMVblank, VblankGetOffsetFailNullOffset)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_get_offset(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               const char *name = (const char *)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_vblank_set_name(vblanks[v], TDM_UT_VBLANK_NAME) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_name(vblanks[v], &name) == TDM_ERROR_NONE);
+               ASSERT_STREQ(name, TDM_UT_VBLANK_NAME);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetOffsetFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankGetNameNullObject)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       int offset;
-       SKIP_FLAG(has_output);
-
-       ASSERT_EXIT({error = tdm_vblank_get_offset((tdm_vblank *)0xFFFFFFFF, &offset);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       const char *name = (const char *)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_vblank_get_name(NULL, &name) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(name == (const char *)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblank, VblankGetOffsetSuccesWithoutSet)
+TEST_P(TDMVblank, VblankGetNameNullOther)
 {
-       tdm_error error;
-       int offset;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_get_offset(default_vblank, &offset);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_get_name(vblanks[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetOffsetSucces)
+TEST_P(TDMVblank, VblankGetNameNoSet)
 {
-       tdm_error error;
-       int set_offset = 567;
-       int ret_offset;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_offset(default_vblank, set_offset);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_get_offset(default_vblank, &ret_offset);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       ASSERT_TRUE(set_offset == ret_offset);
-}
-
-/* tdm_vblank_set_enable_fake() */
-
-TEST_F(TDMVblank, VblankSetEnableFakeFailNullVblank)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_enable_fake(NULL, 1);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               const char *name = (const char *)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_vblank_get_name(vblanks[v], &name) == TDM_ERROR_NONE);
+               ASSERT_STREQ(name, TDM_VBLANK_DEFAULT_NAME);
+       }
 }
 
-TEST_F(TDMVblank, VblankSetEnableFakeFailFailWrongVblankPtr)
+/* tdm_vblank_set_fps() */
+TEST_P(TDMVblank, VblankSetFps)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       ASSERT_EXIT({error = tdm_vblank_set_enable_fake((tdm_vblank *)0xFFFFFFFF, 1);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], 60) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblank, VblankSetEnableFakeSuccessSet)
+TEST_P(TDMVblank, VblankSetFpsNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_enable_fake(default_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_set_fps(NULL, 60) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankSetEnableFakeSuccessSetTwice)
+TEST_P(TDMVblank, VblankSetFpsTwice)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_enable_fake(default_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_enable_fake(default_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], 60) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], 60) == TDM_ERROR_NONE);
+       }
 }
 
-/* tdm_vblank_get_enable_fake() */
-
-TEST_F(TDMVblank, VblankGetEnableFakeFailNullAll)
+/* tdm_vblank_set_fixed_fps() */
+TEST_P(TDMVblank, VblankSetFixedFps)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_enable_fake(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-TEST_F(TDMVblank, VblankGetEnableFakeFailNullVblank)
-{
-       tdm_error error;
-       unsigned int enable_fake;
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_get_enable_fake(NULL, &enable_fake);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_set_fixed_fps(vblanks[v], 60) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeFailNullEnableFake)
+TEST_P(TDMVblank, VblankSetFixedFpsNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_enable_fake(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_set_fixed_fps(NULL, 60) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankSetFixedFpsTwice)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       unsigned int enable_fake;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_EXIT({error = tdm_vblank_get_enable_fake((tdm_vblank *)0xFFFFFFFF, &enable_fake);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(TestCreateVblanks() == true);
+
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_TRUE(tdm_vblank_set_fixed_fps(vblanks[v], 60) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_set_fixed_fps(vblanks[v], 60) == TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeSuccessWithoutSet)
+/* tdm_vblank_get_fps() */
+TEST_P(TDMVblank, VblankGetFps)
 {
-       tdm_error error;
-       unsigned int enable_fake;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_get_enable_fake(default_vblank, &enable_fake);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], 60) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps == 60);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeSuccess)
+TEST_P(TDMVblank, VblankGetFpsNullObject)
 {
-       tdm_error error;
-       unsigned int set_enable_fake = 1;
-       unsigned int ret_enable_fake;
-
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_enable_fake(default_vblank, set_enable_fake);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_get_enable_fake(default_vblank, &ret_enable_fake);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       ASSERT_TRUE(set_enable_fake == ret_enable_fake);
+       unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_vblank_get_fps(NULL, &fps) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(fps == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-/* tdm_vblank_set_client_vblank_fps() */
-
-/* TODO: need to create the tdm client */
-TEST_F(TDMVblank, VblankSetClientVblankFpsFailNullAll)
+TEST_P(TDMVblank, VblankGetFpsNullOther)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_client_vblank_fps(0, 0, 0);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_get_fps(vblanks[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-/* TODO: need to create the tdm client */
-TEST_F(TDMVblank, VblankSetClientVblankFpsFailNullPid)
+TEST_P(TDMVblank, VblankGetFpsNoSet)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_client_vblank_fps(0, 0, 0);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               const tdm_output_mode *mode = (const tdm_output_mode *)TDM_UT_INVALID_VALUE;
+               tdm_error ret;
 
-/* tdm_vblank_wait() */
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps != 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
 
-TEST_F(TDMVblank, VblankWaitFailNullAll)
-{
-       tdm_error error;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_TRUE(output != NULL);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
 
-       SKIP_FLAG(has_output);
+               ASSERT_TRUE(tdm_output_get_mode(output, &mode) == TDM_ERROR_NONE);
+               ASSERT_TRUE(mode != NULL && mode != (const tdm_output_mode *)TDM_UT_INVALID_VALUE);
 
-       error = tdm_vblank_wait(NULL, 0, 0, 0, NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               ASSERT_TRUE(fps == mode->vrefresh);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailNullVblank)
+TEST_P(TDMVblank, VblankGetFpsAfterSetFixedFps)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_wait(NULL, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
 
-TEST_F(TDMVblankWait, VblankWaitFailNullFunc)
-{
-       tdm_error error;
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], 60) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps == 60);
 
-       SKIP_FLAG(has_output);
+               ASSERT_TRUE(tdm_vblank_set_fixed_fps(vblanks[v], 10) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps == 10);
 
-       error = tdm_vblank_wait(default_vblank, 0, 0, 1, NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               /* should return TDM_ERROR_NONE because tdm_vblank_set_fixed_fps would be
+                * called by other who call tdm_vblank_set_fps. If returns error, other
+                * can't handle error.
+                */
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], 60) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps == 10);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailWrongVblankPtr)
+/* tdm_vblank_ignore_global_fps() */
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsNullObject)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       SKIP_FLAG(has_output);
-
-       ASSERT_EXIT({error = tdm_vblank_wait((tdm_vblank *)0xFFFFFFFF, 0, 0, 1, UtVblankHandler, NULL);;
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       ASSERT_TRUE(tdm_vblank_ignore_global_fps(NULL, 1) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-void *UtWaitVblankThreadHndl(void *ptr)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsSet)
 {
-       tdm_error error;
-       TDMVblankWait *vblankWait = (TDMVblankWait *)ptr;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_wait(vblankWait->default_vblank, 0, 0, 1, TDMVblankWait::UtVblankHandler, NULL);
-       if (error != TDM_ERROR_NONE)
-               vblankWait->utWaitVblankThreadHndlResult = 0;
-       else
-               vblankWait->utWaitVblankThreadHndlResult = 1;
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       return NULL;
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_ignore_global_fps(vblanks[v], 1) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailInOtherThread)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsSetTwice)
 {
-       pthread_t thread = 0;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_FALSE(pthread_create(&thread, NULL, UtWaitVblankThreadHndl, this));
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       ASSERT_FALSE(pthread_join(thread, NULL));
-
-       ASSERT_FALSE(utWaitVblankThreadHndlResult);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_TRUE(tdm_vblank_ignore_global_fps(vblanks[v], 1) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_ignore_global_fps(vblanks[v], 1) == TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailDisconnectedOutput)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsUnset)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!discon_output_vblank)
-               return;
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_ignore_global_fps(vblanks[v], 0) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailDpmsOff)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsUnsetTwice)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_TRUE(tdm_vblank_ignore_global_fps(vblanks[v], 0) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_ignore_global_fps(vblanks[v], 0) == TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessFpsNonMultipleVrefresh)
+/* tdm_vblank_set_offset() */
+TEST_P(TDMVblank, VblankSetOffset)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       UtHandleVblankEvent();
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_set_offset(vblanks[v], 10) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessFpsNonMultipleVrefreshRepeatedly)
+TEST_P(TDMVblank, VblankSetOffsetNullObject)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
-       }
+       ASSERT_TRUE(tdm_vblank_set_offset(NULL, 10) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessDisconnectedOutput)
+TEST_P(TDMVblank, VblankSetOffsetTwice)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!discon_output_vblank)
-               return;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_TRUE(tdm_vblank_set_offset(vblanks[v], 10) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_set_offset(vblanks[v], 10) == TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessDisconnectedOutputRepeatedly)
+/* tdm_vblank_get_offset() */
+TEST_P(TDMVblank, VblankGetOffset)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!discon_output_vblank)
-               return;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++) {
+               int offset = TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_vblank_set_offset(vblanks[v], 10) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_offset(vblanks[v], &offset) == TDM_ERROR_NONE);
+               ASSERT_TRUE(offset == 10);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessHW)
+TEST_P(TDMVblank, VblankGetOffsetNullObject)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       int offset = TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_vblank_get_offset(NULL, &offset) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(offset == TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessDestroy)
+TEST_P(TDMVblank, VblankGetOffsetNullOther)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       tdm_vblank_destroy(con_output_vblank);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 0);
-       ASSERT_TRUE(data == 0);
+       ASSERT_TRUE(tdm_vblank_get_offset(vblanks[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessChangeDpms)
+TEST_P(TDMVblank, VblankGetOffsetNoSet)
 {
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_set_enable_fake(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++) {
+               int offset = TDM_UT_INVALID_VALUE;
+               ASSERT_TRUE(tdm_vblank_get_offset(vblanks[v], &offset) == TDM_ERROR_NONE);
+               ASSERT_TRUE(offset == 0);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessChangeDpmsWithEnableFake)
+/* tdm_vblank_set_enable_fake() */
+TEST_P(TDMVblank, VblankSetEnableFake)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_enable_fake(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_TRUE(tdm_vblank_set_enable_fake(vblanks[v], 1) == TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessHWRepeatedly)
+TEST_P(TDMVblank, VblankSetEnableFakeNullObject)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
-       }
+       ASSERT_TRUE(tdm_vblank_set_enable_fake(NULL, 1) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessOffsenGreaterThanZero)
+TEST_P(TDMVblank, VblankSetEnableFakeTwice)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_offset(con_output_vblank, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_TRUE(tdm_vblank_set_enable_fake(vblanks[v], 1) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_set_enable_fake(vblanks[v], 1) == TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessOffsenGreaterThanZeroRepeatedly)
+/* tdm_vblank_get_enable_fake() */
+TEST_P(TDMVblank, VblankGetEnableFake)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_offset(con_output_vblank, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int enable_fake;
+               ASSERT_TRUE(tdm_vblank_set_enable_fake(vblanks[v], 1) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_enable_fake(vblanks[v], &enable_fake) == TDM_ERROR_NONE);
+               ASSERT_TRUE(enable_fake == 1);
 
-               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+               ASSERT_TRUE(tdm_vblank_set_enable_fake(vblanks[v], 0) == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_enable_fake(vblanks[v], &enable_fake) == TDM_ERROR_NONE);
+               ASSERT_TRUE(enable_fake == 0);
        }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessFpsNonMultipleVrefresh)
+TEST_P(TDMVblank, VblankGetEnableFakeNullObject)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       unsigned int enable_fake = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_TRUE(tdm_vblank_get_enable_fake(NULL, &enable_fake) == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_TRUE(enable_fake == (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessFpsNonMultipleVrefreshRepeatedly)
+TEST_P(TDMVblank, VblankGetEnableFakeNullOther)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
-       }
+       ASSERT_TRUE(tdm_vblank_get_enable_fake(vblanks[0], NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessDisconnectedOutput)
+TEST_P(TDMVblank, VblankGetEnableFakeNoSet)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!discon_output_vblank)
-               return;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int enable_fake;
+               ASSERT_TRUE(tdm_vblank_get_enable_fake(vblanks[v], &enable_fake) == TDM_ERROR_NONE);
+               ASSERT_TRUE(enable_fake == 0);
+       }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessDisconnectedOutputRepeatedly)
+static void
+_ut_tdm_vblank_cb(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
+                                 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!discon_output_vblank)
-               return;
-
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
-       }
+       unsigned int *cur_seq = (unsigned int *)user_data;
+       if (cur_seq)
+               *cur_seq = sequence;
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessHW)
+TEST_P(TDMVblank, VblankWait)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               interval = 1.0 / (double)fps;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               for (int t = 0; t < 10; t++) {
+                       unsigned int cur_seq = 0;
 
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) < (interval + interval));
+               }
+       }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessHWRepeatedly)
+TEST_P(TDMVblank, VblankWaitFewTime)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               interval = 1.0 / (double)fps;
 
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               for (int t = 0; t < 10; t++) {
+                       unsigned int cur_seq, seq1, seq2;
 
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+                       cur_seq = seq1 = seq2 = 0;
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &seq1) == TDM_ERROR_NONE);
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &seq2) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       ASSERT_TRUE(seq1 != 0);
+                       ASSERT_TRUE(seq2 != 0);
 
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) < (interval + interval));
+               }
        }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessOffsenGreaterThanZero)
+TEST_P(TDMVblank, VblankWaitInterval0)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_offset(con_output_vblank, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       ASSERT_TRUE(tdm_vblank_wait(vblanks[0], 0, 0, 0, _ut_tdm_vblank_cb, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessOffsenGreaterThanZeroRepeatedly)
+TEST_P(TDMVblank, VblankWaitInterval)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-       error = tdm_vblank_set_offset(con_output_vblank, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               interval = 1.0 / (double)fps;
 
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       unsigned int cur_seq = 0;
 
-               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, t, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) > interval * (t - 1));
+                       ASSERT_TRUE((end - start) < interval * t + interval);
+               }
        }
 }
 
-/* tdm_vblank_wait_seq() */
-
-TEST_F(TDMVblank, VblankWaitSeqFailNullAll)
+TEST_P(TDMVblank, VblankWaitSeq)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_wait_seq(NULL, 0, 0, 0, NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailNullVblank)
-{
-       tdm_error error;
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               interval = 1.0 / (double)fps;
 
-       SKIP_FLAG(has_output);
+               for (int t = 0; t < 10; t++) {
+                       unsigned int cur_seq = 0, temp = 0;
 
-       error = tdm_vblank_wait_seq(NULL, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailWrongVblankPtr)
-{
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       SKIP_FLAG(has_output);
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait_seq(vblanks[v], 0, 0, cur_seq + 1, _ut_tdm_vblank_cb, &temp) == TDM_ERROR_NONE);
+                       while (temp == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       ASSERT_EXIT({error = tdm_vblank_wait_seq((tdm_vblank *)0xFFFFFFFF, 0, 0, 1, UtVblankHandler, NULL);;
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) < (interval + interval));
+               }
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailNullFunc)
+TEST_P(TDMVblank, VblankWaitSeqInterval)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_wait_seq(NULL, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-void *UtWaitVblankSeqThreadHndl(void *ptr)
-{
-       tdm_error error;
-       TDMVblankWait *vblankWait = (TDMVblankWait *)ptr;
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_wait_seq(vblankWait->default_vblank, 0, 0, 1, TDMVblankWait::UtVblankHandler, NULL);
-       if (error != TDM_ERROR_NONE)
-               vblankWait->utWaitVblankSeqThreadHndlResult = 0;
-       else
-               vblankWait->utWaitVblankSeqThreadHndlResult = 1;
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-       return NULL;
-}
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               interval = 1.0 / (double)fps;
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailInOtherThread)
-{
-       pthread_t thread = 0;
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       unsigned int cur_seq = 0, temp = 0;
 
-       SKIP_FLAG(has_output);
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       ASSERT_FALSE(pthread_create(&thread, NULL, UtWaitVblankSeqThreadHndl, this));
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait_seq(vblanks[v], 0, 0, cur_seq + t, _ut_tdm_vblank_cb, &temp) == TDM_ERROR_NONE);
+                       while (temp == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       ASSERT_FALSE(pthread_join(thread, NULL));
+#if 0
+printf("@@@ %s(%d) cur_seq(%d) t(%d) start(%.6f) end(%.6f) diff(%.6f) (%.6f~%.6f)\n",
+       __FUNCTION__, __LINE__, cur_seq, t, start, end, end - start, (interval * (t - 1)), (interval * t + interval));
+#endif
 
-       ASSERT_FALSE(utWaitVblankSeqThreadHndlResult);
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) > (interval * (t - 1)));
+                       ASSERT_TRUE((end - start) < (interval * t + interval));
+               }
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailDisconnectedOutput)
+TEST_P(TDMVblank, VblankWaitNullObject)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!discon_output_vblank)
-               return;
+       unsigned int cur_seq = 0;
 
-       error = tdm_vblank_wait_seq(discon_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_wait(NULL, 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailDpmsOff)
+TEST_P(TDMVblank, VblankWaitNullOther)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_wait(vblanks[0], 0, 0, 0, NULL, NULL) == TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessFpsNonMultipleVrefresh)
+TEST_P(TDMVblank, VblankWaitDpmsOff)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
 
-       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(ut_tdm_output_unset(dpy, output) == true);
 
-       UtHandleVblankEvent();
+               ASSERT_TRUE(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL) == TDM_ERROR_DPMS_OFF);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessFpsNonMultipleVrefreshRepeatedly)
+TEST_P(TDMVblank, VblankWaitSetEnableFakeDpmsOff)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+               ASSERT_TRUE(ut_tdm_output_unset(dpy, output) == true);
 
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
 
-               UtHandleVblankEvent();
+               ASSERT_TRUE(tdm_vblank_set_enable_fake(vblanks[v], 1) == TDM_ERROR_NONE);
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL) == TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessDisconnectedOutput)
+TEST_P(TDMVblank, VblankWaitDisconnectedOutput)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!discon_output_vblank)
-               return;
-
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_wait_seq(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       UtHandleVblankEvent();
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
-}
-
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessDisconnectedOutputRepeatedly)
-{
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!discon_output_vblank)
-               return;
-
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait_seq(discon_output_vblank, 0, 0, i, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
+               if (ut_tdm_output_is_connected(output))
+                       continue;
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL) == TDM_ERROR_OUTPUT_DISCONNECTED);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessHW)
+TEST_P(TDMVblank, VblankWaitSetOffset)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_set_offset(vblanks[v], 100) == TDM_ERROR_NONE);
 
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               interval = 1.0 / (double)fps;
 
-       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               for (int t = 0; t < 3; t++) {
+                       unsigned int cur_seq = 0;
 
-       UtHandleVblankEvent();
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) > (0.1));
+                       ASSERT_TRUE((end - start) < (interval + interval + 0.1));
+               }
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessHWRepeatedly)
+TEST_P(TDMVblank, VblankWaitSetFps)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval, vrefresh_interval;
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               vrefresh_interval = 1.0 / (double)fps;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               fps /= 2;
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], fps) == TDM_ERROR_NONE);
+               interval = 1.0 / (double)fps;
 
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               for (int t = 0; t < 3; t++) {
+                       unsigned int cur_seq = 0;
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+                       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) > (interval - vrefresh_interval));
+                       ASSERT_TRUE((end - start) < (interval + vrefresh_interval));
+               }
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessOffsenGreaterThanZero)
+TEST_P(TDMVblank, VblankWaitSetFixedFps)
 {
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       if (!con_output_vblank)
-               return;
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_get_fps(vblanks[v], &fps) == TDM_ERROR_NONE);
+               ASSERT_TRUE(fps > 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+               interval = 1.0 / (double)fps;
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_TRUE(tdm_vblank_set_fixed_fps(vblanks[v], fps) == TDM_ERROR_NONE);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               /* this fps will be ignored because it has fixed fps value */
+               fps /= 2;
+               ASSERT_TRUE(tdm_vblank_set_fps(vblanks[v], fps) == TDM_ERROR_NONE);
 
-       error = tdm_vblank_set_offset(con_output_vblank, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               for (int t = 0; t < 3; t++) {
+                       unsigned int cur_seq = 0;
 
-       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       start = tdm_helper_get_time();
+                       ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq) == TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+                       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_TRUE((end - start) < (interval + interval));
+               }
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessOffsenGreaterThanZeroRepeatedly)
+TEST_P(TDMVblank, VblankWaitEnableDisableGlobalFps)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+       double vrefresh_interval;
+       unsigned int cur_seq[3];
+       unsigned int global_fps = 5;
+       double start, end, interval;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks3() == true);
+       ASSERT_TRUE(vblank_count == 3);
 
-       error = tdm_vblank_set_offset(con_output_vblank, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(tdm_vblank_get_fps(vblanks[0], &fps) == TDM_ERROR_NONE);
+       ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+       vrefresh_interval = 1.0 / (double)fps;
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < 3; v++) {
+               ASSERT_TRUE(tdm_vblank_set_fixed_fps(vblanks[v], 10 * (v + 1)) == TDM_ERROR_NONE);
+               interval = 1.0 / (double)(10 * (v + 1));
+       }
 
-               UtHandleVblankEvent();
+       /* enable test. global fps doesn't effect server's vblanks */
+       tdm_vblank_enable_global_fps(1, global_fps);
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]) == TDM_ERROR_NONE);
        }
-}
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessRepeatedlyWithSameSeq)
-{
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
+       start = tdm_helper_get_time();
+       while (cur_seq[2] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
 
-       if (!con_output_vblank)
-               return;
+       /* "+- vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_TRUE((end - start) > (interval - vrefresh_interval));
+       ASSERT_TRUE((end - start) < (interval + vrefresh_interval));
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(cur_seq[1] == 0);
+       ASSERT_TRUE(cur_seq[0] == 0);
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       while (cur_seq[1] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       ASSERT_TRUE(cur_seq[0] == 0);
 
-       error = tdm_vblank_set_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       while (cur_seq[0] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+       /* disable test. global fps doesn't effect server's vblanks */
+       tdm_vblank_enable_global_fps(0, 0);
 
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 2, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]) == TDM_ERROR_NONE);
+       }
 
-               UtHandleVblankEvent();
+       while (cur_seq[2] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       ASSERT_TRUE(cur_seq[1] == 0);
+       ASSERT_TRUE(cur_seq[0] == 0);
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
-       }
+       while (cur_seq[1] == 0)
+               ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+       ASSERT_TRUE(cur_seq[0] == 0);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessRepeatedlyWithBigFps)
+TEST_P(TDMVblank, VblankWaitSetEnableFakeDisconnected)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_TRUE(TestPrepareOutput() == true);
+       ASSERT_TRUE(TestCreateVblanks() == true);
 
-       error = tdm_vblank_set_fps(con_output_vblank, 5000);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_TRUE(ret == TDM_ERROR_NONE);
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               if (i < 4)
+               if (ut_tdm_output_is_connected(output))
                        continue;
 
-               UtHandleVblankEvent();
+               ASSERT_TRUE(tdm_vblank_set_enable_fake(vblanks[v], 1) == TDM_ERROR_DPMS_OFF);
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+               ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL) == TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessRepeatedlyWithDelay)
-{
-       tdm_error error;
-       int data = 0;
+INSTANTIATE_TEST_CASE_P(TDMVblankParams,
+                                               TDMVblank,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
 
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
-
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-               usleep(100000);
-
-               UtHandleVblankEvent();
-
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
-       }
-}
+#endif