/*
* Copyright 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
// The unittest header must be included before vaapidisplay.h.
// In vaapidisplay.h we include va_x11.h which includes Xlib.h and X.h.
// The X headers define 'Bool' and 'None' preprocessor types. Gtest
// uses the same names to define some struct placeholders. Thus, this
// creates a compile conflict if X defines them before gtest. Hence, the
// include order requirement here is the only fix for this right now.
// See bug filed on gtest at https://github.com/google/googletest/issues/371
// for more details.
#include "common/unittest.h"
// primary header
#include "vaapidisplay.h"
// system headers
#include <fcntl.h>
#include <set>
#include <unistd.h>
namespace YamiMediaCodec {
class VaapiDisplayTest : public ::testing::Test {
typedef std::set<intptr_t> DrmHandles;
protected:
bool isCompatible(const DisplayPtr display, const NativeDisplay& native) {
return display->isCompatible(native);
}
virtual void SetUp() {
#if defined(__ENABLE_X11__)
m_x11_handle = 0;
#endif
}
intptr_t openDrmHandle() {
intptr_t handle = -1;
handle = open("/dev/dri/renderD128", O_RDWR);
if (handle < 0)
handle = open("/dev/dri/card0", O_RDWR);
if (handle != -1)
m_drm_handles.insert(handle);
return handle;
}
void closeDrmHandle(intptr_t handle) {
if (handle == -1)
return;
close(handle);
const DrmHandles::const_iterator match(m_drm_handles.find(handle));
if (match != m_drm_handles.end())
m_drm_handles.erase(match);
}
#if defined(__ENABLE_X11__)
intptr_t openX11Handle() {
m_x11_handle = (intptr_t)XOpenDisplay(NULL);
return m_x11_handle;
}
#endif
virtual void TearDown() {
const DrmHandles::const_iterator endIt(m_drm_handles.end());
DrmHandles::const_iterator it;
for (it = m_drm_handles.begin(); it != endIt; ++it)
close(*it);
m_drm_handles.clear();
#if defined(__ENABLE_X11__)
if (m_x11_handle)
XCloseDisplay((Display*)(m_x11_handle));
#endif
}
DrmHandles m_drm_handles;
#if defined(__ENABLE_X11__)
intptr_t m_x11_handle;
#endif
};
#if defined(__ENABLE_X11__)
bool haveX11Display()
{
Display* display = XOpenDisplay(NULL);
if (display) {
XCloseDisplay(display);
return true;
}
return false;
}
#endif
const std::string getFullTestName()
{
const ::testing::TestInfo* const info = ::testing::UnitTest::GetInstance()->current_test_info();
return std::string(info->test_case_name())
+ std::string(".")
+ std::string(info->name());
}
#define VAAPI_DISPLAY_TEST(name) \
TEST_F(VaapiDisplayTest, name)
#if defined(__ENABLE_X11__)
VAAPI_DISPLAY_TEST(CreateInvalidHandleX11) {
//this turn off gest warning about multithread
//you can check details at
//https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
::testing::FLAGS_gtest_death_test_style = "threadsafe";
NativeDisplay native = {1, NATIVE_DISPLAY_X11};
//this will crash vaGetDisplay
ASSERT_DEATH({ DisplayPtr display = VaapiDisplay::create(native); }, "");
}
#endif
VAAPI_DISPLAY_TEST(CreateInvalidHandleDRM) {
NativeDisplay native = {1, NATIVE_DISPLAY_DRM};
DisplayPtr display = VaapiDisplay::create(native);
EXPECT_FALSE(display.get());
intptr_t handle = openDrmHandle();
ASSERT_NE(handle, -1);
// DRM handle is invalidated once it's closed.
closeDrmHandle(handle);
native.handle = handle;
native.type = NATIVE_DISPLAY_DRM;
display = VaapiDisplay::create(native);
EXPECT_FALSE(display.get());
}
VAAPI_DISPLAY_TEST(CreateInvalidHandleVA) {
NativeDisplay native = {0, NATIVE_DISPLAY_VA};
DisplayPtr display = VaapiDisplay::create(native);
EXPECT_FALSE(display.get());
//this turn off gest warning about multithread
//you can check details at
//https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
::testing::FLAGS_gtest_death_test_style = "threadsafe";
native.handle = -1;
native.type = NATIVE_DISPLAY_VA;
//This will crash in vaDisplayIsValid
ASSERT_DEATH({ display = VaapiDisplay::create(native); }, "");
}
#if defined(__ENABLE_X11__)
VAAPI_DISPLAY_TEST(CreateX11) {
if (!haveX11Display()) {
RecordProperty("skipped", true);
std::cout << "[ SKIPPED ] " << getFullTestName()
<< " We can't test this in terminal, we need a X11 window for this" << std::endl;
return;
}
// Let yami create the native display
NativeDisplay native = {0, NATIVE_DISPLAY_X11};
DisplayPtr display = VaapiDisplay::create(native);
ASSERT_TRUE(display.get());
EXPECT_TRUE(display->getID() > 0);
// Test the display caching
DisplayPtr display2 = VaapiDisplay::create(native);
ASSERT_TRUE(display2.get());
EXPECT_TRUE(display.get() == display2.get());
EXPECT_EQ(display->getID(), display2->getID());
// DRM native type returns cached X11 display
// TODO: Is this really supposed to be allowed?
native.handle = 0;
native.type = NATIVE_DISPLAY_DRM;
display2 = VaapiDisplay::create(native);
ASSERT_TRUE(display2.get());
EXPECT_TRUE(display.get() == display2.get());
EXPECT_EQ(display->getID(), display2->getID());
// FIXME: If client created the DRM handle, it seems
// that we should not get the cached X11 display, but we do.
intptr_t handle = openDrmHandle();
native.handle = handle;
native.type = NATIVE_DISPLAY_DRM;
display2 = VaapiDisplay::create(native);
ASSERT_NE(handle, -1);
ASSERT_TRUE(display2.get());
EXPECT_FALSE(display.get() == display2.get());
EXPECT_NE(display->getID(), display2->getID());
// Let client create the native display
native.handle = openX11Handle();
native.type = NATIVE_DISPLAY_X11;
display = VaapiDisplay::create(native);
ASSERT_NE(m_x11_handle, -1);
ASSERT_TRUE(display.get());
EXPECT_TRUE(display->getID() > 0);
// Ensure we didn't get the yami cached display
EXPECT_FALSE(display.get() == display2.get());
EXPECT_NE(display->getID(), display2->getID());
}
#endif
VAAPI_DISPLAY_TEST(CreateDRM) {
// Let yami create the native display
NativeDisplay native = {0, NATIVE_DISPLAY_DRM};
DisplayPtr display = VaapiDisplay::create(native);
ASSERT_TRUE(display.get());
EXPECT_TRUE(display->getID() > 0);
// Test the display caching
DisplayPtr display2 = VaapiDisplay::create(native);
ASSERT_TRUE(display2.get());
EXPECT_TRUE(display.get() == display2.get());
EXPECT_EQ(display->getID(), display2->getID());
// Let client create the native display
intptr_t handle = openDrmHandle();
native.handle = handle;
native.type = NATIVE_DISPLAY_DRM;
display = VaapiDisplay::create(native);
ASSERT_NE(handle, -1);
ASSERT_TRUE(display.get());
EXPECT_TRUE(display->getID() > 0);
// Ensure we didn't get the yami cached display
EXPECT_FALSE(display.get() == display2.get());
EXPECT_NE(display->getID(), display2->getID());
}
VAAPI_DISPLAY_TEST(CreateVA) {
NativeDisplay native = {1, NATIVE_DISPLAY_VA};
DisplayPtr display = VaapiDisplay::create(native);
ASSERT_TRUE(display.get());
EXPECT_TRUE(display->getID() > 0);
// Test the display caching
DisplayPtr display2 = VaapiDisplay::create(native);
ASSERT_TRUE(display2.get());
EXPECT_TRUE(display.get() == display2.get());
EXPECT_EQ(display->getID(), display2->getID());
}
#if defined(__ENABLE_X11__)
VAAPI_DISPLAY_TEST(CompatibleX11) {
if (!haveX11Display()) {
RecordProperty("skipped", true);
std::cout << "[ SKIPPED ] " << getFullTestName()
<< " We can't test this in terminal, we need a X11 window for this" << std::endl;
return;
}
NativeDisplay native = {openX11Handle(), NATIVE_DISPLAY_X11};
DisplayPtr display = VaapiDisplay::create(native);
ASSERT_TRUE((Display*)m_x11_handle != NULL);
ASSERT_TRUE(display.get());
EXPECT_TRUE(isCompatible(display, native));
native.handle = m_x11_handle + 1;
native.type = NATIVE_DISPLAY_X11;
EXPECT_FALSE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_X11;
EXPECT_TRUE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_VA;
EXPECT_FALSE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_DRM;
EXPECT_TRUE(isCompatible(display, native));
// FIXME: If client created the DRM handle, it seems
// that we should not get the cached X11 display
intptr_t handle = openDrmHandle();
native.handle = handle;
native.type = NATIVE_DISPLAY_DRM;
ASSERT_NE(handle, -1);
ASSERT_FALSE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_AUTO;
EXPECT_TRUE(isCompatible(display, native));
}
#endif
VAAPI_DISPLAY_TEST(CompatibleDRM) {
intptr_t handle = openDrmHandle();
intptr_t handle2 = openDrmHandle();
NativeDisplay native = {handle, NATIVE_DISPLAY_DRM};
DisplayPtr display = VaapiDisplay::create(native);
ASSERT_NE(handle, -1);
ASSERT_NE(handle2, -1);
ASSERT_NE(handle, handle2);
ASSERT_TRUE(display.get());
EXPECT_TRUE(isCompatible(display, native));
native.handle = handle2;
native.type = NATIVE_DISPLAY_DRM;
EXPECT_FALSE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_DRM;
EXPECT_TRUE(isCompatible(display, native));
native.handle = -1;
native.type = NATIVE_DISPLAY_DRM;
EXPECT_TRUE(isCompatible(display, native));
native.type = NATIVE_DISPLAY_AUTO;
EXPECT_TRUE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_VA;
EXPECT_FALSE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_X11;
EXPECT_FALSE(isCompatible(display, native));
}
VAAPI_DISPLAY_TEST(CompatibleVA) {
NativeDisplay native = {1, NATIVE_DISPLAY_VA};
DisplayPtr display = VaapiDisplay::create(native);
ASSERT_TRUE(display.get());
EXPECT_TRUE(isCompatible(display, native));
native.handle = 2;
native.type = NATIVE_DISPLAY_VA;
EXPECT_FALSE(isCompatible(display, native));
native.handle = 0;
native.type = NATIVE_DISPLAY_VA;
EXPECT_FALSE(isCompatible(display, native));
native.handle = -1;
native.type = NATIVE_DISPLAY_VA;
EXPECT_FALSE(isCompatible(display, native));
native.handle = 1;
native.type = NATIVE_DISPLAY_DRM;
EXPECT_FALSE(isCompatible(display, native));
native.handle = 1;
native.type = NATIVE_DISPLAY_X11;
EXPECT_FALSE(isCompatible(display, native));
native.type = NATIVE_DISPLAY_AUTO;
EXPECT_TRUE(isCompatible(display, native));
}
} //namespace YamiMediaCodec