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
5#ifndef COMMON_PLATFORM_VIEW_H_
6#define COMMON_PLATFORM_VIEW_H_
7
8#include <functional>
9#include <memory>
10
11#include "flutter/common/graphics/texture.h"
12#include "flutter/common/task_runners.h"
13#include "flutter/flow/embedded_views.h"
14#include "flutter/flow/surface.h"
15#include "flutter/fml/macros.h"
16#include "flutter/fml/mapping.h"
17#include "flutter/fml/memory/weak_ptr.h"
18#include "flutter/lib/ui/semantics/custom_accessibility_action.h"
19#include "flutter/lib/ui/semantics/semantics_node.h"
20#include "flutter/lib/ui/window/key_data_packet.h"
21#include "flutter/lib/ui/window/platform_message.h"
22#include "flutter/lib/ui/window/pointer_data_packet.h"
23#include "flutter/lib/ui/window/pointer_data_packet_converter.h"
24#include "flutter/lib/ui/window/viewport_metrics.h"
25#include "flutter/shell/common/platform_message_handler.h"
26#include "flutter/shell/common/pointer_data_dispatcher.h"
27#include "flutter/shell/common/vsync_waiter.h"
28#include "third_party/skia/include/gpu/GrDirectContext.h"
29
30namespace impeller {
31
32class Context;
33
34} // namespace impeller
35
36namespace flutter {
37
38//------------------------------------------------------------------------------
39/// @brief Platform views are created by the shell on the platform task
40/// runner. Unless explicitly specified, all platform view methods
41/// are called on the platform task runner as well. Platform views
42/// are usually sub-classed on a per platform basis and the bulk of
43/// the window system integration happens using that subclass. Since
44/// most platform window toolkits are usually only safe to access on
45/// a single "main" thread, any interaction that requires access to
46/// the underlying platform's window toolkit is routed through the
47/// platform view associated with that shell. This involves
48/// operations like settings up and tearing down the render surface,
49/// platform messages, interacting with accessibility features on
50/// the platform, input events, etc.
51///
52class PlatformView {
53 public:
54 //----------------------------------------------------------------------------
55 /// @brief Used to forward events from the platform view to interested
56 /// subsystems. This forwarding is done by the shell which sets
57 /// itself up as the delegate of the platform view.
58 ///
59 class Delegate {
60 public:
61 using KeyDataResponse = std::function<void(bool)>;
62 //--------------------------------------------------------------------------
63 /// @brief Notifies the delegate that the platform view was created
64 /// with the given render surface. This surface is platform
65 /// (iOS, Android) and client-rendering API (OpenGL, Software,
66 /// Metal, Vulkan) specific. This is usually a sign to the
67 /// rasterizer to set up and begin rendering to that surface.
68 ///
69 /// @param[in] surface The surface
70 ///
71 virtual void OnPlatformViewCreated(std::unique_ptr<Surface> surface) = 0;
72
73 //--------------------------------------------------------------------------
74 /// @brief Notifies the delegate that the platform view was destroyed.
75 /// This is usually a sign to the rasterizer to suspend
76 /// rendering a previously configured surface and collect any
77 /// intermediate resources.
78 ///
79 virtual void OnPlatformViewDestroyed() = 0;
80
81 //--------------------------------------------------------------------------
82 /// @brief Notifies the delegate that the platform needs to schedule a
83 /// frame to regenerate the layer tree and redraw the surface.
84 ///
85 virtual void OnPlatformViewScheduleFrame() = 0;
86
87 //--------------------------------------------------------------------------
88 /// @brief Notifies the delegate that the specified callback needs to
89 /// be invoked after the rasterizer is done rendering the next
90 /// frame. This callback will be called on the render thread and
91 /// it is caller responsibility to perform any re-threading as
92 /// necessary. Due to the asynchronous nature of rendering in
93 /// Flutter, embedders usually add a placeholder over the
94 /// contents in which Flutter is going to render when Flutter is
95 /// first initialized. This callback may be used as a signal to
96 /// remove that placeholder.
97 ///
98 /// @attention The callback will be invoked on the render thread and not
99 /// the calling thread.
100 ///
101 /// @param[in] closure The callback to execute on the next frame.
102 ///
103 virtual void OnPlatformViewSetNextFrameCallback(
104 const fml::closure& closure) = 0;
105
106 //--------------------------------------------------------------------------
107 /// @brief Notifies the delegate the viewport metrics of a view have
108 /// been updated. The rasterizer will need to be reconfigured to
109 /// render the frame in the updated viewport metrics.
110 ///
111 /// @param[in] view_id The ID for the view that `metrics` describes.
112 /// @param[in] metrics The updated viewport metrics.
113 ///
114 virtual void OnPlatformViewSetViewportMetrics(
115 int64_t view_id,
116 const ViewportMetrics& metrics) = 0;
117
118 //--------------------------------------------------------------------------
119 /// @brief Notifies the delegate that the platform has dispatched a
120 /// platform message from the embedder to the Flutter
121 /// application. This message must be forwarded to the running
122 /// isolate hosted by the engine on the UI thread.
123 ///
124 /// @param[in] message The platform message to dispatch to the running
125 /// root isolate.
126 ///
127 virtual void OnPlatformViewDispatchPlatformMessage(
128 std::unique_ptr<PlatformMessage> message) = 0;
129
130 //--------------------------------------------------------------------------
131 /// @brief Notifies the delegate that the platform view has encountered
132 /// a pointer event. This pointer event needs to be forwarded to
133 /// the running root isolate hosted by the engine on the UI
134 /// thread.
135 ///
136 /// @param[in] packet The pointer data packet containing multiple pointer
137 /// events.
138 ///
139 virtual void OnPlatformViewDispatchPointerDataPacket(
140 std::unique_ptr<PointerDataPacket> packet) = 0;
141
142 //--------------------------------------------------------------------------
143 /// @brief Notifies the delegate that the platform view has encountered
144 /// an accessibility related action on the specified node. This
145 /// event must be forwarded to the running root isolate hosted
146 /// by the engine on the UI thread.
147 ///
148 /// @param[in] node_id The identifier of the accessibility node.
149 /// @param[in] action The accessibility related action performed on the
150 /// node of the specified ID.
151 /// @param[in] args An optional list of argument that apply to the
152 /// specified action.
153 ///
154 virtual void OnPlatformViewDispatchSemanticsAction(
155 int32_t node_id,
156 SemanticsAction action,
157 fml::MallocMapping args) = 0;
158
159 //--------------------------------------------------------------------------
160 /// @brief Notifies the delegate that the embedder has expressed an
161 /// opinion about whether the accessibility tree needs to be
162 /// enabled or disabled. This information needs to be forwarded
163 /// to the root isolate running on the UI thread.
164 ///
165 /// @param[in] enabled Whether the accessibility tree is enabled or
166 /// disabled.
167 ///
168 virtual void OnPlatformViewSetSemanticsEnabled(bool enabled) = 0;
169
170 //--------------------------------------------------------------------------
171 /// @brief Notifies the delegate that the embedder has expressed an
172 /// opinion about the features to enable in the accessibility
173 /// tree.
174 ///
175 /// The engine does not care about the accessibility feature
176 /// flags as all it does is forward this information from the
177 /// embedder to the framework. However, curious readers may
178 /// refer to `AccessibilityFeatures` in `window.dart` for
179 /// currently supported accessibility feature flags.
180 ///
181 /// @param[in] flags The features to enable in the accessibility tree.
182 ///
183 virtual void OnPlatformViewSetAccessibilityFeatures(int32_t flags) = 0;
184
185 //--------------------------------------------------------------------------
186 /// @brief Notifies the delegate that the embedder has specified a
187 /// texture that it want the rasterizer to composite within the
188 /// Flutter layer tree. All textures must have a unique
189 /// identifier. When the rasterizer encounters an external
190 /// texture within its hierarchy, it gives the embedder a chance
191 /// to update that texture on the raster thread before it
192 /// composites the same on-screen.
193 ///
194 /// @param[in] texture The texture that is being updated by the embedder
195 /// but composited by Flutter in its own hierarchy.
196 ///
197 virtual void OnPlatformViewRegisterTexture(
198 std::shared_ptr<Texture> texture) = 0;
199
200 //--------------------------------------------------------------------------
201 /// @brief Notifies the delegate that the embedder will no longer
202 /// attempt to composite the specified texture within the layer
203 /// tree. This allows the rasterizer to collect associated
204 /// resources.
205 ///
206 /// @param[in] texture_id The identifier of the texture to unregister. If
207 /// the texture has not been previously registered,
208 /// this call does nothing.
209 ///
210 virtual void OnPlatformViewUnregisterTexture(int64_t texture_id) = 0;
211
212 //--------------------------------------------------------------------------
213 /// @brief Notifies the delegate that the embedder has updated the
214 /// contents of the texture with the specified identifier.
215 /// Typically, Flutter will only render a frame if there is an
216 /// updated layer tree. However, in cases where the layer tree
217 /// is static but one of the externally composited textures has
218 /// been updated by the embedder, the embedder needs to notify
219 /// the rasterizer to render a new frame. In such cases, the
220 /// existing layer tree may be reused with the frame composited
221 /// with all updated external textures.
222 ///
223 /// @param[in] texture_id The identifier of the texture that has been
224 /// updated.
225 ///
226 virtual void OnPlatformViewMarkTextureFrameAvailable(
227 int64_t texture_id) = 0;
228
229 //--------------------------------------------------------------------------
230 /// @brief Loads the dart shared library into the dart VM. When the
231 /// dart library is loaded successfully, the dart future
232 /// returned by the originating loadLibrary() call completes.
233 ///
234 /// The Dart compiler may generate separate shared libraries
235 /// files called 'loading units' when libraries are imported
236 /// as deferred. Each of these shared libraries are identified
237 /// by a unique loading unit id. Callers should open and resolve
238 /// a SymbolMapping from the shared library. The Mappings should
239 /// be moved into this method, as ownership will be assumed by
240 /// the dart root isolate after successful loading and released
241 /// after shutdown of the root isolate. The loading unit may not
242 /// be used after isolate shutdown. If loading fails, the
243 /// mappings will be released.
244 ///
245 /// This method is paired with a RequestDartDeferredLibrary
246 /// invocation that provides the embedder with the loading unit
247 /// id of the deferred library to load.
248 ///
249 ///
250 /// @param[in] loading_unit_id The unique id of the deferred library's
251 /// loading unit.
252 ///
253 /// @param[in] snapshot_data Dart snapshot data of the loading unit's
254 /// shared library.
255 ///
256 /// @param[in] snapshot_data Dart snapshot instructions of the loading
257 /// unit's shared library.
258 ///
259 virtual void LoadDartDeferredLibrary(
260 intptr_t loading_unit_id,
261 std::unique_ptr<const fml::Mapping> snapshot_data,
262 std::unique_ptr<const fml::Mapping> snapshot_instructions) = 0;
263
264 //--------------------------------------------------------------------------
265 /// @brief Indicates to the dart VM that the request to load a deferred
266 /// library with the specified loading unit id has failed.
267 ///
268 /// The dart future returned by the initiating loadLibrary()
269 /// call will complete with an error.
270 ///
271 /// @param[in] loading_unit_id The unique id of the deferred library's
272 /// loading unit, as passed in by
273 /// RequestDartDeferredLibrary.
274 ///
275 /// @param[in] error_message The error message that will appear in the
276 /// dart Future.
277 ///
278 /// @param[in] transient A transient error is a failure due to
279 /// temporary conditions such as no network.
280 /// Transient errors allow the dart VM to
281 /// re-request the same deferred library and
282 /// loading_unit_id again. Non-transient
283 /// errors are permanent and attempts to
284 /// re-request the library will instantly
285 /// complete with an error.
286 virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
287 const std::string error_message,
288 bool transient) = 0;
289
290 //--------------------------------------------------------------------------
291 /// @brief Replaces the asset resolver handled by the engine's
292 /// AssetManager of the specified `type` with
293 /// `updated_asset_resolver`. The matching AssetResolver is
294 /// removed and replaced with `updated_asset_resolvers`.
295 ///
296 /// AssetResolvers should be updated when the existing resolver
297 /// becomes obsolete and a newer one becomes available that
298 /// provides updated access to the same type of assets as the
299 /// existing one. This update process is meant to be performed
300 /// at runtime.
301 ///
302 /// If a null resolver is provided, nothing will be done. If no
303 /// matching resolver is found, the provided resolver will be
304 /// added to the end of the AssetManager resolvers queue. The
305 /// replacement only occurs with the first matching resolver.
306 /// Any additional matching resolvers are untouched.
307 ///
308 /// @param[in] updated_asset_resolver The asset resolver to replace the
309 /// resolver of matching type with.
310 ///
311 /// @param[in] type The type of AssetResolver to update. Only resolvers of
312 /// the specified type will be replaced by the updated
313 /// resolver.
314 ///
315 virtual void UpdateAssetResolverByType(
316 std::unique_ptr<AssetResolver> updated_asset_resolver,
317 AssetResolver::AssetResolverType type) = 0;
318
319 //--------------------------------------------------------------------------
320 /// @brief Called by the platform view on the platform thread to get
321 /// the settings object associated with the platform view
322 /// instance.
323 ///
324 /// @return The settings.
325 ///
326 virtual const Settings& OnPlatformViewGetSettings() const = 0;
327 };
328
329 //----------------------------------------------------------------------------
330 /// @brief Creates a platform view with the specified delegate and task
331 /// runner. The base class by itself does not do much but is
332 /// suitable for use in test environments where full platform
333 /// integration may not be necessary. The platform view may only
334 /// be created, accessed and destroyed on the platform task
335 /// runner.
336 ///
337 /// @param delegate The delegate. This is typically the shell.
338 /// @param[in] task_runners The task runners used by this platform view.
339 ///
340 explicit PlatformView(Delegate& delegate, const TaskRunners& task_runners);
341
342 //----------------------------------------------------------------------------
343 /// @brief Destroys the platform view. The platform view is owned by the
344 /// shell and will be destroyed by the same on the platform tasks
345 /// runner.
346 ///
347 virtual ~PlatformView();
348
349 //----------------------------------------------------------------------------
350 /// @brief Invoked by the shell to obtain a platform specific vsync
351 /// waiter. It is optional for platforms to override this method
352 /// and provide a custom vsync waiter because a timer based
353 /// fall-back waiter is used by default. However, it is highly
354 /// recommended that platform provide their own Vsync waiter as
355 /// the timer based fall-back will not render frames aligned with
356 /// vsync boundaries.
357 ///
358 /// @attention If a timer based fall-back is used, a warning is logged to the
359 /// console. In case this method is overridden in a subclass, it
360 /// must return a valid vsync waiter. Returning null will lead to
361 /// internal errors. If a valid vsync waiter cannot be returned,
362 /// subclasses should just call the based class method instead.
363 ///
364 /// @return A vsync waiter. If is an internal error to return a null
365 /// waiter.
366 ///
367 virtual std::unique_ptr<VsyncWaiter> CreateVSyncWaiter();
368
369 //----------------------------------------------------------------------------
370 /// @brief Used by embedders to dispatch a platform message to a
371 /// running root isolate hosted by the engine. If an isolate is
372 /// not running, the message is dropped. If there is no one on the
373 /// other side listening on the channel, the message is dropped.
374 /// When a platform message is dropped, any response handles
375 /// associated with that message will be dropped as well. All
376 /// users of platform messages must assume that message may not be
377 /// delivered and/or their response handles may not be invoked.
378 /// Platform messages are not buffered.
379 ///
380 /// For embedders that wish to respond to platform message
381 /// directed from the framework to the embedder, the
382 /// `HandlePlatformMessage` method may be overridden.
383 ///
384 /// @see HandlePlatformMessage()
385 ///
386 /// @param[in] message The platform message to deliver to the root isolate.
387 ///
388 void DispatchPlatformMessage(std::unique_ptr<PlatformMessage> message);
389
390 //----------------------------------------------------------------------------
391 /// @brief Overridden by embedders to perform actions in response to
392 /// platform messages sent from the framework to the embedder.
393 /// Default implementation of this method simply returns an empty
394 /// response.
395 ///
396 /// Embedders that wish to send platform messages to the framework
397 /// may use the `DispatchPlatformMessage` method. This method is
398 /// for messages that go the other way.
399 ///
400 /// @see DispatchPlatformMessage()
401 ///
402 /// @param[in] message The message
403 ///
404 virtual void HandlePlatformMessage(std::unique_ptr<PlatformMessage> message);
405
406 //----------------------------------------------------------------------------
407 /// @brief Used by embedders to dispatch an accessibility action to a
408 /// running isolate hosted by the engine.
409 ///
410 /// @param[in] node_id The identifier of the accessibility node on which to
411 /// perform the action.
412 /// @param[in] action The action
413 /// @param[in] args The arguments
414 ///
415 void DispatchSemanticsAction(int32_t node_id,
416 SemanticsAction action,
417 fml::MallocMapping args);
418
419 //----------------------------------------------------------------------------
420 /// @brief Used by embedder to notify the running isolate hosted by the
421 /// engine on the UI thread that the accessibility tree needs to
422 /// be generated.
423 ///
424 /// @attention Subclasses may choose to override this method to perform
425 /// platform specific functions. However, they must call the base
426 /// class method at some point in their implementation.
427 ///
428 /// @param[in] enabled Whether the accessibility tree needs to be generated.
429 ///
430 virtual void SetSemanticsEnabled(bool enabled);
431
432 //----------------------------------------------------------------------------
433 /// @brief Used by the embedder to specify the features to enable in the
434 /// accessibility tree generated by the isolate. This information
435 /// is forwarded to the root isolate hosted by the engine on the
436 /// UI thread.
437 ///
438 /// The engine does not care about the accessibility feature flags
439 /// as all it does is forward this information from the embedder
440 /// to the framework. However, curious readers may refer to
441 /// `AccessibilityFeatures` in `window.dart` for currently
442 /// supported accessibility feature flags.
443 ///
444 /// @attention Subclasses may choose to override this method to perform
445 /// platform specific functions. However, they must call the base
446 /// class method at some point in their implementation.
447 ///
448 /// @param[in] flags The features to enable in the accessibility tree.
449 ///
450 virtual void SetAccessibilityFeatures(int32_t flags);
451
452 //----------------------------------------------------------------------------
453 /// @brief Used by the framework to tell the embedder to apply the
454 /// specified semantics node updates. The default implementation
455 /// of this method does nothing.
456 ///
457 /// @see SemanticsNode, SemticsNodeUpdates,
458 /// CustomAccessibilityActionUpdates
459 ///
460 /// @param[in] updates A map with the stable semantics node identifier as
461 /// key and the node properties as the value.
462 /// @param[in] actions A map with the stable semantics node identifier as
463 /// key and the custom node action as the value.
464 ///
465 virtual void UpdateSemantics(SemanticsNodeUpdates updates,
466 CustomAccessibilityActionUpdates actions);
467
468 //----------------------------------------------------------------------------
469 /// @brief Used by embedders to specify the updated viewport metrics for
470 /// a view. In response to this call, on the raster thread, the
471 /// rasterizer may need to be reconfigured to the updated viewport
472 /// dimensions. On the UI thread, the framework may need to start
473 /// generating a new frame for the updated viewport metrics as
474 /// well.
475 ///
476 /// @param[in] view_id The ID for the view that `metrics` describes.
477 /// @param[in] metrics The updated viewport metrics.
478 ///
479 void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics);
480
481 //----------------------------------------------------------------------------
482 /// @brief Used by embedders to notify the shell that a platform view
483 /// has been created. This notification is used to create a
484 /// rendering surface and pick the client rendering API to use to
485 /// render into this surface. No frames will be scheduled or
486 /// rendered before this call. The surface must remain valid till
487 /// the corresponding call to NotifyDestroyed.
488 ///
489 void NotifyCreated();
490
491 //----------------------------------------------------------------------------
492 /// @brief Used by embedders to notify the shell that the platform view
493 /// has been destroyed. This notification used to collect the
494 /// rendering surface and all associated resources. Frame
495 /// scheduling is also suspended.
496 ///
497 /// @attention Subclasses may choose to override this method to perform
498 /// platform specific functions. However, they must call the base
499 /// class method at some point in their implementation.
500 ///
501 virtual void NotifyDestroyed();
502
503 //----------------------------------------------------------------------------
504 /// @brief Used by embedders to schedule a frame. In response to this
505 /// call, the framework may need to start generating a new frame.
506 ///
507 void ScheduleFrame();
508
509 //----------------------------------------------------------------------------
510 /// @brief Used by the shell to obtain a Skia GPU context that is capable
511 /// of operating on the IO thread. The context must be in the same
512 /// share-group as the Skia GPU context used on the render thread.
513 /// This context will always be used on the IO thread. Because it
514 /// is in the same share-group as the separate render thread
515 /// context, any GPU resources uploaded in this context will be
516 /// visible to the render thread context (synchronization of GPU
517 /// resources is managed by Skia).
518 ///
519 /// If such context cannot be created on the IO thread, callers
520 /// may return `nullptr`. This will mean that all texture uploads
521 /// will be queued onto the render thread which will cause
522 /// performance issues. When this context is `nullptr`, an error
523 /// is logged to the console. It is highly recommended that all
524 /// platforms provide a resource context.
525 ///
526 /// @attention Unlike all other methods on the platform view, this will be
527 /// called on IO task runner.
528 ///
529 /// @return The Skia GPU context that is in the same share-group as the
530 /// main render thread GPU context. May be `nullptr` in case such
531 /// a context cannot be created.
532 ///
533 virtual sk_sp<GrDirectContext> CreateResourceContext() const;
534
535 virtual std::shared_ptr<impeller::Context> GetImpellerContext() const;
536
537 //----------------------------------------------------------------------------
538 /// @brief Used by the shell to notify the embedder that the resource
539 /// context previously obtained via a call to
540 /// `CreateResourceContext()` is being collected. The embedder
541 /// is free to collect an platform specific resources
542 /// associated with this context.
543 ///
544 /// @attention Unlike all other methods on the platform view, this will be
545 /// called on IO task runner.
546 ///
547 virtual void ReleaseResourceContext() const;
548
549 //--------------------------------------------------------------------------
550 /// @brief Returns a platform-specific PointerDataDispatcherMaker so the
551 /// `Engine` can construct the PointerDataPacketDispatcher based
552 /// on platforms.
553 virtual PointerDataDispatcherMaker GetDispatcherMaker();
554
555 //----------------------------------------------------------------------------
556 /// @brief Returns a weak pointer to the platform view. Since the
557 /// platform view may only be created, accessed and destroyed
558 /// on the platform thread, any access to the platform view
559 /// from a non-platform task runner needs a weak pointer to
560 /// the platform view along with a reference to the platform
561 /// task runner. A task must be posted to the platform task
562 /// runner with the weak pointer captured in the same. The
563 /// platform view method may only be called in the posted task
564 /// once the weak pointer validity has been checked. This
565 /// method is used by callers to obtain that weak pointer.
566 ///
567 /// @return The weak pointer to the platform view.
568 ///
569 fml::WeakPtr<PlatformView> GetWeakPtr() const;
570
571 //----------------------------------------------------------------------------
572 /// @brief Gives embedders a chance to react to a "cold restart" of the
573 /// running isolate. The default implementation of this method
574 /// does nothing.
575 ///
576 /// While a "hot restart" patches a running isolate, a "cold
577 /// restart" restarts the root isolate in a running shell.
578 ///
579 virtual void OnPreEngineRestart() const;
580
581 //----------------------------------------------------------------------------
582 /// @brief Sets a callback that gets executed when the rasterizer renders
583 /// the next frame. Due to the asynchronous nature of
584 /// rendering in Flutter, embedders usually add a placeholder
585 /// over the contents in which Flutter is going to render when
586 /// Flutter is first initialized. This callback may be used as
587 /// a signal to remove that placeholder. The callback is
588 /// executed on the render task runner and not the platform
589 /// task runner. It is the embedder's responsibility to
590 /// re-thread as necessary.
591 ///
592 /// @attention The callback is executed on the render task runner and not the
593 /// platform task runner. Embedders must re-thread as necessary.
594 ///
595 /// @param[in] closure The callback to execute on the render thread when the
596 /// next frame gets rendered.
597 ///
598 void SetNextFrameCallback(const fml::closure& closure);
599
600 //----------------------------------------------------------------------------
601 /// @brief Dispatches pointer events from the embedder to the
602 /// framework. Each pointer data packet may contain multiple
603 /// pointer input events. Each call to this method wakes up
604 /// the UI thread.
605 ///
606 /// @param[in] packet The pointer data packet to dispatch to the framework.
607 ///
608 void DispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet);
609
610 //--------------------------------------------------------------------------
611 /// @brief Used by the embedder to specify a texture that it wants the
612 /// rasterizer to composite within the Flutter layer tree. All
613 /// textures must have a unique identifier. When the
614 /// rasterizer encounters an external texture within its
615 /// hierarchy, it gives the embedder a chance to update that
616 /// texture on the raster thread before it composites the same
617 /// on-screen.
618 ///
619 /// @attention This method must only be called once per texture. When the
620 /// texture is updated, calling `MarkTextureFrameAvailable`
621 /// with the specified texture identifier is sufficient to
622 /// make Flutter re-render the frame with the updated texture
623 /// composited in-line.
624 ///
625 /// @see UnregisterTexture, MarkTextureFrameAvailable
626 ///
627 /// @param[in] texture The texture that is being updated by the embedder
628 /// but composited by Flutter in its own hierarchy.
629 ///
630 void RegisterTexture(std::shared_ptr<flutter::Texture> texture);
631
632 //--------------------------------------------------------------------------
633 /// @brief Used by the embedder to notify the rasterizer that it will
634 /// no longer attempt to composite the specified texture within
635 /// the layer tree. This allows the rasterizer to collect
636 /// associated resources.
637 ///
638 /// @attention This call must only be called once per texture identifier.
639 ///
640 /// @see RegisterTexture, MarkTextureFrameAvailable
641 ///
642 /// @param[in] texture_id The identifier of the texture to unregister. If
643 /// the texture has not been previously registered,
644 /// this call does nothing.
645 ///
646 void UnregisterTexture(int64_t texture_id);
647
648 //--------------------------------------------------------------------------
649 /// @brief Used by the embedder to notify the rasterizer that the context
650 /// of the previously registered texture have been updated.
651 /// Typically, Flutter will only render a frame if there is an
652 /// updated layer tree. However, in cases where the layer tree
653 /// is static but one of the externally composited textures
654 /// has been updated by the embedder, the embedder needs to
655 /// notify the rasterizer to render a new frame. In such
656 /// cases, the existing layer tree may be reused with the
657 /// frame re-composited with all updated external textures.
658 /// Unlike the calls to register and unregister the texture,
659 /// this call must be made each time a new texture frame is
660 /// available.
661 ///
662 /// @see RegisterTexture, UnregisterTexture
663 ///
664 /// @param[in] texture_id The identifier of the texture that has been
665 /// updated.
666 ///
667 void MarkTextureFrameAvailable(int64_t texture_id);
668
669 //--------------------------------------------------------------------------
670 /// @brief Directly invokes platform-specific APIs to compute the
671 /// locale the platform would have natively resolved to.
672 ///
673 /// @param[in] supported_locale_data The vector of strings that represents
674 /// the locales supported by the app.
675 /// Each locale consists of three
676 /// strings: languageCode, countryCode,
677 /// and scriptCode in that order.
678 ///
679 /// @return A vector of 3 strings languageCode, countryCode, and
680 /// scriptCode that represents the locale selected by the
681 /// platform. Empty strings mean the value was unassigned. Empty
682 /// vector represents a null locale.
683 ///
684 virtual std::unique_ptr<std::vector<std::string>>
685 ComputePlatformResolvedLocales(
686 const std::vector<std::string>& supported_locale_data);
687
688 virtual std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder();
689
690 //--------------------------------------------------------------------------
691 /// @brief Invoked when the dart VM requests that a deferred library
692 /// be loaded. Notifies the engine that the deferred library
693 /// identified by the specified loading unit id should be
694 /// downloaded and loaded into the Dart VM via
695 /// `LoadDartDeferredLibrary`
696 ///
697 /// Upon encountering errors or otherwise failing to load a
698 /// loading unit with the specified id, the failure should be
699 /// directly reported to dart by calling
700 /// `LoadDartDeferredLibraryFailure` to ensure the waiting dart
701 /// future completes with an error.
702 ///
703 /// @param[in] loading_unit_id The unique id of the deferred library's
704 /// loading unit. This id is to be passed
705 /// back into LoadDartDeferredLibrary
706 /// in order to identify which deferred
707 /// library to load.
708 ///
709 virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id);
710
711 //--------------------------------------------------------------------------
712 /// @brief Loads the Dart shared library into the Dart VM. When the
713 /// Dart library is loaded successfully, the Dart future
714 /// returned by the originating loadLibrary() call completes.
715 ///
716 /// The Dart compiler may generate separate shared libraries
717 /// files called 'loading units' when libraries are imported
718 /// as deferred. Each of these shared libraries are identified
719 /// by a unique loading unit id. Callers should open and resolve
720 /// a SymbolMapping from the shared library. The Mappings should
721 /// be moved into this method, as ownership will be assumed by the
722 /// dart isolate after successful loading and released after
723 /// shutdown of the dart isolate. If loading fails, the mappings
724 /// will naturally go out of scope.
725 ///
726 /// This method is paired with a RequestDartDeferredLibrary
727 /// invocation that provides the embedder with the loading unit id
728 /// of the deferred library to load.
729 ///
730 ///
731 /// @param[in] loading_unit_id The unique id of the deferred library's
732 /// loading unit, as passed in by
733 /// RequestDartDeferredLibrary.
734 ///
735 /// @param[in] snapshot_data Dart snapshot data of the loading unit's
736 /// shared library.
737 ///
738 /// @param[in] snapshot_data Dart snapshot instructions of the loading
739 /// unit's shared library.
740 ///
741 virtual void LoadDartDeferredLibrary(
742 intptr_t loading_unit_id,
743 std::unique_ptr<const fml::Mapping> snapshot_data,
744 std::unique_ptr<const fml::Mapping> snapshot_instructions);
745
746 //--------------------------------------------------------------------------
747 /// @brief Indicates to the dart VM that the request to load a deferred
748 /// library with the specified loading unit id has failed.
749 ///
750 /// The dart future returned by the initiating loadLibrary() call
751 /// will complete with an error.
752 ///
753 /// @param[in] loading_unit_id The unique id of the deferred library's
754 /// loading unit, as passed in by
755 /// RequestDartDeferredLibrary.
756 ///
757 /// @param[in] error_message The error message that will appear in the
758 /// dart Future.
759 ///
760 /// @param[in] transient A transient error is a failure due to
761 /// temporary conditions such as no network.
762 /// Transient errors allow the dart VM to
763 /// re-request the same deferred library and
764 /// loading_unit_id again. Non-transient
765 /// errors are permanent and attempts to
766 /// re-request the library will instantly
767 /// complete with an error.
768 ///
769 virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
770 const std::string error_message,
771 bool transient);
772
773 //--------------------------------------------------------------------------
774 /// @brief Replaces the asset resolver handled by the engine's
775 /// AssetManager of the specified `type` with
776 /// `updated_asset_resolver`. The matching AssetResolver is
777 /// removed and replaced with `updated_asset_resolvers`.
778 ///
779 /// AssetResolvers should be updated when the existing resolver
780 /// becomes obsolete and a newer one becomes available that
781 /// provides updated access to the same type of assets as the
782 /// existing one. This update process is meant to be performed
783 /// at runtime.
784 ///
785 /// If a null resolver is provided, nothing will be done. If no
786 /// matching resolver is found, the provided resolver will be
787 /// added to the end of the AssetManager resolvers queue. The
788 /// replacement only occurs with the first matching resolver.
789 /// Any additional matching resolvers are untouched.
790 ///
791 /// @param[in] updated_asset_resolver The asset resolver to replace the
792 /// resolver of matching type with.
793 ///
794 /// @param[in] type The type of AssetResolver to update. Only resolvers of
795 /// the specified type will be replaced by the updated
796 /// resolver.
797 ///
798 virtual void UpdateAssetResolverByType(
799 std::unique_ptr<AssetResolver> updated_asset_resolver,
800 AssetResolver::AssetResolverType type);
801
802 //--------------------------------------------------------------------------
803 /// @brief Creates an object that produces surfaces suitable for raster
804 /// snapshotting. The rasterizer will request this surface if no
805 /// on screen surface is currently available when an application
806 /// requests a snapshot, e.g. if `Scene.toImage` or
807 /// `Picture.toImage` are called while the application is in the
808 /// background.
809 ///
810 /// Not all backends support this kind of surface usage, and the
811 /// default implementation returns nullptr. Platforms should
812 /// override this if they can support GPU operations in the
813 /// background and support GPU resource context usage.
814 ///
815 virtual std::unique_ptr<SnapshotSurfaceProducer>
816 CreateSnapshotSurfaceProducer();
817
818 //--------------------------------------------------------------------------
819 /// @brief Specifies a delegate that will receive PlatformMessages from
820 /// Flutter to the host platform.
821 ///
822 /// @details If this returns `null` that means PlatformMessages should be sent
823 /// to the PlatformView. That is to protect legacy behavior, any embedder
824 /// that wants to support executing Platform Channel handlers on background
825 /// threads should be returning a thread-safe PlatformMessageHandler instead.
826 virtual std::shared_ptr<PlatformMessageHandler> GetPlatformMessageHandler()
827 const;
828
829 //----------------------------------------------------------------------------
830 /// @brief Get the settings for this platform view instance.
831 ///
832 /// @return The settings.
833 ///
834 const Settings& GetSettings() const;
835
836 protected:
837 // This is the only method called on the raster task runner.
838 virtual std::unique_ptr<Surface> CreateRenderingSurface();
839
840 PlatformView::Delegate& delegate_;
841 const TaskRunners task_runners_;
842 PointerDataPacketConverter pointer_data_packet_converter_;
843 fml::WeakPtrFactory<PlatformView> weak_factory_; // Must be the last member.
844
845 private:
846 FML_DISALLOW_COPY_AND_ASSIGN(PlatformView);
847};
848
849} // namespace flutter
850
851#endif // COMMON_PLATFORM_VIEW_H_
852

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com

source code of flutter_engine/flutter/shell/common/platform_view.h