• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SHELL_COMMON_ACE_SHELL_H_
6 #define SHELL_COMMON_ACE_SHELL_H_
7 
8 #include <functional>
9 #include <string_view>
10 #include <unordered_map>
11 
12 #include "flutter/common/settings.h"
13 #include "flutter/common/task_runners.h"
14 #include "flutter/flow/texture.h"
15 #include "flutter/fml/closure.h"
16 #include "flutter/fml/macros.h"
17 #include "flutter/fml/memory/ref_ptr.h"
18 #include "flutter/fml/memory/thread_checker.h"
19 #include "flutter/fml/memory/weak_ptr.h"
20 #include "flutter/fml/status.h"
21 #include "flutter/fml/synchronization/thread_annotations.h"
22 #include "flutter/fml/synchronization/waitable_event.h"
23 #include "flutter/fml/thread.h"
24 #include "flutter/lib/ui/semantics/semantics_node.h"
25 #include "flutter/lib/ui/window/platform_message.h"
26 #include "flutter/shell/common/animator.h"
27 #include "flutter/shell/common/engine.h"
28 #include "flutter/shell/common/platform_view.h"
29 #include "flutter/shell/common/rasterizer.h"
30 #include "flutter/shell/common/shell_io_manager.h"
31 #include "flutter/shell/common/surface.h"
32 
33 namespace flutter {
34 
35 class Shell final : public PlatformView::Delegate,
36                     public Animator::Delegate,
37                     public Engine::Delegate,
38                     public Rasterizer::Delegate {
39  public:
40   template <class T>
41   using CreateCallback = std::function<std::unique_ptr<T>(Shell&)>;
42 
43   static std::unique_ptr<Shell> Create(
44       TaskRunners task_runners,
45       Settings settings,
46       CreateCallback<PlatformView> on_create_platform_view,
47       CreateCallback<Rasterizer> on_create_rasterizer);
48 
49   //----------------------------------------------------------------------------
50   /// @brief      Destroys the shell. This is a synchronous operation and
51   ///             synchronous barrier blocks are introduced on the various
52   ///             threads to ensure shutdown of all shell sub-components before
53   ///             this method returns.
54   ///
55   ~Shell();
56 
57   //----------------------------------------------------------------------------
58   /// @brief      Starts an isolate for the given RunConfiguration.
59   ///
60   void RunEngine(RunConfiguration run_configuration);
61 
62   //----------------------------------------------------------------------------
63   /// @brief      Starts an isolate for the given RunConfiguration. The
64   ///             result_callback will be called with the status of the
65   ///             operation.
66   ///
67   void RunEngine(RunConfiguration run_configuration,
68                  std::function<void(Engine::RunStatus)> result_callback);
69 
70   //------------------------------------------------------------------------------
71   /// @return     The settings used to launch this shell.
72   ///
73   const Settings& GetSettings() const;
74 
75   //------------------------------------------------------------------------------
76   /// @brief      If callers wish to interact directly with any shell
77   ///             subcomponents, they must (on the platform thread) obtain a
78   ///             task runner that the component is designed to run on and a
79   ///             weak pointer to that component. They may then post a task to
80   ///             that task runner, do the validity check on that task runner
81   ///             before performing any operation on that component. This
82   ///             accessor allows callers to access the task runners for this
83   ///             shell.
84   ///
85   /// @return     The task runners current in use by the shell.
86   ///
87   const TaskRunners& GetTaskRunners() const;
88 
89   //----------------------------------------------------------------------------
90   /// @brief      Rasterizers may only be accessed on the GPU task runner.
91   ///
92   /// @return     A weak pointer to the rasterizer.
93   ///
94   fml::WeakPtr<Rasterizer> GetRasterizer();
95 
96 // TODO(dnfield): Remove this when either Topaz is up to date or flutter_runner
97 // is built out of this repo.
98 #ifdef OS_FUCHSIA
99   //------------------------------------------------------------------------------
100   /// @brief      Engines may only be accessed on the UI thread. This method is
101   ///             deprecated, and implementers should instead use other API
102   ///             available on the Shell or the PlatformView.
103   ///
104   /// @return     A weak pointer to the engine.
105   ///
106   fml::WeakPtr<Engine> GetEngine();
107 #endif  // OS_FUCHSIA
108 
109   //----------------------------------------------------------------------------
110   /// @brief      Platform views may only be accessed on the platform task
111   ///             runner.
112   ///
113   /// @return     A weak pointer to the platform view.
114   ///
115   fml::WeakPtr<PlatformView> GetPlatformView();
116 
117   // Embedders should call this under low memory conditions to free up
118   // internal caches used.
119   //
120   // This method posts a task to the GPU threads to signal the Rasterizer to
121   // free resources.
122 
123   //----------------------------------------------------------------------------
124   /// @brief      Used by embedders to notify that there is a low memory
125   ///             warning. The shell will attempt to purge caches. Current, only
126   ///             the rasterizer cache is purged.
127   void NotifyLowMemoryWarning() const;
128 
129   //----------------------------------------------------------------------------
130   /// @brief      Used by embedders to check if all shell subcomponents are
131   ///             initialized. It is the embedder's responsibility to make this
132   ///             call before accessing any other shell method. A shell that is
133   ///             not setup must be discarded and another one created with
134   ///             updated settings.
135   ///
136   /// @return     Returns if the shell has been setup. Once set up, this does
137   ///             not change for the life-cycle of the shell.
138   ///
139   bool IsSetup() const;
140 
141   //----------------------------------------------------------------------------
142   /// @brief      Captures a screenshot and optionally Base64 encodes the data
143   ///             of the last layer tree rendered by the rasterizer in this
144   ///             shell.
145   ///
146   /// @param[in]  type           The type of screenshot to capture.
147   /// @param[in]  base64_encode  If the screenshot data should be base64
148   ///                            encoded.
149   ///
150   /// @return     The screenshot result.
151   ///
152   Rasterizer::Screenshot Screenshot(Rasterizer::ScreenshotType type,
153                                     bool base64_encode);
154 
155   //----------------------------------------------------------------------------
156   /// @brief   Pauses the calling thread until the first frame is presented.
157   ///
158   /// @return  'kOk' when the first frame has been presented before the timeout
159   ///          successfully, 'kFailedPrecondition' if called from the GPU or UI
160   ///          thread, 'kDeadlineExceeded' if there is a timeout.
161   ///
162   fml::Status WaitForFirstFrame(fml::TimeDelta timeout);
163 
164  private:
165   const TaskRunners task_runners_;
166   const Settings settings_;
167   std::unique_ptr<PlatformView> platform_view_;  // on platform task runner
168   std::unique_ptr<Engine> engine_;               // on UI task runner
169   std::unique_ptr<Rasterizer> rasterizer_;       // on GPU task runner
170   std::unique_ptr<ShellIOManager> io_manager_;   // on IO task runner
171 
172   fml::WeakPtr<Engine> weak_engine_;          // to be shared across threads
173   fml::WeakPtr<Rasterizer> weak_rasterizer_;  // to be shared across threads
174   fml::WeakPtr<PlatformView>
175       weak_platform_view_;  // to be shared across threads
176 
177   bool is_setup_ = false;
178   uint64_t next_pointer_flow_id_ = 0;
179 
180   bool first_frame_rasterized_ = false;
181   std::atomic<bool> waiting_for_first_frame_ = true;
182   std::mutex waiting_for_first_frame_mutex_;
183   std::condition_variable waiting_for_first_frame_condition_;
184 
185   // Written in the UI thread and read from the GPU thread. Hence make it
186   // atomic.
187   std::atomic<bool> needs_report_timings_{false};
188 
189   // Whether there's a task scheduled to report the timings to Dart through
190   // ui.Window.onReportTimings.
191   bool frame_timings_report_scheduled_ = false;
192 
193   // Vector of FrameTiming::kCount * n timestamps for n frames whose timings
194   // have not been reported yet. Vector of ints instead of FrameTiming is stored
195   // here for easier conversions to Dart objects.
196   std::vector<int64_t> unreported_timings_;
197 
198   // How many frames have been timed since last report.
199   size_t UnreportedFramesCount() const;
200 
201   Shell(TaskRunners task_runners, Settings settings);
202 
203   static std::unique_ptr<Shell> CreateShellOnPlatformThread(
204       TaskRunners task_runners,
205       Settings settings,
206       Shell::CreateCallback<PlatformView> on_create_platform_view,
207       Shell::CreateCallback<Rasterizer> on_create_rasterizer);
208 
209   bool Setup(std::unique_ptr<PlatformView> platform_view,
210              std::unique_ptr<Engine> engine,
211              std::unique_ptr<Rasterizer> rasterizer,
212              std::unique_ptr<ShellIOManager> io_manager);
213 
214   void ReportTimings();
215 
216   // |PlatformView::Delegate|
217   void OnPlatformViewCreated(std::unique_ptr<Surface> surface) override;
218 
219   // |PlatformView::Delegate|
220   void OnPlatformViewDestroyed() override;
221 
222   // |PlatformView::Delegate|
223   void OnSetIdleNotificationCallback(
224       const Engine::IdleCallback& idleCallback) override;
225 
226   // |PlatformView::Delegate|
227   void OnPlatformViewSetViewportMetrics(
228       const ViewportMetrics& metrics) override;
229 
230   // |PlatformView::Delegate|
231   void OnPlatformViewDispatchPlatformMessage(
232       fml::RefPtr<PlatformMessage> message) override;
233 
234   // |PlatformView::Delegate|
235   void OnPlatformViewDispatchPointerDataPacket(
236       std::unique_ptr<PointerDataPacket> packet) override;
237 
238   // |PlatformView::Delegate|
239   void OnPlatformViewRegisterTexture(
240       std::shared_ptr<flutter::Texture> texture) override;
241 
242   // |PlatformView::Delegate|
243   void OnPlatformViewUnregisterTexture(int64_t texture_id) override;
244 
245   // |PlatformView::Delegate|
246   void OnPlatformViewMarkTextureFrameAvailable(int64_t texture_id) override;
247 
248   // |PlatformView::Delegate|
249   void OnPlatformViewSetNextFrameCallback(fml::closure closure) override;
250 
251   // |Animator::Delegate|
252   void OnAnimatorBeginFrame(fml::TimePoint frame_time) override;
253 
254   // |Animator::Delegate|
255   void OnAnimatorNotifyIdle(int64_t deadline) override;
256 
257   // |Animator::Delegate|
258   void OnAnimatorDraw(
259       fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) override;
260 
261   // |Animator::Delegate|
262   void OnAnimatorDrawLastLayerTree() override;
263 
264   // |Engine::Delegate|
265   void OnEngineHandlePlatformMessage(
266       fml::RefPtr<PlatformMessage> message) override;
267 
268   void HandleEngineSkiaMessage(fml::RefPtr<PlatformMessage> message);
269 
270   // |Engine::Delegate|
271   void OnPreEngineRestart() override;
272 
273   // |Engine::Delegate|
274   void SetNeedsReportTimings(bool value) override;
275 
276   // |Rasterizer::Delegate|
277   void OnFrameRasterized(const FrameTiming&) override;
278 
279   fml::WeakPtrFactory<Shell> weak_factory_;
280 
281   friend class testing::ShellTest;
282 
283   FML_DISALLOW_COPY_AND_ASSIGN(Shell);
284 };
285 
286 }
287 
288 #endif // SHELL_COMMON_ACE_SHELL_H_
289