**************************************************************************/
#include "gtest/gtest.h"
-#include "tdm.h"
#include "ut_common.h"
+#include <climits>
+#include "tdm.h"
+extern "C" {
+#include "tbm_bufmgr.h"
+#include "tbm_drm_helper.h"
+}
+#include <vector>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <pthread.h>
class TDMOutput : public ::testing::Test {
protected:
tdm_display *dpy = NULL;
- int output_count = -42;
+ int output_count = 0, master_fd = -42, tbm_fd = -42;
bool has_output = false;
- void SetUp(void)
+ tbm_bufmgr tbm_bufmgr = NULL;
+ static unsigned int handle_call;
+ static void tdm_output_change_handler_test_func(tdm_output *output,
+ tdm_output_change_type type,
+ tdm_value value,
+ void *u_data)
{
+ if ( ((intptr_t) u_data) < -100) {
+ TDMOutput::handle_call++;
+ }
+ }
+ virtual void SetEnvs()
+ {
+ setenv("TDM_DEBUG_MODULE", "all", 1);
+ setenv("TDM_DEBUG", "1", 1);
setenv("TDM_DLOG", "1", 1);
- setenv("XDG_RUNTIME_DIR", ".", 1);
+ setenv("XDG_RUNTIME_DIR", "/run", 1);
setenv("TBM_DLOG", "1", 1);
+ setenv("TBM_DISPLAY_SERVER", "1", 1);
+ setenv("TDM_COMMIT_PER_VBLANK", "0", 1);
+ }
+
+ virtual void UnsetEnvs()
+ {
+ unsetenv("TDM_DEBUG_MODULE");
+ unsetenv("TDM_DEBUG");
+ unsetenv("TDM_DLOG");
+ unsetenv("XDG_RUNTIME_DIR");
+ unsetenv("TBM_DLOG");
+ unsetenv("TBM_DISPLAY_SERVER");
+ unsetenv("TDM_COMMIT_PER_VBLANK");
+ }
+
+ void SetUp(void)
+ {
+ SetEnvs();
+
tdm_error error = TDM_ERROR_NONE;
dpy = tdm_display_init(&error);
ASSERT_TRUE(error == TDM_ERROR_NONE);
ASSERT_FALSE(dpy == NULL);
+ tbm_bufmgr = tbm_bufmgr_init(-1);
+ ASSERT_FALSE(tbm_bufmgr == NULL);
+ master_fd = tbm_drm_helper_get_master_fd();
+ tbm_fd = tbm_drm_helper_get_fd();
error = tdm_display_get_output_count(dpy, &output_count);
#ifdef FAIL_ON_UNSUPPORTED
ASSERT_GT(output_count, 0);
#endif
if (output_count > 0)
has_output = true;
+ handle_call = 0;
}
void TearDown(void)
{
tdm_display_deinit(dpy);
dpy = NULL;
+ tbm_bufmgr_deinit(tbm_bufmgr);
+ tbm_bufmgr = NULL;
+ if (master_fd > -1) {
+ int temp_master_fd = tbm_drm_helper_get_master_fd();
+ EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
+ if (temp_master_fd > -1)
+ exit(1);
+ close(master_fd);
+ }
+ if (tbm_fd > -1) {
+ int temp_tbm_fd = tbm_drm_helper_get_fd();
+ EXPECT_EQ(temp_tbm_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
+ if (temp_tbm_fd > -1)
+ exit(1);
+ close(tbm_fd);
+ }
+
+ UnsetEnvs();
+ }
+};
+
+class TDMOutputHWC : public TDMOutput {
+ void SetEnvs(void)
+ {
+ TDMOutput::SetEnvs();
+ setenv("TDM_HWC", "1", 1);
+ }
+ void UnsetEnvs(void)
+ {
+ TDMOutput::UnsetEnvs();
+ unsetenv("TDM_HWC");
+ }
+};
+
+class TDMOutputThread : public TDMOutput {
+ void SetEnvs(void)
+ {
+
+ TDMOutput::SetEnvs();
+ setenv("TDM_THREAD", "1", 1);
+ }
+ void UnsetEnvs(void)
+ {
+ TDMOutput::UnsetEnvs();
+ unsetenv("TDM_THREAD");
+ }
+};
+
+class TDMOutputCommit : public TDMOutput {
+private:
+ int epFd = -1;
+ int timerFd = -1;
+ int tdmFd = -1;
+ static const int timeLimitSec = 1;
+ static const int timeLimitNsec = 0;
+protected:
+ int conn_output_count = 0;
+ tdm_output ** connected_output_array = NULL;
+ const tdm_output_mode** preferred_mode = NULL;
+ bool has_output = false;
+ std::vector<std::vector<tdm_layer *>> layers_array;
+ std::vector<tbm_surface_h> buffers;
+ static unsigned int utOutputCommitHandlerCounter;
+ static void UtOutputCommitHandler(tdm_output *output, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data)
+ {
+ utOutputCommitHandlerCounter++;
+ }
+
+ static unsigned int utOutputVblankHandlerCounter;
+ static void UtOutputVblankHandler(tdm_output *output, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data)
+ {
+ utOutputVblankHandlerCounter++;
+ }
+ friend void *UtOutputRemoveChangeHandlerSuccessfulThread(void *ptr);
+
+ void SetUp(void)
+ {
+ struct epoll_event ep;
+
+ utOutputCommitHandlerCounter = 0;
+ utOutputVblankHandlerCounter = 0;
+
+ ASSERT_NO_FATAL_FAILURE(TDMOutput::SetUp());
+ if (TDMOutput::output_count > 0) {
+ connected_output_array = (tdm_output **) calloc(TDMOutput::output_count, sizeof(tdm_output *));
+ ASSERT_FALSE(NULL == connected_output_array);
+ preferred_mode = (const tdm_output_mode **) calloc(TDMOutput::output_count, sizeof(tdm_output_mode*));
+ ASSERT_FALSE(NULL == preferred_mode);
+ }
+ conn_output_count = 0;
+ for (int i = 0; i < TDMOutput::output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int output_modes_cnt = 0;
+ int layer_count = 0;
+ const tdm_output_mode* output_modes = NULL;
+ tdm_output * output = tdm_display_get_output(TDMOutput::dpy, i, &error);
+ std::vector<tdm_layer *> layers;
+ if (TDM_ERROR_NONE != error || NULL == output)
+ continue;
+ tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+ if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status))
+ continue;
+ if (TDM_OUTPUT_CONN_STATUS_DISCONNECTED == status)
+ continue;
+ if (TDM_ERROR_NONE != tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON))
+ continue;
+ if(TDM_ERROR_NONE != tdm_output_get_available_modes(output,
+ &output_modes,
+ &output_modes_cnt))
+ continue;
+ for(int k = 0; k < output_modes_cnt; k++) {
+ if(output_modes[k].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) {
+ preferred_mode[conn_output_count] = &output_modes[k];
+ break;
+ }
+ }
+ if (NULL == preferred_mode[conn_output_count])
+ continue;
+
+ if (TDM_ERROR_NONE != tdm_output_get_layer_count(output, &layer_count))
+ continue;
+ if (0 == layer_count)
+ continue;
+
+ for (int i = 0; i < layer_count; ++i) {
+ tdm_layer *layer;
+ layer = tdm_output_get_layer(output, i, &error);
+ if (layer == nullptr)
+ continue;
+ layers.push_back(layer);
+ }
+ connected_output_array[conn_output_count++] = output;
+ layers_array.push_back(layers);
+ }
+#ifdef FAIL_ON_UNSUPPORTED
+ ASSERT_GT(conn_output_count, 0);
+#endif
+
+ if (conn_output_count > 0)
+ has_output = true;
+
+ epFd = epoll_create1(0);
+ ASSERT_TRUE(epFd != -1);
+
+ timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+ ASSERT_TRUE(timerFd != -1);
+
+ memset(&ep, 0, sizeof ep);
+ ep.events |= EPOLLIN;
+ ep.data.fd = timerFd;
+ ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
+
+ ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
+
+ memset(&ep, 0, sizeof ep);
+ ep.events |= EPOLLIN;
+ ep.data.fd = tdmFd;
+ ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
+ }
+ void TearDown(void)
+ {
+ for (size_t i = 0; i < layers_array.size(); ++i) {
+ for (tdm_layer *layer : layers_array[i]) {
+ tdm_layer_unset_buffer(layer);
+ }
+ }
+
+ for (tbm_surface_h buffer : buffers) {
+ tbm_surface_destroy(buffer);
+ }
+
+ for (int i = 0; i < conn_output_count; i++) {
+ EXPECT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i],
+ TDM_OUTPUT_DPMS_OFF));
+ }
+ if (connected_output_array)
+ free(connected_output_array);
+ if (preferred_mode)
+ free(preferred_mode);
+ ASSERT_NO_FATAL_FAILURE(TDMOutput::TearDown());
+ }
+
+ tbm_surface_h UtCreateBuffer(int width, int height, tbm_format format)
+ {
+ tbm_surface_h buffer;
+
+ buffer = tbm_surface_internal_create_with_flags(width, height, format, TBM_BO_SCANOUT);
+
+ if (buffer)
+ buffers.push_back(buffer);
+
+ return buffer;
+ }
+
+ void UtPrepareToCommit()
+ {
+ for (size_t i = 0; i < layers_array.size(); ++i) {
+ for (tdm_layer *layer : layers_array[i]) {
+ int w, h;
+ tdm_error error;
+ tdm_layer_capability lcapabilities;
+ tbm_surface_h buffer;
+ tdm_info_layer layer_info = {0};
+
+ w = preferred_mode[i]->hdisplay;
+ h = preferred_mode[i]->vdisplay;
+
+ error = tdm_output_set_mode(connected_output_array[i], preferred_mode[i]);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ error = tdm_layer_get_capabilities(layer, &lcapabilities);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ if (!(lcapabilities & TDM_LAYER_CAPABILITY_PRIMARY)) {
+ w = w / 2;
+ h = h / 2;
+ }
+
+ buffer = UtCreateBuffer(w, h, TBM_FORMAT_ARGB8888);
+ ASSERT_NE(nullptr, buffer);
+
+ layer_info.src_config.size.h = w;
+ layer_info.src_config.size.v = h;
+ layer_info.src_config.pos.x = 0;
+ layer_info.src_config.pos.y = 0;
+ layer_info.src_config.pos.w = w;
+ layer_info.src_config.pos.h = h;
+ layer_info.src_config.format = TBM_FORMAT_ARGB8888;
+ layer_info.dst_pos.x = 0;
+ layer_info.dst_pos.y = 0;
+ layer_info.dst_pos.w = w;
+ layer_info.dst_pos.h = h;
+ layer_info.transform = TDM_TRANSFORM_NORMAL;
+
+ error = tdm_layer_set_info(layer, &layer_info);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ error = tdm_layer_set_buffer(layer, buffer);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+ }
+ }
+
+ void UtHandleEvent(unsigned int & wait_var, unsigned int num)
+ {
+ struct itimerspec its;
+ int count;
+ struct epoll_event ep_event[2];
+
+ if (wait_var == num)
+ return;
+
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+ its.it_value.tv_sec = timeLimitSec;
+ its.it_value.tv_nsec = timeLimitNsec;
+
+ ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
+
+ while (1) {
+ count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
+ ASSERT_TRUE(count >= 0);
+
+ for (int i = 0; i < count; i++) {
+ if (ep_event[i].data.fd == timerFd) {
+ return;
+ } else {
+ ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+ if (wait_var == num)
+ return;
+ }
+ }
+ }
+ }
+
+ void UtHandleCommitEvent()
+ {
+ UtHandleEvent(utOutputCommitHandlerCounter, (unsigned int)conn_output_count);
+ }
+
+ void UtHandleVblankEvent()
+ {
+ UtHandleEvent(utOutputVblankHandlerCounter, conn_output_count);
+ }
+};
+
+class TDMOutputCommitPerVblankEnabled : public TDMOutputCommit {
+ void SetEnvs(void)
+ {
+
+ TDMOutputCommit::SetEnvs();
+ setenv("TDM_COMMIT_PER_VBLANK", "1", 1);
+ }
+ void UnsetEnvs(void)
+ {
+ TDMOutputCommit::UnsetEnvs();
+ unsetenv("TDM_COMMIT_PER_VBLANK");
}
};
+class TDMOutputCommitThread : public TDMOutputCommit {
+ void SetEnvs(void)
+ {
+ TDMOutputCommit::SetEnvs();
+ setenv("TDM_THREAD", "1", 1);
+ }
+
+ void UnsetEnvs(void)
+ {
+ TDMOutputCommit::UnsetEnvs();
+ unsetenv("TDM_THREAD");
+ }
+};
+
+unsigned int TDMOutput::handle_call = 0;
+unsigned int TDMOutputCommit::utOutputCommitHandlerCounter = 0;
+unsigned int TDMOutputCommit::utOutputVblankHandlerCounter = 0;
+
TEST_F(TDMOutput, DisplayGetOutputSuccessful)
{
- CHECK_FLAG(has_output);
+ SKIP_FLAG(has_output);
for (int i = 0; i < output_count; i++) {
tdm_error error = TDM_ERROR_NONE;
ASSERT_FALSE(NULL == tdm_display_get_output(dpy, i, &error));
ASSERT_TRUE(TDM_ERROR_NONE == error);
}
}
+
+TEST_F(TDMOutput, DisplayGetOutputSuccessfulWrongIndex)
+{
+ SKIP_FLAG(has_output);
+ tdm_error error = TDM_ERROR_NONE;
+ ASSERT_TRUE(NULL == tdm_display_get_output(dpy, -1, &error));
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+}
+
+TEST_F(TDMOutput, DisplayGetOutputSuccessfulBigIndex)
+{
+ SKIP_FLAG(has_output);
+ tdm_error error = TDM_ERROR_NONE;
+ ASSERT_TRUE(NULL == tdm_display_get_output(dpy, INT_MAX, &error));
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+}
+
+TEST_F(TDMOutput, DisplayGetOutputSuccessfulSmallIndex)
+{
+ SKIP_FLAG(has_output);
+ tdm_error error = TDM_ERROR_NONE;
+ ASSERT_TRUE(NULL == tdm_display_get_output(dpy, INT_MIN, &error));
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+}
+
+TEST_F(TDMOutput, DisplayGetOutputSuccessfulErrorNull)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_FALSE(NULL == tdm_display_get_output(dpy, 0, NULL));
+}
+
+TEST_F(TDMOutput, DisplayOutputGetCapabilitiesSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output_capability capabilities = (tdm_output_capability) -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_capabilities(output, &capabilities));
+ ASSERT_FALSE(-42 == capabilities);
+ }
+}
+
+TEST_F(TDMOutput, DisplayOutputGetCapabilitiesFailAllNull)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_capabilities(NULL, NULL));
+}
+
+TEST_F(TDMOutput, DisplayOutputGetCapabilitiesFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_capabilities(output, NULL));
+ }
+}
+
+TEST_F(TDMOutput, OutputGetModelInfoSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ const char * maker = NULL, * model = NULL, * name = NULL;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_model_info(output, &maker, &model, &name));
+ ASSERT_FALSE(NULL == maker);
+ ASSERT_FALSE(NULL == model);
+ ASSERT_FALSE(NULL == name);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetModelInfoFailAllNull)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_model_info(NULL, NULL, NULL, NULL));
+}
+
+TEST_F(TDMOutput, OutputGetModelInfoSuccessfulOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_model_info(output, NULL, NULL, NULL));
+ }
+}
+
+TEST_F(TDMOutput, OutputGetConnStatusSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output_conn_status status = (tdm_output_conn_status) -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
+ ASSERT_FALSE(-42 == status);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetConnStatusFailAllNull)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_conn_status(NULL, NULL));
+}
+
+TEST_F(TDMOutput, OutputGetConnStatusFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, NULL));
+ }
+}
+
+TEST_F(TDMOutput, OutputSetDPMSSuccessful)
+{
+ SKIP_FLAG(has_output);
+ bool checked = false;
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output_conn_status status;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
+ if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+ continue;
+ checked = true;
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_STANDBY));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_SUSPEND));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
+ }
+ if (false == checked) {
+ FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
+ }
+}
+
+TEST_F(TDMOutput, OutputAddChangeHandlerSuccessful)
+{
+ SKIP_FLAG(has_output);
+ bool checked = false;
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ tdm_output_conn_status status;
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
+ if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+ continue;
+ checked = true;
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
+ tdm_output_change_handler_test_func,
+ (void *) -101));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
+ ASSERT_GT(handle_call, 0);
+ }
+ if (false == checked) {
+ FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
+ }
+}
+
+TEST_F(TDMOutput, OutputAddChangeHandlerSuccessfulFewFuncs)
+{
+ SKIP_FLAG(has_output);
+ bool checked = false;
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ tdm_output_conn_status status;
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
+ if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+ continue;
+ checked = true;
+ for (intptr_t k = 0; k < 20; k++) {
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
+ tdm_output_change_handler_test_func,
+ (void *) (-101-k)));
+ }
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
+ ASSERT_GT(handle_call, 20);
+ }
+ if (false == checked) {
+ FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
+ }
+}
+
+
+TEST_F(TDMOutput, OutputAddChangeHandlerFailAllNull)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_add_change_handler(NULL, NULL, NULL));
+}
+
+TEST_F(TDMOutput, OutputAddChangeHandlerFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_add_change_handler(output, NULL, NULL));
+ }
+}
+
+TEST_F(TDMOutput, OutputAddChangeHandlerFailWrongOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({tdm_output *output = (tdm_output *) 0xBEAF;
+ tdm_output_add_change_handler(output,
+ tdm_output_change_handler_test_func,
+ (void *) -101);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputRemoveChangeHandlerSuccessful)
+{
+ SKIP_FLAG(has_output);
+ bool checked = false;
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ tdm_output_conn_status status;
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
+ if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+ continue;
+ checked = true;
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
+ tdm_output_change_handler_test_func,
+ (void *) -101));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
+ ASSERT_GT(handle_call, 0);
+ handle_call = 0;
+ tdm_output_remove_change_handler(output, tdm_output_change_handler_test_func, (void *) -101);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
+ ASSERT_EQ(handle_call, 0);
+ }
+ if (false == checked) {
+ FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
+ }
+}
+
+void *UtOutputRemoveChangeHandlerSuccessfulThread(void *ptr)
+{
+ TDMOutputCommitThread *FTDMOutput = (TDMOutputCommitThread *)ptr;
+
+ bool checked = false;
+ for (int i = 0; i < FTDMOutput->output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(FTDMOutput->dpy, i, &error);
+ if (NULL == output || TDM_ERROR_NONE != error)
+ return (void *)1;
+ tdm_output_conn_status status;
+ error = tdm_output_get_conn_status(output, &status);
+ if (TDM_ERROR_NONE != error)
+ return (void *)2;
+ if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+ continue;
+ checked = true;
+ error = tdm_output_add_change_handler(output,
+ FTDMOutput->tdm_output_change_handler_test_func,
+ (void *) -101);
+ if (TDM_ERROR_NONE != error)
+ return (void *)3;
+ error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
+ if (TDM_ERROR_NONE != error)
+ return (void *)4;
+ error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
+ if (TDM_ERROR_NONE != error)
+ return (void *)5;
+ FTDMOutput->UtHandleEvent(FTDMOutput->handle_call, 1);
+ if (FTDMOutput->handle_call <= 0)
+ return (void *)6;
+ FTDMOutput->handle_call = 0;
+ tdm_output_remove_change_handler(output, FTDMOutput->tdm_output_change_handler_test_func, (void *) -101);
+ error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
+ if (TDM_ERROR_NONE != error)
+ return (void *)7;
+ error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
+ if (TDM_ERROR_NONE != error)
+ return (void *)8;
+ FTDMOutput->UtHandleEvent(FTDMOutput->handle_call, 1);
+ if (FTDMOutput->handle_call != 0)
+ return (void *)9;
+ }
+ if (false == checked) {
+ return (void *)10;
+ }
+
+ return nullptr;
+}
+
+TEST_F(TDMOutputCommitThread, OutputRemoveChangeHandlerSuccessfulThread)
+{
+ SKIP_FLAG(has_output);
+ pthread_t thread = 0;
+ int *status = nullptr;
+
+ ASSERT_FALSE(pthread_create(&thread, NULL, UtOutputRemoveChangeHandlerSuccessfulThread, this));
+
+ ASSERT_FALSE(pthread_join(thread, (void **)&status));
+
+ ASSERT_EQ(nullptr, status);
+}
+
+TEST_F(TDMOutput, OutputRemoveChangeHandlerSuccessfulFewFuncs)
+{
+ SKIP_FLAG(has_output);
+ bool checked = false;
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ tdm_output_conn_status status;
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
+ if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+ continue;
+ checked = true;
+ for (intptr_t k = 0; k < 20; k++) {
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
+ tdm_output_change_handler_test_func,
+ (void *) (-101-k)));
+ }
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
+ ASSERT_GT(handle_call, 20);
+ handle_call = 0;
+ for (intptr_t k = 0; k < 20; k++) {
+ tdm_output_remove_change_handler(output, tdm_output_change_handler_test_func, (void *) (-101-k));
+ }
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
+ ASSERT_EQ(handle_call, 0);
+ }
+ if (false == checked) {
+ FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
+ }
+}
+
+TEST_F(TDMOutput, OutputRemoveChangeHandlerFailAllNull)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({tdm_output_remove_change_handler(NULL, NULL, NULL);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputRemoveChangeHandlerFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ tdm_output_remove_change_handler(output, NULL, NULL);
+ } exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputRemoveChangeHandlerFailWrongOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({tdm_output *output = (tdm_output *) 0xBEAF;
+ tdm_output_remove_change_handler(output,
+ tdm_output_change_handler_test_func,
+ (void *) -101);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetOutputTypeSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output_type type = (tdm_output_type) -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_output_type(output, &type));
+ ASSERT_NE(type, -42);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetOutputTypeFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_output_type(NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetOutputTypeFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (tdm_output_get_output_type(output, NULL) == TDM_ERROR_NONE) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetLayerCountSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int count = -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_layer_count(output, &count));
+ ASSERT_NE(count, -42);
+ }
+}
+
+int is_hwc_ennable(tdm_output * output)
+{
+ tdm_output_capability capabilities = (tdm_output_capability)0;
+ tdm_output_get_capabilities(output, &capabilities);
+ return capabilities & TDM_OUTPUT_CAPABILITY_HWC;
+}
+
+TEST_F(TDMOutputHWC, OutputGetLayerCountFailHWC)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int count = -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ if (is_hwc_ennable(output))
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_get_layer_count(output, &count));
+ }
+}
+
+TEST_F(TDMOutputHWC, OutputGetLayerFailHWC)
+{
+ SKIP_FLAG(has_output);
+
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ if (is_hwc_ennable(output)) {
+ ASSERT_TRUE(nullptr == tdm_output_get_layer(output, 0, &error));
+ ASSERT_TRUE(TDM_ERROR_NONE != error);
+ }
+ }
+}
+
+TEST_F(TDMOutput, OutputGetLayerCountFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_layer_count(NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetLayerCountFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (TDM_ERROR_NONE == tdm_output_get_layer_count(output, NULL)) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailablePropertiesSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int count = -42;
+ const tdm_prop *tdm_prop_array = (const tdm_prop *) 0xBEAF;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_properties(output,
+ &tdm_prop_array,
+ &count));
+ ASSERT_NE(count, -42);
+ ASSERT_NE(tdm_prop_array, 0xBEAF);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_available_properties(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailablePropertiesFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (TDM_ERROR_NONE == tdm_output_get_available_properties(output, NULL, NULL)) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullCount)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ const tdm_prop *tdm_prop_array = NULL;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (TDM_ERROR_NONE == tdm_output_get_available_properties(output,
+ &tdm_prop_array,
+ NULL)) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullProperty)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int count = -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (TDM_ERROR_NONE == tdm_output_get_available_properties(output,
+ NULL,
+ &count)) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailableModesSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int count = -42;
+ const tdm_output_mode *modes_array = (const tdm_output_mode *) 0xBEAF;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_modes(output,
+ &modes_array,
+ &count));
+ ASSERT_NE(count, -42);
+ ASSERT_NE(modes_array, 0xBEAF);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetAvailableModesFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_available_modes(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailableModesFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (TDM_ERROR_NONE == tdm_output_get_available_modes(output, NULL, NULL)) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailableModesFailNullCount)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ const tdm_output_mode *modes_array = NULL;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (TDM_ERROR_NONE == tdm_output_get_available_modes(output,
+ &modes_array,
+ NULL)) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailableModesFailNullModes)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int count = -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (TDM_ERROR_NONE == tdm_output_get_available_modes(output,
+ NULL,
+ &count)) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailableSizeSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int min_w = -42, min_h = -42, max_w = -42, max_h = -42, preferred_align = -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_size(output, &min_w, &min_h,
+ &max_w, &max_h, &preferred_align));
+ ASSERT_NE(min_w, -42);
+ ASSERT_NE(min_h, -42);
+ ASSERT_NE(max_w, -42);
+ ASSERT_NE(max_h, -42);
+ ASSERT_NE(preferred_align, -42);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetAvailableSizeFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_available_size(NULL, NULL, NULL,
+ NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetAvailableSizeSuccessfulOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (tdm_output_get_available_size(output, NULL, NULL,
+ NULL, NULL, NULL) != TDM_ERROR_NONE) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+/*TODO: this test has to be fixed in the backends by increase the ABI version upper than 1.5*/
+TEST_F(TDMOutput, DISABLED_OutputGetCursorAvailableSizeSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int min_w = -42, min_h = -42, max_w = -42, max_h = -42, preferred_align = -42;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_cursor_available_size(output, &min_w, &min_h,
+ &max_w, &max_h, &preferred_align));
+ ASSERT_NE(min_w, -42);
+ ASSERT_NE(min_h, -42);
+ ASSERT_NE(max_w, -42);
+ ASSERT_NE(max_h, -42);
+ ASSERT_NE(preferred_align, -42);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetCursorAvailableSizeFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_cursor_available_size(NULL, NULL, NULL,
+ NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+/*TODO: this test has to be fixed in the backends by increase the ABI version upper than 1.5*/
+TEST_F(TDMOutput, DISABLED_OutputGetCursorAvailableSizeSuccessfulOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (tdm_output_get_cursor_available_size(output, NULL, NULL,
+ NULL, NULL, NULL) != TDM_ERROR_NONE) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetPhysicalSizeSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ unsigned int mmWidth = UINT_MAX, mmHeight = UINT_MAX;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_physical_size(output, &mmWidth, &mmHeight));
+ ASSERT_NE(mmWidth, UINT_MAX);
+ ASSERT_NE(mmHeight, UINT_MAX);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetPhysicalSizeFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_physical_size(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetPhysicalSuccessfulOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (tdm_output_get_physical_size(output, NULL, NULL) != TDM_ERROR_NONE) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetSubpixelSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ unsigned int subpixel = UINT_MAX;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_subpixel(output, &subpixel));
+ ASSERT_NE(subpixel, UINT_MAX);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetSubpixelFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_subpixel(NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetSubpixelFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (tdm_output_get_subpixel(output, NULL) == TDM_ERROR_NONE) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetPipeSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ unsigned int pipe = UINT_MAX;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_pipe(output, &pipe));
+ ASSERT_NE(pipe, UINT_MAX);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetPipeFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_pipe(NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetPipeFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (tdm_output_get_pipe(output, NULL) == TDM_ERROR_NONE) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetPrimaryIndexSuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ int primary_index = INT_MAX;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_primary_index(output, &primary_index));
+ ASSERT_NE(primary_index, INT_MAX);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetPrimaryIndexFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({if (tdm_output_get_primary_index(NULL, NULL) == TDM_ERROR_NONE) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetPrimaryIndexFailOnlyOutput)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ if (NULL == output) exit(1);
+ if (TDM_ERROR_NONE != error) exit(1);
+ if (tdm_output_get_primary_index(output, NULL) == TDM_ERROR_NONE) exit(1);
+ }
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputSetPropertySuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_value value = {.u32 = 0};
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ error = tdm_output_set_property(output, UINT_MAX, value);
+ ASSERT_TRUE(error == TDM_ERROR_NOT_IMPLEMENTED || error == TDM_ERROR_OPERATION_FAILED);
+ }
+}
+
+TEST_F(TDMOutput, OutputSetPropertyFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({tdm_error error = TDM_ERROR_NONE;
+ tdm_value value = {.u32 = 0};
+ error = tdm_output_set_property(NULL, 0, value);
+ if (error == TDM_ERROR_NONE || error == TDM_ERROR_NOT_IMPLEMENTED ||
+ error == TDM_ERROR_OPERATION_FAILED) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutput, OutputGetPropertySuccessful)
+{
+ SKIP_FLAG(has_output);
+ for (int i = 0; i < output_count; i++) {
+ tdm_error error = TDM_ERROR_NONE;
+ tdm_value value = {.u32 = 0};
+ tdm_output * output = tdm_display_get_output(dpy, i, &error);
+ ASSERT_FALSE(NULL == output);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ error = tdm_output_get_property(output, UINT_MAX, &value);
+ ASSERT_TRUE(error == TDM_ERROR_NOT_IMPLEMENTED || error == TDM_ERROR_NONE);
+ }
+}
+
+TEST_F(TDMOutput, OutputGetPropertyFailNullAll)
+{
+ SKIP_FLAG(has_output);
+ ASSERT_EXIT({tdm_error error = TDM_ERROR_NONE;
+ error = tdm_output_get_property(NULL, 0, NULL);
+ if (error == TDM_ERROR_NONE || error == TDM_ERROR_NOT_IMPLEMENTED ||
+ error == TDM_ERROR_OPERATION_FAILED) exit(1);
+ exit(0);}, ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMOutputCommit, OutputCommitFailNullAll)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(NULL, 0, NULL, NULL));
+}
+
+TEST_F(TDMOutputCommit, OutputCommit)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+
+ UtHandleCommitEvent();
+
+ ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+}
+
+TEST_F(TDMOutputCommitThread, OutputCommit)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+
+ UtHandleCommitEvent();
+
+ ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+}
+
+TEST_F(TDMOutputCommitPerVblankEnabled, OutputCommitFailLayerCommit)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (size_t i = 0; i < layers_array.size(); ++i) {
+ for (tdm_layer *layer : layers_array[i]) {
+ tdm_layer_commit(layer, NULL, NULL);
+ }
+ }
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+}
+
+TEST_F(TDMOutputCommitPerVblankEnabled, OutputCommitFailCommitPerVblankEnabled)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+}
+
+TEST_F(TDMOutputCommit, OutputCommitFailDpmsOff)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++) {
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i], TDM_OUTPUT_DPMS_OFF));
+
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+ }
+}
+
+TEST_F(TDMOutputCommit, OutputWaitVBlankFailNullAll)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_wait_vblank(nullptr, 1, 0, nullptr, nullptr));
+}
+
+TEST_F(TDMOutputCommit, OutputWaitVBlankFailDpmsOff)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++) {
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i], TDM_OUTPUT_DPMS_OFF));
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, nullptr));
+ }
+}
+
+TEST_F(TDMOutputCommit, OutputWaitVBlank)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, nullptr));
+
+ UtHandleCommitEvent();
+
+ ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, nullptr));
+
+ UtHandleVblankEvent();
+
+ ASSERT_EQ(conn_output_count, utOutputVblankHandlerCounter);
+}
+
+TEST_F(TDMOutputCommitThread, OutputWaitVBlank)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+
+ UtHandleCommitEvent();
+
+ ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, NULL));
+
+ UtHandleVblankEvent();
+
+ ASSERT_EQ(conn_output_count, utOutputVblankHandlerCounter);
+}
+
+TEST_F(TDMOutputCommit, OutputRemoveVblankHandlerFailNullAll)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_remove_vblank_handler(nullptr, nullptr, nullptr));
+}
+
+TEST_F(TDMOutputCommitThread, OutputRemoveVblankHandlerSuccess)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+
+ UtHandleCommitEvent();
+
+ ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 2, 0, UtOutputVblankHandler, NULL));
+
+ for (int i = 0; i < conn_output_count; i++) {
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_remove_vblank_handler(connected_output_array[i], UtOutputVblankHandler, NULL));
+ }
+
+ UtHandleVblankEvent();
+
+ ASSERT_EQ(0, utOutputVblankHandlerCounter);
+}
+
+TEST_F(TDMOutputCommit, OutputRemoveCommitHandlerFailNullAll)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_remove_commit_handler(nullptr, nullptr, nullptr));
+}
+
+TEST_F(TDMOutputCommitThread, OutputRemoveCommitHandlerSuccess)
+{
+ SKIP_FLAG(has_output);
+
+ ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
+
+ for (int i = 0; i < conn_output_count; i++)
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
+
+ for (int i = 0; i < conn_output_count; i++) {
+ ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_remove_commit_handler(connected_output_array[i], UtOutputCommitHandler, NULL));
+ }
+
+ UtHandleCommitEvent();
+}