179 lines
7.4 KiB
C++
179 lines
7.4 KiB
C++
|
|
#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
|