| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "flutter/shell/common/platform_view.h" | |
| #include <utility> | |
| #include "flutter/fml/make_copyable.h" | |
| #include "flutter/fml/synchronization/waitable_event.h" | |
| #include "flutter/shell/common/vsync_waiter_fallback.h" | |
| #include "third_party/skia/include/gpu/gl/GrGLInterface.h" | |
| namespace flutter { | |
| PlatformView::PlatformView(Delegate& delegate, const TaskRunners& task_runners) | |
| : delegate_(delegate), task_runners_(task_runners), weak_factory_(this) {} | |
| PlatformView::~PlatformView() = default; | |
| std::unique_ptr<VsyncWaiter> PlatformView::CreateVSyncWaiter() { | |
| FML_DLOG(WARNING) | |
| << "This platform does not provide a Vsync waiter implementation. A " | |
| "simple timer based fallback is being used."; | |
| return std::make_unique<VsyncWaiterFallback>(task_runners_); | |
| } | |
| void PlatformView::DispatchPlatformMessage( | |
| std::unique_ptr<PlatformMessage> message) { | |
| delegate_.OnPlatformViewDispatchPlatformMessage(std::move(message)); | |
| } | |
| void PlatformView::DispatchPointerDataPacket( | |
| std::unique_ptr<PointerDataPacket> packet) { | |
| delegate_.OnPlatformViewDispatchPointerDataPacket( | |
| pointer_data_packet_converter_.Convert(std::move(packet))); | |
| } | |
| void PlatformView::DispatchSemanticsAction(int32_t node_id, | |
| SemanticsAction action, | |
| fml::MallocMapping args) { | |
| delegate_.OnPlatformViewDispatchSemanticsAction(node_id, action, | |
| std::move(args)); | |
| } | |
| void PlatformView::SetSemanticsEnabled(bool enabled) { | |
| delegate_.OnPlatformViewSetSemanticsEnabled(enabled); | |
| } | |
| void PlatformView::SetAccessibilityFeatures(int32_t flags) { | |
| delegate_.OnPlatformViewSetAccessibilityFeatures(flags); | |
| } | |
| void PlatformView::SetViewportMetrics(int64_t view_id, | |
| const ViewportMetrics& metrics) { | |
| delegate_.OnPlatformViewSetViewportMetrics(view_id, metrics); | |
| } | |
| void PlatformView::NotifyCreated() { | |
| std::unique_ptr<Surface> surface; | |
| // Threading: We want to use the platform view on the non-platform thread. | |
| // Using the weak pointer is illegal. But, we are going to introduce a latch | |
| // so that the platform view is not collected till the surface is obtained. | |
| auto* platform_view = this; | |
| fml::ManualResetWaitableEvent latch; | |
| fml::TaskRunner::RunNowOrPostTask( | |
| task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() { | |
| surface = platform_view->CreateRenderingSurface(); | |
| if (surface && !surface->IsValid()) { | |
| surface.reset(); | |
| } | |
| latch.Signal(); | |
| }); | |
| latch.Wait(); | |
| if (!surface) { | |
| FML_LOG(ERROR) << "Failed to create platform view rendering surface"; | |
| return; | |
| } | |
| delegate_.OnPlatformViewCreated(std::move(surface)); | |
| } | |
| void PlatformView::NotifyDestroyed() { | |
| delegate_.OnPlatformViewDestroyed(); | |
| } | |
| void PlatformView::ScheduleFrame() { | |
| delegate_.OnPlatformViewScheduleFrame(); | |
| } | |
| sk_sp<GrDirectContext> PlatformView::CreateResourceContext() const { | |
| FML_DLOG(WARNING) << "This platform does not set up the resource " | |
| "context on the IO thread for async texture uploads."; | |
| return nullptr; | |
| } | |
| std::shared_ptr<impeller::Context> PlatformView::GetImpellerContext() const { | |
| return nullptr; | |
| } | |
| void PlatformView::ReleaseResourceContext() const {} | |
| PointerDataDispatcherMaker PlatformView::GetDispatcherMaker() { | |
| return [](DefaultPointerDataDispatcher::Delegate& delegate) { | |
| return std::make_unique<DefaultPointerDataDispatcher>(delegate); | |
| }; | |
| } | |
| fml::WeakPtr<PlatformView> PlatformView::GetWeakPtr() const { | |
| return weak_factory_.GetWeakPtr(); | |
| } | |
| void PlatformView::UpdateSemantics( | |
| SemanticsNodeUpdates update, // NOLINT(performance-unnecessary-value-param) | |
| // NOLINTNEXTLINE(performance-unnecessary-value-param) | |
| CustomAccessibilityActionUpdates actions) {} | |
| void PlatformView::SendChannelUpdate(const std::string& name, bool listening) {} | |
| void PlatformView::HandlePlatformMessage( | |
| std::unique_ptr<PlatformMessage> message) { | |
| if (auto response = message->response()) { | |
| response->CompleteEmpty(); | |
| } | |
| } | |
| void PlatformView::OnPreEngineRestart() const {} | |
| void PlatformView::RegisterTexture(std::shared_ptr<flutter::Texture> texture) { | |
| delegate_.OnPlatformViewRegisterTexture(std::move(texture)); | |
| } | |
| void PlatformView::UnregisterTexture(int64_t texture_id) { | |
| delegate_.OnPlatformViewUnregisterTexture(texture_id); | |
| } | |
| void PlatformView::MarkTextureFrameAvailable(int64_t texture_id) { | |
| delegate_.OnPlatformViewMarkTextureFrameAvailable(texture_id); | |
| } | |
| std::unique_ptr<Surface> PlatformView::CreateRenderingSurface() { | |
| // We have a default implementation because tests create a platform view but | |
| // never a rendering surface. | |
| FML_DCHECK(false) << "This platform does not provide a rendering surface but " | |
| "it was notified of surface rendering surface creation."; | |
| return nullptr; | |
| } | |
| std::shared_ptr<ExternalViewEmbedder> | |
| PlatformView::CreateExternalViewEmbedder() { | |
| FML_DLOG(WARNING) | |
| << "This platform doesn't support embedding external views."; | |
| return nullptr; | |
| } | |
| void PlatformView::SetNextFrameCallback(const fml::closure& closure) { | |
| if (!closure) { | |
| return; | |
| } | |
| delegate_.OnPlatformViewSetNextFrameCallback(closure); | |
| } | |
| std::unique_ptr<std::vector<std::string>> | |
| PlatformView::ComputePlatformResolvedLocales( | |
| const std::vector<std::string>& supported_locale_data) { | |
| std::unique_ptr<std::vector<std::string>> out = | |
| std::make_unique<std::vector<std::string>>(); | |
| return out; | |
| } | |
| void PlatformView::RequestDartDeferredLibrary(intptr_t loading_unit_id) {} | |
| void PlatformView::LoadDartDeferredLibrary( | |
| intptr_t loading_unit_id, | |
| std::unique_ptr<const fml::Mapping> snapshot_data, | |
| std::unique_ptr<const fml::Mapping> snapshot_instructions) {} | |
| void PlatformView::LoadDartDeferredLibraryError( | |
| intptr_t loading_unit_id, | |
| const std::string | |
| error_message, // NOLINT(performance-unnecessary-value-param) | |
| bool transient) {} | |
| void PlatformView::UpdateAssetResolverByType( | |
| std::unique_ptr<AssetResolver> updated_asset_resolver, | |
| AssetResolver::AssetResolverType type) { | |
| delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type); | |
| } | |
| std::unique_ptr<SnapshotSurfaceProducer> | |
| PlatformView::CreateSnapshotSurfaceProducer() { | |
| return nullptr; | |
| } | |
| std::shared_ptr<PlatformMessageHandler> | |
| PlatformView::GetPlatformMessageHandler() const { | |
| return nullptr; | |
| } | |
| const Settings& PlatformView::GetSettings() const { | |
| return delegate_.OnPlatformViewGetSettings(); | |
| } | |
| double PlatformView::GetScaledFontSize(double unscaled_font_size, | |
| int configuration_id) const { | |
| // Unreachable by default, as most platforms do not support nonlinear scaling | |
| // and the Flutter application never invokes this method. | |
| FML_UNREACHABLE(); | |
| return -1; | |
| } | |
| } // namespace flutter |