blob: 348a99e96bef4bf5b9bc187d1793df81b0a6559b [file] [log] [blame]
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "utils/RenderDoc.h"
#include <type_traits>
#include "aemu/base/SharedLibrary.h"
namespace emugl {
namespace {
using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::MockFunction;
using ::testing::Return;
using ::testing::SetArgPointee;
using FunctionPtr = android::base::SharedLibrary::FunctionPtr;
using RenderDocApi = RenderDoc::RenderDocApi;
class MockSharedLibrary : public android::base::SharedLibrary {
public:
MockSharedLibrary() : SharedLibrary(NULL) {}
MOCK_METHOD(FunctionPtr, findSymbol, (const char*), (const, override));
};
TEST(RenderDocTest, InitializeWithNullSharedLibrary) {
EXPECT_EQ(RenderDoc::create(nullptr), nullptr);
}
TEST(RenderDocTest, CantFindRENDERDOC_GetAPI) {
MockSharedLibrary sharedLibrary;
EXPECT_CALL(sharedLibrary, findSymbol(_)).WillRepeatedly(Return(nullptr));
EXPECT_EQ(RenderDoc::create(&sharedLibrary), nullptr);
}
TEST(RenderDocTest, RENDERDOC_GetAPIFails) {
MockSharedLibrary sharedLibrary;
static MockFunction<std::remove_pointer_t<pRENDERDOC_GetAPI>> mockRENDERDOC_GetAPI;
static pRENDERDOC_GetAPI fpMockRENDERDOC_GetAPI = [](RENDERDOC_Version version,
void** outAPIPointers) {
return mockRENDERDOC_GetAPI.Call(version, outAPIPointers);
};
RenderDocApi rdocApi;
EXPECT_CALL(sharedLibrary, findSymbol(_)).WillRepeatedly(Return(nullptr));
EXPECT_CALL(sharedLibrary, findSymbol("RENDERDOC_GetAPI"))
.WillRepeatedly(Return(reinterpret_cast<FunctionPtr>(fpMockRENDERDOC_GetAPI)));
EXPECT_CALL(mockRENDERDOC_GetAPI, Call(_, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(&rdocApi), Return(0)));
EXPECT_EQ(RenderDoc::create(&sharedLibrary), nullptr);
EXPECT_CALL(mockRENDERDOC_GetAPI, Call(_, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(nullptr), Return(1)));
EXPECT_EQ(RenderDoc::create(&sharedLibrary), nullptr);
}
TEST(RenderDocTest, CreateSuccessfully) {
MockSharedLibrary sharedLibrary;
static MockFunction<std::remove_pointer_t<pRENDERDOC_GetAPI>> mockRENDERDOC_GetAPI;
static pRENDERDOC_GetAPI fpMockRENDERDOC_GetAPI = [](RENDERDOC_Version version,
void** outAPIPointers) {
return mockRENDERDOC_GetAPI.Call(version, outAPIPointers);
};
RenderDocApi rdocApiMock;
static MockFunction<std::remove_pointer_t<pRENDERDOC_GetCaptureOptionU32>>
getCaptureOptionU32Mock;
rdocApiMock.GetCaptureOptionU32 = [](RENDERDOC_CaptureOption option) {
return getCaptureOptionU32Mock.Call(option);
};
EXPECT_CALL(sharedLibrary, findSymbol(_)).WillRepeatedly(Return(nullptr));
EXPECT_CALL(sharedLibrary, findSymbol("RENDERDOC_GetAPI"))
.WillRepeatedly(Return(reinterpret_cast<FunctionPtr>(fpMockRENDERDOC_GetAPI)));
EXPECT_CALL(mockRENDERDOC_GetAPI, Call(_, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(&rdocApiMock), Return(1)));
std::unique_ptr<RenderDoc> renderDoc = RenderDoc::create(&sharedLibrary);
EXPECT_NE(renderDoc, nullptr);
EXPECT_CALL(getCaptureOptionU32Mock, Call(eRENDERDOC_Option_DebugOutputMute))
.WillRepeatedly(Return(1));
EXPECT_EQ(renderDoc->call(RenderDoc::kGetCaptureOptionU32, eRENDERDOC_Option_DebugOutputMute),
1);
}
class RenderDocMock {
public:
// For StartFrameCapture
MOCK_METHOD(void, call,
(void (*RenderDocApi::*function)(RENDERDOC_DevicePointer, RENDERDOC_WindowHandle),
RENDERDOC_DevicePointer, RENDERDOC_WindowHandle),
(const));
// For EndFrameCapture
MOCK_METHOD(uint32_t, call,
(uint32_t(*RenderDocApi::*function)(RENDERDOC_DevicePointer,
RENDERDOC_WindowHandle),
RENDERDOC_DevicePointer, RENDERDOC_WindowHandle),
(const));
// For IsFrameCapturing
MOCK_METHOD(uint32_t, call, (uint32_t(*RenderDocApi::*function)()), (const));
};
using RenderDocWithMultipleVkInstances = RenderDocWithMultipleVkInstancesBase<RenderDocMock>;
TEST(RenderDocWithMultipleVkInstancesTest,
ShouldNotStartFrameCaptureOnFrameDelimiterWhenNotCapturing) {
RenderDocMock renderDocMock;
intptr_t vkInstanceInternal = 0x1234;
VkInstance vkInstance = reinterpret_cast<VkInstance>(&vkInstanceInternal);
RenderDocWithMultipleVkInstances renderDocWithMultipleVkInstances(renderDocMock);
EXPECT_CALL(renderDocMock, call(RenderDoc::kIsFrameCapturing)).WillRepeatedly(Return(0));
EXPECT_CALL(renderDocMock, call(RenderDoc::kStartFrameCapture, _, _)).Times(0);
EXPECT_CALL(renderDocMock, call(RenderDoc::kEndFrameCapture, _, _)).Times(0);
renderDocWithMultipleVkInstances.onFrameDelimiter(vkInstance);
}
TEST(RenderDocWithMultipleVkInstancesTest, ShouldStartAndEndFrameCaptureOnFrameDelimiter) {
RenderDocMock renderDocMock;
intptr_t vkInstanceInternal = 0x4321;
VkInstance vkInstance = reinterpret_cast<VkInstance>(&vkInstanceInternal);
RenderDocWithMultipleVkInstances renderDocWithMultipleVkInstances(renderDocMock);
EXPECT_CALL(renderDocMock, call(RenderDoc::kIsFrameCapturing)).WillRepeatedly(Return(1));
{
InSequence s;
EXPECT_CALL(renderDocMock, call(RenderDoc::kStartFrameCapture,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vkInstance), NULL))
.Times(1);
EXPECT_CALL(renderDocMock, call(RenderDoc::kEndFrameCapture,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vkInstance), NULL))
.Times(1)
.WillRepeatedly(Return(1));
EXPECT_CALL(renderDocMock, call(RenderDoc::kStartFrameCapture,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vkInstance), NULL))
.Times(1);
EXPECT_CALL(renderDocMock, call(RenderDoc::kEndFrameCapture,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vkInstance), NULL))
.Times(1)
.WillRepeatedly(Return(1));
}
renderDocWithMultipleVkInstances.onFrameDelimiter(vkInstance);
renderDocWithMultipleVkInstances.onFrameDelimiter(vkInstance);
}
TEST(RenderDocWithMultipleVkInstancesTest, ShouldEndFrameCaptureOnVkInstanceRemoved) {
RenderDocMock renderDocMock;
intptr_t vkInstanceInternal = 0x4321;
VkInstance vkInstance = reinterpret_cast<VkInstance>(&vkInstanceInternal);
RenderDocWithMultipleVkInstances renderDocWithMultipleVkInstances(renderDocMock);
EXPECT_CALL(renderDocMock, call(RenderDoc::kIsFrameCapturing)).WillRepeatedly(Return(1));
{
InSequence s;
EXPECT_CALL(renderDocMock, call(RenderDoc::kStartFrameCapture,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vkInstance), NULL))
.Times(1);
EXPECT_CALL(renderDocMock, call(RenderDoc::kEndFrameCapture,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vkInstance), NULL))
.Times(1)
.WillRepeatedly(Return(1));
}
renderDocWithMultipleVkInstances.onFrameDelimiter(vkInstance);
renderDocWithMultipleVkInstances.removeVkInstance(vkInstance);
EXPECT_CALL(renderDocMock, call(RenderDoc::kEndFrameCapture,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(vkInstance), NULL))
.Times(0);
}
} // namespace
} // namespace emugl