mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Migrate vsync away from Mojo services (flutter/engine#3169)
Instead, just use JNI and Objective-C directly.
This commit is contained in:
parent
562000be9a
commit
54ee61e60a
2
DEPS
2
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',
|
||||
|
||||
@ -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:
|
||||
|
||||
11
engine/src/flutter/shell/common/vsync_waiter.cc
Normal file
11
engine/src/flutter/shell/common/vsync_waiter.cc
Normal file
@ -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
|
||||
25
engine/src/flutter/shell/common/vsync_waiter.h
Normal file
25
engine/src/flutter/shell/common/vsync_waiter.h
Normal file
@ -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 <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_
|
||||
51
engine/src/flutter/shell/common/vsync_waiter_fallback.cc
Normal file
51
engine/src/flutter/shell/common/vsync_waiter_fallback.cc
Normal file
@ -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
|
||||
33
engine/src/flutter/shell/common/vsync_waiter_fallback.h
Normal file
33
engine/src/flutter/shell/common/vsync_waiter_fallback.h
Normal file
@ -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<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>();
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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 <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
|
||||
@ -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<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",
|
||||
|
||||
@ -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<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
|
||||
@ -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<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();
|
||||
|
||||
|
||||
@ -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 <CoreVideo/CoreVideo.h>
|
||||
|
||||
#include "flutter/common/threads.h"
|
||||
#include "lib/ftl/logging.h"
|
||||
|
||||
namespace shell {
|
||||
|
||||
#define link_ (reinterpret_cast<CVDisplayLinkRef>(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<VsyncWaiterMac*>(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
|
||||
@ -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_
|
||||
@ -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",
|
||||
|
||||
@ -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_
|
||||
@ -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 <utility>
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <QuartzCore/CADisplayLink.h>
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
#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
|
||||
@ -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;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user