Flutter Windows Embedder
flutter_windows_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <dxgi.h>
8 #include <wrl/client.h>
9 #include <thread>
10 
11 #include "flutter/fml/synchronization/count_down_latch.h"
12 #include "flutter/fml/synchronization/waitable_event.h"
14 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
16 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
17 #include "flutter/shell/platform/windows/testing/windows_test.h"
18 #include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
19 #include "flutter/shell/platform/windows/testing/windows_test_context.h"
21 #include "flutter/testing/stream_capture.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "third_party/tonic/converter/dart_converter.h"
25 
26 namespace flutter {
27 namespace testing {
28 
29 namespace {
30 
31 // An EGL manager that initializes EGL but fails to create surfaces.
32 class HalfBrokenEGLManager : public egl::Manager {
33  public:
34  HalfBrokenEGLManager() : egl::Manager(/*enable_impeller = */ false) {}
35 
36  std::unique_ptr<egl::WindowSurface>
37  CreateWindowSurface(HWND hwnd, size_t width, size_t height) override {
38  return nullptr;
39  }
40 };
41 
42 class MockWindowsLifecycleManager : public WindowsLifecycleManager {
43  public:
44  MockWindowsLifecycleManager(FlutterWindowsEngine* engine)
45  : WindowsLifecycleManager(engine) {}
46 
47  MOCK_METHOD(void, SetLifecycleState, (AppLifecycleState), (override));
48 };
49 
50 } // namespace
51 
52 // Verify that we can fetch a texture registrar.
53 // Prevent regression: https://github.com/flutter/flutter/issues/86617
54 TEST(WindowsNoFixtureTest, GetTextureRegistrar) {
55  FlutterDesktopEngineProperties properties = {};
56  properties.assets_path = L"";
57  properties.icu_data_path = L"icudtl.dat";
58  auto engine = FlutterDesktopEngineCreate(&properties);
59  ASSERT_NE(engine, nullptr);
60  auto texture_registrar = FlutterDesktopEngineGetTextureRegistrar(engine);
61  EXPECT_NE(texture_registrar, nullptr);
63 }
64 
65 // Verify we can successfully launch main().
66 TEST_F(WindowsTest, LaunchMain) {
67  auto& context = GetContext();
68  WindowsConfigBuilder builder(context);
69  ViewControllerPtr controller{builder.Run()};
70  ASSERT_NE(controller, nullptr);
71 }
72 
73 // Verify there is no unexpected output from launching main.
74 TEST_F(WindowsTest, LaunchMainHasNoOutput) {
75  // Replace stdout & stderr stream buffers with our own.
76  StreamCapture stdout_capture(&std::cout);
77  StreamCapture stderr_capture(&std::cerr);
78 
79  auto& context = GetContext();
80  WindowsConfigBuilder builder(context);
81  ViewControllerPtr controller{builder.Run()};
82  ASSERT_NE(controller, nullptr);
83 
84  stdout_capture.Stop();
85  stderr_capture.Stop();
86 
87  // Verify stdout & stderr have no output.
88  EXPECT_TRUE(stdout_capture.GetOutput().empty());
89  EXPECT_TRUE(stderr_capture.GetOutput().empty());
90 }
91 
92 // Verify we can successfully launch a custom entry point.
93 TEST_F(WindowsTest, LaunchCustomEntrypoint) {
94  auto& context = GetContext();
95  WindowsConfigBuilder builder(context);
96  builder.SetDartEntrypoint("customEntrypoint");
97  ViewControllerPtr controller{builder.Run()};
98  ASSERT_NE(controller, nullptr);
99 }
100 
101 // Verify that engine launches with the custom entrypoint specified in the
102 // FlutterDesktopEngineRun parameter when no entrypoint is specified in
103 // FlutterDesktopEngineProperties.dart_entrypoint.
104 //
105 // TODO(cbracken): https://github.com/flutter/flutter/issues/109285
106 TEST_F(WindowsTest, LaunchCustomEntrypointInEngineRunInvocation) {
107  auto& context = GetContext();
108  WindowsConfigBuilder builder(context);
109  EnginePtr engine{builder.InitializeEngine()};
110  ASSERT_NE(engine, nullptr);
111 
112  ASSERT_TRUE(FlutterDesktopEngineRun(engine.get(), "customEntrypoint"));
113 }
114 
115 // Verify that the engine can launch in headless mode.
116 TEST_F(WindowsTest, LaunchHeadlessEngine) {
117  auto& context = GetContext();
118  WindowsConfigBuilder builder(context);
119  EnginePtr engine{builder.RunHeadless()};
120  ASSERT_NE(engine, nullptr);
121 }
122 
123 // Verify that the engine can return to headless mode.
124 TEST_F(WindowsTest, EngineCanTransitionToHeadless) {
125  auto& context = GetContext();
126  WindowsConfigBuilder builder(context);
127  EnginePtr engine{builder.RunHeadless()};
128  ASSERT_NE(engine, nullptr);
129 
130  // Create and then destroy a view controller that does not own its engine.
131  // This causes the engine to transition back to headless mode.
132  {
134  ViewControllerPtr controller{
135  FlutterDesktopEngineCreateViewController(engine.get(), &properties)};
136 
137  ASSERT_NE(controller, nullptr);
138  }
139 
140  // The engine is back in headless mode now.
141  ASSERT_NE(engine, nullptr);
142 }
143 
144 // Verify that accessibility features are initialized when a view is created.
145 TEST_F(WindowsTest, LaunchRefreshesAccessibility) {
146  auto& context = GetContext();
147  WindowsConfigBuilder builder(context);
148  EnginePtr engine{builder.InitializeEngine()};
149  EngineModifier modifier{
150  reinterpret_cast<FlutterWindowsEngine*>(engine.get())};
151 
152  auto called = false;
153  modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
154  UpdateAccessibilityFeatures, ([&called](auto engine, auto flags) {
155  called = true;
156  return kSuccess;
157  }));
158 
159  ViewControllerPtr controller{
160  FlutterDesktopViewControllerCreate(0, 0, engine.release())};
161 
162  ASSERT_TRUE(called);
163 }
164 
165 // Verify that engine fails to launch when a conflicting entrypoint in
166 // FlutterDesktopEngineProperties.dart_entrypoint and the
167 // FlutterDesktopEngineRun parameter.
168 //
169 // TODO(cbracken): https://github.com/flutter/flutter/issues/109285
170 TEST_F(WindowsTest, LaunchConflictingCustomEntrypoints) {
171  auto& context = GetContext();
172  WindowsConfigBuilder builder(context);
173  builder.SetDartEntrypoint("customEntrypoint");
174  EnginePtr engine{builder.InitializeEngine()};
175  ASSERT_NE(engine, nullptr);
176 
177  ASSERT_FALSE(FlutterDesktopEngineRun(engine.get(), "conflictingEntrypoint"));
178 }
179 
180 // Verify that native functions can be registered and resolved.
181 TEST_F(WindowsTest, VerifyNativeFunction) {
182  auto& context = GetContext();
183  WindowsConfigBuilder builder(context);
184  builder.SetDartEntrypoint("verifyNativeFunction");
185 
186  fml::AutoResetWaitableEvent latch;
187  auto native_entry =
188  CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { latch.Signal(); });
189  context.AddNativeFunction("Signal", native_entry);
190 
191  ViewControllerPtr controller{builder.Run()};
192  ASSERT_NE(controller, nullptr);
193 
194  // Wait until signal has been called.
195  latch.Wait();
196 }
197 
198 // Verify that native functions that pass parameters can be registered and
199 // resolved.
200 TEST_F(WindowsTest, VerifyNativeFunctionWithParameters) {
201  auto& context = GetContext();
202  WindowsConfigBuilder builder(context);
203  builder.SetDartEntrypoint("verifyNativeFunctionWithParameters");
204 
205  bool bool_value = false;
206  fml::AutoResetWaitableEvent latch;
207  auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
208  auto handle = Dart_GetNativeBooleanArgument(args, 0, &bool_value);
209  ASSERT_FALSE(Dart_IsError(handle));
210  latch.Signal();
211  });
212  context.AddNativeFunction("SignalBoolValue", native_entry);
213 
214  ViewControllerPtr controller{builder.Run()};
215  ASSERT_NE(controller, nullptr);
216 
217  // Wait until signalBoolValue has been called.
218  latch.Wait();
219  EXPECT_TRUE(bool_value);
220 }
221 
222 // Verify that Platform.executable returns the executable name.
223 TEST_F(WindowsTest, PlatformExecutable) {
224  auto& context = GetContext();
225  WindowsConfigBuilder builder(context);
226  builder.SetDartEntrypoint("readPlatformExecutable");
227 
228  std::string executable_name;
229  fml::AutoResetWaitableEvent latch;
230  auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
231  auto handle = Dart_GetNativeArgument(args, 0);
232  ASSERT_FALSE(Dart_IsError(handle));
233  executable_name = tonic::DartConverter<std::string>::FromDart(handle);
234  latch.Signal();
235  });
236  context.AddNativeFunction("SignalStringValue", native_entry);
237 
238  ViewControllerPtr controller{builder.Run()};
239  ASSERT_NE(controller, nullptr);
240 
241  // Wait until signalStringValue has been called.
242  latch.Wait();
243  EXPECT_EQ(executable_name, "flutter_windows_unittests.exe");
244 }
245 
246 // Verify that native functions that return values can be registered and
247 // resolved.
248 TEST_F(WindowsTest, VerifyNativeFunctionWithReturn) {
249  auto& context = GetContext();
250  WindowsConfigBuilder builder(context);
251  builder.SetDartEntrypoint("verifyNativeFunctionWithReturn");
252 
253  bool bool_value_to_return = true;
254  fml::CountDownLatch latch(2);
255  auto bool_return_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
256  Dart_SetBooleanReturnValue(args, bool_value_to_return);
257  latch.CountDown();
258  });
259  context.AddNativeFunction("SignalBoolReturn", bool_return_entry);
260 
261  bool bool_value_passed = false;
262  auto bool_pass_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
263  auto handle = Dart_GetNativeBooleanArgument(args, 0, &bool_value_passed);
264  ASSERT_FALSE(Dart_IsError(handle));
265  latch.CountDown();
266  });
267  context.AddNativeFunction("SignalBoolValue", bool_pass_entry);
268 
269  ViewControllerPtr controller{builder.Run()};
270  ASSERT_NE(controller, nullptr);
271 
272  // Wait until signalBoolReturn and signalBoolValue have been called.
273  latch.Wait();
274  EXPECT_TRUE(bool_value_passed);
275 }
276 
277 // Verify the next frame callback is executed.
278 TEST_F(WindowsTest, NextFrameCallback) {
279  struct Captures {
280  fml::AutoResetWaitableEvent frame_scheduled_latch;
281  fml::AutoResetWaitableEvent frame_drawn_latch;
282  std::thread::id thread_id;
283  };
284  Captures captures;
285 
286  CreateNewThread("test_platform_thread")->PostTask([&]() {
287  captures.thread_id = std::this_thread::get_id();
288 
289  auto& context = GetContext();
290  WindowsConfigBuilder builder(context);
291  builder.SetDartEntrypoint("drawHelloWorld");
292 
293  auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
294  ASSERT_FALSE(captures.frame_drawn_latch.IsSignaledForTest());
295  captures.frame_scheduled_latch.Signal();
296  });
297  context.AddNativeFunction("NotifyFirstFrameScheduled", native_entry);
298 
299  ViewControllerPtr controller{builder.Run()};
300  ASSERT_NE(controller, nullptr);
301 
302  auto engine = FlutterDesktopViewControllerGetEngine(controller.get());
303 
305  engine,
306  [](void* user_data) {
307  auto captures = static_cast<Captures*>(user_data);
308 
309  ASSERT_TRUE(captures->frame_scheduled_latch.IsSignaledForTest());
310 
311  // Callback should execute on platform thread.
312  ASSERT_EQ(std::this_thread::get_id(), captures->thread_id);
313 
314  // Signal the test passed and end the Windows message loop.
315  captures->frame_drawn_latch.Signal();
316  ::PostQuitMessage(0);
317  },
318  &captures);
319 
320  // Pump messages for the Windows platform task runner.
321  ::MSG msg;
322  while (::GetMessage(&msg, nullptr, 0, 0)) {
323  ::TranslateMessage(&msg);
324  ::DispatchMessage(&msg);
325  }
326  });
327 
328  captures.frame_drawn_latch.Wait();
329 }
330 
331 // Implicit view has the implicit view ID.
332 TEST_F(WindowsTest, GetViewId) {
333  auto& context = GetContext();
334  WindowsConfigBuilder builder(context);
335  ViewControllerPtr controller{builder.Run()};
336  ASSERT_NE(controller, nullptr);
337  FlutterDesktopViewId view_id =
338  FlutterDesktopViewControllerGetViewId(controller.get());
339 
340  ASSERT_EQ(view_id, static_cast<FlutterDesktopViewId>(kImplicitViewId));
341 }
342 
343 TEST_F(WindowsTest, GetGraphicsAdapter) {
344  auto& context = GetContext();
345  WindowsConfigBuilder builder(context);
346  ViewControllerPtr controller{builder.Run()};
347  ASSERT_NE(controller, nullptr);
348  auto view = FlutterDesktopViewControllerGetView(controller.get());
349 
350  Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
351  dxgi_adapter = FlutterDesktopViewGetGraphicsAdapter(view);
352  ASSERT_NE(dxgi_adapter, nullptr);
353  DXGI_ADAPTER_DESC desc{};
354  ASSERT_TRUE(SUCCEEDED(dxgi_adapter->GetDesc(&desc)));
355 }
356 
357 // Implicit view has the implicit view ID.
358 TEST_F(WindowsTest, PluginRegistrarGetImplicitView) {
359  auto& context = GetContext();
360  WindowsConfigBuilder builder(context);
361  ViewControllerPtr controller{builder.Run()};
362  ASSERT_NE(controller, nullptr);
363 
364  FlutterDesktopEngineRef engine =
365  FlutterDesktopViewControllerGetEngine(controller.get());
367  FlutterDesktopEngineGetPluginRegistrar(engine, "foo_bar");
368  FlutterDesktopViewRef implicit_view =
370 
371  ASSERT_NE(implicit_view, nullptr);
372 }
373 
374 TEST_F(WindowsTest, PluginRegistrarGetView) {
375  auto& context = GetContext();
376  WindowsConfigBuilder builder(context);
377  ViewControllerPtr controller{builder.Run()};
378  ASSERT_NE(controller, nullptr);
379 
380  FlutterDesktopEngineRef engine =
381  FlutterDesktopViewControllerGetEngine(controller.get());
383  FlutterDesktopEngineGetPluginRegistrar(engine, "foo_bar");
384 
385  FlutterDesktopViewId view_id =
386  FlutterDesktopViewControllerGetViewId(controller.get());
387  FlutterDesktopViewRef view =
388  FlutterDesktopPluginRegistrarGetViewById(registrar, view_id);
389 
391  registrar, static_cast<FlutterDesktopViewId>(123));
392 
393  ASSERT_NE(view, nullptr);
394  ASSERT_EQ(view_123, nullptr);
395 }
396 
397 TEST_F(WindowsTest, PluginRegistrarGetViewHeadless) {
398  auto& context = GetContext();
399  WindowsConfigBuilder builder(context);
400  EnginePtr engine{builder.RunHeadless()};
401  ASSERT_NE(engine, nullptr);
402 
404  FlutterDesktopEngineGetPluginRegistrar(engine.get(), "foo_bar");
405 
406  FlutterDesktopViewRef implicit_view =
409  registrar, static_cast<FlutterDesktopViewId>(123));
410 
411  ASSERT_EQ(implicit_view, nullptr);
412  ASSERT_EQ(view_123, nullptr);
413 }
414 
415 // Verify the app does not crash if EGL initializes successfully but
416 // the rendering surface cannot be created.
417 TEST_F(WindowsTest, SurfaceOptional) {
418  auto& context = GetContext();
419  WindowsConfigBuilder builder(context);
420  EnginePtr engine{builder.InitializeEngine()};
421  EngineModifier modifier{
422  reinterpret_cast<FlutterWindowsEngine*>(engine.get())};
423 
424  auto egl_manager = std::make_unique<HalfBrokenEGLManager>();
425  ASSERT_TRUE(egl_manager->IsValid());
426  modifier.SetEGLManager(std::move(egl_manager));
427 
428  ViewControllerPtr controller{
429  FlutterDesktopViewControllerCreate(0, 0, engine.release())};
430 
431  ASSERT_NE(controller, nullptr);
432 }
433 
434 // Verify the app produces the expected lifecycle events.
435 TEST_F(WindowsTest, Lifecycle) {
436  auto& context = GetContext();
437  WindowsConfigBuilder builder(context);
438  EnginePtr engine{builder.InitializeEngine()};
439  auto windows_engine = reinterpret_cast<FlutterWindowsEngine*>(engine.get());
440  EngineModifier modifier{windows_engine};
441 
442  auto lifecycle_manager =
443  std::make_unique<MockWindowsLifecycleManager>(windows_engine);
444  auto lifecycle_manager_ptr = lifecycle_manager.get();
445  modifier.SetLifecycleManager(std::move(lifecycle_manager));
446 
447  EXPECT_CALL(*lifecycle_manager_ptr,
448  SetLifecycleState(AppLifecycleState::kResumed))
449  .WillOnce([lifecycle_manager_ptr](AppLifecycleState state) {
450  lifecycle_manager_ptr->WindowsLifecycleManager::SetLifecycleState(
451  state);
452  });
453 
454  EXPECT_CALL(*lifecycle_manager_ptr,
455  SetLifecycleState(AppLifecycleState::kHidden))
456  .WillOnce([lifecycle_manager_ptr](AppLifecycleState state) {
457  lifecycle_manager_ptr->WindowsLifecycleManager::SetLifecycleState(
458  state);
459  });
460 
461  // Create a controller. This launches the engine and sets the app lifecycle
462  // to the "resumed" state.
463  ViewControllerPtr controller{
464  FlutterDesktopViewControllerCreate(0, 0, engine.release())};
465 
466  FlutterDesktopViewRef view =
467  FlutterDesktopViewControllerGetView(controller.get());
468  ASSERT_NE(view, nullptr);
469 
470  HWND hwnd = FlutterDesktopViewGetHWND(view);
471  ASSERT_NE(hwnd, nullptr);
472 
473  // Give the window a non-zero size to show it. This does not change the app
474  // lifecycle directly. However, destroying the view will now result in a
475  // "hidden" app lifecycle event.
476  ::MoveWindow(hwnd, /* X */ 0, /* Y */ 0, /* nWidth*/ 100, /* nHeight*/ 100,
477  /* bRepaint*/ false);
478 }
479 
480 } // namespace testing
481 } // namespace flutter
flutter::kImplicitViewId
constexpr FlutterViewId kImplicitViewId
Definition: flutter_windows_engine.h:54
FlutterDesktopViewGetHWND
HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view)
Definition: flutter_windows.cc:241
flutter::AppLifecycleState::kHidden
@ kHidden
FlutterDesktopViewControllerGetView
FlutterDesktopViewRef FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef ref)
Definition: flutter_windows.cc:148
FlutterDesktopEngineGetTextureRegistrar
FlutterDesktopTextureRegistrarRef FlutterDesktopEngineGetTextureRegistrar(FlutterDesktopEngineRef engine)
Definition: flutter_windows.cc:228
FlutterDesktopPluginRegistrarGetView
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(FlutterDesktopPluginRegistrarRef registrar)
Definition: flutter_windows.cc:285
FlutterDesktopEngineProperties
Definition: flutter_windows.h:39
windows_lifecycle_manager.h
FlutterDesktopViewId
int64_t FlutterDesktopViewId
Definition: flutter_windows.h:36
user_data
void * user_data
Definition: flutter_windows_view_unittests.cc:52
flutter::FlutterWindowsEngine
Definition: flutter_windows_engine.h:89
FlutterDesktopViewControllerProperties
Definition: flutter_windows_internal.h:18
FlutterDesktopEngineProperties::icu_data_path
const wchar_t * icu_data_path
Definition: flutter_windows.h:48
FlutterDesktopEngineGetPluginRegistrar
FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine, const char *plugin_name)
Definition: flutter_windows.cc:213
flutter::FlutterWindowsEngine::UpdateAccessibilityFeatures
void UpdateAccessibilityFeatures()
Definition: flutter_windows_engine.cc:795
FlutterDesktopViewControllerGetViewId
FlutterDesktopViewId FlutterDesktopViewControllerGetViewId(FlutterDesktopViewControllerRef ref)
Definition: flutter_windows.cc:136
flutter::testing::MockWindowsLifecycleManager::MockWindowsLifecycleManager
MockWindowsLifecycleManager(FlutterWindowsEngine *engine)
Definition: flutter_windows_engine_unittests.cc:751
app_lifecycle_state.h
FlutterDesktopViewRef
struct FlutterDesktopView * FlutterDesktopViewRef
Definition: flutter_windows.h:29
FlutterDesktopEngineRef
struct FlutterDesktopEngine * FlutterDesktopEngineRef
Definition: flutter_windows.h:33
flutter::WindowsLifecycleManager::SetLifecycleState
virtual void SetLifecycleState(AppLifecycleState state)
Definition: windows_lifecycle_manager.cc:195
flutter::WindowsLifecycleManager::WindowsLifecycleManager
WindowsLifecycleManager(FlutterWindowsEngine *engine)
Definition: windows_lifecycle_manager.cc:16
flutter
Definition: accessibility_bridge_windows.cc:11
FlutterDesktopViewControllerCreate
FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(int width, int height, FlutterDesktopEngineRef engine)
Definition: flutter_windows.cc:117
FlutterDesktopEngineDestroy
bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine_ref)
Definition: flutter_windows.cc:185
manager.h
FlutterDesktopEngineCreate
FlutterDesktopEngineRef FlutterDesktopEngineCreate(const FlutterDesktopEngineProperties *engine_properties)
Definition: flutter_windows.cc:178
FlutterDesktopViewControllerGetEngine
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef ref)
Definition: flutter_windows.cc:142
flutter::AppLifecycleState::kResumed
@ kResumed
flutter_windows.h
flutter::testing::TEST
TEST(AccessibilityBridgeWindows, GetParent)
Definition: accessibility_bridge_windows_unittests.cc:237
flutter::AppLifecycleState
AppLifecycleState
Definition: app_lifecycle_state.h:32
FlutterDesktopEngineSetNextFrameCallback
void FlutterDesktopEngineSetNextFrameCallback(FlutterDesktopEngineRef engine, VoidCallback callback, void *user_data)
Definition: flutter_windows.cc:234
FlutterDesktopEngineCreateViewController
FlutterDesktopViewControllerRef FlutterDesktopEngineCreateViewController(FlutterDesktopEngineRef engine, const FlutterDesktopViewControllerProperties *properties)
Definition: flutter_windows.cc:124
flutter::testing::MockWindowsLifecycleManager::MOCK_METHOD
MOCK_METHOD(void, Quit,(std::optional< HWND >, std::optional< WPARAM >, std::optional< LPARAM >, UINT),(override))
flutter::testing::TEST_F
TEST_F(CompositorOpenGLTest, CreateBackingStore)
Definition: compositor_opengl_unittests.cc:128
FlutterDesktopViewGetGraphicsAdapter
IDXGIAdapter * FlutterDesktopViewGetGraphicsAdapter(FlutterDesktopViewRef view)
Definition: flutter_windows.cc:245
FlutterDesktopEngineProperties::assets_path
const wchar_t * assets_path
Definition: flutter_windows.h:43
FlutterDesktopPluginRegistrar
Definition: window_state.h:23
FlutterDesktopEngineRun
bool FlutterDesktopEngineRun(FlutterDesktopEngineRef engine, const char *entry_point)
Definition: flutter_windows.cc:195
FlutterDesktopPluginRegistrarGetViewById
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetViewById(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopViewId view_id)
Definition: flutter_windows.cc:290