--- /dev/null
+#include "gtest/gtest.h"
+#include "ut_common.h"
+#include "stdint.h"
+
+extern "C" {
+#include "tdm.h"
+#include "tdm_backend.h"
+#include "tbm_bufmgr.h"
+#include "tbm_surface.h"
+#include "tbm_surface_internal.h"
+#include "tbm_drm_helper.h"
+}
+
+class TDMBuffer: public ::testing::Test
+{
+protected:
+ static tbm_bufmgr tbm_bufmgr;
+ static int master_fd;
+
+ tbm_surface_h surface;
+
+ tdm_error error;
+
+ static void SetEnv(void)
+ {
+ setenv("TDM_DEBUG_MODULE", "all", 1);
+ setenv("TDM_DEBUG", "1", 1);
+ setenv("TDM_THREAD", "0", 1);
+ setenv("XDG_RUNTIME_DIR", "/run", 1);
+ setenv("TBM_DISPLAY_SERVER", "1", 1);
+ }
+
+ static void UnsetEnv(void)
+ {
+ unsetenv("TDM_DEBUG_MODULE");
+ unsetenv("TDM_DEBUG");
+ unsetenv("TDM_THREAD");
+ unsetenv("XDG_RUNTIME_DIR");
+ unsetenv("TBM_DISPLAY_SERVER");
+ }
+
+ static void SetUpTestCase()
+ {
+ SetEnv();
+ tbm_bufmgr = tbm_bufmgr_init(-1);
+ ASSERT_FALSE(tbm_bufmgr == NULL);
+ master_fd = tbm_drm_helper_get_master_fd();
+ }
+
+ static void TearDownTestCase()
+ {
+ 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);
+ }
+
+ UnsetEnv();
+ }
+ void SetUp()
+ {
+ surface = tbm_surface_create(256, 256, TBM_FORMAT_ARGB8888);
+ ASSERT_TRUE(surface != NULL);
+ }
+ void TearDown()
+ {
+ if (surface) {
+ while (tbm_surface_internal_is_valid(surface))
+ tbm_surface_destroy(surface);
+ }
+ }
+};
+
+tbm_bufmgr TDMBuffer::tbm_bufmgr = NULL;
+int TDMBuffer::master_fd = -42;
+
+
+static int handler_is_called = 0;
+static void release_handler(tbm_surface_h buffer, void *user_data)
+{
+ if (user_data == &handler_is_called)
+ handler_is_called = 1;
+}
+static void destroy_handler(tbm_surface_h buffer, void *user_data)
+{
+ if (user_data == &handler_is_called)
+ handler_is_called = 1;
+}
+
+/* tbm_surface_h tdm_buffer_ref_backend(tbm_surface_h buffer) */
+TEST_F(TDMBuffer, RefFailNULL)
+{
+ tbm_surface_h buffer = NULL;
+
+ buffer = tdm_buffer_ref_backend(NULL);
+ ASSERT_EQ(NULL, buffer);
+}
+
+TEST_F(TDMBuffer, RefSuccessful)
+{
+ tbm_surface_h buffer = NULL;
+
+ buffer = tdm_buffer_ref_backend(surface);
+ ASSERT_EQ(buffer, surface);
+
+ buffer = tdm_buffer_ref_backend(surface);
+ ASSERT_EQ(buffer, surface);
+
+}
+
+/* void tdm_buffer_unref_backend(tbm_surface_h buffer) */
+TEST_F(TDMBuffer, UnrefFailNULL)
+{
+ tdm_buffer_unref_backend(NULL);
+}
+
+TEST_F(TDMBuffer, UnrefSuccessfulTwoRefUnref)
+{
+ tbm_surface_h buffer = NULL;
+
+ buffer = tdm_buffer_ref_backend(surface);
+ ASSERT_EQ(buffer, surface);
+ buffer = tdm_buffer_ref_backend(surface);
+ ASSERT_EQ(buffer, surface);
+
+ // first unref
+ tdm_buffer_unref_backend(surface);
+ ASSERT_TRUE(tbm_surface_internal_is_valid(surface));
+
+ // second unref
+ tdm_buffer_unref_backend(surface);
+ ASSERT_TRUE(tbm_surface_internal_is_valid(surface));
+}
+
+TEST_F(TDMBuffer, UnrefSuccessfulWithoutRef)
+{
+ tdm_buffer_unref_backend(surface);
+ ASSERT_FALSE(tbm_surface_internal_is_valid(surface));
+}
+
+TEST_F(TDMBuffer, UnrefSuccessfulOneRefTwoUnref)
+{
+ tbm_surface_h buffer = NULL;
+
+ buffer = tdm_buffer_ref_backend(surface);
+ ASSERT_EQ(buffer, surface);
+
+ tdm_buffer_unref_backend(surface);
+ ASSERT_TRUE(tbm_surface_internal_is_valid(surface));
+
+ tdm_buffer_unref_backend(surface);
+ ASSERT_FALSE(tbm_surface_internal_is_valid(surface));
+}
+
+/* tdm_error tdm_buffer_add_release_handler(tbm_surface_h buffer, tdm_buffer_release_handler func, void *user_data) */
+TEST_F(TDMBuffer, AddReleaseHandlerFailNULL)
+{
+ error = tdm_buffer_add_release_handler(NULL, release_handler, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
+
+ error = tdm_buffer_add_release_handler(surface, NULL, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
+}
+
+TEST_F(TDMBuffer, AddReleaseHandlerSuccessful)
+{
+ error = tdm_buffer_add_release_handler(surface, release_handler, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ handler_is_called = 0;
+ tdm_buffer_unref_backend(surface);
+ ASSERT_TRUE(handler_is_called);
+}
+
+
+/* void tdm_buffer_remove_release_handler(tbm_surface_h buffer, tdm_buffer_release_handler func, void *user_data) */
+TEST_F(TDMBuffer, RemoveReleaseHandlerFailNULL)
+{
+ tdm_buffer_remove_release_handler(NULL, release_handler, &handler_is_called);
+
+ tdm_buffer_remove_release_handler(surface, NULL, &handler_is_called);
+}
+
+TEST_F(TDMBuffer, RemoveReleaseHandlerFailWithoutAdd)
+{
+ tdm_buffer_remove_release_handler(surface, release_handler, &handler_is_called);
+}
+
+TEST_F(TDMBuffer, RemoveReleaseHandlerSuccessful)
+{
+ error = tdm_buffer_add_release_handler(surface, release_handler, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ tdm_buffer_remove_release_handler(surface, release_handler, &handler_is_called);
+
+ handler_is_called = 0;
+ tdm_buffer_unref_backend(surface);
+ ASSERT_FALSE(handler_is_called);
+}
+
+/* tdm_error tdm_buffer_add_destroy_handler(tbm_surface_h buffer, tdm_buffer_destroy_handler func, void *user_data) */
+TEST_F(TDMBuffer, AddDestroyHandlerFailNULL)
+{
+ error = tdm_buffer_add_destroy_handler(NULL, destroy_handler, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
+
+ error = tdm_buffer_add_destroy_handler(surface, NULL, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_INVALID_PARAMETER, error);
+}
+
+TEST_F(TDMBuffer, AddDestroyHandlerSuccessful)
+{
+ error = tdm_buffer_add_destroy_handler(surface, destroy_handler, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ handler_is_called = 0;
+ tbm_surface_internal_unref(surface);
+ ASSERT_TRUE(handler_is_called);
+ surface = NULL;
+}
+
+/* void tdm_buffer_remove_destroy_handler() */
+TEST_F(TDMBuffer, RemoveDestroyHandlerFailNULL)
+{
+ tdm_buffer_remove_destroy_handler(NULL, release_handler, &handler_is_called);
+
+ tdm_buffer_remove_destroy_handler(surface, NULL, &handler_is_called);
+}
+
+TEST_F(TDMBuffer, RemoveDestroyHandlerFailWithoutAdd)
+{
+ tdm_buffer_remove_destroy_handler(surface, release_handler, &handler_is_called);
+}
+
+TEST_F(TDMBuffer, RemoveDestroyHandlerSuccessful)
+{
+ error = tdm_buffer_add_destroy_handler(surface, release_handler, &handler_is_called);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+
+ tdm_buffer_remove_destroy_handler(surface, release_handler, &handler_is_called);
+
+ handler_is_called = 0;
+ tbm_surface_internal_unref(surface);
+ ASSERT_FALSE(handler_is_called);
+}
+