5 #include "flutter/fml/synchronization/waitable_event.h"
6 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
10 #include "flutter/shell/platform/windows/testing/egl/mock_proc_table.h"
11 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
12 #include "gtest/gtest.h"
18 using ::testing::AtLeast;
20 using Microsoft::WRL::ComPtr;
24 std::unique_ptr<FlutterWindowsEngine> GetTestEngine() {
26 properties.
assets_path = L
"C:\\foo\\flutter_assets";
29 FlutterProjectBundle project(properties);
30 auto engine = std::make_unique<FlutterWindowsEngine>(project);
32 EngineModifier modifier(engine.get());
33 modifier.embedder_api().RegisterExternalTexture =
34 MOCK_ENGINE_PROC(RegisterExternalTexture,
35 ([](
auto engine,
auto texture_id) {
return kSuccess; }));
41 ComPtr<ID3D11Texture2D> CreateD3dTexture(FlutterWindowsEngine* engine,
44 ComPtr<ID3D11Device> d3d_device;
45 ComPtr<ID3D11Texture2D> d3d_texture;
46 if (engine->egl_manager()->GetDevice(d3d_device.GetAddressOf())) {
47 D3D11_TEXTURE2D_DESC texture_description = {};
48 texture_description.MipLevels = 1;
49 texture_description.SampleDesc.Count = 1;
50 texture_description.BindFlags = D3D11_BIND_RENDER_TARGET;
51 texture_description.Usage = D3D11_USAGE_DEFAULT;
52 texture_description.CPUAccessFlags = 0;
53 texture_description.ArraySize = 1;
54 texture_description.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
55 texture_description.Height = width;
56 texture_description.Width = height;
57 texture_description.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
59 d3d_device->CreateTexture2D(&texture_description,
nullptr,
60 d3d_texture.GetAddressOf());
67 TEST(FlutterWindowsTextureRegistrarTest, CreateDestroy) {
68 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
69 auto gl = std::make_shared<egl::MockProcTable>();
75 TEST(FlutterWindowsTextureRegistrarTest, RegisterUnregisterTexture) {
76 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
77 EngineModifier modifier(engine.get());
78 auto gl = std::make_shared<egl::MockProcTable>();
85 [](
size_t width,
size_t height,
90 int64_t registered_texture_id = 0;
91 bool register_called =
false;
92 modifier.embedder_api().RegisterExternalTexture = MOCK_ENGINE_PROC(
93 RegisterExternalTexture, ([®ister_called, ®istered_texture_id](
95 register_called =
true;
100 bool unregister_called =
false;
101 modifier.embedder_api().UnregisterExternalTexture = MOCK_ENGINE_PROC(
102 UnregisterExternalTexture, ([&unregister_called, ®istered_texture_id](
104 unregister_called =
true;
109 bool mark_frame_available_called =
false;
110 modifier.embedder_api().MarkExternalTextureFrameAvailable =
111 MOCK_ENGINE_PROC(MarkExternalTextureFrameAvailable,
112 ([&mark_frame_available_called, ®istered_texture_id](
114 mark_frame_available_called =
true;
119 modifier.embedder_api().PostRenderThreadTask =
120 MOCK_ENGINE_PROC(PostRenderThreadTask,
121 [](
auto engine,
auto callback,
void* callback_data) {
127 EXPECT_TRUE(register_called);
132 EXPECT_TRUE(mark_frame_available_called);
134 fml::AutoResetWaitableEvent latch;
137 ASSERT_TRUE(unregister_called);
140 TEST(FlutterWindowsTextureRegistrarTest, RegisterUnknownTextureType) {
141 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
142 auto gl = std::make_shared<egl::MockProcTable>();
154 TEST(FlutterWindowsTextureRegistrarTest, PopulatePixelBufferTexture) {
155 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
156 auto gl = std::make_shared<egl::MockProcTable>();
160 bool release_callback_called =
false;
163 std::unique_ptr<uint8_t[]> pixels =
164 std::make_unique<uint8_t[]>(width * height * 4);
166 pixel_buffer.
width = width;
167 pixel_buffer.
height = height;
168 pixel_buffer.
buffer = pixels.get();
171 bool* called =
reinterpret_cast<bool*
>(release_context);
179 [](
size_t width,
size_t height,
184 FlutterOpenGLTexture flutter_texture = {};
188 EXPECT_CALL(*gl.get(), GenTextures(1, _))
190 .WillOnce([](GLsizei n, GLuint* textures) { textures[0] = 1; });
191 EXPECT_CALL(*gl.get(), BindTexture).Times(1);
192 EXPECT_CALL(*gl.get(), TexParameteri).Times(AtLeast(1));
193 EXPECT_CALL(*gl.get(), TexImage2D).Times(1);
194 EXPECT_CALL(*gl.get(), DeleteTextures(1, _)).Times(1);
199 EXPECT_EQ(flutter_texture.width, width);
200 EXPECT_EQ(flutter_texture.height, height);
201 EXPECT_EQ(flutter_texture.target, GL_TEXTURE_2D);
202 EXPECT_TRUE(release_callback_called);
205 TEST(FlutterWindowsTextureRegistrarTest, PopulateD3dTextureWithHandle) {
206 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
207 auto gl = std::make_shared<egl::MockProcTable>();
212 auto d3d_texture = CreateD3dTexture(engine.get(), width, height);
213 EXPECT_TRUE(d3d_texture);
215 ComPtr<IDXGIResource> shared_resource;
216 EXPECT_TRUE(SUCCEEDED(d3d_texture.As(&shared_resource)));
218 HANDLE shared_handle;
219 EXPECT_TRUE(SUCCEEDED(shared_resource->GetSharedHandle(&shared_handle)));
221 bool release_callback_called =
false;
224 surface_descriptor.
handle = shared_handle;
229 bool* called =
reinterpret_cast<bool*
>(release_context);
241 [](
size_t width,
size_t height,
247 FlutterOpenGLTexture flutter_texture = {};
251 EXPECT_CALL(*gl.get(), GenTextures(1, _))
253 .WillOnce([](GLsizei n, GLuint* textures) { textures[0] = 1; });
254 EXPECT_CALL(*gl.get(), BindTexture).Times(1);
255 EXPECT_CALL(*gl.get(), TexParameteri).Times(AtLeast(1));
256 EXPECT_CALL(*gl.get(), DeleteTextures(1, _)).Times(1);
261 EXPECT_EQ(flutter_texture.width, width);
262 EXPECT_EQ(flutter_texture.height, height);
263 EXPECT_EQ(flutter_texture.target, GL_TEXTURE_2D);
264 EXPECT_TRUE(release_callback_called);
267 TEST(FlutterWindowsTextureRegistrarTest, PopulateD3dTexture) {
268 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
269 auto gl = std::make_shared<egl::MockProcTable>();
274 auto d3d_texture = CreateD3dTexture(engine.get(), width, height);
275 EXPECT_TRUE(d3d_texture);
277 bool release_callback_called =
false;
280 surface_descriptor.
handle = d3d_texture.Get();
285 bool* called =
reinterpret_cast<bool*
>(release_context);
297 [](
size_t width,
size_t height,
303 FlutterOpenGLTexture flutter_texture = {};
307 EXPECT_CALL(*gl.get(), GenTextures(1, _))
309 .WillOnce([](GLsizei n, GLuint* textures) { textures[0] = 1; });
310 EXPECT_CALL(*gl.get(), BindTexture).Times(1);
311 EXPECT_CALL(*gl.get(), TexParameteri).Times(AtLeast(1));
312 EXPECT_CALL(*gl.get(), DeleteTextures(1, _)).Times(1);
317 EXPECT_EQ(flutter_texture.width, width);
318 EXPECT_EQ(flutter_texture.height, height);
319 EXPECT_EQ(flutter_texture.target, GL_TEXTURE_2D);
320 EXPECT_TRUE(release_callback_called);
323 TEST(FlutterWindowsTextureRegistrarTest, PopulateInvalidTexture) {
324 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
325 auto gl = std::make_shared<egl::MockProcTable>();
330 EXPECT_FALSE(result);
333 TEST(FlutterWindowsTextureRegistrarTest,
334 UnregisterTextureWithEngineDownInvokesCallback) {
335 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
336 auto gl = std::make_shared<egl::MockProcTable>();
340 fml::AutoResetWaitableEvent latch;