5 #include "flutter/fml/synchronization/waitable_event.h"
6 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
9 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
10 #include "flutter/shell/platform/windows/testing/mock_gl_proc_table.h"
11 #include "gtest/gtest.h"
17 using ::testing::AtLeast;
19 using Microsoft::WRL::ComPtr;
23 std::unique_ptr<FlutterWindowsEngine> GetTestEngine() {
25 properties.
assets_path = L
"C:\\foo\\flutter_assets";
28 FlutterProjectBundle project(properties);
29 auto engine = std::make_unique<FlutterWindowsEngine>(project);
31 EngineModifier modifier(engine.get());
32 modifier.embedder_api().RegisterExternalTexture =
33 MOCK_ENGINE_PROC(RegisterExternalTexture,
34 ([](
auto engine,
auto texture_id) {
return kSuccess; }));
40 ComPtr<ID3D11Texture2D> CreateD3dTexture(FlutterWindowsEngine* engine,
43 ComPtr<ID3D11Device> d3d_device;
44 ComPtr<ID3D11Texture2D> d3d_texture;
45 if (engine->surface_manager()->GetDevice(d3d_device.GetAddressOf())) {
46 D3D11_TEXTURE2D_DESC texture_description = {};
47 texture_description.MipLevels = 1;
48 texture_description.SampleDesc.Count = 1;
49 texture_description.BindFlags = D3D11_BIND_RENDER_TARGET;
50 texture_description.Usage = D3D11_USAGE_DEFAULT;
51 texture_description.CPUAccessFlags = 0;
52 texture_description.ArraySize = 1;
53 texture_description.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
54 texture_description.Height = width;
55 texture_description.Width = height;
56 texture_description.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
58 d3d_device->CreateTexture2D(&texture_description,
nullptr,
59 d3d_texture.GetAddressOf());
66 TEST(FlutterWindowsTextureRegistrarTest, CreateDestroy) {
67 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
68 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
74 TEST(FlutterWindowsTextureRegistrarTest, RegisterUnregisterTexture) {
75 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
76 EngineModifier modifier(engine.get());
77 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
84 [](
size_t width,
size_t height,
89 int64_t registered_texture_id = 0;
90 bool register_called =
false;
91 modifier.embedder_api().RegisterExternalTexture = MOCK_ENGINE_PROC(
92 RegisterExternalTexture, ([®ister_called, ®istered_texture_id](
94 register_called =
true;
99 bool unregister_called =
false;
100 modifier.embedder_api().UnregisterExternalTexture = MOCK_ENGINE_PROC(
101 UnregisterExternalTexture, ([&unregister_called, ®istered_texture_id](
103 unregister_called =
true;
108 bool mark_frame_available_called =
false;
109 modifier.embedder_api().MarkExternalTextureFrameAvailable =
110 MOCK_ENGINE_PROC(MarkExternalTextureFrameAvailable,
111 ([&mark_frame_available_called, ®istered_texture_id](
113 mark_frame_available_called =
true;
118 modifier.embedder_api().PostRenderThreadTask =
119 MOCK_ENGINE_PROC(PostRenderThreadTask,
120 [](
auto engine,
auto callback,
void* callback_data) {
126 EXPECT_TRUE(register_called);
131 EXPECT_TRUE(mark_frame_available_called);
133 fml::AutoResetWaitableEvent latch;
136 ASSERT_TRUE(unregister_called);
139 TEST(FlutterWindowsTextureRegistrarTest, RegisterUnknownTextureType) {
140 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
141 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
153 TEST(FlutterWindowsTextureRegistrarTest, PopulatePixelBufferTexture) {
154 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
155 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
159 bool release_callback_called =
false;
162 std::unique_ptr<uint8_t[]> pixels =
163 std::make_unique<uint8_t[]>(width * height * 4);
165 pixel_buffer.
width = width;
166 pixel_buffer.
height = height;
167 pixel_buffer.
buffer = pixels.get();
170 bool* called =
reinterpret_cast<bool*
>(release_context);
178 [](
size_t width,
size_t height,
183 FlutterOpenGLTexture flutter_texture = {};
187 EXPECT_CALL(*gl.get(), GenTextures(1, _))
189 .WillOnce([](GLsizei n, GLuint* textures) { textures[0] = 1; });
190 EXPECT_CALL(*gl.get(), BindTexture).Times(1);
191 EXPECT_CALL(*gl.get(), TexParameteri).Times(AtLeast(1));
192 EXPECT_CALL(*gl.get(), TexImage2D).Times(1);
193 EXPECT_CALL(*gl.get(), DeleteTextures(1, _)).Times(1);
198 EXPECT_EQ(flutter_texture.width, width);
199 EXPECT_EQ(flutter_texture.height, height);
200 EXPECT_EQ(flutter_texture.target, GL_TEXTURE_2D);
201 EXPECT_TRUE(release_callback_called);
204 TEST(FlutterWindowsTextureRegistrarTest, PopulateD3dTextureWithHandle) {
205 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
206 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
211 auto d3d_texture = CreateD3dTexture(engine.get(), width, height);
212 EXPECT_TRUE(d3d_texture);
214 ComPtr<IDXGIResource> shared_resource;
215 EXPECT_TRUE(SUCCEEDED(d3d_texture.As(&shared_resource)));
217 HANDLE shared_handle;
218 EXPECT_TRUE(SUCCEEDED(shared_resource->GetSharedHandle(&shared_handle)));
220 bool release_callback_called =
false;
223 surface_descriptor.
handle = shared_handle;
228 bool* called =
reinterpret_cast<bool*
>(release_context);
240 [](
size_t width,
size_t height,
246 FlutterOpenGLTexture flutter_texture = {};
250 EXPECT_CALL(*gl.get(), GenTextures(1, _))
252 .WillOnce([](GLsizei n, GLuint* textures) { textures[0] = 1; });
253 EXPECT_CALL(*gl.get(), BindTexture).Times(1);
254 EXPECT_CALL(*gl.get(), TexParameteri).Times(AtLeast(1));
255 EXPECT_CALL(*gl.get(), DeleteTextures(1, _)).Times(1);
260 EXPECT_EQ(flutter_texture.width, width);
261 EXPECT_EQ(flutter_texture.height, height);
262 EXPECT_EQ(flutter_texture.target, GL_TEXTURE_2D);
263 EXPECT_TRUE(release_callback_called);
266 TEST(FlutterWindowsTextureRegistrarTest, PopulateD3dTexture) {
267 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
268 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
273 auto d3d_texture = CreateD3dTexture(engine.get(), width, height);
274 EXPECT_TRUE(d3d_texture);
276 bool release_callback_called =
false;
279 surface_descriptor.
handle = d3d_texture.Get();
284 bool* called =
reinterpret_cast<bool*
>(release_context);
296 [](
size_t width,
size_t height,
302 FlutterOpenGLTexture flutter_texture = {};
306 EXPECT_CALL(*gl.get(), GenTextures(1, _))
308 .WillOnce([](GLsizei n, GLuint* textures) { textures[0] = 1; });
309 EXPECT_CALL(*gl.get(), BindTexture).Times(1);
310 EXPECT_CALL(*gl.get(), TexParameteri).Times(AtLeast(1));
311 EXPECT_CALL(*gl.get(), DeleteTextures(1, _)).Times(1);
316 EXPECT_EQ(flutter_texture.width, width);
317 EXPECT_EQ(flutter_texture.height, height);
318 EXPECT_EQ(flutter_texture.target, GL_TEXTURE_2D);
319 EXPECT_TRUE(release_callback_called);
322 TEST(FlutterWindowsTextureRegistrarTest, PopulateInvalidTexture) {
323 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
324 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
329 EXPECT_FALSE(result);
332 TEST(FlutterWindowsTextureRegistrarTest,
333 UnregisterTextureWithEngineDownInvokesCallback) {
334 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
335 std::shared_ptr<MockGlProcTable> gl = std::make_shared<MockGlProcTable>();
339 fml::AutoResetWaitableEvent latch;