doc: update dot file
[platform/core/uifw/libtdm.git] / utests / src / ut_tdm_vblank.cpp
index 746d4c7..b9ae767 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
-#include "tdm.h"
-#include "tbm_bufmgr.h"
-#include "ut_common.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("TDM_DLOG", "1", 1);
-               setenv("XDG_RUNTIME_DIR", ".", 1);
-               setenv("TBM_DLOG", "1", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-
-               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_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);
+#include "ut_tdm.h"
 
-                       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;
-               }
+static void _ut_tdm_vblank_create_cb(tdm_vblank *vblank, void *user_data);
+static void _ut_tdm_vblank_create_cb2(tdm_vblank *vblank, void *user_data);
 
-               default_output = disconnected_output;
+class TDMVblank : public TDMOutput
+{
+public:
+       bool has_vblanks;
 
-               if (connected_output) {
-                       int output_modes_cnt = 0;
-                       const tdm_output_mode* output_modes;
+       tdm_vblank **vblanks;
+       int vblank_count;
 
-                       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;
-                       }
+       bool done;
 
-                       for(int i = 0; i < output_modes_cnt; i++) {
-                               if(output_modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) {
-                                       preferred_mode = &output_modes[i];
+       TDMVblank();
+       void SetUp(void);
+       void TearDown(void);
 
-                                       default_output = connected_output;
+       bool TestCreateVblanks(void);
+       bool TestCreateVblanks3(void);
+       void TestDestroyVblanks(void);
 
-                                       return;
-                               }
-                       }
-               }
-
-               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;
-
-               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);
-               }
-
-               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;
-               }
+TDMVblank::TDMVblank()
+{
+       has_vblanks = false;
+       vblanks = NULL;
+       vblank_count = 0;
+       done = false;
+}
 
-               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::SetUp(void)
+{
+       TDMOutput::SetUp();
+}
 
-               ASSERT_TRUE(default_vblank != NULL);
-       }
+void TDMVblank::TearDown(void)
+{
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, this);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, NULL);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb2, this);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb2, NULL);
 
-       void TearDown(void)
-       {
-               if (buffer) {
-                       tdm_layer_unset_buffer(layer);
-                       tdm_output_commit(connected_output, 0, NULL, NULL);
-                       tbm_surface_destroy(buffer);
-               }
+       TestDestroyVblanks();
 
-               TDMVblankWithoutCreating::TearDown();
-       }
-};
+       tdm_vblank_enable_global_fps(0, 0);
 
-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;
+       TDMOutput::TearDown();
+}
 
-               if (data)
-                       *data = 1;
+bool TDMVblank::TestCreateVblanks(void)
+{
+       TDM_UT_GOTO_IF_FAIL(output_count > 0, failed);
 
-               utVblankHandlerIsCalled = 1;
-       }
-       int utWaitVblankThreadHndlResult = -1;
-       friend void *UtWaitVblankThreadHndl(void *ptr);
-       int utWaitVblankSeqThreadHndlResult = -1;
-       friend void *UtWaitVblankSeqThreadHndl(void *ptr);
+       vblanks = (tdm_vblank**)calloc(output_count, sizeof(tdm_vblank*));
+       TDM_UT_GOTO_IF_FAIL(vblanks != NULL, failed);
 
-private:
-       int epFd = -1;
-       int timerFd = -1;
-       int tdmFd = -1;
-       static const int timeLimitSec = 1;
+       vblank_count = output_count;
+       has_vblanks = true;
 
-protected:
-       void SetUp(void)
-        {
-               struct epoll_event ep;
+       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);
+       }
 
-               utVblankHandlerIsCalled = 0;
+       return true;
+failed:
+       TestDestroyVblanks();
+       has_vblanks = false;
+       return false;
+}
 
-               setModeAndDpms = 1;
-               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);
-               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;
 
-       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), "");
-}
+               TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_output_prepare(dpy, outputs[o], false) == true);
+       }
 
-/* tdm_vblank_create() */
+       return true;
+}
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullAll)
+bool ut_tdm_vblank_is_avaiable(tdm_vblank *vblank)
 {
-       tdm_vblank *ret_vblank;
-
-       SKIP_FLAG(has_output);
+       tdm_error ret;
+       tdm_output *output = tdm_vblank_get_output(vblank, &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-       ret_vblank = tdm_vblank_create(NULL, NULL, NULL);
-       ASSERT_TRUE(ret_vblank == NULL);
+       /* only check if connected */
+       return ut_tdm_output_is_connected(output);
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullDpy)
+/* tdm_vblank_set_client_vblank_fps */
+TEST_P(TDMVblank, DISABLED_VblankSetClientVblankFps)
 {
-       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);
+       /* tested in ut_tdm_client.c */
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullOutput)
+TEST_P(TDMVblank, VblankSetClientVblankFpsNullObject)
 {
-       tdm_vblank *ret_vblank;
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       ret_vblank = tdm_vblank_create(dpy, NULL, &error);
-       ASSERT_TRUE(ret_vblank == NULL);
-       ASSERT_TRUE(error == TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(tdm_vblank_set_client_vblank_fps(0, NULL, 60), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(tdm_vblank_set_client_vblank_fps(123, NULL, 0), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailWrongDpy)
+/* tdm_vblank_set_client_vblank_fps */
+TEST_P(TDMVblank, DISABLED_VblankSetClientIgnoreGlobalFps)
 {
-       tdm_vblank *ret_vblank = NULL;
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       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), "");
+       /* tested in ut_tdm_client.c */
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateFailWrongOutput)
+TEST_P(TDMVblank, VblankSetClientIgnoreGlobalFpsNullObject)
 {
-       tdm_vblank *ret_vblank = NULL;
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       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), "");
+       ASSERT_EQ(tdm_vblank_set_client_ignore_global_fps(0, NULL, 0), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(tdm_vblank_set_client_ignore_global_fps(0, NULL, 1), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateSuccessForConnectedOutput)
+/* tdm_vblank_create() */
+TEST_P(TDMVblank, VblankCreateDestroy)
 {
-       tdm_vblank *ret_vblank;
-       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_EQ(ret, TDM_ERROR_NONE);
+               ASSERT_NE(vblank, NULL);
 
-       if (!connected_output)
-               return;
-
-       ret_vblank = tdm_vblank_create(dpy, connected_output, &error);
-       ASSERT_TRUE(ret_vblank != NULL);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblankWithoutCreating, VblankCreateSuccessForDisconnectedOutput)
+TEST_P(TDMVblank, VblankCreateNullDpy)
 {
-       tdm_vblank *ret_vblank;
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       tdm_error ret;
 
-       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 *vblank = tdm_vblank_create(NULL, outputs[0], &ret);
+       ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(vblank, NULL);
 }
 
-/* tdm_vblank_destroy() */
-
-TEST_F(TDMVblank, VblankDestroyWrongVblankPtr)
+TEST_P(TDMVblank, VblankCreateNullOutput)
 {
-       SKIP_FLAG(has_output);
+       tdm_error ret;
 
-       ASSERT_EXIT({tdm_vblank_destroy((tdm_vblank *)0xFFFFFFFF);},
-                               ::testing::ExitedWithCode(0), "");
+       tdm_vblank *vblank = tdm_vblank_create(dpy, NULL, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(vblank, NULL);
 }
 
-TEST_F(TDMVblank, VblankDestroySuccess)
+TEST_P(TDMVblank, VblankCreateNullOther)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       tdm_vblank_destroy(con_output_vblank);
+       tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[0], NULL);
+       ASSERT_NE(vblank, NULL);
 
-       error = tdm_vblank_set_enable_fake(default_vblank, 1);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       tdm_vblank_destroy(vblank);
 }
 
-/* tdm_vblank_set_name() */
-
-TEST_F(TDMVblank, VblankSetNameFailNullAll)
+/* tdm_vblank_destroy() */
+TEST_P(TDMVblank, VblankDestroyNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_name(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       tdm_vblank_destroy(NULL);
 }
 
-TEST_F(TDMVblank, VblankSetNameFailWrongVblankPtr)
+static void
+_ut_tdm_vblank_create_cb(tdm_vblank *vblank, void *user_data)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-
-       SKIP_FLAG(has_output);
-
-       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), "");
+       TDMVblank *test_vblank = (TDMVblank*)user_data;
+       if (test_vblank)
+               test_vblank->done = true;
 }
 
-TEST_F(TDMVblank, VblankSetNameSuccess)
+/* tdm_vblank_add_create_handler */
+TEST_P(TDMVblank, VblankAddCreateHandler)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_name(default_vblank, "ut_vblank");
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-}
+       ASSERT_EQ(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, this), TDM_ERROR_NONE);
 
-TEST_F(TDMVblank, VblankSetNameSuccessNullName)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       error = tdm_vblank_set_name(default_vblank, NULL);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-}
+               done = false;
 
-/* tdm_vblank_get_name() */
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
+               ASSERT_NE(vblank, NULL);
+               ASSERT_EQ(done, true);
 
-TEST_F(TDMVblank, VblankGetNameFailNullAll)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_name(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetNameFailNullVblank)
+TEST_P(TDMVblank, VblankAddCreateHandlerTwice)
 {
-       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_EQ(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, NULL), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, NULL), TDM_ERROR_BAD_REQUEST);
 }
 
-TEST_F(TDMVblank, VblankGetNameFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankAddCreateHandlerNullObject)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       const char *ret_name;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
-
-       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), "");
+       ASSERT_EQ(tdm_vblank_add_create_handler(NULL, _ut_tdm_vblank_create_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetNameFailNullName)
+TEST_P(TDMVblank, VblankAddCreateHandlerNullOther)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_name(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_add_create_handler(dpy, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetNameSuccessWhithoutSetName)
+/* tdm_vblank_remove_create_handler */
+TEST_P(TDMVblank, VblankRemoveCreateHandler)
 {
-       tdm_error error;
-       const char *ret_name;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_name(default_vblank, &ret_name);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-}
+       ASSERT_EQ(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);
 
-TEST_F(TDMVblank, VblankGetNameSuccess)
-{
-       tdm_error error;
-       const char *ret_name;
-       SKIP_FLAG(has_output);
-       const char *set_name = "ut_vblank";
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       error = tdm_vblank_set_name(default_vblank, set_name);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               done = false;
 
-       error = tdm_vblank_get_name(default_vblank, &ret_name);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
+               ASSERT_NE(vblank, NULL);
+               ASSERT_EQ(done, false);
 
-       ASSERT_STREQ(set_name, ret_name);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-/* tdm_vblank_set_fps() */
-
-TEST_F(TDMVblank, VblankSetFpsFailNullVblank)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerFewTimes)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_fps(NULL, 10);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       ASSERT_EQ(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, this), TDM_ERROR_NONE);
 
-TEST_F(TDMVblank, VblankSetFpsFailFpsNull)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       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);
 
-       error = tdm_vblank_set_fps(default_vblank, 0);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-TEST_F(TDMVblank, VblankSetFpsFailWrongVblankPtr)
-{
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+               done = false;
 
-       SKIP_FLAG(has_output);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
+               ASSERT_NE(vblank, NULL);
+               ASSERT_EQ(done, false);
 
-       ASSERT_EXIT({error = tdm_vblank_set_fps((tdm_vblank *)0xFFFFFFFF, 60);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankSetFpsSuccess)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerDifferentData)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_fps(default_vblank, 60);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-}
+       ASSERT_EQ(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb, this), TDM_ERROR_NONE);
 
-TEST_F(TDMVblank, VblankSetFpsSuccessSetTwice)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       tdm_vblank_remove_create_handler(dpy, _ut_tdm_vblank_create_cb, NULL);
 
-       error = tdm_vblank_set_fps(default_vblank, 60);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       error = tdm_vblank_set_fps(default_vblank, 60);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-}
+               done = false;
 
-/* tdm_vblank_get_fps() */
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
+               ASSERT_NE(vblank, NULL);
+               ASSERT_EQ(done, true);
 
-TEST_F(TDMVblank, VblankGetFpsFailNullAll)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_fps(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetFpsFailNullVblank)
+static void
+_ut_tdm_vblank_create_cb2(tdm_vblank *vblank, void *user_data)
 {
-       tdm_error error;
-       unsigned int ret_fps;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_fps(NULL, &ret_fps);
-       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);
 }
 
-TEST_F(TDMVblank, VblankGetFpsFailNullFps)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerInHandler)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_fps(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
-
-TEST_F(TDMVblank, VblankGetFpsFailWrongVblankPtr)
-{
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       unsigned int ret_fps;
+       ASSERT_EQ(tdm_vblank_add_create_handler(dpy, _ut_tdm_vblank_create_cb2, this), TDM_ERROR_NONE);
 
-       SKIP_FLAG(has_output);
+       for (int o = 0; o < output_count; o++) {
+               tdm_error ret;
 
-       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), "");
-}
+               done = false;
 
-TEST_F(TDMVblank, VblankGetNameSuccessWhithoutSetFps)
-{
-       tdm_error error;
-       unsigned int ret_fps;
-       SKIP_FLAG(has_output);
+               tdm_vblank *vblank = tdm_vblank_create(dpy, outputs[o], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
+               ASSERT_NE(vblank, NULL);
+               if (o == 0)
+                       ASSERT_EQ(done, true);
+               else
+                       ASSERT_EQ(done, false);
 
-       error = tdm_vblank_get_fps(default_vblank, &ret_fps);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               tdm_vblank_destroy(vblank);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetFpsSuccess)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerNullObject)
 {
-       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);
-
-       error = tdm_vblank_get_fps(default_vblank, &ret_fps);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_TRUE(set_fps == ret_fps);
+       tdm_vblank_remove_create_handler(NULL, _ut_tdm_vblank_create_cb, NULL);
 }
 
-/* tdm_vblank_ignore_global_fps() */
-
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsFailNullVblank)
+TEST_P(TDMVblank, VblankRemoveCreateHandlerNullOther)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_ignore_global_fps(NULL, 1);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       tdm_vblank_remove_create_handler(dpy, NULL, NULL);
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsFailWrongVblankPtr)
+/* tdm_vblank_get_output() */
+TEST_P(TDMVblank, VblankGetOutput)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       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), "");
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               ASSERT_NE(tdm_vblank_get_output(vblanks[v], &ret), NULL);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessUnset)
+TEST_P(TDMVblank, VblankGetOutputNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       tdm_error ret;
+       ASSERT_EQ(tdm_vblank_get_output(NULL, &ret), NULL);
+       ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessUnsetTwice)
+TEST_P(TDMVblank, VblankGetOutputNullOther)
 {
-       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_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_NE(tdm_vblank_get_output(vblanks[0], NULL), NULL);
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessSet)
+/* 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, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(TestCreateVblanks(), true);
+
+       for (int v = 0; v < vblank_count; v++) {
+               pid_t pid = (pid_t)TDM_UT_INVALID_VALUE;
+               ASSERT_EQ(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_EQ(pid, 0);
+       }
 }
 
-TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessSetTwice)
+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);
-
-       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_EQ(tdm_vblank_get_client_pid(NULL, &pid), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(pid, (pid_t)TDM_UT_INVALID_VALUE);
 }
 
-/* tdm_vblank_set_offset() */
-
-TEST_F(TDMVblank, VblankSetOffsetFailNullVblank)
+TEST_P(TDMVblank, VblankGetClientPidNullOther)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_offset(NULL, 10);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_EQ(TestCreateVblanks(), true);
+
+       ASSERT_EQ(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_EQ(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_EQ(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_EQ(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_EQ(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_EQ(tdm_vblank_set_name(vblanks[v], NULL), TDM_ERROR_NONE);
 }
 
-/* tdm_vblank_get_offset() */
-
-TEST_F(TDMVblank, VblankGetOffsetFailNullAll)
+/* tdm_vblank_get_name() */
+TEST_P(TDMVblank, VblankGetName)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_offset(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-TEST_F(TDMVblank, VblankGetOffsetFailNullVblank)
-{
-       tdm_error error;
-       int offset;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_offset(NULL, &offset);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               const char *name = (const char *)TDM_UT_INVALID_VALUE;
+               ASSERT_EQ(tdm_vblank_set_name(vblanks[v], TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_name(vblanks[v], &name), TDM_ERROR_NONE);
+               ASSERT_STREQ(name, TDM_UT_VBLANK_NAME);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetOffsetFailNullOffset)
+TEST_P(TDMVblank, VblankGetNameNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_offset(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       const char *name = (const char *)TDM_UT_INVALID_VALUE;
+       ASSERT_EQ(tdm_vblank_get_name(NULL, &name), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(name, (const char *)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblank, VblankGetOffsetFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankGetNameNullOther)
 {
-       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), "");
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-TEST_F(TDMVblank, VblankGetOffsetFailWrongOffsetPtr)
-{
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       ASSERT_EXIT({error = tdm_vblank_get_offset(default_vblank, (int *)0xFFFFFFFF);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       ASSERT_EQ(tdm_vblank_get_name(vblanks[0], NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetOffsetSuccesWithoutSet)
+TEST_P(TDMVblank, VblankGetNameNoSet)
 {
-       tdm_error error;
-       int offset;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_get_offset(default_vblank, &offset);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               const char *name = (const char *)TDM_UT_INVALID_VALUE;
+               ASSERT_EQ(tdm_vblank_get_name(vblanks[v], &name), TDM_ERROR_NONE);
+               ASSERT_STREQ(name, TDM_VBLANK_DEFAULT_NAME);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetOffsetSucces)
+/* tdm_vblank_set_fps() */
+TEST_P(TDMVblank, VblankSetFps)
 {
-       tdm_error error;
-       int set_offset = 567;
-       int ret_offset;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(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);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_EQ(tdm_vblank_set_fps(vblanks[v], 60), TDM_ERROR_NONE);
 }
 
-/* tdm_vblank_set_enable_fake() */
-
-TEST_F(TDMVblank, VblankSetEnableFakeFailNullVblank)
+TEST_P(TDMVblank, VblankSetFpsNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_enable_fake(NULL, 1);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_set_fps(NULL, 60), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankSetEnableFakeFailFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankSetFpsTwice)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       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), "");
-}
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-TEST_F(TDMVblank, VblankSetEnableFakeSuccessSet)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_set_enable_fake(default_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_EQ(tdm_vblank_set_fps(vblanks[v], 60), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_set_fps(vblanks[v], 60), TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblank, VblankSetEnableFakeSuccessSetTwice)
+/* tdm_vblank_set_fixed_fps() */
+TEST_P(TDMVblank, VblankSetFixedFps)
 {
-       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_EQ(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_EQ(tdm_vblank_set_fixed_fps(vblanks[v], 60), TDM_ERROR_NONE);
 }
 
-/* tdm_vblank_get_enable_fake() */
-
-TEST_F(TDMVblank, VblankGetEnableFakeFailNullAll)
+TEST_P(TDMVblank, VblankSetFixedFpsNullObject)
 {
-       tdm_error error;
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_get_enable_fake(NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_set_fixed_fps(NULL, 60), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeFailNullVblank)
+TEST_P(TDMVblank, VblankSetFixedFpsTwice)
 {
-       tdm_error error;
-       unsigned int enable_fake;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_get_enable_fake(NULL, &enable_fake);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
-
-TEST_F(TDMVblank, VblankGetEnableFakeFailNullEnableFake)
-{
-       tdm_error error;
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_get_enable_fake(default_vblank, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_EQ(tdm_vblank_set_fixed_fps(vblanks[v], 60), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_set_fixed_fps(vblanks[v], 60), TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeFailWrongVblankPtr)
+/* tdm_vblank_get_fps() */
+TEST_P(TDMVblank, VblankGetFps)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       unsigned int enable_fake;
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       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), "");
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               ASSERT_EQ(tdm_vblank_set_fps(vblanks[v], 60), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_fps(vblanks[v], &fps), TDM_ERROR_NONE);
+               ASSERT_EQ(fps, 60);
+       }
 }
 
-TEST_F(TDMVblank, DISABLED_VblankGetEnableFakeFailWrongOffsetPtr)
+TEST_P(TDMVblank, VblankGetFpsNullObject)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       SKIP_FLAG(has_output);
-
-       ASSERT_EXIT({error = tdm_vblank_get_enable_fake(default_vblank, (unsigned int *)0xFFFFFFFF);
-                               if (error == TDM_ERROR_NONE)
-                                       exit(1);
-                               else
-                                       exit(0);},
-                               ::testing::ExitedWithCode(0), "");
+       unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_EQ(tdm_vblank_get_fps(NULL, &fps), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(fps, (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeSuccessWithoutSet)
+TEST_P(TDMVblank, VblankGetFpsNullOther)
 {
-       tdm_error error;
-       unsigned int enable_fake;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_get_enable_fake(default_vblank, &enable_fake);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_get_fps(vblanks[0], NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblank, VblankGetEnableFakeSuccess)
+TEST_P(TDMVblank, VblankGetFpsNoSet)
 {
-       tdm_error error;
-       unsigned int set_enable_fake = 1;
-       unsigned int ret_enable_fake;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_enable_fake(default_vblank, set_enable_fake);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_get_enable_fake(default_vblank, &ret_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;
+               const tdm_output_mode *mode = (const tdm_output_mode *)TDM_UT_INVALID_VALUE;
+               tdm_error ret;
 
-       ASSERT_TRUE(set_enable_fake == ret_enable_fake);
-}
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-/* tdm_vblank_set_client_vblank_fps() */
+               ASSERT_EQ(tdm_vblank_get_fps(vblanks[v], &fps), TDM_ERROR_NONE);
+               ASSERT_TRUE(fps != 0 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
 
-/* TODO: need to create the tdm client */
-TEST_F(TDMVblank, VblankSetClientVblankFpsFailNullAll)
-{
-       tdm_error error;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_NE(output, NULL);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
 
-       SKIP_FLAG(has_output);
+               ASSERT_EQ(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_set_client_vblank_fps(0, 0, 0);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               ASSERT_EQ(fps, mode->vrefresh);
+       }
 }
 
-/* TODO: need to create the tdm client */
-TEST_F(TDMVblank, VblankSetClientVblankFpsFailNullPid)
+TEST_P(TDMVblank, VblankGetFpsAfterSetFixedFps)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_set_client_vblank_fps(0, 0, 0);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-/* tdm_vblank_wait() */
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
 
-TEST_F(TDMVblank, VblankWaitFailNullAll)
-{
-       tdm_error error;
+               ASSERT_EQ(tdm_vblank_set_fps(vblanks[v], 60), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_fps(vblanks[v], &fps), TDM_ERROR_NONE);
+               ASSERT_EQ(fps, 60);
 
-       SKIP_FLAG(has_output);
+               ASSERT_EQ(tdm_vblank_set_fixed_fps(vblanks[v], 10), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_fps(vblanks[v], &fps), TDM_ERROR_NONE);
+               ASSERT_EQ(fps, 10);
 
-       error = tdm_vblank_wait(NULL, 0, 0, 0, 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_EQ(tdm_vblank_set_fps(vblanks[v], 60), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_fps(vblanks[v], &fps), TDM_ERROR_NONE);
+               ASSERT_EQ(fps, 10);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailNullVblank)
+/* tdm_vblank_ignore_global_fps() */
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsNullObject)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_wait(NULL, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_ignore_global_fps(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailNullFunc)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsSet)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_wait(default_vblank, 0, 0, 1, NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[v], 1), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsSetTwice)
 {
-       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), "");
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-void *UtWaitVblankThreadHndl(void *ptr)
-{
-       tdm_error error;
-       TDMVblankWait *vblankWait = (TDMVblankWait *)ptr;
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_wait(vblankWait->default_vblank, 0, 0, 1, TDMVblankWait::UtVblankHandler, NULL);
-       if (error != TDM_ERROR_NONE)
-               vblankWait->utWaitVblankThreadHndlResult = 0;
-       else
-               vblankWait->utWaitVblankThreadHndlResult = 0;
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[v], 1), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[v], 1), TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailInOtherThread)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsUnset)
 {
-       pthread_t thread;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       ASSERT_FALSE(pthread_create(&thread, NULL, UtWaitVblankThreadHndl, this));
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       ASSERT_FALSE(pthread_join(thread, NULL));
-
-       ASSERT_FALSE(utWaitVblankThreadHndlResult);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[v], 0), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailDisconnectedOutput)
+TEST_P(TDMVblank, VblankIgnoreGlobalFpsUnsetTwice)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!discon_output_vblank)
-               return;
+       ASSERT_EQ(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_EQ(tdm_vblank_ignore_global_fps(vblanks[v], 0), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[v], 0), TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitFailDpmsOff)
+/* tdm_vblank_set_offset() */
+TEST_P(TDMVblank, VblankSetOffset)
 {
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       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_EQ(tdm_vblank_set_offset(vblanks[v], 10), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessFpsNonMultipleVrefresh)
+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);
-
-       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_EQ(tdm_vblank_set_offset(NULL, 10), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessFpsNonMultipleVrefreshRepeatedly)
+TEST_P(TDMVblank, VblankSetOffsetTwice)
 {
-       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);
+       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_EQ(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);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_EQ(tdm_vblank_set_offset(vblanks[v], 10), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_set_offset(vblanks[v], 10), TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessDisconnectedOutput)
+/* tdm_vblank_get_offset() */
+TEST_P(TDMVblank, VblankGetOffset)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!discon_output_vblank)
-               return;
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       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_EQ(tdm_vblank_set_offset(vblanks[v], 10), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_offset(vblanks[v], &offset), TDM_ERROR_NONE);
+               ASSERT_EQ(offset, 10);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessDisconnectedOutputRepeatedly)
+TEST_P(TDMVblank, VblankGetOffsetNullObject)
 {
-       tdm_error error;
-       int data = 0;
-
-       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);
-       }
+       int offset = TDM_UT_INVALID_VALUE;
+       ASSERT_EQ(tdm_vblank_get_offset(NULL, &offset), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(offset, TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessHW)
+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_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, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       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_EQ(tdm_vblank_get_offset(vblanks[0], NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessDestroy)
+TEST_P(TDMVblank, VblankGetOffsetNoSet)
 {
-       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_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       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_vblank_destroy(con_output_vblank);
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 0);
-       ASSERT_TRUE(data == 0);
+       for (int v = 0; v < vblank_count; v++) {
+               int offset = TDM_UT_INVALID_VALUE;
+               ASSERT_EQ(tdm_vblank_get_offset(vblanks[v], &offset), TDM_ERROR_NONE);
+               ASSERT_EQ(offset, 0);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessChangeDpms)
+/* 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_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);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       for (int v = 0; v < vblank_count; v++)
+               ASSERT_EQ(tdm_vblank_set_enable_fake(vblanks[v], 1), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessChangeDpmsWithEnableFake)
+TEST_P(TDMVblank, VblankSetEnableFakeNullObject)
 {
-       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_enable_fake(con_output_vblank, 1);
-       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);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+       ASSERT_EQ(tdm_vblank_set_enable_fake(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessHWRepeatedly)
+TEST_P(TDMVblank, VblankSetEnableFakeTwice)
 {
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       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);
+       for (int v = 0; v < vblank_count; v++) {
+               ASSERT_EQ(tdm_vblank_set_enable_fake(vblanks[v], 1), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_set_enable_fake(vblanks[v], 1), TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessOffsenGreaterThanZero)
+/* 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);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(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 enable_fake;
+               ASSERT_EQ(tdm_vblank_set_enable_fake(vblanks[v], 1), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_enable_fake(vblanks[v], &enable_fake), TDM_ERROR_NONE);
+               ASSERT_EQ(enable_fake, 1);
 
-       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_EQ(tdm_vblank_set_enable_fake(vblanks[v], 0), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_get_enable_fake(vblanks[v], &enable_fake), TDM_ERROR_NONE);
+               ASSERT_EQ(enable_fake, 0);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSuccessOffsenGreaterThanZeroRepeatedly)
+TEST_P(TDMVblank, VblankGetEnableFakeNullObject)
 {
-       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, 10);
-       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);
-       }
+       unsigned int enable_fake = (unsigned int)TDM_UT_INVALID_VALUE;
+       ASSERT_EQ(tdm_vblank_get_enable_fake(NULL, &enable_fake), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(enable_fake, (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessFpsNonMultipleVrefresh)
+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_EQ(TestCreateVblanks(), true);
 
-       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_EQ(tdm_vblank_get_enable_fake(vblanks[0], NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessFpsNonMultipleVrefreshRepeatedly)
+TEST_P(TDMVblank, VblankGetEnableFakeNoSet)
 {
-       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_EQ(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);
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int enable_fake;
+               ASSERT_EQ(tdm_vblank_get_enable_fake(vblanks[v], &enable_fake), TDM_ERROR_NONE);
+               ASSERT_EQ(enable_fake, 0);
        }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessDisconnectedOutput)
+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);
-
-       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 = (error == TDM_ERROR_NONE) ? sequence : ((unsigned int)-1);
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessDisconnectedOutputRepeatedly)
+TEST_P(TDMVblank, VblankWait)
 {
-       tdm_error error;
-       int data;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       if (!discon_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_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+               ASSERT_EQ(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(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+               for (int t = 0; t < 10; t++) {
+                       unsigned int cur_seq = 0;
 
-               UtHandleVblankEvent();
+                       start = tdm_helper_get_time();
+                       ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_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_LT((end - start), (interval + interval));
+               }
        }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessHW)
+TEST_P(TDMVblank, VblankWaitFewTime)
 {
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       if (!con_output_vblank)
-               return;
-
-       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);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_EQ(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;
 
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       cur_seq = seq1 = seq2 = 0;
+                       start = tdm_helper_get_time();
+                       ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &seq1), TDM_ERROR_NONE);
+                       ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &seq2), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       UtHandleVblankEvent();
+                       ASSERT_NE(seq1, 0);
+                       ASSERT_NE(seq2, 0);
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+                       /* "+ interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_LT((end - start), (interval + interval));
+               }
+       }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessHWRepeatedly)
+TEST_P(TDMVblank, VblankWaitInterval0)
 {
-       tdm_error error;
-       int data;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_EQ(tdm_vblank_wait(vblanks[0], 0, 0, 0, _ut_tdm_vblank_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
+}
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+TEST_P(TDMVblank, VblankWaitInterval)
+{
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(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, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       for (int i = 0; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+               ASSERT_EQ(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(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+               /* start from 1 */
+               for (int t = 1; t < 10; t++) {
+                       unsigned int cur_seq = 0;
 
-               UtHandleVblankEvent();
+                       start = tdm_helper_get_time();
+                       ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, t, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_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_GT((end - start), interval * (t - 1));
+                       ASSERT_LT((end - start), interval * t + interval);
+               }
        }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessOffsenGreaterThanZero)
+TEST_P(TDMVblank, VblankWaitSeq)
 {
-       tdm_error error;
-       int data = 0;
-
-       SKIP_FLAG(has_output);
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       if (!con_output_vblank)
-               return;
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(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);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_EQ(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, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               for (int t = 0; t < 10; t++) {
+                       unsigned int cur_seq = 0, temp = 0;
 
-       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
 
-       UtHandleVblankEvent();
+                       start = tdm_helper_get_time();
+                       ASSERT_EQ(tdm_vblank_wait_seq(vblanks[v], 0, 0, cur_seq + 1, _ut_tdm_vblank_cb, &temp), TDM_ERROR_NONE);
+                       while (temp == 0)
+                               ASSERT_EQ(ut_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_LT((end - start), (interval + interval));
+               }
+       }
 }
 
-TEST_F(TDMVblankWaitThread, VblankWaitSuccessOffsenGreaterThanZeroRepeatedly)
+TEST_P(TDMVblank, VblankWaitSeqInterval)
 {
-       tdm_error error;
-       int data;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(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);
-
-       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);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       error = tdm_vblank_set_offset(con_output_vblank, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_EQ(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, temp = 0;
 
-               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
 
-               UtHandleVblankEvent();
+                       start = tdm_helper_get_time();
+                       ASSERT_EQ(tdm_vblank_wait_seq(vblanks[v], 0, 0, cur_seq + t, _ut_tdm_vblank_cb, &temp), TDM_ERROR_NONE);
+                       while (temp == 0)
+                               ASSERT_EQ(ut_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_GT((end - start), (interval * (t - 1)));
+                       ASSERT_LT((end - start), (interval * t + interval));
+               }
        }
 }
 
-/* tdm_vblank_wait_seq() */
-
-TEST_F(TDMVblank, VblankWaitSeqFailNullAll)
-{
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_wait_seq(NULL, 0, 0, 0, NULL, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
-
-TEST_F(TDMVblankWait, VblankWaitSeqFailNullVblank)
+TEST_P(TDMVblank, VblankWaitNullObject)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       unsigned int cur_seq = 0;
 
-       error = tdm_vblank_wait_seq(NULL, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_wait(NULL, 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailWrongVblankPtr)
+TEST_P(TDMVblank, VblankWaitNullOther)
 {
-       tdm_error error = TDM_ERROR_BAD_MODULE;
-       SKIP_FLAG(has_output);
-
-       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), "");
-}
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailNullFunc)
-{
-       tdm_error error;
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       SKIP_FLAG(has_output);
-
-       error = tdm_vblank_wait_seq(NULL, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_vblank_wait(vblanks[0], 0, 0, 0, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-void *UtWaitVblankSeqThreadHndl(void *ptr)
+TEST_P(TDMVblank, VblankWaitDpmsOff)
 {
-       tdm_error error;
-       TDMVblankWait *vblankWait = (TDMVblankWait *)ptr;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       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 = 0;
-}
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailInOtherThread)
-{
-       pthread_t thread;
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
 
-       SKIP_FLAG(has_output);
-
-       ASSERT_FALSE(pthread_create(&thread, NULL, UtWaitVblankSeqThreadHndl, this));
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
 
-       ASSERT_FALSE(pthread_join(thread, NULL));
+               ASSERT_EQ(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF), TDM_ERROR_NONE);
 
-       ASSERT_FALSE(utWaitVblankSeqThreadHndlResult);
+               ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL), TDM_ERROR_DPMS_OFF);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailDisconnectedOutput)
+TEST_P(TDMVblank, VblankWaitBeforeDpmsOff)
 {
-       tdm_error error;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       if (!discon_output_vblank)
-               return;
-
-       error = tdm_vblank_wait_seq(discon_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
-}
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int temp = 0;
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
 
-TEST_F(TDMVblankWait, VblankWaitSeqFailDpmsOff)
-{
-       tdm_error error;
-
-       SKIP_FLAG(has_output);
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
 
-       if (!con_output_vblank)
-               return;
+               ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &temp), TDM_ERROR_NONE);
 
-       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF), TDM_ERROR_NONE);
 
-       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
-       ASSERT_TRUE(error != TDM_ERROR_NONE);
+               while (temp == 0)
+                       ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessFpsNonMultipleVrefresh)
+TEST_P(TDMVblank, VblankWaitSetEnableFakeDpmsOff)
 {
-       tdm_error error;
-       int data = 0;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       if (!con_output_vblank)
-               return;
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
 
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       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_EQ(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF), TDM_ERROR_NONE);
 
-       UtHandleVblankEvent();
+               ASSERT_EQ(tdm_vblank_set_enable_fake(vblanks[v], 1), TDM_ERROR_NONE);
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+               ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL), TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessFpsNonMultipleVrefreshRepeatedly)
+TEST_P(TDMVblank, VblankWaitDisconnectedOutput)
 {
-       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_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
 
-               error = tdm_vblank_wait_seq(con_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_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL), TDM_ERROR_OUTPUT_DISCONNECTED);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessDisconnectedOutput)
+TEST_P(TDMVblank, VblankWaitSetOffset)
 {
-       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_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       UtHandleVblankEvent();
+       for (int v = 0; v < vblank_count; v++) {
+               unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+               double start, end, interval;
 
-       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;
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_vblank_set_offset(vblanks[v], 100), TDM_ERROR_NONE);
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+               ASSERT_EQ(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(discon_output_vblank, 0, 0, i, 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_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_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_GT((end - start), (0.1));
+                       ASSERT_LT((end - start), (interval + interval + 0.1));
+               }
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessHW)
+TEST_P(TDMVblank, VblankWaitSetFps)
 {
-       tdm_error error;
-       int data;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
-               return;
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(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);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_EQ(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_offset(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               fps /= 2;
+               ASSERT_EQ(tdm_vblank_set_fps(vblanks[v], fps), TDM_ERROR_NONE);
+               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_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
+                       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_GT((end - start), (interval - vrefresh_interval));
+                       ASSERT_LT((end - start), (interval + vrefresh_interval));
+               }
+       }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessHWRepeatedly)
+TEST_P(TDMVblank, VblankWaitSetFixedFps)
 {
-       tdm_error error;
-       int data;
+       TDM_UT_SKIP_FLAG(has_outputs);
 
-       SKIP_FLAG(has_output);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       if (!con_output_vblank)
-               return;
-
-       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);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_EQ(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);
+               ASSERT_EQ(tdm_vblank_set_fixed_fps(vblanks[v], fps), TDM_ERROR_NONE);
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+               /* this fps will be ignored because it has fixed fps value */
+               fps /= 2;
+               ASSERT_EQ(tdm_vblank_set_fps(vblanks[v], fps), TDM_ERROR_NONE);
 
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, 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_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE);
+                       while (cur_seq == 0)
+                               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+                       end = tdm_helper_get_time();
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+                       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+                       ASSERT_LT((end - start), (interval + interval));
+               }
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessOffsenGreaterThanZero)
+TEST_P(TDMVblank, VblankWaitEnableDisableGlobalFps)
 {
-       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);
+       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_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
-
-       UtHandleVblankEvent();
-
-       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-       ASSERT_TRUE(data == 1);
-}
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks3(), true);
+       ASSERT_EQ(vblank_count, 3);
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessOffsenGreaterThanZeroRepeatedly)
-{
-       tdm_error error;
-       int data;
-
-       SKIP_FLAG(has_output);
-
-       if (!con_output_vblank)
+       if (!ut_tdm_vblank_is_avaiable(vblanks[0]))
                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, 10);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(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_EQ(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_EQ(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;
+       start = tdm_helper_get_time();
+       while (cur_seq[2] == 0)
+               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
 
-       SKIP_FLAG(has_output);
+       /* "+- vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_GT((end - start), (interval - vrefresh_interval));
+       ASSERT_LT((end - start), (interval + vrefresh_interval));
 
-       if (!con_output_vblank)
-               return;
-
-       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(cur_seq[1], 0);
+       ASSERT_EQ(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_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       ASSERT_EQ(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_EQ(ut_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_EQ(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_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       ASSERT_EQ(cur_seq[1], 0);
+       ASSERT_EQ(cur_seq[0], 0);
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
-       }
+       while (cur_seq[1] == 0)
+               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       ASSERT_EQ(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;
-
-       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_fps(con_output_vblank, 5000);
-       ASSERT_TRUE(error == TDM_ERROR_NONE);
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks(), true);
 
-       for (int i = 1; i < 10; ++i) {
-               utVblankHandlerIsCalled = 0;
-               data = 0;
+       for (int v = 0; v < vblank_count; v++) {
+               tdm_error ret;
+               tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret);
+               ASSERT_EQ(ret, TDM_ERROR_NONE);
 
-               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
-               ASSERT_TRUE(error == TDM_ERROR_NONE);
+               if (!ut_tdm_vblank_is_avaiable(vblanks[v]))
+                       continue;
 
-               if (i < 4)
+               if (ut_tdm_output_is_connected(output))
                        continue;
 
-               UtHandleVblankEvent();
+               ASSERT_EQ(tdm_vblank_set_enable_fake(vblanks[v], 1), TDM_ERROR_DPMS_OFF);
 
-               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
-               ASSERT_TRUE(data == 1);
+               ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, NULL), TDM_ERROR_NONE);
        }
 }
 
-TEST_F(TDMVblankWait, VblankWaitSeqSuccessRepeatedlyWithDelay)
+TEST_P(TDMVblank, DISABLED_VblankWaitBeforeDpmsOff)
 {
-       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);
-
-       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);
-       }
+       /* wait vblank -> dpms off -> then? (vblank handler is called? or not?) */
 }
+
+#ifdef TDM_UT_TEST_WITH_PARAMS
+INSTANTIATE_TEST_CASE_P(TDMVblankParams,
+                                               TDMVblank,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+#else
+INSTANTIATE_TEST_CASE_P(TDMVblankParams,
+                                               TDMVblank,
+                                               Values(TDM_DEFAULT_MODULE));
+#endif
\ No newline at end of file