提交 d4f67e6b 编写于 作者: A Adam Barth 提交者: GitHub

Migrate vsync away from Mojo services (#3169)

Instead, just use JNI and Objective-C directly.
上级 83034619
......@@ -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',
......
......@@ -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);
......
# 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.
}
}
// 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
// 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 <vector>
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<AwaitVSyncCallback> pending_;
base::TimeTicks phase_;
bool armed_;
base::WeakPtrFactory<VsyncProviderFallbackImpl> weak_factory_;
void ArmIfNecessary();
void OnFakeVSync();
DISALLOW_COPY_AND_ASSIGN(VsyncProviderFallbackImpl);
};
} // namespace vsync
} // namespace services
} // namespace sky
#endif // FLUTTER_SERVICES_VSYNC_FALLBACK_VSYNCPROVIDERFALLBACKIMPL_H_
// 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_
// 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 <vector>
#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_
// 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<AwaitVSyncResponse> mCallbacks = new ArrayList<AwaitVSyncResponse>();
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();
}
}
......@@ -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",
......
......@@ -12,17 +12,16 @@
namespace shell {
Animator::Animator(ftl::WeakPtr<Rasterizer> rasterizer, Engine* engine)
Animator::Animator(ftl::WeakPtr<Rasterizer> rasterizer,
VsyncWaiter* waiter,
Engine* engine)
: rasterizer_(rasterizer),
waiter_(waiter),
engine_(engine),
layer_tree_pipeline_(ftl::MakeRefCounted<LayerTreePipeline>(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
......@@ -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> rasterizer, Engine* engine);
Animator(ftl::WeakPtr<Rasterizer> 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<flow::LayerTree>;
void BeginFrame(int64_t time_stamp);
void BeginFrame(ftl::TimePoint frame_time);
void AwaitVSync(const vsync::VSyncProvider::AwaitVSyncCallback& callback);
void AwaitVSync();
ftl::WeakPtr<Rasterizer> rasterizer_;
VsyncWaiter* waiter_;
Engine* engine_;
vsync::VSyncProviderPtr vsync_provider_;
vsync::VSyncProviderPtr fallback_vsync_provider_;
ftl::TimePoint last_begin_frame_time_;
ftl::RefPtr<LayerTreePipeline> layer_tree_pipeline_;
flutter::Semaphore pending_frame_semaphore_;
LayerTreePipeline::ProducerContinuation producer_continuation_;
bool paused_;
base::WeakPtrFactory<Animator> weak_factory_;
ftl::WeakPtrFactory<Animator> weak_factory_;
FTL_DISALLOW_COPY_AND_ASSIGN(Animator);
};
} // namespace shell
#endif // SHELL_COMMON_ANIMATOR_H_
#endif // FLUTTER_SHELL_COMMON_ANIMATOR_H_
......@@ -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<Animator>(
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<mojo::ServiceProvider> request) {
service_provider_bindings_.AddBinding(&service_provider_impl_,
request.Pass());
}
void Engine::StopAnimator() {
animator_->Stop();
}
......
......@@ -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<mojo::ServiceProvider> 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<PlatformView> platform_view_;
std::unique_ptr<Animator> animator_;
sky::ServicesDataPtr services_;
mojo::ServiceProviderImpl service_provider_impl_;
mojo::ServiceProviderPtr incoming_services_;
mojo::BindingSet<mojo::ServiceProvider> service_provider_bindings_;
mojo::asset_bundle::AssetBundlePtr root_bundle_;
std::unique_ptr<blink::RuntimeController> runtime_;
......
......@@ -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)
: 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<blink::PlatformMessage> message) {
blink::Threads::UI()->PostTask(
......@@ -124,6 +127,12 @@ ftl::WeakPtr<PlatformView> PlatformView::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
VsyncWaiter* PlatformView::GetVsyncWaiter() {
if (!vsync_waiter_)
vsync_waiter_ = std::make_unique<VsyncWaiterFallback>();
return vsync_waiter_.get();
}
void PlatformView::UpdateSemantics(std::vector<blink::SemanticsNode> update) {}
void PlatformView::HandlePlatformMessage(
......
......@@ -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<PlatformView> GetWeakPtr();
// The VsyncWaiter will live at least as long as the PlatformView.
virtual VsyncWaiter* GetVsyncWaiter();
virtual bool ResourceContextMakeCurrent() = 0;
virtual void UpdateSemantics(std::vector<blink::SemanticsNode> update);
......@@ -67,12 +71,15 @@ class PlatformView {
protected:
explicit PlatformView(std::unique_ptr<Rasterizer> rasterizer);
void CreateEngine();
void SetupResourceContextOnIOThreadPerform(
ftl::AutoResetWaitableEvent* event);
SurfaceConfig surface_config_;
std::unique_ptr<Rasterizer> rasterizer_;
std::unique_ptr<Engine> engine_;
std::unique_ptr<VsyncWaiter> vsync_waiter_;
SkISize size_;
private:
......
// 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
// 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 <functional>
#include "lib/ftl/time/time_point.h"
namespace shell {
class VsyncWaiter {
public:
using Callback = std::function<void(ftl::TimePoint frame_time)>;
virtual void AsyncWaitForVsync(Callback callback) = 0;
virtual ~VsyncWaiter();
};
} // namespace shell
#endif // FLUTTER_SHELL_COMMON_VSYNC_WAITER_H_
// 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
// 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<VsyncWaiterFallback> weak_factory_;
FTL_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterFallback);
};
} // namespace shell
#endif // FLUTTER_SHELL_COMMON_VSYNC_WAITER_FALLBACK_H_
......@@ -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",
......
......@@ -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.
......
......@@ -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<String, OnMessageListener> mOnMessageListeners;
private HashMap<String, OnMessageListenerAsync> 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<String, OnMessageListener>();
......@@ -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<ServiceProvider.Proxy, InterfaceRequest<ServiceProvider>> platformServiceProvider =
ServiceProvider.MANAGER.getInterfaceRequest(core);
mPlatformServiceProviderBinding = ServiceProvider.MANAGER.bind(
mPlatformServiceProvider, platformServiceProvider.second);
ServicesData services = new ServicesData();
services.incomingServices = platformServiceProvider.first;
mSkyEngine.setServices(services);
resetAccessibilityTree();
}
......
......@@ -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<String, ServiceFactory>();
}
......
// 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);
}
......@@ -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},
};
......
......@@ -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<GPURasterizer>()) {}
: PlatformView(std::make_unique<GPURasterizer>()) {
CreateEngine();
}
PlatformViewAndroid::~PlatformViewAndroid() = default;
......@@ -259,6 +262,12 @@ void PlatformViewAndroid::ReleaseSurface() {
}
}
VsyncWaiter* PlatformViewAndroid::GetVsyncWaiter() {
if (!vsync_waiter_)
vsync_waiter_ = std::make_unique<VsyncWaiterAndroid>();
return vsync_waiter_.get();
}
bool PlatformViewAndroid::ResourceContextMakeCurrent() {
return surface_gl_ ? surface_gl_->GLOffscreenContextMakeCurrent() : false;
}
......
......@@ -60,6 +60,8 @@ class PlatformViewAndroid : public PlatformView {
base::android::ScopedJavaLocalRef<jobject> GetBitmap(JNIEnv* env,
jobject obj);
VsyncWaiter* GetVsyncWaiter() override;
bool ResourceContextMakeCurrent() override;
void UpdateSemantics(std::vector<blink::SemanticsNode> update) override;
......
// 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 <utility>
#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<VsyncWaiterAndroid>* weak =
new ftl::WeakPtr<VsyncWaiterAndroid>();
*weak = weak_factory_.GetWeakPtr();
blink::Threads::Platform()->PostTask([weak] {
JNIEnv* env = base::android::AttachCurrentThread();
Java_VsyncWaiter_asyncWaitForVsync(env, reinterpret_cast<intptr_t>(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<VsyncWaiterAndroid>* weak =
reinterpret_cast<ftl::WeakPtr<VsyncWaiterAndroid>*>(cookie);
VsyncWaiterAndroid* waiter = weak->get();
delete weak;
if (waiter)
waiter->OnVsync(frameTimeNanos);
}
bool VsyncWaiterAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
}
} // namespace shell
// 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<VsyncWaiterAndroid> self_;
ftl::WeakPtrFactory<VsyncWaiterAndroid> weak_factory_;
FTL_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterAndroid);
};
} // namespace shell
#endif // SHELL_PLATFORM_ANDROID_ASYNC_WAITER_ANDROID_H_
......@@ -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",
......
// 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<mojo::ServiceProvider> 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
// 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<mojo::ServiceProvider> request);
~PlatformServiceProvider() override;
void ConnectToService(const mojo::String& service_name,
mojo::ScopedMessagePipeHandle client_handle) override;
private:
mojo::StrongBinding<mojo::ServiceProvider> binding_;
FTL_DISALLOW_COPY_AND_ASSIGN(PlatformServiceProvider);
};
} // namespace shell
#endif // SHELL_PLATFORM_MAC_PLATFORM_SERVICE_PROVIDER_H_
......@@ -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 = [
......
......@@ -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,
......
......@@ -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<VsyncWaiterMac>();
return vsync_waiter_.get();
}
bool PlatformViewMac::ResourceContextMakeCurrent() {
NSOpenGLContext* context = resource_loading_context_.get();
......
......@@ -2,21 +2,18 @@
// 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 "flutter/shell/platform/darwin/desktop/vsync_waiter_mac.h"
#include <mach/mach_time.h>
#include <CoreVideo/CoreVideo.h>
namespace sky {
namespace services {
namespace vsync {
#include "flutter/common/threads.h"
#include "lib/ftl/logging.h"
namespace shell {
#define link_ (reinterpret_cast<CVDisplayLinkRef>(opaque_))
VsyncProviderMacImpl::VsyncProviderMacImpl(
mojo::InterfaceRequest<::vsync::VSyncProvider> request)
: binding_(this, request.Pass()), opaque_(nullptr) {
VsyncWaiterMac::VsyncWaiterMac() : opaque_(nullptr) {
// Create the link.
CVDisplayLinkRef link = nullptr;
CVDisplayLinkCreateWithActiveCGDisplays(&link);
......@@ -34,44 +31,28 @@ VsyncProviderMacImpl::VsyncProviderMacImpl(
this);
}
VsyncProviderMacImpl::~VsyncProviderMacImpl() {
VsyncWaiterMac::~VsyncWaiterMac() {
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<VsyncProviderMacImpl*>(thiz)->OnDisplayLink();
void VsyncWaiterMac::OnDisplayLink(void* context) {
reinterpret_cast<VsyncWaiterMac*>(context)->OnDisplayLink();
}
void VsyncProviderMacImpl::OnDisplayLink() {
TRACE_EVENT_INSTANT1("flutter", "PlatformVSync", TRACE_EVENT_SCOPE_PROCESS,
"items", pending_callbacks_.size());
// Stop the link.
void VsyncWaiterMac::OnDisplayLink() {
ftl::TimePoint frame_time = ftl::TimePoint::Now();
CVDisplayLinkStop(link_);
auto callback = std::move(callback_);
callback_ = Callback();
// Fire all callbacks and clear.
uint64_t micros = CurrentTimeMicroseconds();
for (const auto& callback : pending_callbacks_) {
callback.Run(micros);
}
pending_callbacks_.clear();
blink::Threads::UI()->PostTask(
[callback, frame_time] { callback(frame_time); });
}
void VsyncProviderMacImpl::AwaitVSync(const AwaitVSyncCallback& callback) {
pending_callbacks_.push_back(callback);
void VsyncWaiterMac::AsyncWaitForVsync(Callback callback) {
FTL_DCHECK(!callback_);
callback_ = std::move(callback);
CVDisplayLinkStart(link_);
}
} // namespace vsync
} // namespace services
} // namespace sky
} // namespace shell
// 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_
......@@ -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",
......
// 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_
......@@ -2,31 +2,24 @@
// 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 "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
#include <utility>
#include <Foundation/Foundation.h>
#include <QuartzCore/CADisplayLink.h>
#include <mach/mach_time.h>
#include <vector>
#include "flutter/common/threads.h"
#include "lib/ftl/logging.h"
@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;
shell::VsyncWaiter::Callback _pendingCallback;
}
- (instancetype)init {
......@@ -44,19 +37,19 @@ static inline uint64_t CurrentTimeMicroseconds() {
return self;
}
- (void)await:(::vsync::VSyncProvider::AwaitVSyncCallback)callback {
_pendingCallbacks.push_back(callback);
- (void)await:(shell::VsyncWaiter::Callback)callback {
FTL_DCHECK(!_pendingCallback);
_pendingCallback = std::move(callback);
_displayLink.paused = NO;
}
- (void)onDisplayLink:(CADisplayLink*)link {
TRACE_EVENT_INSTANT0("flutter", "PlatformVSync", TRACE_EVENT_SCOPE_PROCESS);
ftl::TimePoint frame_time = ftl::TimePoint::Now();
_displayLink.paused = YES;
uint64_t micros = CurrentTimeMicroseconds();
for (const auto& callback : _pendingCallbacks) {
callback.Run(micros);
}
_pendingCallbacks.clear();
auto callback = std::move(_pendingCallback);
_pendingCallback = shell::VsyncWaiter::Callback();
blink::Threads::UI()->PostTask(
[callback, frame_time] { callback(frame_time); });
}
- (void)dealloc {
......@@ -68,22 +61,16 @@ static inline uint64_t CurrentTimeMicroseconds() {
@end
namespace sky {
namespace services {
namespace vsync {
namespace shell {
VsyncProviderIOSImpl::VsyncProviderIOSImpl(
mojo::InterfaceRequest<::vsync::VSyncProvider> request)
: binding_(this, request.Pass()), client_([[VSyncClient alloc] init]) {}
VsyncWaiterIOS::VsyncWaiterIOS() : client_([[VSyncClient alloc] init]) {}
VsyncProviderIOSImpl::~VsyncProviderIOSImpl() {
VsyncWaiterIOS::~VsyncWaiterIOS() {
[client_ release];
}
void VsyncProviderIOSImpl::AwaitVSync(const AwaitVSyncCallback& callback) {
[client_ await:callback];
void VsyncWaiterIOS::AsyncWaitForVsync(Callback callback) {
[client_ await:std::move(callback)];
}
} // namespace vsync
} // namespace services
} // namespace sky
} // namespace shell
......@@ -38,6 +38,8 @@ class PlatformViewIOS : public PlatformView, public GPUSurfaceGLDelegate {
return platform_message_router_;
}
VsyncWaiter* GetVsyncWaiter() override;
bool ResourceContextMakeCurrent() override;
bool GLContextMakeCurrent() override;
......
......@@ -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<GPURasterizer>()),
context_(std::make_unique<IOSGLContext>(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<VsyncWaiterIOS>();
return vsync_waiter_.get();
}
bool PlatformViewIOS::ResourceContextMakeCurrent() {
return context_ != nullptr ? context_->ResourceMakeCurrent() : false;
}
......
......@@ -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() {
......
......@@ -10,7 +10,9 @@
namespace shell {
PlatformViewTest::PlatformViewTest()
: PlatformView(std::unique_ptr<Rasterizer>(new NullRasterizer())) {}
: PlatformView(std::unique_ptr<Rasterizer>(new NullRasterizer())) {
CreateEngine();
}
PlatformViewTest::~PlatformViewTest() = default;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册