diff --git a/sky/services/vsync/BUILD.gn b/sky/services/vsync/BUILD.gn index 8b9e4200181a515d97a607562d77bcfb759db82e..c5caf8e5826127f5a67719f72277e5cf6d36e36d 100644 --- a/sky/services/vsync/BUILD.gn +++ b/sky/services/vsync/BUILD.gn @@ -27,7 +27,7 @@ if (is_android) { import("//build/config/android/rules.gni") android_library("vsync_lib") { - java_files = [ "src/org/domokit/vsync/VsyncProviderImpl.java" ] + java_files = [ "src/org/domokit/vsync/VSyncProviderImpl.java" ] deps = [ "//base:base_java", diff --git a/sky/services/vsync/src/org/domokit/vsync/VSyncProviderImpl.java b/sky/services/vsync/src/org/domokit/vsync/VSyncProviderImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..3087cd1405886c60769b4ad1b9394371715b4161 --- /dev/null +++ b/sky/services/vsync/src/org/domokit/vsync/VSyncProviderImpl.java @@ -0,0 +1,47 @@ +// 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.mojo.system.MessagePipeHandle; +import org.chromium.mojo.system.MojoException; +import org.chromium.mojom.vsync.VSyncProvider; + +/** + * Android implementation of VSyncProvider. + */ +public class VSyncProviderImpl implements VSyncProvider, Choreographer.FrameCallback { + private Choreographer mChoreographer; + private AwaitVSyncResponse mCallback; + 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) { + if (mCallback != null) { + mPipe.close(); + return; + } + mCallback = callback; + mChoreographer.postFrameCallback(this); + } + + @Override + public void doFrame(long frameTimeNanos) { + mCallback.call(frameTimeNanos / 1000); + mCallback = null; + } +} diff --git a/sky/services/vsync/src/org/domokit/vsync/VsyncProviderImpl.java b/sky/services/vsync/src/org/domokit/vsync/VsyncProviderImpl.java deleted file mode 100644 index fa0d6d28bfd0fac32b3b5d04e5ddea5587a8f1bf..0000000000000000000000000000000000000000 --- a/sky/services/vsync/src/org/domokit/vsync/VsyncProviderImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.domokit.vsync; - -import android.view.Choreographer; - -import org.chromium.mojo.system.MojoException; -import org.chromium.mojom.vsync.VsyncProvider; - -/** - * Android implementation of VsyncProvider. - */ -public class VsyncProviderImpl implements VsyncProvider { - private static final String TAG = "VsyncProviderImpl"; - - public VsyncProviderImpl() { - } - - @Override - public void close() {} - - @Override - public void onConnectionError(MojoException e) {} - - @Override - public void awaitVsync(final AwaitVsyncResponse callback) { - Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() { - @Override - public void doFrame(long frameTimeNanos) { - callback.call(frameTimeNanos); - } - }); - } -} diff --git a/sky/services/vsync/vsync.mojom b/sky/services/vsync/vsync.mojom index d4445bac749013878e21bf6b215d3f0563904f84..715b9067994ab9b8069270ff719a25e738348f6c 100644 --- a/sky/services/vsync/vsync.mojom +++ b/sky/services/vsync/vsync.mojom @@ -4,6 +4,8 @@ module vsync; -interface VsyncProvider { - AwaitVsync() => (int64 time_stamp); +interface VSyncProvider { + // Timebase is in MojoGetTimeTicksNow. + // Only one callback can be parked at a given time. + AwaitVSync() => (int64 time_stamp); }; diff --git a/sky/shell/android/org/domokit/sky/shell/SkyApplication.java b/sky/shell/android/org/domokit/sky/shell/SkyApplication.java index f89fae83102982b357f02002f5f1a91abd48ab50..ca27b1637302601b4cad22b10e0d764270294b94 100644 --- a/sky/shell/android/org/domokit/sky/shell/SkyApplication.java +++ b/sky/shell/android/org/domokit/sky/shell/SkyApplication.java @@ -21,11 +21,11 @@ import org.chromium.mojom.keyboard.KeyboardService; import org.chromium.mojom.media.MediaService; import org.chromium.mojom.mojo.NetworkService; import org.chromium.mojom.sensors.SensorService; -import org.chromium.mojom.vsync.VsyncProvider; +import org.chromium.mojom.vsync.VSyncProvider; import org.domokit.activity.ActivityImpl; import org.domokit.media.MediaServiceImpl; import org.domokit.oknet.NetworkServiceImpl; -import org.domokit.vsync.VsyncProviderImpl; +import org.domokit.vsync.VSyncProviderImpl; /** * Sky implementation of {@link android.app.Application}, managing application-level global @@ -100,10 +100,10 @@ public class SkyApplication extends BaseChromiumApplication { } }); - registry.register(VsyncProvider.MANAGER.getName(), new ServiceFactory() { + registry.register(VSyncProvider.MANAGER.getName(), new ServiceFactory() { @Override public void connectToService(Context context, Core core, MessagePipeHandle pipe) { - VsyncProvider.MANAGER.bind(new VsyncProviderImpl(), pipe); + VSyncProvider.MANAGER.bind(new VSyncProviderImpl(pipe), pipe); } }); } diff --git a/sky/shell/ui/animator.cc b/sky/shell/ui/animator.cc index 39eb5cf3124884a3571e4e395f90f599f4b0328c..990d9b108339d10ef6bb14dc2b903a4a9e159602 100644 --- a/sky/shell/ui/animator.cc +++ b/sky/shell/ui/animator.cc @@ -11,7 +11,7 @@ namespace sky { namespace shell { -const int kPipelineDepth = 2; +const int kPipelineDepth = 3; Animator::Animator(const Engine::Config& config, Engine* engine) : config_(config), @@ -39,10 +39,7 @@ void Animator::RequestFrame() { return; } - if (vsync_provider_) { - vsync_provider_->AwaitVsync( - base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr())); - } else { + if (!AwaitVSync()) { base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr(), 0)); @@ -87,9 +84,19 @@ void Animator::OnFrameComplete() { if (did_defer_frame_request_) { did_defer_frame_request_ = false; - BeginFrame(0); + + if (!AwaitVSync()) + BeginFrame(0); } } +bool Animator::AwaitVSync() { + if (!vsync_provider_) + return false; + vsync_provider_->AwaitVSync( + base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr())); + return true; +} + } // namespace shell } // namespace sky diff --git a/sky/shell/ui/animator.h b/sky/shell/ui/animator.h index 764b3b01079a2b2bb7cb3fa9dba0217bf1464cbd..1befdad15d8e6dbbee78986c2234b7c2ebceaa2e 100644 --- a/sky/shell/ui/animator.h +++ b/sky/shell/ui/animator.h @@ -22,17 +22,18 @@ class Animator { void Start(); void Stop(); - void set_vsync_provider(vsync::VsyncProviderPtr vsync_provider) { + void set_vsync_provider(vsync::VSyncProviderPtr vsync_provider) { vsync_provider_ = vsync_provider.Pass(); } private: void BeginFrame(int64_t time_stamp); void OnFrameComplete(); + bool AwaitVSync(); Engine::Config config_; Engine* engine_; - vsync::VsyncProviderPtr vsync_provider_; + vsync::VSyncProviderPtr vsync_provider_; int outstanding_requests_; bool did_defer_frame_request_; bool engine_requested_frame_; diff --git a/sky/shell/ui/engine.cc b/sky/shell/ui/engine.cc index 840dd9fa0205c7fa7ae4b8000d09f6f48ea14fe9..5fdef5eb7bd93c284ec777a660cfec1ebdf3088e 100644 --- a/sky/shell/ui/engine.cc +++ b/sky/shell/ui/engine.cc @@ -67,8 +67,8 @@ Engine::Engine(const Config& config) mojo::ConnectToService(service_provider.get(), &network_service_); #if defined(OS_ANDROID) - // TODO(abarth): Implement VsyncProvider on other platforms. - vsync::VsyncProviderPtr vsync_provider; + // TODO(abarth): Implement VSyncProvider on other platforms. + vsync::VSyncProviderPtr vsync_provider; mojo::ConnectToService(service_provider.get(), &vsync_provider); animator_->set_vsync_provider(vsync_provider.Pass()); #endif