Flutter Engine
 
Loading...
Searching...
No Matches
flutter_windows.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 <io.h>
8
9#include <algorithm>
10#include <chrono>
11#include <cstdlib>
12#include <filesystem>
13#include <memory>
14#include <vector>
15
28
29static_assert(FLUTTER_ENGINE_VERSION == 1, "");
30
31// Returns the engine corresponding to the given opaque API handle.
36
37// Returns the opaque API handle for the given engine instance.
42
47
50 return reinterpret_cast<FlutterDesktopViewControllerRef>(view_controller);
51}
52
53// Returns the view corresponding to the given opaque API handle.
57
58// Returns the opaque API handle for the given view instance.
62
63// Returns the texture registrar corresponding to the given opaque API handle.
68
69// Returns the opaque API handle for the given texture registrar instance.
74
75// Creates a view controller that might own the engine.
76//
77// If `owns_engine` is true, then the returned `FlutterDesktopViewControllerRef`
78// owns `engine_ref` and will deallocate `engine_ref` upon its own destruction.
80 FlutterDesktopEngineRef engine_ref,
81 int width,
82 int height,
83 bool owns_engine) {
84 flutter::FlutterWindowsEngine* engine_ptr = EngineFromHandle(engine_ref);
85 std::unique_ptr<flutter::WindowBindingHandler> window_wrapper =
86 std::make_unique<flutter::FlutterWindow>(
87 width, height, engine_ptr->display_manager(),
88 engine_ptr->windows_proc_table());
89
90 std::unique_ptr<flutter::FlutterWindowsEngine> engine;
91 if (owns_engine) {
92 engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);
93 }
94
95 std::unique_ptr<flutter::FlutterWindowsView> view =
96 engine_ptr->CreateView(std::move(window_wrapper));
97 if (!view) {
98 return nullptr;
99 }
100
101 auto controller = std::make_unique<flutter::FlutterWindowsViewController>(
102 std::move(engine), std::move(view));
103
104 // Launch the engine if it is not running already.
105 if (!controller->engine()->running()) {
106 if (!controller->engine()->Run()) {
107 return nullptr;
108 }
109 }
110
111 // Must happen after engine is running.
112 controller->view()->SendInitialBounds();
113
114 // The Windows embedder listens to accessibility updates using the
115 // view's HWND. The embedder's accessibility features may be stale if
116 // the app was in headless mode.
117 controller->engine()->UpdateAccessibilityFeatures();
118
119 return HandleForViewController(controller.release());
120}
121
128
135
137 auto controller = ViewControllerFromHandle(ref);
138 controller->Destroy();
139 delete controller;
140}
141
144 auto controller = ViewControllerFromHandle(ref);
145 return static_cast<FlutterDesktopViewId>(controller->view()->view_id());
146}
147
153
159
162 auto controller = ViewControllerFromHandle(ref);
163 controller->view()->ForceRedraw();
164}
165
168 HWND hwnd,
170 WPARAM wparam,
171 LPARAM lparam,
172 LRESULT* result) {
173 auto controller = ViewControllerFromHandle(ref);
174 std::optional<LRESULT> delegate_result =
175 controller->engine()
176 ->window_proc_delegate_manager()
177 ->OnTopLevelWindowProc(hwnd, message, wparam, lparam);
178 if (delegate_result) {
179 *result = *delegate_result;
180 }
181 return delegate_result.has_value();
182}
183
185 const FlutterDesktopEngineProperties* engine_properties) {
186 flutter::FlutterProjectBundle project(*engine_properties);
187 auto engine = std::make_unique<flutter::FlutterWindowsEngine>(project);
188 return HandleForEngine(engine.release());
189}
190
193 bool result = true;
194 if (engine->running()) {
195 result = engine->Stop();
196 }
197 delete engine;
198 return result;
199}
200
206
208 const char* entry_point) {
209 std::string_view entry_point_view{""};
210 if (entry_point != nullptr) {
211 entry_point_view = entry_point;
212 }
213
214 return EngineFromHandle(engine)->Run(entry_point_view);
215}
216
218 return std::chrono::nanoseconds::max().count();
219}
220
224
227 const char* plugin_name) {
228 // Currently, one registrar acts as the registrar for all plugins, so the
229 // name is ignored. It is part of the API to reduce churn in the future when
230 // aligning more closely with the Flutter registrar system.
231
233}
234
239
245
252
256
258 auto egl_manager = ViewFromHandle(view)->GetEngine()->egl_manager();
259 if (egl_manager) {
260 Microsoft::WRL::ComPtr<ID3D11Device> d3d_device;
261 Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device;
262 if (egl_manager->GetDevice(d3d_device.GetAddressOf()) &&
263 SUCCEEDED(d3d_device.As(&dxgi_device))) {
264 IDXGIAdapter* adapter;
265 if (SUCCEEDED(dxgi_device->GetAdapter(&adapter))) {
266 return adapter;
267 }
268 }
269 }
270 return nullptr;
271}
272
275 HWND hwnd,
277 WPARAM wparam,
278 LPARAM lparam,
279 LRESULT* result) {
280 std::optional<LRESULT> lresult =
282 wparam, lparam);
283 if (result && lresult.has_value()) {
284 *result = lresult.value();
285 }
286 return lresult.has_value();
287}
288
291 const char* view_type_name,
293 // TODO(schectman): forward to platform view manager.
294 // https://github.com/flutter/flutter/issues/143375
295}
296
301
307
311 void* user_data) {
312 registrar->engine->window_proc_delegate_manager()
313 ->RegisterTopLevelWindowProcDelegate(delegate, user_data);
314}
315
319 registrar->engine->window_proc_delegate_manager()
320 ->UnregisterTopLevelWindowProcDelegate(delegate);
321}
322
324 return flutter::GetDpiForHWND(hwnd);
325}
326
328 return flutter::GetDpiForMonitor(monitor);
329}
330
332 FILE* unused;
333 if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
334 _dup2(_fileno(stdout), 1);
335 }
336 if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
337 _dup2(_fileno(stdout), 2);
338 }
339 std::ios::sync_with_stdio();
340}
341
342// Implementations of common/ API methods.
343
348
352 registrar->engine->AddPluginRegistrarDestructionCallback(callback, registrar);
353}
354
356 const char* channel,
357 const uint8_t* message,
358 const size_t message_size,
359 const FlutterDesktopBinaryReply reply,
360 void* user_data) {
362 << "Messenger must reference a running engine to send a message";
363
365 ->GetEngine()
366 ->SendPlatformMessage(channel, message, message_size, reply, user_data);
367}
368
370 const char* channel,
371 const uint8_t* message,
372 const size_t message_size) {
374 message_size, nullptr, nullptr);
375}
376
380 const uint8_t* data,
381 size_t data_length) {
383 << "Messenger must reference a running engine to send a response";
384
386 ->GetEngine()
387 ->SendPlatformMessageResponse(handle, data, data_length);
388}
389
391 const char* channel,
393 void* user_data) {
395 << "Messenger must reference a running engine to set a callback";
396
398 ->GetEngine()
401}
402
409
413
418
424
428
433
440
443 int64_t texture_id,
444 void (*callback)(void* user_data),
445 void* user_data) {
447 if (callback) {
448 registrar->UnregisterTexture(
450 return;
451 }
452 registrar->UnregisterTexture(texture_id);
453}
454
FlutterDesktopMessengerRef ToRef()
Convert to FlutterDesktopMessengerRef.
flutter::FlutterWindowsEngine * GetEngine() const
Getter for the engine field.
static FlutterDesktopMessenger * FromRef(FlutterDesktopMessengerRef ref)
Convert from FlutterDesktopMessengerRef.
FlutterDesktopMessengerRef messenger()
bool SendPlatformMessage(const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
std::optional< LRESULT > ProcessExternalWindowMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
std::shared_ptr< WindowsProcTable > windows_proc_table()
IncomingMessageDispatcher * message_dispatcher()
void SendPlatformMessageResponse(const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
static FlutterWindowsEngine * GetEngineForId(int64_t engine_id)
std::shared_ptr< DisplayManagerWin32 > display_manager()
std::unique_ptr< FlutterWindowsView > CreateView(std::unique_ptr< WindowBindingHandler > window)
void SetNextFrameCallback(fml::closure callback)
FlutterDesktopPluginRegistrarRef GetRegistrar()
int64_t RegisterTexture(const FlutterDesktopTextureInfo *texture_info)
Controls a view that displays Flutter content.
FlutterWindowsEngine * GetEngine() const
void SetMessageCallback(const std::string &channel, FlutterDesktopMessageCallback callback, void *user_data)
void(* VoidCallback)(void *)
Definition embedder.h:409
#define FLUTTER_ENGINE_VERSION
Definition embedder.h:70
FlutterEngine engine
Definition main.cc:84
FlView * view
const gchar * channel
G_BEGIN_DECLS GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
#define FLUTTER_EXPORT
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
void(* FlutterDesktopMessageCallback)(FlutterDesktopMessengerRef, const FlutterDesktopMessage *, void *)
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
struct FlutterDesktopTextureRegistrar * FlutterDesktopTextureRegistrarRef
void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char *channel, FlutterDesktopMessageCallback callback, void *user_data)
UINT FlutterDesktopGetDpiForHWND(HWND hwnd)
void FlutterDesktopViewControllerForceRedraw(FlutterDesktopViewControllerRef ref)
static FlutterDesktopTextureRegistrarRef HandleForTextureRegistrar(flutter::FlutterWindowsTextureRegistrar *registrar)
FlutterDesktopEngineRef FlutterDesktopEngineCreate(const FlutterDesktopEngineProperties *engine_properties)
void FlutterDesktopEngineReloadSystemFonts(FlutterDesktopEngineRef engine)
bool FlutterDesktopEngineProcessExternalWindowMessage(FlutterDesktopEngineRef engine, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT *result)
static flutter::FlutterWindowsEngine * EngineFromHandle(FlutterDesktopEngineRef ref)
void FlutterDesktopResyncOutputStreams()
void FlutterDesktopEngineRegisterPlatformViewType(FlutterDesktopEngineRef engine, const char *view_type_name, FlutterPlatformViewTypeEntry view_type)
static FlutterDesktopViewRef HandleForView(flutter::FlutterWindowsView *view)
static FlutterDesktopViewControllerRef CreateViewController(FlutterDesktopEngineRef engine_ref, int width, int height, bool owns_engine)
FLUTTER_EXPORT FlutterDesktopEngineRef FlutterDesktopEngineForId(int64_t engine_id)
void FlutterDesktopMessengerSendResponse(FlutterDesktopMessengerRef messenger, const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetViewById(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopViewId view_id)
static FlutterDesktopEngineRef HandleForEngine(flutter::FlutterWindowsEngine *engine)
bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
void FlutterDesktopPluginRegistrarSetDestructionHandler(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopOnPluginRegistrarDestroyed callback)
FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine, const char *plugin_name)
int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, const FlutterDesktopTextureInfo *texture_info)
static FlutterDesktopViewControllerRef HandleForViewController(flutter::FlutterWindowsViewController *view_controller)
bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id)
FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(int width, int height, FlutterDesktopEngineRef engine)
FlutterDesktopMessengerRef FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger)
void FlutterDesktopTextureRegistrarUnregisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id, void(*callback)(void *user_data), void *user_data)
bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine_ref)
UINT FlutterDesktopGetDpiForMonitor(HMONITOR monitor)
bool FlutterDesktopMessengerIsAvailable(FlutterDesktopMessengerRef messenger)
bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size)
FlutterDesktopTextureRegistrarRef FlutterDesktopEngineGetTextureRegistrar(FlutterDesktopEngineRef engine)
void FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate)
bool FlutterDesktopViewControllerHandleTopLevelWindowProc(FlutterDesktopViewControllerRef ref, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT *result)
static flutter::FlutterWindowsTextureRegistrar * TextureRegistrarFromHandle(FlutterDesktopTextureRegistrarRef ref)
uint64_t FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine)
static flutter::FlutterWindowsView * ViewFromHandle(FlutterDesktopViewRef ref)
void FlutterDesktopMessengerUnlock(FlutterDesktopMessengerRef messenger)
void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate, void *user_data)
static flutter::FlutterWindowsViewController * ViewControllerFromHandle(FlutterDesktopViewControllerRef ref)
FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine)
IDXGIAdapter * FlutterDesktopViewGetGraphicsAdapter(FlutterDesktopViewRef view)
FlutterDesktopViewId FlutterDesktopViewControllerGetViewId(FlutterDesktopViewControllerRef ref)
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef ref)
FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar(FlutterDesktopPluginRegistrarRef registrar)
FlutterDesktopMessengerRef FlutterDesktopPluginRegistrarGetMessenger(FlutterDesktopPluginRegistrarRef registrar)
void FlutterDesktopEngineSetNextFrameCallback(FlutterDesktopEngineRef engine, VoidCallback callback, void *user_data)
HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view)
void FlutterDesktopMessengerRelease(FlutterDesktopMessengerRef messenger)
FlutterDesktopViewRef FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef ref)
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(FlutterDesktopPluginRegistrarRef registrar)
FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger)
FlutterDesktopViewControllerRef FlutterDesktopEngineCreateViewController(FlutterDesktopEngineRef engine, const FlutterDesktopViewControllerProperties *properties)
void FlutterDesktopViewControllerDestroy(FlutterDesktopViewControllerRef ref)
bool FlutterDesktopEngineRun(FlutterDesktopEngineRef engine, const char *entry_point)
struct FlutterDesktopViewController * FlutterDesktopViewControllerRef
bool(* FlutterDesktopWindowProcCallback)(HWND, UINT, WPARAM, LPARAM, void *, LRESULT *result)
int64_t FlutterDesktopViewId
struct FlutterDesktopView * FlutterDesktopViewRef
FlutterDesktopBinaryReply callback
#define FML_DCHECK(condition)
Definition logging.h:122
G_BEGIN_DECLS FlTextureRegistrar * texture_registrar
UINT GetDpiForHWND(HWND hwnd)
Definition dpi_utils.cc:128
UINT GetDpiForMonitor(HMONITOR monitor)
Definition dpi_utils.cc:132
constexpr FlutterViewId kImplicitViewId
int32_t height
int32_t width
FlutterDesktopMessengerReferenceOwner messenger
FlutterDesktopEngineState * engine
std::shared_ptr< const fml::Mapping > data
int64_t texture_id
#define SUCCEEDED(hr)
LONG_PTR LRESULT
unsigned int UINT
LONG_PTR LPARAM
UINT_PTR WPARAM