#include "gtest/gtest.h"
#include "ut_common.h"
-extern "C" {
#include "tdm.h"
+extern "C" {
#include "tbm_bufmgr.h"
#include "tbm_drm_helper.h"
}
-class TDMCapture : public ::testing::Test {
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <vector>
+
+class TDMCaptureWithoutCreation : public testing::Test {
protected:
- tdm_display *dpy = NULL;
- tdm_capture_capability capture_capabilities = (tdm_capture_capability) -42;
+ tdm_display *dpy = nullptr;
+ tbm_bufmgr bufmgr = nullptr;
+ tdm_display_capability display_capability = (tdm_display_capability)0;
bool has_capture = false;
- tbm_bufmgr tbm_bufmgr = NULL;
- void SetUp(void)
+ std::vector<tdm_output *> output_array;
+
+ virtual void SetEnvs()
{
setenv("TDM_DLOG", "1", 1);
setenv("XDG_RUNTIME_DIR", ".", 1);
setenv("TBM_DLOG", "1", 1);
+ setenv("TDM_DEBUG_MODULE", "all", 1);
+ setenv("TDM_DEBUG", "1", 1);
setenv("TBM_DISPLAY_SERVER", "1", 1);
+ }
+
+ virtual void UnsetEnvs()
+ {
+ unsetenv("TDM_DLOG");
+ unsetenv("XDG_RUNTIME_DIR");
+ unsetenv("TBM_DLOG");
+ unsetenv("TDM_DEBUG_MODULE");
+ unsetenv("TDM_DEBUG");
+ unsetenv("TBM_DISPLAY_SERVER");
+ }
+
+ void SetUp(void)
+ {
+ tdm_error error = TDM_ERROR_NONE;
+ int output_count;
+
+ SetEnvs();
+
+ /* FIXME: fix the error. If we initialize TBM before TDM we get fail
+ * in the tdm_output_set_dpms */
+#if 0
tbm_bufmgr = tbm_bufmgr_init(-1);
ASSERT_FALSE(tbm_bufmgr == NULL);
- tdm_error error = TDM_ERROR_NONE;
+#endif
+
dpy = tdm_display_init(&error);
ASSERT_TRUE(error == TDM_ERROR_NONE);
- ASSERT_FALSE(dpy == NULL);
- error = tdm_display_get_capture_capabilities(dpy, &capture_capabilities);
+ ASSERT_FALSE(dpy == nullptr);
+
+ error = tdm_display_get_capabilities(dpy, &display_capability);
#ifdef FAIL_ON_UNSUPPORTED
- ASSERT_GT(capture_capabilities, 0);
+ ASSERT_TRUE(display_capability & TDM_DISPLAY_CAPABILITY_CAPTURE);
#endif
- if (capture_capabilities > 0)
+ ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+ if (display_capability & TDM_DISPLAY_CAPABILITY_CAPTURE)
has_capture = true;
+
+ ASSERT_TRUE(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE);
+
+ for (int i = 0; i < output_count; i++) {
+ tdm_output *output = tdm_display_get_output(dpy, i, &error);
+
+ if (TDM_ERROR_NONE != error || nullptr == output)
+ continue;
+
+ tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+ if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status))
+ continue;
+
+ if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+ continue;
+
+ output_array.push_back(output);
+ }
}
+
void TearDown(void)
{
- tdm_display_deinit(dpy);
- dpy = NULL;
- tbm_bufmgr_deinit(tbm_bufmgr);
- tbm_bufmgr = NULL;
- unsetenv("TDM_DLOG");
- unsetenv("XDG_RUNTIME_DIR");
- unsetenv("TBM_DLOG");
- unsetenv("TBM_DISPLAY_SERVER");
+ if (dpy)
+ tdm_display_deinit(dpy);
+ if (bufmgr)
+ tbm_bufmgr_deinit(bufmgr);
+
+ UnsetEnvs();
+ }
+};
+
+struct UtCapture
+{
+ tdm_output *output;
+ const tdm_output_mode *output_mode;
+ tdm_capture *capture;
+ std::vector<tdm_layer *> layers;
+ UtCapture(tdm_output *, const tdm_output_mode *, tdm_capture *, std::vector<tdm_layer *>);
+};
+
+UtCapture::UtCapture(tdm_output *_output, const tdm_output_mode *_output_mode,
+ tdm_capture *_capture, std::vector<tdm_layer *> _layers)
+{
+ output = _output;
+ output_mode = _output_mode;
+ capture = _capture;
+ layers = _layers;
+}
+
+class TDMCapture : public TDMCaptureWithoutCreation {
+protected:
+ const tbm_format *formats = nullptr;
+ int format_count = 0;
+ std::vector<UtCapture> captures;
+ std::vector<tbm_surface_h> buffers;
+ static int utCaptureDoneHandlerSuccessCounter;
+ friend void UtCaptureDoneHandler(tdm_capture *capture,
+ tbm_surface_h buffer, void *user_data);
+ void SetUp(void);
+ void TearDown(void);
+ void UtCaptureGetInfo(UtCapture *capture, double scale, tdm_transform transform, tdm_info_capture *info);
+ void UtCaptureGetInfo(UtCapture *capture, tdm_info_capture *info);
+ tbm_surface_h UtCaptureCreateBuffer(UtCapture *capture);
+ tbm_surface_h UtCaptureCreateBuffer(int width, int height, tbm_format format, int scanout);
+ tbm_surface_h UtCaptureCreateBuffer(int width, int height, tbm_format format);
+};
+
+int TDMCapture::utCaptureDoneHandlerSuccessCounter = 0;
+
+void UtCaptureDoneHandler(tdm_capture *capture,
+ tbm_surface_h buffer, void *user_data)
+{
+ TDMCapture *fcapture = (TDMCapture *)user_data;
+
+ if (!fcapture)
+ return;
+
+ for (tbm_surface_h buf : fcapture->buffers) {
+ if (buf == buffer) {
+ fcapture->utCaptureDoneHandlerSuccessCounter++;
+ break;
+ }
+ }
+}
+
+void TDMCapture::SetUp(void)
+{
+ tdm_error error;
+
+ utCaptureDoneHandlerSuccessCounter = 0;
+
+ ASSERT_NO_FATAL_FAILURE(TDMCaptureWithoutCreation::SetUp());
+
+ if (!has_capture)
+ return;
+
+ for (tdm_output *output : output_array) {
+ const tdm_output_mode *output_mode = nullptr;
+ int output_modes_cnt = 0;
+ const tdm_output_mode *output_modes;
+ int temp_layer_count = 0;
+ std::vector<tdm_layer *> layers;
+
+ error = tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ for(int j = 0; j < output_modes_cnt; j++)
+ if(output_modes[j].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
+ output_mode = &output_modes[j];
+
+ ASSERT_NE(nullptr, output_mode);
+
+ if (TDM_ERROR_NONE != tdm_output_get_layer_count(output, &temp_layer_count))
+ continue;
+ if (0 == temp_layer_count)
+ continue;
+
+ for (int i = 0; i < temp_layer_count; ++i) {
+ tdm_layer *layer;
+ layer = tdm_output_get_layer(output, i, &error);
+ ASSERT_TRUE(TDM_ERROR_NONE == error);
+ ASSERT_FALSE(NULL == layer);
+ layers.push_back(layer);
+ }
+
+ tdm_capture *capture = tdm_output_create_capture(output, &error);
+ ASSERT_NE(nullptr, capture);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ captures.emplace_back(output, output_mode, capture, layers);
+ }
+
+ error =
+ tdm_display_get_catpure_available_formats(dpy, &formats, &format_count);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ ASSERT_NE(nullptr, formats);
+ ASSERT_GE(format_count, 0);
+}
+
+void TDMCapture::TearDown(void)
+{
+ for (UtCapture & utCapture : captures)
+ tdm_capture_destroy(utCapture.capture);
+
+ for (tbm_surface_h buffer : buffers) {
+ tbm_surface_destroy(buffer);
+ }
+
+ TDMCaptureWithoutCreation::TearDown();
+}
+
+void TDMCapture::UtCaptureGetInfo(UtCapture *capture, double scale,
+ tdm_transform transform, tdm_info_capture *info)
+{
+ memset((void *)info, 0, sizeof(tdm_info_capture));
+
+ const tdm_output_mode *output_mode = capture->output_mode;
+
+ int w = output_mode->hdisplay * scale;
+ int h = output_mode->vdisplay * scale;
+
+ info->dst_config.size.h = w;
+ info->dst_config.size.v = h;
+ info->dst_config.pos.x = 0;
+ info->dst_config.pos.y = 0;
+ info->dst_config.pos.w = w;
+ info->dst_config.pos.h = h;
+ info->dst_config.format = formats[0];
+ info->transform = transform;
+ info->type = TDM_CAPTURE_TYPE_ONESHOT;
+}
+
+void TDMCapture::UtCaptureGetInfo(UtCapture *capture, tdm_info_capture *info)
+{
+ UtCaptureGetInfo(capture, 1.0, TDM_TRANSFORM_NORMAL, info);
+}
+
+tbm_surface_h
+TDMCapture::UtCaptureCreateBuffer(UtCapture *capture)
+{
+ tbm_surface_h buffer;
+
+ buffer = tbm_surface_create(capture->output_mode->hdisplay,
+ capture->output_mode->vdisplay, formats[0]);
+ if (buffer)
+ buffers.push_back(buffer);
+
+ return buffer;
+}
+
+tbm_surface_h
+TDMCapture::UtCaptureCreateBuffer(int width, int height, tbm_format format, int scanout)
+{
+ tbm_surface_h buffer;
+
+ if (scanout)
+ buffer = tbm_surface_internal_create_with_flags(width, height, format, TBM_BO_SCANOUT);
+ else
+ buffer = tbm_surface_internal_create_with_flags(width, height, format, TBM_BO_DEFAULT);
+
+ if (buffer)
+ buffers.push_back(buffer);
+
+ return buffer;
+}
+
+tbm_surface_h
+TDMCapture::UtCaptureCreateBuffer(int width, int height, tbm_format format)
+{
+ return UtCaptureCreateBuffer(width, height, format, 0);
+}
+
+class TDMCaptureCommit : public TDMCapture {
+public:
+private:
+ int epFd = -1;
+ int timerFd = -1;
+ int tdmFd = -1;
+ static const int timeLimitSec = 3;
+ static const int timeLimitNsec = 0;
+protected:
+ void SetUp(void);
+ void TearDown(void);
+ void UtHandleCaptureEvent();
+ int UtPrepareToCapture(double scale, tdm_transform transform);
+ int UtPrepareToCapture();
+};
+
+void TDMCaptureCommit::SetUp(void)
+{
+ struct epoll_event ep;
+ tdm_error error;
+
+ ASSERT_NO_FATAL_FAILURE(TDMCapture::SetUp());
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_output_set_mode(utCapture.output, utCapture.output_mode);
+ ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+ error = tdm_output_set_dpms(utCapture.output, TDM_OUTPUT_DPMS_ON);
+ ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+ for (tdm_layer *layer : utCapture.layers) {
+ int w, h;
+ tdm_layer_capability lcapabilities;
+ tbm_surface_h buffer;
+ tdm_info_layer layer_info = {0};
+
+ w = utCapture.output_mode->hdisplay;
+ h = utCapture.output_mode->vdisplay;
+
+ 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 = UtCaptureCreateBuffer(w, h, TBM_FORMAT_ARGB8888, 1);
+ ASSERT_NE(nullptr, buffer);
+
+ layer_info.src_config.size.h = w;
+ layer_info.src_config.size.v = h;
+ layer_info.src_config.pos.x = 0;
+ layer_info.src_config.pos.y = 0;
+ layer_info.src_config.pos.w = w;
+ layer_info.src_config.pos.h = h;
+ layer_info.src_config.format = TBM_FORMAT_ARGB8888;
+ layer_info.dst_pos.x = 0;
+ layer_info.dst_pos.y = 0;
+ layer_info.dst_pos.w = w;
+ layer_info.dst_pos.h = h;
+ layer_info.transform = TDM_TRANSFORM_NORMAL;
+
+ error = tdm_layer_set_info(layer, &layer_info);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ error = tdm_layer_set_buffer(layer, buffer);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+
+ error = tdm_output_commit(utCapture.output, 0, nullptr, nullptr);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+
+ /* TODO: use output_commit_handle */
+ usleep(200000);
+
+ epFd = epoll_create1(0);
+ ASSERT_TRUE(epFd != -1);
+
+ timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+ ASSERT_TRUE(timerFd != -1);
+
+ memset(&ep, 0, sizeof ep);
+ ep.events |= EPOLLIN;
+ ep.data.fd = timerFd;
+ ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
+
+ ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
+
+ memset(&ep, 0, sizeof ep);
+ ep.events |= EPOLLIN;
+ ep.data.fd = tdmFd;
+ ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
+}
+
+void TDMCaptureCommit::TearDown(void)
+{
+ if (epFd)
+ close(epFd);
+ if (timerFd)
+ close(timerFd);
+
+ for (UtCapture & utCapture : captures) {
+ for (tdm_layer *layer : utCapture.layers)
+ tdm_layer_unset_buffer(layer);
+
+ tdm_output_set_dpms(utCapture.output, TDM_OUTPUT_DPMS_OFF);
+ }
+
+ TDMCapture::TearDown();
+}
+
+void TDMCaptureCommit::UtHandleCaptureEvent()
+{
+ struct itimerspec its;
+ int count;
+ struct epoll_event ep_event[2];
+
+ if (utCaptureDoneHandlerSuccessCounter == (int)captures.size())
+ 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 (utCaptureDoneHandlerSuccessCounter == (int)captures.size())
+ return;
+ }
+ }
+ }
+}
+
+int TDMCaptureCommit::UtPrepareToCapture(double scale, tdm_transform transform)
+{
+ tdm_error error;
+ tbm_surface_h buffer;
+
+ for (UtCapture & utCapture : captures) {
+ tdm_info_capture info = {0};
+
+ UtCaptureGetInfo(&utCapture, scale, transform, &info);
+
+ error = tdm_capture_set_done_handler(utCapture.capture, UtCaptureDoneHandler, this);
+ EXPECT_EQ(TDM_ERROR_NONE, error);
+ if (error != TDM_ERROR_NONE)
+ return -1;
+
+ error = tdm_capture_set_info(utCapture.capture, &info);
+ EXPECT_EQ(TDM_ERROR_NONE, error);
+ if (error != TDM_ERROR_NONE)
+ return -1;
+
+ buffer = UtCaptureCreateBuffer(info.dst_config.size.h,
+ info.dst_config.size.v,
+ info.dst_config.format);
+ EXPECT_NE(NULL, buffer);
+ if (!buffer)
+ return -1;
+
+ error = tdm_capture_attach(utCapture.capture, buffer);
+ EXPECT_EQ(TDM_ERROR_NONE, error);
+ if (error != TDM_ERROR_NONE)
+ return -1;
+ }
+
+ return 0;
+}
+
+int TDMCaptureCommit::UtPrepareToCapture()
+{
+ return UtPrepareToCapture(1.0, TDM_TRANSFORM_NORMAL);
+}
+
+class TDMCaptureCommitThread : public TDMCaptureCommit {
+protected:
+ void SetEnvs()
+ {
+ TDMCaptureCommit::SetEnvs();
+ setenv("TDM_THREAD", "1", 1);
+ }
+ void UnsetEnvs()
+ {
+ TDMCaptureCommit::UnsetEnvs();
+ unsetenv("TDM_THREAD");
}
};
-TEST_F(TDMCapture, DisplayGetCaptureAvailableFormatsSuccessful)
+TEST_F(TDMCaptureWithoutCreation, DisplayGetCaptureAvailableFormatsSuccessful)
{
SKIP_FLAG(has_capture);
- const tbm_format * formats = NULL;
+ const tbm_format * formats = nullptr;
int count = -42;
ASSERT_TRUE(TDM_ERROR_NONE == tdm_display_get_catpure_available_formats(dpy, &formats, &count));
ASSERT_FALSE(-42 == count);
- ASSERT_FALSE(NULL == formats);
+ ASSERT_FALSE(nullptr == formats);
+}
+
+/* tdm_display_create_pp() */
+
+TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureNullAll)
+{
+ SKIP_FLAG(has_capture);
+ tdm_capture *capture;
+
+ capture = tdm_output_create_capture(nullptr, nullptr);
+ ASSERT_EQ(nullptr, capture);
+}
+
+TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureNullOutput)
+{
+ SKIP_FLAG(has_capture);
+ tdm_capture *capture;
+ tdm_error error;
+
+ capture = tdm_output_create_capture(nullptr, &error);
+ ASSERT_EQ(nullptr, capture);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureSuccessNullError)
+{
+ SKIP_FLAG(has_capture);
+ tdm_capture *capture;
+
+ for (tdm_output *output : output_array) {
+ capture = tdm_output_create_capture(output, nullptr);
+ ASSERT_NE(nullptr, capture);
+ }
+}
+
+TEST_F(TDMCaptureWithoutCreation, DisplayCreateCaptureSuccess)
+{
+ SKIP_FLAG(has_capture);
+ tdm_capture *capture;
+ tdm_error error;
+
+ for (tdm_output *output : output_array) {
+ capture = tdm_output_create_capture(output, &error);
+ ASSERT_NE(nullptr, capture);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+}
+
+/* tdm_display_get_capture_available_size */
+
+TEST_F(TDMCapture, DisplayGetCaptureAvailableSizeFailNullAll)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ error = tdm_display_get_capture_available_size(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, DisplayGetCaptureAvailableSizeSuccess)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+ int min_w;
+ int min_h;
+ int max_w;
+ int max_h;
+ int preferred_align;
+
+ error = tdm_display_get_capture_available_size(dpy, &min_w, &min_h,
+ &max_w, &max_h, &preferred_align);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+}
+
+
+/* tdm_capture_set_info() */
+
+TEST_F(TDMCapture, CaptureSetInfoFailNullAll)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ error = tdm_capture_set_info(nullptr, nullptr);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, CaptureSetInfoFailNullCapture)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+ tdm_info_capture info;
+
+ error = tdm_capture_set_info(nullptr, &info);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, CaptureSetInfoNullInfo)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_set_info(utCapture.capture, nullptr);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ }
+}
+
+TEST_F(TDMCapture, CaptureSetInfoSuccessStream)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+ tdm_info_capture info;
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_output_set_mode(utCapture.output, utCapture.output_mode);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ UtCaptureGetInfo(&utCapture, &info);
+
+ info.type = TDM_CAPTURE_TYPE_STREAM;
+
+ error = tdm_capture_set_info(utCapture.capture, &info);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+}
+
+TEST_F(TDMCapture, CaptureSetInfoSuccess)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+ tdm_info_capture info;
+
+ for (UtCapture & utCapture : captures) {
+ UtCaptureGetInfo(&utCapture, &info);
+
+ error = tdm_capture_set_info(utCapture.capture, &info);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+}
+
+/* tdm_capture_set_done_handler() */
+
+TEST_F(TDMCapture, CaptureSetDoneHandlerFailNullAll)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ error = tdm_capture_set_done_handler(nullptr, nullptr, nullptr);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, CaptureSetDoneHandlerFailNullCapture)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ error = tdm_capture_set_done_handler(nullptr, UtCaptureDoneHandler, this);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, CaptureSetDoneHandlerSuccessNullFailNullFunc)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_pp_set_done_handler(utCapture.capture, nullptr, this);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ }
+}
+
+TEST_F(TDMCapture, CaptureSetDoneHandlerSuccessNullData)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_set_done_handler(utCapture.capture, UtCaptureDoneHandler, this);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+}
+
+TEST_F(TDMCapture, CaptureSetDoneHandlerSuccess)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_set_done_handler(utCapture.capture, UtCaptureDoneHandler, this);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+}
+
+/* tdm_capture_attach() */
+
+TEST_F(TDMCapture, CaptureAttachFailNullAll)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ error = tdm_capture_attach(nullptr, nullptr);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, CaptureAttachFailNullCapture)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+ tbm_surface_h buffer;
+
+ buffer = UtCaptureCreateBuffer(&captures[0]);
+ ASSERT_NE(nullptr, buffer);
+
+ error = tdm_capture_attach(nullptr, buffer);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, CaptureAttachFailNullBuffer)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_attach(utCapture.capture, nullptr);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ }
+}
+
+TEST_F(TDMCapture, CaptureAttachSuccess)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+ tbm_surface_h buffer;
+
+ for (UtCapture & utCapture : captures) {
+ buffer = UtCaptureCreateBuffer(&utCapture);
+ ASSERT_NE(nullptr, buffer);
+
+ error = tdm_capture_attach(utCapture.capture, buffer);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+}
+
+/* tdm_pp_commit() */
+
+TEST_F(TDMCapture, CaptureCommitFailNullCapture)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ error = tdm_capture_commit(nullptr);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+
+TEST_F(TDMCapture, CaptureCommitFailDpmsOff)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_commit(utCapture.capture);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ }
+}
+
+TEST_F(TDMCaptureCommit, CaptureCommitSuccess)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ ASSERT_NE(-1, UtPrepareToCapture());
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_commit(utCapture.capture);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+
+ UtHandleCaptureEvent();
+
+ ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
+}
+
+TEST_F(TDMCaptureCommitThread, CaptureCommitSuccess)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ ASSERT_NE(-1, UtPrepareToCapture());
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_commit(utCapture.capture);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+
+ UtHandleCaptureEvent();
+
+ ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
+}
+
+TEST_F(TDMCaptureCommit, CaptureCommitSuccessScale)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_NORMAL));
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_commit(utCapture.capture);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+
+ UtHandleCaptureEvent();
+
+ ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
+}
+
+TEST_F(TDMCaptureCommit, CaptureCommitSuccessScaleAndTransform)
+{
+ SKIP_FLAG(has_capture);
+ tdm_error error;
+
+ ASSERT_NE(-1, UtPrepareToCapture(2.0, TDM_TRANSFORM_180));
+
+ for (UtCapture & utCapture : captures) {
+ error = tdm_capture_commit(utCapture.capture);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+
+ UtHandleCaptureEvent();
+
+ ASSERT_EQ(captures.size(), utCaptureDoneHandlerSuccessCounter);
}