| 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 | #include "flutter/shell/common/platform_view.h" |
| 6 | |
| 7 | #include <utility> |
| 8 | |
| 9 | #include "flutter/fml/make_copyable.h" |
| 10 | #include "flutter/fml/synchronization/waitable_event.h" |
| 11 | #include "flutter/shell/common/vsync_waiter_fallback.h" |
| 12 | #include "third_party/skia/include/gpu/gl/GrGLInterface.h" |
| 13 | |
| 14 | namespace flutter { |
| 15 | |
| 16 | PlatformView::PlatformView(Delegate& delegate, const TaskRunners& task_runners) |
| 17 | : delegate_(delegate), task_runners_(task_runners), weak_factory_(this) {} |
| 18 | |
| 19 | PlatformView::~PlatformView() = default; |
| 20 | |
| 21 | std::unique_ptr<VsyncWaiter> PlatformView::CreateVSyncWaiter() { |
| 22 | FML_DLOG(WARNING) |
| 23 | << "This platform does not provide a Vsync waiter implementation. A " |
| 24 | "simple timer based fallback is being used." ; |
| 25 | return std::make_unique<VsyncWaiterFallback>(args: task_runners_); |
| 26 | } |
| 27 | |
| 28 | void PlatformView::DispatchPlatformMessage( |
| 29 | std::unique_ptr<PlatformMessage> message) { |
| 30 | delegate_.OnPlatformViewDispatchPlatformMessage(message: std::move(message)); |
| 31 | } |
| 32 | |
| 33 | void PlatformView::DispatchPointerDataPacket( |
| 34 | std::unique_ptr<PointerDataPacket> packet) { |
| 35 | delegate_.OnPlatformViewDispatchPointerDataPacket( |
| 36 | packet: pointer_data_packet_converter_.Convert(packet: std::move(packet))); |
| 37 | } |
| 38 | |
| 39 | void PlatformView::DispatchSemanticsAction(int32_t node_id, |
| 40 | SemanticsAction action, |
| 41 | fml::MallocMapping args) { |
| 42 | delegate_.OnPlatformViewDispatchSemanticsAction(node_id, action, |
| 43 | args: std::move(args)); |
| 44 | } |
| 45 | |
| 46 | void PlatformView::SetSemanticsEnabled(bool enabled) { |
| 47 | delegate_.OnPlatformViewSetSemanticsEnabled(enabled); |
| 48 | } |
| 49 | |
| 50 | void PlatformView::SetAccessibilityFeatures(int32_t flags) { |
| 51 | delegate_.OnPlatformViewSetAccessibilityFeatures(flags); |
| 52 | } |
| 53 | |
| 54 | void PlatformView::SetViewportMetrics(int64_t view_id, |
| 55 | const ViewportMetrics& metrics) { |
| 56 | delegate_.OnPlatformViewSetViewportMetrics(view_id, metrics); |
| 57 | } |
| 58 | |
| 59 | void PlatformView::NotifyCreated() { |
| 60 | std::unique_ptr<Surface> surface; |
| 61 | // Threading: We want to use the platform view on the non-platform thread. |
| 62 | // Using the weak pointer is illegal. But, we are going to introduce a latch |
| 63 | // so that the platform view is not collected till the surface is obtained. |
| 64 | auto* platform_view = this; |
| 65 | fml::ManualResetWaitableEvent latch; |
| 66 | fml::TaskRunner::RunNowOrPostTask( |
| 67 | runner: task_runners_.GetRasterTaskRunner(), task: [platform_view, &surface, &latch]() { |
| 68 | surface = platform_view->CreateRenderingSurface(); |
| 69 | if (surface && !surface->IsValid()) { |
| 70 | surface.reset(); |
| 71 | } |
| 72 | latch.Signal(); |
| 73 | }); |
| 74 | latch.Wait(); |
| 75 | if (!surface) { |
| 76 | FML_LOG(ERROR) << "Failed to create platform view rendering surface" ; |
| 77 | return; |
| 78 | } |
| 79 | delegate_.OnPlatformViewCreated(surface: std::move(surface)); |
| 80 | } |
| 81 | |
| 82 | void PlatformView::NotifyDestroyed() { |
| 83 | delegate_.OnPlatformViewDestroyed(); |
| 84 | } |
| 85 | |
| 86 | void PlatformView::ScheduleFrame() { |
| 87 | delegate_.OnPlatformViewScheduleFrame(); |
| 88 | } |
| 89 | |
| 90 | sk_sp<GrDirectContext> PlatformView::CreateResourceContext() const { |
| 91 | FML_DLOG(WARNING) << "This platform does not set up the resource " |
| 92 | "context on the IO thread for async texture uploads." ; |
| 93 | return nullptr; |
| 94 | } |
| 95 | |
| 96 | std::shared_ptr<impeller::Context> PlatformView::GetImpellerContext() const { |
| 97 | return nullptr; |
| 98 | } |
| 99 | |
| 100 | void PlatformView::ReleaseResourceContext() const {} |
| 101 | |
| 102 | PointerDataDispatcherMaker PlatformView::GetDispatcherMaker() { |
| 103 | return [](DefaultPointerDataDispatcher::Delegate& delegate) { |
| 104 | return std::make_unique<DefaultPointerDataDispatcher>(args&: delegate); |
| 105 | }; |
| 106 | } |
| 107 | |
| 108 | fml::WeakPtr<PlatformView> PlatformView::GetWeakPtr() const { |
| 109 | return weak_factory_.GetWeakPtr(); |
| 110 | } |
| 111 | |
| 112 | void PlatformView::UpdateSemantics( |
| 113 | SemanticsNodeUpdates update, // NOLINT(performance-unnecessary-value-param) |
| 114 | // NOLINTNEXTLINE(performance-unnecessary-value-param) |
| 115 | CustomAccessibilityActionUpdates actions) {} |
| 116 | |
| 117 | void PlatformView::HandlePlatformMessage( |
| 118 | std::unique_ptr<PlatformMessage> message) { |
| 119 | if (auto response = message->response()) { |
| 120 | response->CompleteEmpty(); |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | void PlatformView::OnPreEngineRestart() const {} |
| 125 | |
| 126 | void PlatformView::RegisterTexture(std::shared_ptr<flutter::Texture> texture) { |
| 127 | delegate_.OnPlatformViewRegisterTexture(texture: std::move(texture)); |
| 128 | } |
| 129 | |
| 130 | void PlatformView::UnregisterTexture(int64_t texture_id) { |
| 131 | delegate_.OnPlatformViewUnregisterTexture(texture_id); |
| 132 | } |
| 133 | |
| 134 | void PlatformView::MarkTextureFrameAvailable(int64_t texture_id) { |
| 135 | delegate_.OnPlatformViewMarkTextureFrameAvailable(texture_id); |
| 136 | } |
| 137 | |
| 138 | std::unique_ptr<Surface> PlatformView::CreateRenderingSurface() { |
| 139 | // We have a default implementation because tests create a platform view but |
| 140 | // never a rendering surface. |
| 141 | FML_DCHECK(false) << "This platform does not provide a rendering surface but " |
| 142 | "it was notified of surface rendering surface creation." ; |
| 143 | return nullptr; |
| 144 | } |
| 145 | |
| 146 | std::shared_ptr<ExternalViewEmbedder> |
| 147 | PlatformView::CreateExternalViewEmbedder() { |
| 148 | FML_DLOG(WARNING) |
| 149 | << "This platform doesn't support embedding external views." ; |
| 150 | return nullptr; |
| 151 | } |
| 152 | |
| 153 | void PlatformView::SetNextFrameCallback(const fml::closure& closure) { |
| 154 | if (!closure) { |
| 155 | return; |
| 156 | } |
| 157 | |
| 158 | delegate_.OnPlatformViewSetNextFrameCallback(closure); |
| 159 | } |
| 160 | |
| 161 | std::unique_ptr<std::vector<std::string>> |
| 162 | PlatformView::ComputePlatformResolvedLocales( |
| 163 | const std::vector<std::string>& supported_locale_data) { |
| 164 | std::unique_ptr<std::vector<std::string>> out = |
| 165 | std::make_unique<std::vector<std::string>>(); |
| 166 | return out; |
| 167 | } |
| 168 | |
| 169 | void PlatformView::RequestDartDeferredLibrary(intptr_t loading_unit_id) {} |
| 170 | |
| 171 | void PlatformView::LoadDartDeferredLibrary( |
| 172 | intptr_t loading_unit_id, |
| 173 | std::unique_ptr<const fml::Mapping> snapshot_data, |
| 174 | std::unique_ptr<const fml::Mapping> snapshot_instructions) {} |
| 175 | |
| 176 | void PlatformView::LoadDartDeferredLibraryError( |
| 177 | intptr_t loading_unit_id, |
| 178 | const std::string |
| 179 | error_message, // NOLINT(performance-unnecessary-value-param) |
| 180 | bool transient) {} |
| 181 | |
| 182 | void PlatformView::UpdateAssetResolverByType( |
| 183 | std::unique_ptr<AssetResolver> updated_asset_resolver, |
| 184 | AssetResolver::AssetResolverType type) { |
| 185 | delegate_.UpdateAssetResolverByType(updated_asset_resolver: std::move(updated_asset_resolver), type); |
| 186 | } |
| 187 | |
| 188 | std::unique_ptr<SnapshotSurfaceProducer> |
| 189 | PlatformView::CreateSnapshotSurfaceProducer() { |
| 190 | return nullptr; |
| 191 | } |
| 192 | |
| 193 | std::shared_ptr<PlatformMessageHandler> |
| 194 | PlatformView::GetPlatformMessageHandler() const { |
| 195 | return nullptr; |
| 196 | } |
| 197 | |
| 198 | const Settings& PlatformView::GetSettings() const { |
| 199 | return delegate_.OnPlatformViewGetSettings(); |
| 200 | } |
| 201 | |
| 202 | } // namespace flutter |
| 203 | |