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