diff --git a/DEPS b/DEPS index 00613ee22272d114851f745d7d3a86c1a6e9d348..6b76d67750ee271d6a0b6257e4e6516d8a85b553 100644 --- a/DEPS +++ b/DEPS @@ -54,7 +54,7 @@ deps = { # and not have to specific specific hashes. 'src/lib/ftl': - Var('fuchsia_git') + '/ftl' + '@' + 'e8d8bf108418d5de96971ecd04b7cc0a58d8a568', + Var('fuchsia_git') + '/ftl' + '@' + '9f51f24056554352b045fda338e9101c0e5af272', 'src/lib/tonic': Var('fuchsia_git') + '/tonic' + '@' + 'e1d221b924cb2a604363a8a9dd393d319becc0e8', diff --git a/services/engine/sky_engine.mojom b/services/engine/sky_engine.mojom index 27a94f1f44b642aeef6aa1bbd149222768ba4c7f..34aadc8b3207a5ef6f201e637448b24f8fc1abae 100644 --- a/services/engine/sky_engine.mojom +++ b/services/engine/sky_engine.mojom @@ -24,17 +24,8 @@ struct ViewportMetrics { uint32 scene_version; }; -struct ServicesData { - mojo.Shell? shell; - mojo.ServiceProvider? incoming_services; - mojo.ServiceProvider&? outgoing_services; - mojo.ServiceProvider? view_services; -}; - [ServiceName="sky::SkyEngine"] interface SkyEngine { - SetServices(ServicesData services); - OnAppLifecycleStateChanged(AppLifecycleState state); OnViewportMetricsChanged(ViewportMetrics metrics); diff --git a/services/vsync/BUILD.gn b/services/vsync/BUILD.gn deleted file mode 100644 index e7d7ef0f6af1b08b2dde4efb0e42dc1825f129bf..0000000000000000000000000000000000000000 --- a/services/vsync/BUILD.gn +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//mojo/public/tools/bindings/mojom.gni") - -source_set("vsync_lib_fallback") { - sources = [ - "fallback/vsync_provider_fallback_impl.h", - "fallback/vsync_provider_fallback_impl.cc", - ] - - deps = [ - "//base:base", - "//mojo/public/cpp/application", - "//mojo/public/cpp/bindings:utility", - "//mojo/services/vsync/interfaces", - ] -} - -group("vsync") { - public_deps = [ - ":vsync_lib", - ":vsync_lib_fallback", - ] -} - -if (is_android) { - # Choreographer backed VSync - import("//build/config/android/config.gni") - import("//build/config/android/rules.gni") - - android_library("vsync_lib") { - java_files = [ "src/org/domokit/vsync/VSyncProviderImpl.java" ] - - deps = [ - "//base:base_java", - "//mojo/public/java:bindings", - "//mojo/public/java:system", - "//mojo/services/vsync/interfaces:interfaces_java", - ] - } -} else if (is_ios) { - # DisplayLink backed VSync - source_set("vsync_lib") { - sources = [ - "ios/vsync_provider_ios_impl.h", - "ios/vsync_provider_ios_impl.mm", - ] - - deps = [ - "//base:base", - "//mojo/public/cpp/application", - "//mojo/public/cpp/bindings:utility", - "//mojo/services/vsync/interfaces", - ] - } -} else if (is_mac) { - # CVDisplayLink backed VSync - source_set("vsync_lib") { - sources = [ - "mac/vsync_provider_mac_impl.h", - "mac/vsync_provider_mac_impl.cc", - ] - - deps = [ - "//base:base", - "//mojo/public/cpp/application", - "//mojo/public/cpp/bindings:utility", - "//mojo/services/vsync/interfaces", - ] - } -} else { - group("vsync_lib") { - # Empty, will use fallbacks by default. - } -} diff --git a/services/vsync/fallback/vsync_provider_fallback_impl.cc b/services/vsync/fallback/vsync_provider_fallback_impl.cc deleted file mode 100644 index b432c7cc9aa5148e491f5e9df2430c8b5a9b059f..0000000000000000000000000000000000000000 --- a/services/vsync/fallback/vsync_provider_fallback_impl.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2016 The Chromium 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/services/vsync/fallback/vsync_provider_fallback_impl.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/message_loop/message_loop.h" - -namespace sky { -namespace services { -namespace vsync { - -VsyncProviderFallbackImpl::VsyncProviderFallbackImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider> request) - : binding_(this, request.Pass()), - phase_(base::TimeTicks::Now()), - armed_(false), - weak_factory_(this) {} - -VsyncProviderFallbackImpl::~VsyncProviderFallbackImpl() = default; - -void VsyncProviderFallbackImpl::AwaitVSync(const AwaitVSyncCallback& callback) { - pending_.emplace_back(std::move(callback)); - ArmIfNecessary(); -} - -void VsyncProviderFallbackImpl::ArmIfNecessary() { - if (armed_) { - return; - } - - armed_ = true; - - const base::TimeDelta interval = base::TimeDelta::FromSecondsD(1.0 / 60.0); - - const base::TimeTicks now = base::TimeTicks::Now(); - const base::TimeTicks next = now.SnappedToNextTick(phase_, interval); - - auto callback = base::Bind(&VsyncProviderFallbackImpl::OnFakeVSync, - weak_factory_.GetWeakPtr()); - - base::MessageLoop::current()->PostDelayedTask(FROM_HERE, callback, - next - now); -} - -void VsyncProviderFallbackImpl::OnFakeVSync() { - DCHECK(armed_); - - armed_ = false; - - auto now = base::TimeTicks::Now().ToInternalValue(); - - for (const auto& callback : pending_) { - callback.Run(now); - } - - pending_.clear(); -} - -} // namespace vsync -} // namespace services -} // namespace sky diff --git a/services/vsync/fallback/vsync_provider_fallback_impl.h b/services/vsync/fallback/vsync_provider_fallback_impl.h deleted file mode 100644 index ea06e3f50cf08f7597dcb0067f5e7dc52e806f83..0000000000000000000000000000000000000000 --- a/services/vsync/fallback/vsync_provider_fallback_impl.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_SERVICES_VSYNC_FALLBACK_VSYNCPROVIDERFALLBACKIMPL_H_ -#define FLUTTER_SERVICES_VSYNC_FALLBACK_VSYNCPROVIDERFALLBACKIMPL_H_ - -#include "base/macros.h" -#include "base/time/time.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/services/vsync/interfaces/vsync.mojom.h" -#include "base/memory/weak_ptr.h" - -#include - -namespace sky { -namespace services { -namespace vsync { - -class VsyncProviderFallbackImpl : public ::vsync::VSyncProvider { - public: - explicit VsyncProviderFallbackImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider> request); - - ~VsyncProviderFallbackImpl() override; - - void AwaitVSync(const AwaitVSyncCallback& callback) override; - - private: - mojo::StrongBinding<::vsync::VSyncProvider> binding_; - std::vector pending_; - base::TimeTicks phase_; - bool armed_; - base::WeakPtrFactory weak_factory_; - - void ArmIfNecessary(); - void OnFakeVSync(); - - DISALLOW_COPY_AND_ASSIGN(VsyncProviderFallbackImpl); -}; - -} // namespace vsync -} // namespace services -} // namespace sky - -#endif // FLUTTER_SERVICES_VSYNC_FALLBACK_VSYNCPROVIDERFALLBACKIMPL_H_ diff --git a/services/vsync/ios/vsync_provider_ios_impl.h b/services/vsync/ios/vsync_provider_ios_impl.h deleted file mode 100644 index 658283b95ac14269dde90d880ae1ba982feab765..0000000000000000000000000000000000000000 --- a/services/vsync/ios/vsync_provider_ios_impl.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_SERVICES_VSYNC_IOS_VSYNCPROVIDERIOSIMPL_H_ -#define FLUTTER_SERVICES_VSYNC_IOS_VSYNCPROVIDERIOSIMPL_H_ - -#include "base/macros.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/services/vsync/interfaces/vsync.mojom.h" - -#if __OBJC__ -@class VSyncClient; -#else // __OBJC__ -class VSyncClient; -#endif // __OBJC__ - -namespace sky { -namespace services { -namespace vsync { - -class VsyncProviderIOSImpl : public ::vsync::VSyncProvider { - public: - explicit VsyncProviderIOSImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider> request); - ~VsyncProviderIOSImpl() override; - void AwaitVSync(const AwaitVSyncCallback& callback) override; - - private: - mojo::StrongBinding<::vsync::VSyncProvider> binding_; - VSyncClient* client_; - - DISALLOW_COPY_AND_ASSIGN(VsyncProviderIOSImpl); -}; - -} // namespace vsync -} // namespace services -} // namespace sky - -#endif // FLUTTER_SERVICES_VSYNC_IOS_VSYNCPROVIDERIOSIMPL_H_ diff --git a/services/vsync/ios/vsync_provider_ios_impl.mm b/services/vsync/ios/vsync_provider_ios_impl.mm deleted file mode 100644 index 0f75c96dc36b4d7a4b16fa2fe405f675cd3f6036..0000000000000000000000000000000000000000 --- a/services/vsync/ios/vsync_provider_ios_impl.mm +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2015 The Chromium 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/services/vsync/ios/vsync_provider_ios_impl.h" -#include "base/trace_event/trace_event.h" - -#include -#include -#include -#include - -@interface VSyncClient : NSObject - -@end - -static inline uint64_t CurrentTimeMicroseconds() { - static mach_timebase_info_data_t timebase = {0}; - - if (timebase.denom == 0) { - (void)mach_timebase_info(&timebase); - } - - return (mach_absolute_time() * 1e-3 * timebase.numer) / timebase.denom; -} - -@implementation VSyncClient { - CADisplayLink* _displayLink; - std::vector<::vsync::VSyncProvider::AwaitVSyncCallback> _pendingCallbacks; -} - -- (instancetype)init { - self = [super init]; - - if (self) { - _displayLink = [[CADisplayLink - displayLinkWithTarget:self - selector:@selector(onDisplayLink:)] retain]; - _displayLink.paused = YES; - [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; - } - - return self; -} - -- (void)await:(::vsync::VSyncProvider::AwaitVSyncCallback)callback { - _pendingCallbacks.push_back(callback); - _displayLink.paused = NO; -} - -- (void)onDisplayLink:(CADisplayLink*)link { - TRACE_EVENT_INSTANT0("flutter", "PlatformVSync", TRACE_EVENT_SCOPE_PROCESS); - _displayLink.paused = YES; - uint64_t micros = CurrentTimeMicroseconds(); - for (const auto& callback : _pendingCallbacks) { - callback.Run(micros); - } - _pendingCallbacks.clear(); -} - -- (void)dealloc { - [_displayLink invalidate]; - [_displayLink release]; - - [super dealloc]; -} - -@end - -namespace sky { -namespace services { -namespace vsync { - -VsyncProviderIOSImpl::VsyncProviderIOSImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider> request) - : binding_(this, request.Pass()), client_([[VSyncClient alloc] init]) {} - -VsyncProviderIOSImpl::~VsyncProviderIOSImpl() { - [client_ release]; -} - -void VsyncProviderIOSImpl::AwaitVSync(const AwaitVSyncCallback& callback) { - [client_ await:callback]; -} - -} // namespace vsync -} // namespace services -} // namespace sky diff --git a/services/vsync/mac/vsync_provider_mac_impl.cc b/services/vsync/mac/vsync_provider_mac_impl.cc deleted file mode 100644 index 4bde37e0505af54ee352789c82bbb74ed63c8d7d..0000000000000000000000000000000000000000 --- a/services/vsync/mac/vsync_provider_mac_impl.cc +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2015 The Chromium 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/services/vsync/mac/vsync_provider_mac_impl.h" -#include "base/trace_event/trace_event.h" - -#include -#include - -namespace sky { -namespace services { -namespace vsync { - -#define link_ (reinterpret_cast(opaque_)) - -VsyncProviderMacImpl::VsyncProviderMacImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider> request) - : binding_(this, request.Pass()), opaque_(nullptr) { - // Create the link. - CVDisplayLinkRef link = nullptr; - CVDisplayLinkCreateWithActiveCGDisplays(&link); - opaque_ = link; - - // Set the output callback. - CVDisplayLinkSetOutputCallback( - link_, - [](CVDisplayLinkRef link, const CVTimeStamp* now, - const CVTimeStamp* output, CVOptionFlags flags_in, - CVOptionFlags* flags_out, void* context) -> CVReturn { - OnDisplayLink(context); - return kCVReturnSuccess; - }, - this); -} - -VsyncProviderMacImpl::~VsyncProviderMacImpl() { - CVDisplayLinkRelease(link_); -} - -static inline uint64_t CurrentTimeMicroseconds() { - static mach_timebase_info_data_t timebase = {0}; - - if (timebase.denom == 0) { - (void)mach_timebase_info(&timebase); - } - - return (mach_absolute_time() * 1e-3 * timebase.numer) / timebase.denom; -} - -void VsyncProviderMacImpl::OnDisplayLink(void* thiz) { - reinterpret_cast(thiz)->OnDisplayLink(); -} - -void VsyncProviderMacImpl::OnDisplayLink() { - TRACE_EVENT_INSTANT1("flutter", "PlatformVSync", TRACE_EVENT_SCOPE_PROCESS, - "items", pending_callbacks_.size()); - // Stop the link. - CVDisplayLinkStop(link_); - - // Fire all callbacks and clear. - uint64_t micros = CurrentTimeMicroseconds(); - for (const auto& callback : pending_callbacks_) { - callback.Run(micros); - } - - pending_callbacks_.clear(); -} - -void VsyncProviderMacImpl::AwaitVSync(const AwaitVSyncCallback& callback) { - pending_callbacks_.push_back(callback); - CVDisplayLinkStart(link_); -} - -} // namespace vsync -} // namespace services -} // namespace sky diff --git a/services/vsync/mac/vsync_provider_mac_impl.h b/services/vsync/mac/vsync_provider_mac_impl.h deleted file mode 100644 index 12bb1cbe2e942572257c7a4118b8c0ae20856585..0000000000000000000000000000000000000000 --- a/services/vsync/mac/vsync_provider_mac_impl.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_SERVICES_VSYNC_MAC_VSYNCPROVIDERMACIMPL_H_ -#define FLUTTER_SERVICES_VSYNC_MAC_VSYNCPROVIDERMACIMPL_H_ - -#include - -#include "base/macros.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/services/vsync/interfaces/vsync.mojom.h" - -namespace sky { -namespace services { -namespace vsync { - -class VsyncProviderMacImpl : public ::vsync::VSyncProvider { - public: - explicit VsyncProviderMacImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider> request); - - ~VsyncProviderMacImpl() override; - - void AwaitVSync(const AwaitVSyncCallback& callback) override; - - private: - mojo::StrongBinding<::vsync::VSyncProvider> binding_; - void* opaque_; - std::vector<::vsync::VSyncProvider::AwaitVSyncCallback> pending_callbacks_; - - static void OnDisplayLink(void* thiz); - void OnDisplayLink(); - - DISALLOW_COPY_AND_ASSIGN(VsyncProviderMacImpl); -}; - -} // namespace vsync -} // namespace services -} // namespace sky - -#endif // FLUTTER_SERVICES_VSYNC_MAC_VSYNCPROVIDERMACIMPL_H_ diff --git a/services/vsync/src/org/domokit/vsync/VSyncProviderImpl.java b/services/vsync/src/org/domokit/vsync/VSyncProviderImpl.java deleted file mode 100644 index 317a6779c9f3aea57c532b804abe2d30ff9ca789..0000000000000000000000000000000000000000 --- a/services/vsync/src/org/domokit/vsync/VSyncProviderImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.domokit.vsync; - -import android.view.Choreographer; - -import org.chromium.base.TraceEvent; -import org.chromium.mojo.system.MessagePipeHandle; -import org.chromium.mojo.system.MojoException; -import org.chromium.mojom.vsync.VSyncProvider; - -import java.util.ArrayList; - -/** - * Android implementation of VSyncProvider. - */ -public class VSyncProviderImpl implements VSyncProvider, Choreographer.FrameCallback { - private Choreographer mChoreographer; - private ArrayList mCallbacks = new ArrayList(); - private MessagePipeHandle mPipe; - - public VSyncProviderImpl(MessagePipeHandle pipe) { - mPipe = pipe; - mChoreographer = Choreographer.getInstance(); - } - - @Override - public void close() {} - - @Override - public void onConnectionError(MojoException e) {} - - @Override - public void awaitVSync(final AwaitVSyncResponse callback) { - mCallbacks.add(callback); - if (mCallbacks.size() == 1) { - mChoreographer.postFrameCallback(this); - } - } - - @Override - public void doFrame(long frameTimeNanos) { - TraceEvent.instant("PlatformVSync"); - long frameTimeMicros = frameTimeNanos / 1000; - for (AwaitVSyncResponse callback : mCallbacks) { - callback.call(frameTimeMicros); - } - mCallbacks.clear(); - } -} diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 4a5319b9fd8bb3d761d795d02bd498f742e9db90..cee06445e7223e4614ec9b454eddb095b0f4e55e 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -40,6 +40,10 @@ source_set("common") { "switches.h", "tracing_controller.cc", "tracing_controller.h", + "vsync_waiter.cc", + "vsync_waiter.h", + "vsync_waiter_fallback.cc", + "vsync_waiter_fallback.h", ] deps = [ @@ -54,7 +58,6 @@ source_set("common") { "//flutter/lib/ui", "//flutter/runtime", "//flutter/services/engine:interfaces", - "//flutter/services/vsync", "//flutter/skia", "//flutter/sky/engine/wtf", "//flutter/synchronization", diff --git a/shell/common/animator.cc b/shell/common/animator.cc index ddedfc8eb3a3ada9c3b44d9343d3f94cedbd342e..15768fc9737c5ce4d12f6aec52cb52dc1932208d 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -12,17 +12,16 @@ namespace shell { -Animator::Animator(ftl::WeakPtr rasterizer, Engine* engine) +Animator::Animator(ftl::WeakPtr rasterizer, + VsyncWaiter* waiter, + Engine* engine) : rasterizer_(rasterizer), + waiter_(waiter), engine_(engine), layer_tree_pipeline_(ftl::MakeRefCounted(3)), pending_frame_semaphore_(1), paused_(false), - weak_factory_(this) { - new sky::services::vsync::VsyncProviderFallbackImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider>( - mojo::GetProxy(&fallback_vsync_provider_))); -} + weak_factory_(this) {} Animator::~Animator() = default; @@ -39,7 +38,7 @@ void Animator::Start() { RequestFrame(); } -void Animator::BeginFrame(int64_t time_stamp) { +void Animator::BeginFrame(ftl::TimePoint frame_time) { pending_frame_semaphore_.Signal(); if (!producer_continuation_) { @@ -63,6 +62,8 @@ void Animator::BeginFrame(int64_t time_stamp) { // to service potential frame. DCHECK(producer_continuation_); + // TODO(abarth): We should use |frame_time| instead, but the frame time we get + // on Android appears to be unstable. last_begin_frame_time_ = ftl::TimePoint::Now(); engine_->BeginFrame(last_begin_frame_time_); } @@ -92,7 +93,7 @@ void Animator::RequestFrame() { if (!pending_frame_semaphore_.TryWait()) { // Multiple calls to Animator::RequestFrame will still result in a single - // request to the VSyncProvider. + // request to the VsyncWaiter. return; } @@ -107,30 +108,16 @@ void Animator::RequestFrame() { if (!self.get()) return; TRACE_EVENT_INSTANT0("flutter", "RequestFrame", TRACE_EVENT_SCOPE_PROCESS); - self->AwaitVSync(base::Bind(&Animator::BeginFrame, self)); + self->AwaitVSync(); }); } -void Animator::set_vsync_provider(vsync::VSyncProviderPtr vsync_provider) { - vsync_provider_ = vsync_provider.Pass(); - - // We may be waiting on a VSync signal from the old VSync provider. - pending_frame_semaphore_.Signal(); - - RequestFrame(); -} - -void Animator::AwaitVSync( - const vsync::VSyncProvider::AwaitVSyncCallback& callback) { - // First, try the platform provided VSync provider. - if (vsync_provider_) { - vsync_provider_->AwaitVSync(callback); - return; - } - - // Then, use the fallback provider if the platform cannot reliably supply - // VSync signals to us. - return fallback_vsync_provider_->AwaitVSync(callback); +void Animator::AwaitVSync() { + waiter_->AsyncWaitForVsync([self = weak_factory_.GetWeakPtr()]( + ftl::TimePoint frame_time) { + if (self) + self->BeginFrame(frame_time); + }); } } // namespace shell diff --git a/shell/common/animator.h b/shell/common/animator.h index 107cfa51123f1f94de93ce8f735576f413a14732..fc84fe62ec0dccfb2d9daa06be279c0351cfd717 100644 --- a/shell/common/animator.h +++ b/shell/common/animator.h @@ -2,24 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_COMMON_ANIMATOR_H_ -#define SHELL_COMMON_ANIMATOR_H_ +#ifndef FLUTTER_SHELL_COMMON_ANIMATOR_H_ +#define FLUTTER_SHELL_COMMON_ANIMATOR_H_ -#include "base/memory/weak_ptr.h" -#include "flutter/services/vsync/fallback/vsync_provider_fallback_impl.h" #include "flutter/shell/common/engine.h" #include "flutter/shell/common/rasterizer.h" +#include "flutter/shell/common/vsync_waiter.h" #include "flutter/synchronization/pipeline.h" #include "flutter/synchronization/semaphore.h" #include "lib/ftl/memory/ref_ptr.h" +#include "lib/ftl/memory/weak_ptr.h" #include "lib/ftl/time/time_point.h" -#include "mojo/services/vsync/interfaces/vsync.mojom.h" namespace shell { class Animator { public: - explicit Animator(ftl::WeakPtr rasterizer, Engine* engine); + Animator(ftl::WeakPtr rasterizer, + VsyncWaiter* waiter, + Engine* engine); ~Animator(); @@ -31,30 +32,28 @@ class Animator { void Stop(); - void set_vsync_provider(vsync::VSyncProviderPtr vsync_provider); - private: using LayerTreePipeline = flutter::Pipeline; - void BeginFrame(int64_t time_stamp); + void BeginFrame(ftl::TimePoint frame_time); - void AwaitVSync(const vsync::VSyncProvider::AwaitVSyncCallback& callback); + void AwaitVSync(); ftl::WeakPtr rasterizer_; + VsyncWaiter* waiter_; Engine* engine_; - vsync::VSyncProviderPtr vsync_provider_; - vsync::VSyncProviderPtr fallback_vsync_provider_; + ftl::TimePoint last_begin_frame_time_; ftl::RefPtr layer_tree_pipeline_; flutter::Semaphore pending_frame_semaphore_; LayerTreePipeline::ProducerContinuation producer_continuation_; bool paused_; - base::WeakPtrFactory weak_factory_; + ftl::WeakPtrFactory weak_factory_; FTL_DISALLOW_COPY_AND_ASSIGN(Animator); }; } // namespace shell -#endif // SHELL_COMMON_ANIMATOR_H_ +#endif // FLUTTER_SHELL_COMMON_ANIMATOR_H_ diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 1dc4bb5b21e1f99d8305b2f088c1c19c70e2c89d..472b0c63a1fdf968634858d4cfd0315ad922096a 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -52,8 +52,10 @@ std::string FindPackagesPath(const std::string& main_dart) { Engine::Engine(PlatformView* platform_view) : platform_view_(platform_view->GetWeakPtr()), - animator_(new Animator(platform_view->rasterizer().GetWeakRasterizerPtr(), - this)), + animator_(std::make_unique( + platform_view->rasterizer().GetWeakRasterizerPtr(), + platform_view->GetVsyncWaiter(), + this)), binding_(this), activity_running_(false), have_surface_(false), @@ -119,32 +121,6 @@ void Engine::OnOutputSurfaceDestroyed(const ftl::Closure& gpu_continuation) { blink::Threads::Gpu()->PostTask(gpu_continuation); } -void Engine::SetServices(sky::ServicesDataPtr services) { - services_ = services.Pass(); - - if (services_->incoming_services) { - incoming_services_ = - mojo::ServiceProviderPtr::Create(services_->incoming_services.Pass()); - service_provider_impl_.set_fallback_service_provider( - incoming_services_.get()); - } - - vsync::VSyncProviderPtr vsync_provider; - if (services_->shell) { - // We bind and unbind our Shell here, since this is the only place we - // use - // it in this class. - auto shell = mojo::ShellPtr::Create(services_->shell.Pass()); - mojo::ConnectToService(shell.get(), "mojo:vsync", - mojo::GetProxy(&vsync_provider)); - services_->shell = shell.Pass(); - } else { - mojo::ConnectToService(incoming_services_.get(), - mojo::GetProxy(&vsync_provider)); - } - animator_->set_vsync_provider(vsync_provider.Pass()); -} - void Engine::OnViewportMetricsChanged(sky::ViewportMetricsPtr metrics) { viewport_metrics_ = metrics.Pass(); if (runtime_) @@ -307,12 +283,6 @@ void Engine::DidCreateMainIsolate(Dart_Isolate isolate) { void Engine::DidCreateSecondaryIsolate(Dart_Isolate isolate) {} -void Engine::BindToServiceProvider( - mojo::InterfaceRequest request) { - service_provider_bindings_.AddBinding(&service_provider_impl_, - request.Pass()); -} - void Engine::StopAnimator() { animator_->Stop(); } diff --git a/shell/common/engine.h b/shell/common/engine.h index c7191d6f4f60910162463cadf780c72928c7d1c6..ab78cab12ea6053f2795bd04e4f5f228e336fffd 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -63,7 +63,6 @@ class Engine : public sky::SkyEngine, public blink::RuntimeDelegate { private: // SkyEngine implementation: - void SetServices(sky::ServicesDataPtr services) override; void OnViewportMetricsChanged(sky::ViewportMetricsPtr metrics) override; void OnLocaleChanged(const mojo::String& language_code, const mojo::String& country_code) override; @@ -90,9 +89,6 @@ class Engine : public sky::SkyEngine, public blink::RuntimeDelegate { void DidCreateMainIsolate(Dart_Isolate isolate) override; void DidCreateSecondaryIsolate(Dart_Isolate isolate) override; - void BindToServiceProvider( - mojo::InterfaceRequest request); - void RunFromSnapshotStream(const std::string& script_uri, mojo::ScopedDataPipeConsumerHandle snapshot); @@ -107,11 +103,6 @@ class Engine : public sky::SkyEngine, public blink::RuntimeDelegate { ftl::WeakPtr platform_view_; std::unique_ptr animator_; - sky::ServicesDataPtr services_; - mojo::ServiceProviderImpl service_provider_impl_; - mojo::ServiceProviderPtr incoming_services_; - mojo::BindingSet service_provider_bindings_; - mojo::asset_bundle::AssetBundlePtr root_bundle_; std::unique_ptr runtime_; diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index f1c7944c5de1103cef4e1ae852b60d4c6ebb758c..cef3de79fca05e0a64ce4e7d76536e8eca990447 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -9,6 +9,7 @@ #include "flutter/common/threads.h" #include "flutter/lib/ui/painting/resource_context.h" #include "flutter/shell/common/rasterizer.h" +#include "flutter/shell/common/vsync_waiter_fallback.h" #include "lib/ftl/functional/make_copyable.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" @@ -17,9 +18,7 @@ namespace shell { PlatformView::PlatformView(std::unique_ptr rasterizer) : rasterizer_(std::move(rasterizer)), size_(SkISize::Make(0, 0)), - weak_factory_(this) { - engine_.reset(new Engine(this)); -} + weak_factory_(this) {} PlatformView::~PlatformView() { blink::Threads::UI()->PostTask( @@ -32,6 +31,10 @@ PlatformView::~PlatformView() { blink::Threads::UI()->PostTask([engine]() { delete engine; }); } +void PlatformView::CreateEngine() { + engine_.reset(new Engine(this)); +} + void PlatformView::DispatchPlatformMessage( ftl::RefPtr message) { blink::Threads::UI()->PostTask( @@ -124,6 +127,12 @@ ftl::WeakPtr PlatformView::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } +VsyncWaiter* PlatformView::GetVsyncWaiter() { + if (!vsync_waiter_) + vsync_waiter_ = std::make_unique(); + return vsync_waiter_.get(); +} + void PlatformView::UpdateSemantics(std::vector update) {} void PlatformView::HandlePlatformMessage( diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 97ff4da4b35e0d1c8bfe46612f6a2c79725381f9..2c37062fa5a49833775b58487d8b88b8a36e066d 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -11,6 +11,7 @@ #include "flutter/shell/common/engine.h" #include "flutter/shell/common/shell.h" #include "flutter/shell/common/surface.h" +#include "flutter/shell/common/vsync_waiter.h" #include "lib/ftl/macros.h" #include "lib/ftl/memory/weak_ptr.h" #include "lib/ftl/synchronization/waitable_event.h" @@ -51,6 +52,9 @@ class PlatformView { ftl::WeakPtr GetWeakPtr(); + // The VsyncWaiter will live at least as long as the PlatformView. + virtual VsyncWaiter* GetVsyncWaiter(); + virtual bool ResourceContextMakeCurrent() = 0; virtual void UpdateSemantics(std::vector update); @@ -67,12 +71,15 @@ class PlatformView { protected: explicit PlatformView(std::unique_ptr rasterizer); + void CreateEngine(); + void SetupResourceContextOnIOThreadPerform( ftl::AutoResetWaitableEvent* event); SurfaceConfig surface_config_; std::unique_ptr rasterizer_; std::unique_ptr engine_; + std::unique_ptr vsync_waiter_; SkISize size_; private: diff --git a/shell/common/vsync_waiter.cc b/shell/common/vsync_waiter.cc new file mode 100644 index 0000000000000000000000000000000000000000..5acc235b1f68d99635e0a4641bccacdc8381fb79 --- /dev/null +++ b/shell/common/vsync_waiter.cc @@ -0,0 +1,11 @@ +// Copyright 2015 The Chromium 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/vsync_waiter.h" + +namespace shell { + +VsyncWaiter::~VsyncWaiter() = default; + +} // namespace shell diff --git a/shell/common/vsync_waiter.h b/shell/common/vsync_waiter.h new file mode 100644 index 0000000000000000000000000000000000000000..c061e0e7d422c70aab173140e2be7acefbfb42cd --- /dev/null +++ b/shell/common/vsync_waiter.h @@ -0,0 +1,25 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_COMMON_VSYNC_WAITER_H_ +#define FLUTTER_SHELL_COMMON_VSYNC_WAITER_H_ + +#include + +#include "lib/ftl/time/time_point.h" + +namespace shell { + +class VsyncWaiter { + public: + using Callback = std::function; + + virtual void AsyncWaitForVsync(Callback callback) = 0; + + virtual ~VsyncWaiter(); +}; + +} // namespace shell + +#endif // FLUTTER_SHELL_COMMON_VSYNC_WAITER_H_ diff --git a/shell/common/vsync_waiter_fallback.cc b/shell/common/vsync_waiter_fallback.cc new file mode 100644 index 0000000000000000000000000000000000000000..e6c671ee346fae9ad58154aab72a7f27fe39cb0c --- /dev/null +++ b/shell/common/vsync_waiter_fallback.cc @@ -0,0 +1,51 @@ +// Copyright 2016 The Chromium 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/vsync_waiter_fallback.h" + +#include "lib/ftl/logging.h" +#include "flutter/common/threads.h" + +namespace shell { +namespace { + +ftl::TimePoint SnapToNextTick(ftl::TimePoint value, + ftl::TimePoint tick_phase, + ftl::TimeDelta tick_interval) { + ftl::TimeDelta offset = (tick_phase - value) % tick_interval; + if (offset != ftl::TimeDelta::Zero()) + offset = offset + tick_interval; + return value + offset; +} + +} // namespace + +VsyncWaiterFallback::VsyncWaiterFallback() + : phase_(ftl::TimePoint::Now()), weak_factory_(this) {} + +VsyncWaiterFallback::~VsyncWaiterFallback() = default; + +void VsyncWaiterFallback::AsyncWaitForVsync(Callback callback) { + FTL_LOG(INFO) << "VsyncWaiterFallback::AsyncWaitForVsync"; + FTL_DCHECK(!callback_); + callback_ = std::move(callback); + + constexpr ftl::TimeDelta interval = ftl::TimeDelta::FromSecondsF(1.0 / 60.0); + + ftl::TimePoint now = ftl::TimePoint::Now(); + ftl::TimePoint next = SnapToNextTick(now, phase_, interval); + + blink::Threads::UI()->PostDelayedTask( + [self = weak_factory_.GetWeakPtr()] { + if (!self) + return; + ftl::TimePoint frame_time = ftl::TimePoint::Now(); + Callback callback = std::move(self->callback_); + self->callback_ = Callback(); + callback(frame_time); + }, + next - now); +} + +} // namespace shell diff --git a/shell/common/vsync_waiter_fallback.h b/shell/common/vsync_waiter_fallback.h new file mode 100644 index 0000000000000000000000000000000000000000..d9978c2ee39166cb35d3ce4b40c90a15b02764ab --- /dev/null +++ b/shell/common/vsync_waiter_fallback.h @@ -0,0 +1,33 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_COMMON_VSYNC_WAITER_FALLBACK_H_ +#define FLUTTER_SHELL_COMMON_VSYNC_WAITER_FALLBACK_H_ + +#include "flutter/shell/common/vsync_waiter.h" +#include "lib/ftl/macros.h" +#include "lib/ftl/memory/weak_ptr.h" +#include "lib/ftl/time/time_point.h" + +namespace shell { + +class VsyncWaiterFallback : public VsyncWaiter { + public: + VsyncWaiterFallback(); + ~VsyncWaiterFallback() override; + + void AsyncWaitForVsync(Callback callback) override; + + private: + ftl::TimePoint phase_; + Callback callback_; + + ftl::WeakPtrFactory weak_factory_; + + FTL_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterFallback); +}; + +} // namespace shell + +#endif // FLUTTER_SHELL_COMMON_VSYNC_WAITER_FALLBACK_H_ diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index be515f57556488eeedb2c7a59d33e5119ce85731..cf35858707d8451391b2c50a993890b682238cd2 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -11,6 +11,7 @@ generate_jni("jni_headers") { sources = [ "io/flutter/view/FlutterMain.java", "io/flutter/view/FlutterView.java", + "io/flutter/view/VsyncWaiter.java", ] jni_package = "shell" } @@ -32,6 +33,8 @@ shared_library("sky_shell") { "library_loader.cc", "platform_view_android.cc", "platform_view_android.h", + "vsync_waiter_android.cc", + "vsync_waiter_android.h", ] deps = [ @@ -78,6 +81,7 @@ android_library("java") { "io/flutter/view/ServiceFactory.java", "io/flutter/view/ServiceProviderImpl.java", "io/flutter/view/ServiceRegistry.java", + "io/flutter/view/VsyncWaiter.java", "org/domokit/sky/shell/SkyActivity.java", "org/domokit/sky/shell/SkyApplication.java", ] @@ -86,7 +90,6 @@ android_library("java") { "//base:base_java", "//flutter/services/engine:interfaces_java", "//flutter/services/platform:interfaces_java", - "//flutter/services/vsync:vsync_lib", "//mojo/android:system_java", "//mojo/public/interfaces/application:application_java", "//mojo/public/java:bindings", diff --git a/shell/platform/android/io/flutter/view/FlutterMain.java b/shell/platform/android/io/flutter/view/FlutterMain.java index 9ee102e00a1cd1ee378cf9c761e0560bd181acd4..068f32b8e073a9fd9885a3a66c2f578f321ede21 100644 --- a/shell/platform/android/io/flutter/view/FlutterMain.java +++ b/shell/platform/android/io/flutter/view/FlutterMain.java @@ -34,8 +34,6 @@ import org.chromium.mojo.bindings.Interface.Binding; import org.chromium.mojo.system.Core; import org.chromium.mojo.system.impl.CoreImpl; import org.chromium.mojo.system.MessagePipeHandle; -import org.chromium.mojom.vsync.VSyncProvider; -import org.domokit.vsync.VSyncProviderImpl; /** * A class to intialize the Flutter engine. @@ -135,8 +133,6 @@ public class FlutterMain { // of the JNI call is negligible). long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis; nativeRecordStartTimestamp(initTimeMillis); - - onServiceRegistryAvailable(applicationContext, ServiceRegistry.SHARED); } /** @@ -179,15 +175,6 @@ public class FlutterMain { private static native void nativeInit(Context context, String[] args); private static native void nativeRecordStartTimestamp(long initTimeMillis); - private static void onServiceRegistryAvailable(final Context applicationContext, ServiceRegistry registry) { - registry.register(VSyncProvider.MANAGER.getName(), new ServiceFactory() { - @Override - public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { - return VSyncProvider.MANAGER.bind(new VSyncProviderImpl(pipe), pipe); - } - }); - } - /** * Initialize our Flutter config values by obtaining them from the * manifest XML file, falling back to default values. diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index 30d123067549d1135a49f9acae33ea059f69a7d7..c0c70ac1d0b0147a79f13465c737e828b91ecfb6 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -44,7 +44,6 @@ import org.chromium.mojo.system.Pair; import org.chromium.mojo.system.impl.CoreImpl; import org.chromium.mojom.mojo.ServiceProvider; import org.chromium.mojom.sky.AppLifecycleState; -import org.chromium.mojom.sky.ServicesData; import org.chromium.mojom.sky.SkyEngine; import org.chromium.mojom.sky.ViewportMetrics; @@ -75,8 +74,6 @@ public class FlutterView extends SurfaceView private TextInputPlugin mTextInputPlugin; private SkyEngine.Proxy mSkyEngine; - private ServiceProviderImpl mPlatformServiceProvider; - private Binding mPlatformServiceProviderBinding; private HashMap mOnMessageListeners; private HashMap mAsyncOnMessageListeners; private final SurfaceHolder.Callback mSurfaceCallback; @@ -131,8 +128,6 @@ public class FlutterView extends SurfaceView Core core = CoreImpl.getInstance(); - mPlatformServiceProvider = new ServiceProviderImpl(core, this, ServiceRegistry.SHARED); - mAccessibilityManager = (AccessibilityManager)getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); mOnMessageListeners = new HashMap(); @@ -236,11 +231,6 @@ public class FlutterView extends SurfaceView getContext().unregisterReceiver(discoveryReceiver); } - if (mPlatformServiceProviderBinding != null) { - mPlatformServiceProviderBinding.unbind().close(); - mPlatformServiceProvider.unbindServices(); - } - getHolder().removeCallback(mSurfaceCallback); nativeDetach(mNativePlatformView); mNativePlatformView = 0; @@ -446,22 +436,6 @@ public class FlutterView extends SurfaceView } private void preRun() { - if (mPlatformServiceProviderBinding != null) { - mPlatformServiceProviderBinding.unbind().close(); - mPlatformServiceProvider.unbindServices(); - } - - Core core = CoreImpl.getInstance(); - - Pair> platformServiceProvider = - ServiceProvider.MANAGER.getInterfaceRequest(core); - mPlatformServiceProviderBinding = ServiceProvider.MANAGER.bind( - mPlatformServiceProvider, platformServiceProvider.second); - - ServicesData services = new ServicesData(); - services.incomingServices = platformServiceProvider.first; - mSkyEngine.setServices(services); - resetAccessibilityTree(); } diff --git a/shell/platform/android/io/flutter/view/ServiceRegistry.java b/shell/platform/android/io/flutter/view/ServiceRegistry.java index 0973a6087afa74979d01454e5672e125505d8ea5..1c3a95d92758aff92e0f3264a8cb8fe43c49e251 100644 --- a/shell/platform/android/io/flutter/view/ServiceRegistry.java +++ b/shell/platform/android/io/flutter/view/ServiceRegistry.java @@ -18,8 +18,6 @@ class ServiceRegistry { static final ServiceRegistry SHARED = new ServiceRegistry(); - // In addition to the shared registry, there is a per-view registry - // maintained by the PlatformServiceProvider. ServiceRegistry() { mRegistrations = new TreeMap(); } diff --git a/shell/platform/android/io/flutter/view/VsyncWaiter.java b/shell/platform/android/io/flutter/view/VsyncWaiter.java new file mode 100644 index 0000000000000000000000000000000000000000..6d319f149e316fcf90326dd05b170b29b2c37460 --- /dev/null +++ b/shell/platform/android/io/flutter/view/VsyncWaiter.java @@ -0,0 +1,25 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.view; + +import android.view.Choreographer; + +import org.chromium.base.CalledByNative; +import org.chromium.base.JNINamespace; + +@JNINamespace("shell") +public class VsyncWaiter { + @CalledByNative + public static void asyncWaitForVsync(final long cookie) { + Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() { + @Override + public void doFrame(long frameTimeNanos) { + nativeOnVsync(frameTimeNanos, cookie); + } + }); + } + + private static native void nativeOnVsync(long frameTimeNanos, long cookie); +} diff --git a/shell/platform/android/library_loader.cc b/shell/platform/android/library_loader.cc index a50d132e0541ae08c7dd5e542a78f3b594e886d9..887c251c6fb46d8f9e78694ef19d9a105ca4b5ba 100644 --- a/shell/platform/android/library_loader.cc +++ b/shell/platform/android/library_loader.cc @@ -14,6 +14,7 @@ #include "mojo/android/system/core_impl.h" #include "flutter/shell/platform/android/flutter_main.h" #include "flutter/shell/platform/android/platform_view_android.h" +#include "flutter/shell/platform/android/vsync_waiter_android.h" namespace { @@ -21,6 +22,7 @@ base::android::RegistrationMethod kSkyRegisteredMethods[] = { {"CoreImpl", mojo::android::RegisterCoreImpl}, {"BaseRunLoop", mojo::android::RegisterBaseRunLoop}, {"FlutterView", shell::PlatformViewAndroid::Register}, + {"VsyncWaiter", shell::VsyncWaiterAndroid::Register}, {"FlutterMain", shell::RegisterFlutterMain}, }; diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 6d7ebf1104b8f27a173a8c099017ba0a17161f6b..83e1e32c103080a7084f6c33a7d3e0d3874b0343 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -25,6 +25,7 @@ #include "flutter/shell/common/engine.h" #include "flutter/shell/common/shell.h" #include "flutter/shell/gpu/gpu_rasterizer.h" +#include "flutter/shell/platform/android/vsync_waiter_android.h" #include "jni/FlutterView_jni.h" #include "lib/ftl/functional/make_copyable.h" #include "third_party/skia/include/core/SkSurface.h" @@ -62,7 +63,9 @@ class PlatformMessageResponseAndroid : public blink::PlatformMessageResponse { } // namespace PlatformViewAndroid::PlatformViewAndroid() - : PlatformView(std::make_unique()) {} + : PlatformView(std::make_unique()) { + CreateEngine(); +} PlatformViewAndroid::~PlatformViewAndroid() = default; @@ -259,6 +262,12 @@ void PlatformViewAndroid::ReleaseSurface() { } } +VsyncWaiter* PlatformViewAndroid::GetVsyncWaiter() { + if (!vsync_waiter_) + vsync_waiter_ = std::make_unique(); + return vsync_waiter_.get(); +} + bool PlatformViewAndroid::ResourceContextMakeCurrent() { return surface_gl_ ? surface_gl_->GLOffscreenContextMakeCurrent() : false; } diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index b4f7fc3596d5e1154406d430c37be72040fddb9a..8ab430b0c4a68657cb2a772437b6f271adcbf8a2 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -60,6 +60,8 @@ class PlatformViewAndroid : public PlatformView { base::android::ScopedJavaLocalRef GetBitmap(JNIEnv* env, jobject obj); + VsyncWaiter* GetVsyncWaiter() override; + bool ResourceContextMakeCurrent() override; void UpdateSemantics(std::vector update) override; diff --git a/shell/platform/android/vsync_waiter_android.cc b/shell/platform/android/vsync_waiter_android.cc new file mode 100644 index 0000000000000000000000000000000000000000..a927121cf2a6299148f9366ca9050feb87992129 --- /dev/null +++ b/shell/platform/android/vsync_waiter_android.cc @@ -0,0 +1,58 @@ +// Copyright 2016 The Chromium 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/platform/android/vsync_waiter_android.h" + +#include + +#include "jni/VsyncWaiter_jni.h" +#include "lib/ftl/logging.h" +#include "flutter/common/threads.h" + +namespace shell { + +VsyncWaiterAndroid::VsyncWaiterAndroid() : weak_factory_(this) {} + +VsyncWaiterAndroid::~VsyncWaiterAndroid() = default; + +void VsyncWaiterAndroid::AsyncWaitForVsync(Callback callback) { + FTL_DCHECK(!callback_); + callback_ = std::move(callback); + ftl::WeakPtr* weak = + new ftl::WeakPtr(); + *weak = weak_factory_.GetWeakPtr(); + + blink::Threads::Platform()->PostTask([weak] { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_VsyncWaiter_asyncWaitForVsync(env, reinterpret_cast(weak)); + }); +} + +void VsyncWaiterAndroid::OnVsync(long frameTimeNanos) { + Callback callback = std::move(callback_); + callback_ = Callback(); + + blink::Threads::UI()->PostTask([callback, frameTimeNanos] { + callback(ftl::TimePoint::FromEpochDelta( + ftl::TimeDelta::FromNanoseconds(frameTimeNanos))); + }); +} + +static void OnVsync(JNIEnv* env, + jclass jcaller, + jlong frameTimeNanos, + jlong cookie) { + ftl::WeakPtr* weak = + reinterpret_cast*>(cookie); + VsyncWaiterAndroid* waiter = weak->get(); + delete weak; + if (waiter) + waiter->OnVsync(frameTimeNanos); +} + +bool VsyncWaiterAndroid::Register(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +} // namespace shell diff --git a/shell/platform/android/vsync_waiter_android.h b/shell/platform/android/vsync_waiter_android.h new file mode 100644 index 0000000000000000000000000000000000000000..0fb884787e5441149b6bcb03759d3f30d93aefa8 --- /dev/null +++ b/shell/platform/android/vsync_waiter_android.h @@ -0,0 +1,37 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_PLATFORM_ANDROID_VSYNC_WAITER_ANDROID_H_ +#define SHELL_PLATFORM_ANDROID_VSYNC_WAITER_ANDROID_H_ + +#include "base/android/jni_android.h" +#include "flutter/shell/common/vsync_waiter.h" +#include "lib/ftl/macros.h" +#include "lib/ftl/memory/weak_ptr.h" + +namespace shell { + +class VsyncWaiterAndroid : public VsyncWaiter { + public: + VsyncWaiterAndroid(); + ~VsyncWaiterAndroid() override; + + static bool Register(JNIEnv* env); + + void AsyncWaitForVsync(Callback callback) override; + + void OnVsync(long frameTimeNanos); + + private: + Callback callback_; + ftl::WeakPtr self_; + + ftl::WeakPtrFactory weak_factory_; + + FTL_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterAndroid); +}; + +} // namespace shell + +#endif // SHELL_PLATFORM_ANDROID_ASYNC_WAITER_ANDROID_H_ diff --git a/shell/platform/darwin/common/BUILD.gn b/shell/platform/darwin/common/BUILD.gn index 71c969df10118e28fa90fb0f052ccc3f878067e5..f7622fcccb055915bfad03f633efe772cae2429a 100644 --- a/shell/platform/darwin/common/BUILD.gn +++ b/shell/platform/darwin/common/BUILD.gn @@ -9,8 +9,6 @@ source_set("common") { sources = [ "platform_mac.h", "platform_mac.mm", - "platform_service_provider.cc", - "platform_service_provider.h", "string_conversions.mm", "string_conversions.h", ] @@ -23,7 +21,6 @@ source_set("common") { "//flutter/runtime", "//flutter/services/engine:interfaces", "//flutter/services/platform", - "//flutter/services/vsync", "//flutter/shell/common", "//flutter/shell/gpu", "//flutter/shell/testing", diff --git a/shell/platform/darwin/common/platform_service_provider.cc b/shell/platform/darwin/common/platform_service_provider.cc deleted file mode 100644 index 45c58e36e74d9381d47d0e9cb3f010a2df8eef0c..0000000000000000000000000000000000000000 --- a/shell/platform/darwin/common/platform_service_provider.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015 The Chromium 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/platform/darwin/common/platform_service_provider.h" - -#if TARGET_OS_IPHONE -#include "flutter/services/vsync/ios/vsync_provider_ios_impl.h" -#else -#include "flutter/services/vsync/mac/vsync_provider_mac_impl.h" -#endif // TARGET_OS_IPHONE - -namespace shell { - -PlatformServiceProvider::PlatformServiceProvider( - mojo::InterfaceRequest request) - : binding_(this, request.Pass()) {} - -PlatformServiceProvider::~PlatformServiceProvider() {} - -void PlatformServiceProvider::ConnectToService( - const mojo::String& service_name, - mojo::ScopedMessagePipeHandle client_handle) { -#if TARGET_OS_IPHONE - if (service_name == ::vsync::VSyncProvider::Name_) { - new sky::services::vsync::VsyncProviderIOSImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider>(client_handle.Pass())); - return; - } -#else // TARGET_OS_IPHONE - if (service_name == ::vsync::VSyncProvider::Name_) { - new sky::services::vsync::VsyncProviderMacImpl( - mojo::InterfaceRequest<::vsync::VSyncProvider>(client_handle.Pass())); - return; - } -#endif // TARGET_OS_IPHONE -} - -} // namespace shell diff --git a/shell/platform/darwin/common/platform_service_provider.h b/shell/platform/darwin/common/platform_service_provider.h deleted file mode 100644 index 09a06eecf8c1848690a65e0318d35de37a5ab268..0000000000000000000000000000000000000000 --- a/shell/platform/darwin/common/platform_service_provider.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SHELL_PLATFORM_MAC_PLATFORM_SERVICE_PROVIDER_H_ -#define SHELL_PLATFORM_MAC_PLATFORM_SERVICE_PROVIDER_H_ - -#include "base/callback.h" -#include "lib/ftl/macros.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/interfaces/application/service_provider.mojom.h" - -namespace shell { - -class PlatformServiceProvider : public mojo::ServiceProvider { - public: - PlatformServiceProvider(mojo::InterfaceRequest request); - - ~PlatformServiceProvider() override; - - void ConnectToService(const mojo::String& service_name, - mojo::ScopedMessagePipeHandle client_handle) override; - - private: - mojo::StrongBinding binding_; - - FTL_DISALLOW_COPY_AND_ASSIGN(PlatformServiceProvider); -}; - -} // namespace shell - -#endif // SHELL_PLATFORM_MAC_PLATFORM_SERVICE_PROVIDER_H_ diff --git a/shell/platform/darwin/desktop/BUILD.gn b/shell/platform/darwin/desktop/BUILD.gn index 8fb26edb2826cb7aa5bbe46697bee531f51871a3..194e3fa84db8314db5222853342dee851a01edf0 100644 --- a/shell/platform/darwin/desktop/BUILD.gn +++ b/shell/platform/darwin/desktop/BUILD.gn @@ -19,6 +19,8 @@ source_set("mac_desktop_platform") { "sky_application.mm", "sky_window.h", "sky_window.mm", + "vsync_waiter_mac.cc", + "vsync_waiter_mac.h", ] deps = [ diff --git a/shell/platform/darwin/desktop/platform_view_mac.h b/shell/platform/darwin/desktop/platform_view_mac.h index d2bda9180ed7c1fdaf61fbb6888b6674a5dd5613..6b308cf04230c1aaf52a2a63fe8d9e975d34ca19 100644 --- a/shell/platform/darwin/desktop/platform_view_mac.h +++ b/shell/platform/darwin/desktop/platform_view_mac.h @@ -33,6 +33,8 @@ class PlatformViewMac : public PlatformView, public GPUSurfaceGLDelegate { intptr_t GLContextFBO() const override; + VsyncWaiter* GetVsyncWaiter() override; + bool ResourceContextMakeCurrent() override; void RunFromSource(const std::string& main, diff --git a/shell/platform/darwin/desktop/platform_view_mac.mm b/shell/platform/darwin/desktop/platform_view_mac.mm index e720a4bdb2845e95d0ec5b501bd92e423d0784a9..e8666e77327d80348e1821d1b9bad13c54c1f005 100644 --- a/shell/platform/darwin/desktop/platform_view_mac.mm +++ b/shell/platform/darwin/desktop/platform_view_mac.mm @@ -12,7 +12,7 @@ #include "flutter/shell/common/switches.h" #include "flutter/shell/gpu/gpu_rasterizer.h" #include "flutter/shell/platform/darwin/common/platform_mac.h" -#include "flutter/shell/platform/darwin/common/platform_service_provider.h" +#include "flutter/shell/platform/darwin/desktop/vsync_waiter_mac.h" #include "lib/ftl/synchronization/waitable_event.h" namespace shell { @@ -23,6 +23,8 @@ PlatformViewMac::PlatformViewMac(NSOpenGLView* gl_view) resource_loading_context_([[NSOpenGLContext alloc] initWithFormat:gl_view.pixelFormat shareContext:gl_view.openGLContext]) { + CreateEngine(); + NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); if (paths.count > 0) { @@ -35,13 +37,6 @@ PlatformViewMac::~PlatformViewMac() = default; void PlatformViewMac::ConnectToEngineAndSetupServices() { ConnectToEngine(mojo::GetProxy(&sky_engine_)); - - mojo::ServiceProviderPtr service_provider; - new PlatformServiceProvider(mojo::GetProxy(&service_provider)); - - sky::ServicesDataPtr services = sky::ServicesData::New(); - services->incoming_services = service_provider.Pass(); - sky_engine_->SetServices(services.Pass()); } void PlatformViewMac::SetupAndLoadDart() { @@ -118,6 +113,12 @@ bool PlatformViewMac::GLContextPresent() { return true; } +VsyncWaiter* PlatformViewMac::GetVsyncWaiter() { + if (!vsync_waiter_) + vsync_waiter_ = std::make_unique(); + return vsync_waiter_.get(); +} + bool PlatformViewMac::ResourceContextMakeCurrent() { NSOpenGLContext* context = resource_loading_context_.get(); diff --git a/shell/platform/darwin/desktop/vsync_waiter_mac.cc b/shell/platform/darwin/desktop/vsync_waiter_mac.cc new file mode 100644 index 0000000000000000000000000000000000000000..2a34d099584ef43ef164173580c2a1b80a90fd6a --- /dev/null +++ b/shell/platform/darwin/desktop/vsync_waiter_mac.cc @@ -0,0 +1,58 @@ +// Copyright 2015 The Chromium 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/platform/darwin/desktop/vsync_waiter_mac.h" + +#include + +#include "flutter/common/threads.h" +#include "lib/ftl/logging.h" + +namespace shell { + +#define link_ (reinterpret_cast(opaque_)) + +VsyncWaiterMac::VsyncWaiterMac() : opaque_(nullptr) { + // Create the link. + CVDisplayLinkRef link = nullptr; + CVDisplayLinkCreateWithActiveCGDisplays(&link); + opaque_ = link; + + // Set the output callback. + CVDisplayLinkSetOutputCallback( + link_, + [](CVDisplayLinkRef link, const CVTimeStamp* now, + const CVTimeStamp* output, CVOptionFlags flags_in, + CVOptionFlags* flags_out, void* context) -> CVReturn { + OnDisplayLink(context); + return kCVReturnSuccess; + }, + this); +} + +VsyncWaiterMac::~VsyncWaiterMac() { + CVDisplayLinkRelease(link_); +} + +void VsyncWaiterMac::OnDisplayLink(void* context) { + reinterpret_cast(context)->OnDisplayLink(); +} + +void VsyncWaiterMac::OnDisplayLink() { + ftl::TimePoint frame_time = ftl::TimePoint::Now(); + CVDisplayLinkStop(link_); + auto callback = std::move(callback_); + callback_ = Callback(); + + blink::Threads::UI()->PostTask( + [callback, frame_time] { callback(frame_time); }); +} + +void VsyncWaiterMac::AsyncWaitForVsync(Callback callback) { + FTL_DCHECK(!callback_); + callback_ = std::move(callback); + CVDisplayLinkStart(link_); +} + +} // namespace shell diff --git a/shell/platform/darwin/desktop/vsync_waiter_mac.h b/shell/platform/darwin/desktop/vsync_waiter_mac.h new file mode 100644 index 0000000000000000000000000000000000000000..1e26ea9c5a70aa83e90519eed9f9d4df52bf2c69 --- /dev/null +++ b/shell/platform/darwin/desktop/vsync_waiter_mac.h @@ -0,0 +1,33 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_DESKTOP_VSYNC_WAITER_MAC_H_ +#define FLUTTER_SHELL_PLATFORM_DARWIN_DESKTOP_VSYNC_WAITER_MAC_H_ + +#include "lib/ftl/macros.h" +#include "flutter/shell/common/vsync_waiter.h" + +namespace shell { + +class VsyncWaiterMac : public VsyncWaiter { + public: + VsyncWaiterMac(); + + ~VsyncWaiterMac() override; + + void AsyncWaitForVsync(Callback callback) override; + + private: + void* opaque_; + Callback callback_; + + static void OnDisplayLink(void* context); + void OnDisplayLink(); + + FTL_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterMac); +}; + +} // namespace shell + +#endif // FLUTTER_SHELL_PLATFORM_DARWIN_DESKTOP_VSYNC_WAITER_MAC_H_ diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 80d8db55278dcb2dc98f167f5bba597b63d6d4e8..3f461c417e7e1ed9e97e0dff95229210e0605b3c 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -43,6 +43,8 @@ shared_library("flutter_framework_dylib") { "framework/Source/FlutterViewController.mm", "framework/Source/platform_message_router.h", "framework/Source/platform_message_router.mm", + "framework/Source/vsync_waiter_ios.h", + "framework/Source/vsync_waiter_ios.mm", "platform_view_ios.h", "platform_view_ios.mm", ] @@ -54,7 +56,6 @@ shared_library("flutter_framework_dylib") { "//flutter/lib/ui", "//flutter/services/engine:interfaces", "//flutter/services/platform", - "//flutter/services/vsync", "//flutter/shell/common", "//flutter/shell/gpu", "//flutter/shell/platform/darwin/common", diff --git a/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h new file mode 100644 index 0000000000000000000000000000000000000000..fa30510b2d667c5260c35e6cb0f1091e5bdf68fb --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h @@ -0,0 +1,35 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_VSYNC_WAITER_IOS_H_ +#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_VSYNC_WAITER_IOS_H_ + +#include "lib/ftl/macros.h" +#include "flutter/shell/common/vsync_waiter.h" + +#if __OBJC__ +@class VSyncClient; +#else // __OBJC__ +class VSyncClient; +#endif // __OBJC__ + +namespace shell { + +class VsyncWaiterIOS : public VsyncWaiter { + public: + VsyncWaiterIOS(); + ~VsyncWaiterIOS() override; + + void AsyncWaitForVsync(Callback callback) override; + + private: + Callback callback_; + VSyncClient* client_; + + FTL_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterIOS); +}; + +} // namespace shell + +#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_VSYNC_WAITER_IOS_H_ diff --git a/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm new file mode 100644 index 0000000000000000000000000000000000000000..3bd8e0b3110ea0a7c6ff3372da1cdec881cfa756 --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm @@ -0,0 +1,76 @@ +// Copyright 2015 The Chromium 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/platform/darwin/ios/framework/Source/vsync_waiter_ios.h" + +#include + +#include +#include +#include + +#include "flutter/common/threads.h" +#include "lib/ftl/logging.h" + +@interface VSyncClient : NSObject + +@end + +@implementation VSyncClient { + CADisplayLink* _displayLink; + shell::VsyncWaiter::Callback _pendingCallback; +} + +- (instancetype)init { + self = [super init]; + + if (self) { + _displayLink = [[CADisplayLink + displayLinkWithTarget:self + selector:@selector(onDisplayLink:)] retain]; + _displayLink.paused = YES; + [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] + forMode:NSRunLoopCommonModes]; + } + + return self; +} + +- (void)await:(shell::VsyncWaiter::Callback)callback { + FTL_DCHECK(!_pendingCallback); + _pendingCallback = std::move(callback); + _displayLink.paused = NO; +} + +- (void)onDisplayLink:(CADisplayLink*)link { + ftl::TimePoint frame_time = ftl::TimePoint::Now(); + _displayLink.paused = YES; + auto callback = std::move(_pendingCallback); + _pendingCallback = shell::VsyncWaiter::Callback(); + blink::Threads::UI()->PostTask( + [callback, frame_time] { callback(frame_time); }); +} + +- (void)dealloc { + [_displayLink invalidate]; + [_displayLink release]; + + [super dealloc]; +} + +@end + +namespace shell { + +VsyncWaiterIOS::VsyncWaiterIOS() : client_([[VSyncClient alloc] init]) {} + +VsyncWaiterIOS::~VsyncWaiterIOS() { + [client_ release]; +} + +void VsyncWaiterIOS::AsyncWaitForVsync(Callback callback) { + [client_ await:std::move(callback)]; +} + +} // namespace shell diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 1b289312b6830c05b550e5fe51a28251c1743cc5..bea98e8b8572f9a35bed7a4938a03bb16961f514 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -38,6 +38,8 @@ class PlatformViewIOS : public PlatformView, public GPUSurfaceGLDelegate { return platform_message_router_; } + VsyncWaiter* GetVsyncWaiter() override; + bool ResourceContextMakeCurrent() override; bool GLContextMakeCurrent() override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 78062d6bb9fb9bcb63453d6e06cbc1e3682ce7e9..bfc498b11a9251e734ad9fedae6dba8f2fd84b27 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -14,7 +14,7 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "base/trace_event/trace_event.h" #include "flutter/shell/gpu/gpu_rasterizer.h" -#include "flutter/shell/platform/darwin/common/platform_service_provider.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h" #include "lib/ftl/synchronization/waitable_event.h" #include "mojo/public/cpp/application/connect.h" @@ -276,6 +276,8 @@ class IOSGLContext { PlatformViewIOS::PlatformViewIOS(CAEAGLLayer* layer) : PlatformView(std::make_unique()), context_(std::make_unique(surface_config_, layer)) { + CreateEngine(); + NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); shell::Shell::Shared().tracing_controller().set_traces_base_path( @@ -291,8 +293,7 @@ sky::SkyEnginePtr& PlatformViewIOS::engineProxy() { void PlatformViewIOS::ToggleAccessibility(UIView* view, bool enabled) { if (enabled) { if (!accessibility_bridge_) { - accessibility_bridge_.reset( - new shell::AccessibilityBridge(view, this)); + accessibility_bridge_.reset(new shell::AccessibilityBridge(view, this)); } } else { accessibility_bridge_ = nullptr; @@ -302,13 +303,6 @@ void PlatformViewIOS::ToggleAccessibility(UIView* view, bool enabled) { void PlatformViewIOS::ConnectToEngineAndSetupServices() { ConnectToEngine(mojo::GetProxy(&engine_)); - - mojo::ServiceProviderPtr service_provider; - new PlatformServiceProvider(mojo::GetProxy(&service_provider)); - - sky::ServicesDataPtr services = sky::ServicesData::New(); - services->incoming_services = service_provider.Pass(); - engine_->SetServices(services.Pass()); } void PlatformViewIOS::SetupAndLoadFromSource( @@ -319,6 +313,12 @@ void PlatformViewIOS::SetupAndLoadFromSource( engine_->RunFromFile(main, packages, assets_directory); } +VsyncWaiter* PlatformViewIOS::GetVsyncWaiter() { + if (!vsync_waiter_) + vsync_waiter_ = std::make_unique(); + return vsync_waiter_.get(); +} + bool PlatformViewIOS::ResourceContextMakeCurrent() { return context_ != nullptr ? context_->ResourceMakeCurrent() : false; } diff --git a/shell/platform/linux/platform_view_glfw.cc b/shell/platform/linux/platform_view_glfw.cc index 0618034ed6915103823701841ee94c171674d29a..b755163662af4fd4ebb86f17883bd85ea114ca0e 100644 --- a/shell/platform/linux/platform_view_glfw.cc +++ b/shell/platform/linux/platform_view_glfw.cc @@ -19,6 +19,8 @@ PlatformViewGLFW::PlatformViewGLFW() valid_(false), glfw_window_(nullptr), buttons_(0) { + CreateEngine(); + if (!glfwInit()) { return; } @@ -60,13 +62,6 @@ PlatformViewGLFW::~PlatformViewGLFW() { void PlatformViewGLFW::ConnectToEngineAndSetupServices() { ConnectToEngine(mojo::GetProxy(&engine_)); - - mojo::ServiceProviderPtr platform_service_provider; - new GLFWServiceProvider(mojo::GetProxy(&platform_service_provider)); - - sky::ServicesDataPtr services = sky::ServicesData::New(); - services->incoming_services = platform_service_provider.Pass(); - engine_->SetServices(services.Pass()); } sky::SkyEnginePtr& PlatformViewGLFW::EngineProxy() { diff --git a/shell/testing/platform_view_test.cc b/shell/testing/platform_view_test.cc index 04340a36fa4d128740c1152931d36091f6f9c68e..69909de57af609986fe7095d52b7f5c4518c5ac0 100644 --- a/shell/testing/platform_view_test.cc +++ b/shell/testing/platform_view_test.cc @@ -10,7 +10,9 @@ namespace shell { PlatformViewTest::PlatformViewTest() - : PlatformView(std::unique_ptr(new NullRasterizer())) {} + : PlatformView(std::unique_ptr(new NullRasterizer())) { + CreateEngine(); +} PlatformViewTest::~PlatformViewTest() = default;