From df3c24c9b6d9b01358f517ae77046e65f39b40f3 Mon Sep 17 00:00:00 2001 From: "brianderson@chromium.org" Date: Wed, 19 Jun 2013 03:54:35 +0000 Subject: cc: Add BeginFrameArgs In addition to the frame_time, include a deadline and interval with BeginFrame. Values used are placeholders for now, but will be used in the near future. BUG=240945 Review URL: https://chromiumcodereview.appspot.com/17391006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207166 0039d316-1c4b-4281-b951-d872f2087c98 --- cc/cc.gyp | 2 + cc/output/begin_frame_args.cc | 55 ++++++++++++++++++++ cc/output/begin_frame_args.h | 49 ++++++++++++++++++ cc/output/output_surface.cc | 12 +++-- cc/output/output_surface.h | 16 ++++-- cc/output/output_surface_client.h | 3 +- cc/output/output_surface_unittest.cc | 14 +++--- cc/scheduler/frame_rate_controller.cc | 14 +++++- cc/scheduler/frame_rate_controller.h | 11 ++-- cc/scheduler/frame_rate_controller_unittest.cc | 3 +- cc/scheduler/scheduler.cc | 23 +++++---- cc/scheduler/scheduler.h | 6 +-- cc/scheduler/scheduler_state_machine.cc | 14 +++--- cc/scheduler/scheduler_state_machine.h | 6 +-- cc/scheduler/scheduler_state_machine_unittest.cc | 58 +++++++++++----------- cc/scheduler/scheduler_unittest.cc | 38 +++++++------- cc/test/fake_layer_tree_host_impl_client.h | 3 +- cc/test/fake_output_surface.cc | 2 +- cc/test/fake_output_surface.h | 1 + cc/test/pixel_test.cc | 2 +- cc/test/scheduler_test_common.cc | 4 +- cc/trees/layer_tree_host_impl.cc | 6 +-- cc/trees/layer_tree_host_impl.h | 5 +- cc/trees/layer_tree_host_impl_unittest.cc | 3 +- cc/trees/layer_tree_host_unittest.cc | 1 + cc/trees/single_thread_proxy.h | 3 +- cc/trees/thread_proxy.cc | 4 +- cc/trees/thread_proxy.h | 2 +- content/browser/android/content_view_core_impl.cc | 23 ++++++++- content/browser/android/content_view_core_impl.h | 6 ++- .../synchronous_compositor_output_surface.cc | 4 +- .../renderer_host/compositor_impl_android.cc | 18 +++++-- .../renderer_host/image_transport_factory.cc | 1 + .../render_widget_host_view_android.cc | 7 ++- .../render_widget_host_view_android.h | 3 +- content/common/cc_messages.h | 7 +++ content/common/view_messages.h | 3 +- content/renderer/gpu/compositor_output_surface.cc | 4 +- content/renderer/gpu/compositor_output_surface.h | 3 +- 39 files changed, 315 insertions(+), 124 deletions(-) create mode 100644 cc/output/begin_frame_args.cc create mode 100644 cc/output/begin_frame_args.h diff --git a/cc/cc.gyp b/cc/cc.gyp index f64974a..81c2bba 100644 --- a/cc/cc.gyp +++ b/cc/cc.gyp @@ -154,6 +154,8 @@ 'layers/video_layer.h', 'layers/video_layer_impl.cc', 'layers/video_layer_impl.h', + 'output/begin_frame_args.cc', + 'output/begin_frame_args.h', 'output/compositor_frame.cc', 'output/compositor_frame.h', 'output/compositor_frame_ack.cc', diff --git a/cc/output/begin_frame_args.cc b/cc/output/begin_frame_args.cc new file mode 100644 index 0000000..ea14954 --- /dev/null +++ b/cc/output/begin_frame_args.cc @@ -0,0 +1,55 @@ +// Copyright 2013 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 "cc/output/begin_frame_args.h" + +namespace cc { + +BeginFrameArgs::BeginFrameArgs() + : frame_time(base::TimeTicks()), + deadline(base::TimeTicks()), + interval(base::TimeDelta::FromMicroseconds(-1)) +{ +} + +BeginFrameArgs::BeginFrameArgs(base::TimeTicks frame_time, + base::TimeTicks deadline, + base::TimeDelta interval) + : frame_time(frame_time), + deadline(deadline), + interval(interval) +{} + +BeginFrameArgs BeginFrameArgs::Create(base::TimeTicks frame_time, + base::TimeTicks deadline, + base::TimeDelta interval) { + return BeginFrameArgs(frame_time, deadline, interval); +} + +BeginFrameArgs BeginFrameArgs::CreateForSynchronousCompositor() { + // For WebView/SynchronousCompositor, we always want to draw immediately, + // so we set the deadline to 0 and guess that the interval is 16 milliseconds. + return BeginFrameArgs(base::TimeTicks::Now(), + base::TimeTicks(), + DefaultInterval()); +} + +BeginFrameArgs BeginFrameArgs::CreateForTesting() { + base::TimeTicks now = base::TimeTicks::Now(); + return BeginFrameArgs(now, + now + (DefaultInterval() / 2), + DefaultInterval()); +} + +base::TimeDelta BeginFrameArgs::DefaultDeadlineAdjustment() { + // Using a large deadline adjustment will effectively revert BeginFrame + // scheduling to the hard vsync scheduling we used to have. + return base::TimeDelta::FromSeconds(-1); +} + +base::TimeDelta BeginFrameArgs::DefaultInterval() { + return base::TimeDelta::FromMicroseconds(16666); +} + +} // namespace cc diff --git a/cc/output/begin_frame_args.h b/cc/output/begin_frame_args.h new file mode 100644 index 0000000..616a86a --- /dev/null +++ b/cc/output/begin_frame_args.h @@ -0,0 +1,49 @@ +// Copyright 2013 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 CC_OUTPUT_BEGIN_FRAME_H_ +#define CC_OUTPUT_BEGIN_FRAME_H_ + +#include "base/time.h" +#include "cc/base/cc_export.h" + +namespace cc { + +struct CC_EXPORT BeginFrameArgs { + // Creates an invalid set of values. + BeginFrameArgs(); + + // You should be able to find all instances where a BeginFrame has been + // created by searching for "BeginFrameArgs::Create". + static BeginFrameArgs Create(base::TimeTicks frame_time, + base::TimeTicks deadline, + base::TimeDelta interval); + static BeginFrameArgs CreateForSynchronousCompositor(); + static BeginFrameArgs CreateForTesting(); + + // This is the default delta that will be used to adjust the deadline when + // proper draw-time estimations are not yet available. + static base::TimeDelta DefaultDeadlineAdjustment(); + + // This is the default interval to use to avoid sprinkling the code with + // magic numbers. + static base::TimeDelta DefaultInterval(); + + bool IsInvalid() const { + return interval < base::TimeDelta(); + } + + base::TimeTicks frame_time; + base::TimeTicks deadline; + base::TimeDelta interval; + + private: + BeginFrameArgs(base::TimeTicks frame_time, + base::TimeTicks deadline, + base::TimeDelta interval); +}; + +} // namespace cc + +#endif // CC_OUTPUT_BEGIN_FRAME_H_ diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 160f86d..60789b0 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -104,6 +104,9 @@ void OutputSurface::InitializeBeginFrameEmulation( frame_rate_controller_->SetClient(this); frame_rate_controller_->SetMaxSwapsPending(max_frames_pending_); + frame_rate_controller_->SetDeadlineAdjustment( + capabilities_.adjust_deadline_for_parent ? + BeginFrameArgs::DefaultDeadlineAdjustment() : base::TimeDelta()); // The new frame rate controller will consume the swap acks of the old // frame rate controller, so we set that expectation up here. @@ -126,10 +129,11 @@ void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase, frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); } -void OutputSurface::FrameRateControllerTick(bool throttled) { +void OutputSurface::FrameRateControllerTick(bool throttled, + const BeginFrameArgs& args) { DCHECK(frame_rate_controller_); if (!throttled) - BeginFrame(frame_rate_controller_->LastTickTime()); + BeginFrame(args); } // Forwarded to OutputSurfaceClient @@ -145,7 +149,7 @@ void OutputSurface::SetNeedsBeginFrame(bool enable) { frame_rate_controller_->SetActive(enable); } -void OutputSurface::BeginFrame(base::TimeTicks frame_time) { +void OutputSurface::BeginFrame(const BeginFrameArgs& args) { TRACE_EVENT2("cc", "OutputSurface::BeginFrame", "begin_frame_pending_", begin_frame_pending_, "pending_swap_buffers_", pending_swap_buffers_); @@ -153,7 +157,7 @@ void OutputSurface::BeginFrame(base::TimeTicks frame_time) { (pending_swap_buffers_ >= max_frames_pending_ && max_frames_pending_ > 0)) return; begin_frame_pending_ = true; - client_->BeginFrame(frame_time); + client_->BeginFrame(args); } void OutputSurface::DidSwapBuffers() { diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index 0ef25aed..3172f41 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -41,6 +41,10 @@ class OutputSurfaceCallbacks; // surface (on the compositor thread) and go back to step 1. class CC_EXPORT OutputSurface : public FrameRateControllerClient { public: + enum { + DEFAULT_MAX_FRAMES_PENDING = 2 + }; + explicit OutputSurface(scoped_ptr context3d); explicit OutputSurface(scoped_ptr software_device); @@ -54,11 +58,14 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { Capabilities() : delegated_rendering(false), max_frames_pending(0), - deferred_gl_initialization(false) {} - + deferred_gl_initialization(false), + adjust_deadline_for_parent(true) {} bool delegated_rendering; int max_frames_pending; bool deferred_gl_initialization; + // This doesn't handle the case, but once BeginFrame is + // supported natively, we shouldn't need adjust_deadline_for_parent. + bool adjust_deadline_for_parent; }; const Capabilities& capabilities() const { @@ -142,7 +149,8 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { // Platforms should move to native BeginFrames instead. void OnVSyncParametersChanged(base::TimeTicks timebase, base::TimeDelta interval); - virtual void FrameRateControllerTick(bool throttled) OVERRIDE; + virtual void FrameRateControllerTick(bool throttled, + const BeginFrameArgs& args) OVERRIDE; scoped_ptr frame_rate_controller_; int max_frames_pending_; int pending_swap_buffers_; @@ -152,7 +160,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { // first so OutputSurface has a chance to update the FrameRateController bool HasClient() { return !!client_; } void SetNeedsRedrawRect(gfx::Rect damage_rect); - void BeginFrame(base::TimeTicks frame_time); + void BeginFrame(const BeginFrameArgs& args); void DidSwapBuffers(); void OnSwapBuffersComplete(const CompositorFrameAck* ack); void DidLoseOutputSurface(); diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h index d727629..fe669cb 100644 --- a/cc/output/output_surface_client.h +++ b/cc/output/output_surface_client.h @@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "base/time.h" #include "cc/base/cc_export.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/context_provider.h" #include "ui/gfx/rect.h" @@ -27,7 +28,7 @@ class CC_EXPORT OutputSurfaceClient { virtual bool DeferredInitialize( scoped_refptr offscreen_context_provider) = 0; virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) = 0; - virtual void BeginFrame(base::TimeTicks frame_time) = 0; + virtual void BeginFrame(const BeginFrameArgs& args) = 0; virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) = 0; virtual void DidLoseOutputSurface() = 0; virtual void SetExternalDrawConstraints(const gfx::Transform& transform, diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index e42777a..68053e8 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -42,8 +42,8 @@ class TestOutputSurface : public OutputSurface { OnVSyncParametersChanged(timebase, interval); } - void BeginFrameForTesting(base::TimeTicks frame_time) { - BeginFrame(frame_time); + void BeginFrameForTesting() { + BeginFrame(BeginFrameArgs::CreateForTesting()); } void DidSwapBuffersForTesting() { @@ -73,7 +73,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { return deferred_initialize_result_; } virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {} - virtual void BeginFrame(base::TimeTicks frame_time) OVERRIDE { + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE { begin_frame_count_++; } virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {} @@ -213,7 +213,7 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { new base::TestSimpleTaskRunner; bool throttle_frame_production = true; const base::TimeDelta display_refresh_interval = - base::TimeDelta::FromMicroseconds(16666); + BeginFrameArgs::DefaultInterval(); output_surface.InitializeBeginFrameEmulation( task_runner.get(), @@ -281,13 +281,13 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { // Optimistically injected BeginFrames without a SetNeedsBeginFrame should be // allowed. - output_surface.BeginFrameForTesting(base::TimeTicks::Now()); + output_surface.BeginFrameForTesting(); EXPECT_EQ(client.begin_frame_count(), 5); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); // Optimistically injected BeginFrames without a SetNeedsBeginFrame should // still be throttled by pending begin frames however. - output_surface.BeginFrameForTesting(base::TimeTicks::Now()); + output_surface.BeginFrameForTesting(); EXPECT_EQ(client.begin_frame_count(), 5); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); @@ -296,7 +296,7 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { output_surface.DidSwapBuffersForTesting(); EXPECT_EQ(client.begin_frame_count(), 5); EXPECT_EQ(output_surface.pending_swap_buffers(), 2); - output_surface.BeginFrameForTesting(base::TimeTicks::Now()); + output_surface.BeginFrameForTesting(); EXPECT_EQ(client.begin_frame_count(), 5); EXPECT_EQ(output_surface.pending_swap_buffers(), 2); } diff --git a/cc/scheduler/frame_rate_controller.cc b/cc/scheduler/frame_rate_controller.cc index 1977294..811892d 100644 --- a/cc/scheduler/frame_rate_controller.cc +++ b/cc/scheduler/frame_rate_controller.cc @@ -38,6 +38,7 @@ FrameRateController::FrameRateController(scoped_refptr timer) : client_(NULL), num_frames_pending_(0), max_swaps_pending_(0), + interval_(BeginFrameArgs::DefaultInterval()), time_source_(timer), active_(false), is_time_source_throttling_(true), @@ -53,6 +54,7 @@ FrameRateController::FrameRateController( : client_(NULL), num_frames_pending_(0), max_swaps_pending_(0), + interval_(BeginFrameArgs::DefaultInterval()), active_(false), is_time_source_throttling_(false), weak_factory_(this), @@ -86,10 +88,15 @@ void FrameRateController::SetMaxSwapsPending(int max_swaps_pending) { void FrameRateController::SetTimebaseAndInterval(base::TimeTicks timebase, base::TimeDelta interval) { + interval_ = interval; if (is_time_source_throttling_) time_source_->SetTimebaseAndInterval(timebase, interval); } +void FrameRateController::SetDeadlineAdjustment(base::TimeDelta delta) { + deadline_adjustment_ = delta; +} + void FrameRateController::OnTimerTick() { TRACE_EVENT0("cc", "FrameRateController::OnTimerTick"); DCHECK(active_); @@ -100,7 +107,12 @@ void FrameRateController::OnTimerTick() { TRACE_COUNTER_ID1("cc", "ThrottledCompositor", task_runner_, throttled); if (client_) { - client_->FrameRateControllerTick(throttled); + // TODO(brianderson): Use an adaptive parent compositor deadline. + base::TimeTicks frame_time = LastTickTime(); + base::TimeTicks deadline = NextTickTime() + deadline_adjustment_; + client_->FrameRateControllerTick( + throttled, + BeginFrameArgs::Create(frame_time, deadline, interval_)); } if (!is_time_source_throttling_ && !throttled) diff --git a/cc/scheduler/frame_rate_controller.h b/cc/scheduler/frame_rate_controller.h index bf667446..32e757b 100644 --- a/cc/scheduler/frame_rate_controller.h +++ b/cc/scheduler/frame_rate_controller.h @@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "base/time.h" #include "cc/base/cc_export.h" +#include "cc/output/begin_frame_args.h" namespace base { class SingleThreadTaskRunner; } @@ -24,7 +25,8 @@ class CC_EXPORT FrameRateControllerClient { public: // Throttled is true when we have a maximum number of frames pending. - virtual void FrameRateControllerTick(bool throttled) = 0; + virtual void FrameRateControllerTick(bool throttled, + const BeginFrameArgs& args) = 0; }; class FrameRateControllerTimeSourceAdapter; @@ -33,10 +35,6 @@ class FrameRateControllerTimeSourceAdapter; // is not sent by a parent compositor. class CC_EXPORT FrameRateController { public: - enum { - DEFAULT_MAX_FRAMES_PENDING = 2 - }; - explicit FrameRateController(scoped_refptr timer); // Alternate form of FrameRateController with unthrottled frame-rate. explicit FrameRateController(base::SingleThreadTaskRunner* task_runner); @@ -68,6 +66,7 @@ class CC_EXPORT FrameRateController { void SetTimebaseAndInterval(base::TimeTicks timebase, base::TimeDelta interval); + void SetDeadlineAdjustment(base::TimeDelta delta); protected: friend class FrameRateControllerTimeSourceAdapter; @@ -79,6 +78,8 @@ class CC_EXPORT FrameRateController { FrameRateControllerClient* client_; int num_frames_pending_; int max_swaps_pending_; + base::TimeDelta interval_; + base::TimeDelta deadline_adjustment_; scoped_refptr time_source_; scoped_ptr time_source_client_adapter_; bool active_; diff --git a/cc/scheduler/frame_rate_controller_unittest.cc b/cc/scheduler/frame_rate_controller_unittest.cc index 7c0a0cc..353d984 100644 --- a/cc/scheduler/frame_rate_controller_unittest.cc +++ b/cc/scheduler/frame_rate_controller_unittest.cc @@ -18,7 +18,8 @@ class FakeFrameRateControllerClient : public cc::FrameRateControllerClient { void Reset() { began_frame_ = false; } bool BeganFrame() const { return began_frame_; } - virtual void FrameRateControllerTick(bool throttled) OVERRIDE { + virtual void FrameRateControllerTick( + bool throttled, const BeginFrameArgs& args) OVERRIDE { began_frame_ = !throttled; } diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 9b9ac87..d1997ea 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -18,9 +18,6 @@ Scheduler::Scheduler(SchedulerClient* client, weak_factory_(this), last_set_needs_begin_frame_(false), has_pending_begin_frame_(false), - last_begin_frame_time_(base::TimeTicks()), - // TODO(brianderson): Pass with BeginFrame in the near future. - interval_(base::TimeDelta::FromMicroseconds(16666)), state_machine_(scheduler_settings), inside_process_scheduled_actions_(false) { DCHECK(client_); @@ -111,16 +108,21 @@ void Scheduler::DidCreateAndInitializeOutputSurface() { base::TimeTicks Scheduler::AnticipatedDrawTime() { TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime"); - if (!last_set_needs_begin_frame_) + + if (!last_set_needs_begin_frame_ || + last_begin_frame_args_.interval <= base::TimeDelta()) return base::TimeTicks(); + // TODO(brianderson): Express this in terms of the deadline. base::TimeTicks now = base::TimeTicks::Now(); - int64 intervals = ((now - last_begin_frame_time_) / interval_) + 1; - return last_begin_frame_time_ + (interval_ * intervals); + int64 intervals = 1 + ((now - last_begin_frame_args_.frame_time) / + last_begin_frame_args_.interval); + return last_begin_frame_args_.frame_time + + (last_begin_frame_args_.interval * intervals); } base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() { - return last_begin_frame_time_; + return last_begin_frame_args_.frame_time; } void Scheduler::SetupNextBeginFrameIfNeeded() { @@ -162,14 +164,13 @@ void Scheduler::SetupNextBeginFrameIfNeeded() { } } -void Scheduler::BeginFrame(base::TimeTicks frame_time) { +void Scheduler::BeginFrame(const BeginFrameArgs& args) { TRACE_EVENT0("cc", "Scheduler::BeginFrame"); DCHECK(!has_pending_begin_frame_); has_pending_begin_frame_ = true; - last_begin_frame_time_ = frame_time; safe_to_expect_begin_frame_ = true; - state_machine_.DidEnterBeginFrame(); - state_machine_.SetFrameTime(frame_time); + last_begin_frame_args_ = args; + state_machine_.DidEnterBeginFrame(args); ProcessScheduledActions(); state_machine_.DidLeaveBeginFrame(); } diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index facd7a2..93d5b4e 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "base/time.h" #include "cc/base/cc_export.h" +#include "cc/output/begin_frame_args.h" #include "cc/scheduler/scheduler_settings.h" #include "cc/scheduler/scheduler_state_machine.h" #include "cc/trees/layer_tree_host.h" @@ -100,7 +101,7 @@ class CC_EXPORT Scheduler { base::TimeTicks LastBeginFrameOnImplThreadTime(); - void BeginFrame(base::TimeTicks frame_time); + void BeginFrame(const BeginFrameArgs& args); std::string StateAsStringForTesting() { return state_machine_.ToString(); } @@ -122,8 +123,7 @@ class CC_EXPORT Scheduler { // TODO(brianderson): crbug.com/249806 : Remove safe_to_expect_begin_frame_ // workaround. bool safe_to_expect_begin_frame_; - base::TimeTicks last_begin_frame_time_; - base::TimeDelta interval_; + BeginFrameArgs last_begin_frame_args_; SchedulerStateMachine state_machine_; bool inside_process_scheduled_actions_; diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc index 7b8faf7..6446e8d 100644 --- a/cc/scheduler/scheduler_state_machine.cc +++ b/cc/scheduler/scheduler_state_machine.cc @@ -84,7 +84,12 @@ std::string SchedulerStateMachine::ToString() { base::StringAppendF(&str, "inside_begin_frame_ = %d; ", inside_begin_frame_); base::StringAppendF(&str, "last_frame_time_ = %"PRId64"; ", - (last_frame_time_ - base::TimeTicks()).InMilliseconds()); + (last_begin_frame_args_.frame_time - base::TimeTicks()) + .InMilliseconds()); + base::StringAppendF(&str, "last_deadline_ = %"PRId64"; ", + (last_begin_frame_args_.deadline - base::TimeTicks()).InMilliseconds()); + base::StringAppendF(&str, "last_interval_ = %"PRId64"; ", + last_begin_frame_args_.interval.InMilliseconds()); base::StringAppendF(&str, "visible_ = %d; ", visible_); base::StringAppendF(&str, "can_start_ = %d; ", can_start_); base::StringAppendF(&str, "can_draw_ = %d; ", can_draw_); @@ -367,12 +372,9 @@ bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { return false; } -void SchedulerStateMachine::DidEnterBeginFrame() { +void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { inside_begin_frame_ = true; -} - -void SchedulerStateMachine::SetFrameTime(base::TimeTicks frame_time) { - last_frame_time_ = frame_time; + last_begin_frame_args_ = args; } void SchedulerStateMachine::DidLeaveBeginFrame() { diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index 79c6a6e..3784f6f 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/time.h" #include "cc/base/cc_export.h" +#include "cc/output/begin_frame_args.h" #include "cc/scheduler/scheduler_settings.h" namespace cc { @@ -79,8 +80,7 @@ class CC_EXPORT SchedulerStateMachine { // Indicates that the system has entered and left a BeginFrame callback. // The scheduler will not draw more than once in a given BeginFrame // callback. - void DidEnterBeginFrame(); - void SetFrameTime(base::TimeTicks frame_time); + void DidEnterBeginFrame(const BeginFrameArgs& args); void DidLeaveBeginFrame(); bool inside_begin_frame() const { return inside_begin_frame_; } @@ -189,7 +189,7 @@ class CC_EXPORT SchedulerStateMachine { bool expect_immediate_begin_frame_for_main_thread_; bool main_thread_needs_layer_textures_; bool inside_begin_frame_; - base::TimeTicks last_frame_time_; + BeginFrameArgs last_begin_frame_args_; bool visible_; bool can_start_; bool can_draw_; diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc index 7d7c820..51f167a 100644 --- a/cc/scheduler/scheduler_state_machine_unittest.cc +++ b/cc/scheduler/scheduler_state_machine_unittest.cc @@ -56,7 +56,7 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { state.DidLeaveBeginFrame(); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); } @@ -72,7 +72,7 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { state.DidLeaveBeginFrame(); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); } @@ -123,7 +123,7 @@ TEST(SchedulerStateMachineTest, state.SetNeedsRedraw(); EXPECT_TRUE(state.RedrawPending()); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); // We're drawing now. EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); @@ -155,7 +155,7 @@ TEST(SchedulerStateMachineTest, state.SetNeedsRedraw(); EXPECT_TRUE(state.RedrawPending()); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); // We're drawing now. EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); @@ -197,7 +197,7 @@ TEST(SchedulerStateMachineTest, // Then initiate a draw. state.SetNeedsRedraw(); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); EXPECT_TRUE(state.RedrawPending()); @@ -240,7 +240,7 @@ TEST(SchedulerStateMachineTest, // Then initiate a draw. state.SetNeedsRedraw(); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); EXPECT_TRUE(state.RedrawPending()); @@ -295,7 +295,7 @@ TEST(SchedulerStateMachineTest, // Then initiate a draw. state.SetNeedsRedraw(); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); EXPECT_TRUE(state.RedrawPending()); @@ -331,7 +331,7 @@ TEST(SchedulerStateMachineTest, // Start a draw. state.SetNeedsRedraw(); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); EXPECT_TRUE(state.RedrawPending()); @@ -347,7 +347,7 @@ TEST(SchedulerStateMachineTest, state.DidLeaveBeginFrame(); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); // We should try to draw again in the next begin frame on the impl thread. EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); @@ -363,7 +363,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { state.SetCanDraw(true); state.SetNeedsRedraw(); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); @@ -376,7 +376,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { state.DidDrawIfPossibleCompleted(true); state.DidLeaveBeginFrame(); EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); @@ -400,7 +400,7 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginFrame) { state.SetCommitState(all_commit_states[i]); bool visible = j; if (!visible) { - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); state.SetVisible(false); } else { state.SetVisible(true); @@ -430,7 +430,7 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginFrame) { state.SetCommitState(all_commit_states[i]); bool forced_draw = j; if (!forced_draw) { - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); state.SetNeedsRedraw(true); state.SetVisible(true); } else { @@ -476,7 +476,7 @@ TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) { state.SetNeedsRedraw(true); state.SetNeedsForcedRedraw(false); if (j == 1) - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); // Case 1: needs_commit=false. EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, @@ -507,7 +507,7 @@ TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) { state.SetNeedsRedraw(true); state.SetNeedsForcedRedraw(false); if (j == 1) - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); state.SetCanDraw(false); EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, @@ -562,7 +562,7 @@ TEST(SchedulerStateMachineTest, TestsetNeedsCommitIsNotLost) { // Expect to commit regardless of BeginFrame state. state.DidLeaveBeginFrame(); EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); // Commit and make sure we draw on next BeginFrame @@ -617,7 +617,7 @@ TEST(SchedulerStateMachineTest, TestFullCycle) { EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); // At BeginFrame, draw. - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); state.DidDrawIfPossibleCompleted(true); @@ -671,7 +671,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); // At BeginFrame, draw. - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); state.DidDrawIfPossibleCompleted(true); @@ -825,7 +825,7 @@ TEST(SchedulerStateMachineTest, // Once the context is recreated, whether we draw should be based on // SetCanDraw. state.SetNeedsRedraw(true); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); state.SetCanDraw(false); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); @@ -850,7 +850,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { // Set damage and expect a draw. state.SetNeedsRedraw(true); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); state.UpdateState(state.NextAction()); state.DidLeaveBeginFrame(); @@ -876,7 +876,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { // Expect to be told to begin context recreation, independent of // BeginFrame state. - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, state.NextAction()); state.DidLeaveBeginFrame(); @@ -902,7 +902,7 @@ TEST(SchedulerStateMachineTest, // Set damage and expect a draw. state.SetNeedsRedraw(true); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); state.UpdateState(state.NextAction()); state.DidLeaveBeginFrame(); @@ -929,7 +929,7 @@ TEST(SchedulerStateMachineTest, // Expect to be told to begin context recreation, independent of // BeginFrame state - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, state.NextAction()); state.DidLeaveBeginFrame(); @@ -951,7 +951,7 @@ TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { // Ask a forced redraw and verify it ocurrs. state.SetNeedsForcedRedraw(true); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); state.DidLeaveBeginFrame(); @@ -966,7 +966,7 @@ TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { // Ask a forced redraw and verify it ocurrs. state.SetNeedsForcedRedraw(true); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); state.DidLeaveBeginFrame(); } @@ -1100,7 +1100,7 @@ TEST(SchedulerStateMachineTest, TestImmediateFinishCommit) { EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.CommitState()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); state.SetNeedsForcedRedraw(true); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); @@ -1139,7 +1139,7 @@ TEST(SchedulerStateMachineTest, TestImmediateFinishCommitDuringCommit) { EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.CommitState()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); state.SetNeedsForcedRedraw(true); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); @@ -1178,7 +1178,7 @@ TEST(SchedulerStateMachineTest, EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.CommitState()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); state.SetNeedsForcedRedraw(true); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); @@ -1224,7 +1224,7 @@ TEST(SchedulerStateMachineTest, ImmediateFinishCommitWhileCantDraw) { EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.CommitState()); - state.DidEnterBeginFrame(); + state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); state.SetNeedsForcedRedraw(true); EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc index e0ddbcc..f0f91a8 100644 --- a/cc/scheduler/scheduler_unittest.cc +++ b/cc/scheduler/scheduler_unittest.cc @@ -170,7 +170,7 @@ TEST(SchedulerTest, RequestCommit) { client.Reset(); // BeginFrame should draw. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); EXPECT_FALSE(client.needs_begin_frame()); @@ -208,7 +208,7 @@ TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { client.Reset(); // Tick should draw but then begin another frame. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_TRUE(client.needs_begin_frame()); EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 2); @@ -216,7 +216,7 @@ TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { // Go back to quiescent state and verify we no longer request BeginFrames. scheduler->FinishCommit(); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_FALSE(client.needs_begin_frame()); } @@ -237,7 +237,7 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { EXPECT_TRUE(client.needs_begin_frame()); client.Reset(); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); EXPECT_FALSE(scheduler->RedrawPending()); @@ -261,7 +261,7 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { // No draw happens since the textures are acquired by the main thread. client.Reset(); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); EXPECT_TRUE(scheduler->RedrawPending()); EXPECT_TRUE(client.needs_begin_frame()); @@ -275,7 +275,7 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { // Now we can draw again after the commit happens. client.Reset(); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); EXPECT_FALSE(scheduler->RedrawPending()); @@ -323,7 +323,7 @@ TEST(SchedulerTest, TextureAcquisitionCollision) { client.Reset(); // Once compositor draw complete, the delayed texture acquisition fires. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 3); EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", client, @@ -404,12 +404,12 @@ TEST(SchedulerTest, RequestRedrawInsideDraw) { EXPECT_TRUE(client.needs_begin_frame()); EXPECT_EQ(0, client.num_draws()); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(scheduler->RedrawPending()); EXPECT_TRUE(client.needs_begin_frame()); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(2, client.num_draws()); EXPECT_FALSE(scheduler->RedrawPending()); EXPECT_FALSE(client.needs_begin_frame()); @@ -433,7 +433,7 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { EXPECT_EQ(0, client.num_draws()); // Fail the draw. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(1, client.num_draws()); // We have a commit pending and the draw failed, and we didn't lose the redraw @@ -443,7 +443,7 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { EXPECT_TRUE(client.needs_begin_frame()); // Fail the draw again. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(2, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_TRUE(scheduler->RedrawPending()); @@ -451,7 +451,7 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { // Draw successfully. client.SetDrawWillHappen(true); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(3, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_FALSE(scheduler->RedrawPending()); @@ -496,13 +496,13 @@ TEST(SchedulerTest, RequestCommitInsideDraw) { EXPECT_EQ(0, client.num_draws()); EXPECT_TRUE(client.needs_begin_frame()); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(1, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_TRUE(client.needs_begin_frame()); scheduler->FinishCommit(); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(2, client.num_draws());; EXPECT_FALSE(scheduler->RedrawPending()); EXPECT_FALSE(scheduler->CommitPending()); @@ -527,7 +527,7 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { EXPECT_EQ(0, client.num_draws()); // Fail the draw. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(1, client.num_draws()); // We have a commit pending and the draw failed, and we didn't lose the commit @@ -537,7 +537,7 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { EXPECT_TRUE(client.needs_begin_frame()); // Fail the draw again. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(2, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_TRUE(scheduler->RedrawPending()); @@ -545,7 +545,7 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { // Draw successfully. client.SetDrawWillHappen(true); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(3, client.num_draws()); EXPECT_TRUE(scheduler->CommitPending()); EXPECT_FALSE(scheduler->RedrawPending()); @@ -567,7 +567,7 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { EXPECT_EQ(0, client.num_draws()); // Draw successfully, this starts a new frame. - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(1, client.num_draws()); scheduler->SetNeedsRedraw(); @@ -576,7 +576,7 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { // Fail to draw, this should not start a frame. client.SetDrawWillHappen(false); - scheduler->BeginFrame(base::TimeTicks::Now()); + scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); EXPECT_EQ(2, client.num_draws()); } diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h index 58816cc..efc40f2 100644 --- a/cc/test/fake_layer_tree_host_impl_client.h +++ b/cc/test/fake_layer_tree_host_impl_client.h @@ -5,6 +5,7 @@ #ifndef CC_TEST_FAKE_LAYER_TREE_HOST_IMPL_CLIENT_H_ #define CC_TEST_FAKE_LAYER_TREE_HOST_IMPL_CLIENT_H_ +#include "cc/output/begin_frame_args.h" #include "cc/trees/layer_tree_host_impl.h" namespace cc { @@ -17,7 +18,7 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient { scoped_refptr offscreen_context_provider) OVERRIDE {} virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {} virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {} - virtual void BeginFrameOnImplThread(base::TimeTicks frame_time) + virtual void BeginFrameOnImplThread(const BeginFrameArgs& args) OVERRIDE {} virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {} virtual void OnHasPendingTreeStateChanged(bool has_pending_tree) OVERRIDE {} diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index 9ceadda..35d03e6 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -83,7 +83,7 @@ void FakeOutputSurface::SetNeedsBeginFrame(bool enable) { } void FakeOutputSurface::OnBeginFrame() { - OutputSurface::BeginFrame(base::TimeTicks::Now()); + OutputSurface::BeginFrame(BeginFrameArgs::CreateForTesting()); } diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index 7bc1a4f..b14deff 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -6,6 +6,7 @@ #define CC_TEST_FAKE_OUTPUT_SURFACE_H_ #include "base/time.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/compositor_frame.h" #include "cc/output/output_surface.h" #include "cc/output/software_output_device.h" diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index 654804b..6e66002 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc @@ -61,7 +61,7 @@ class PixelTest::PixelTestRendererClient return false; } virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {} - virtual void BeginFrame(base::TimeTicks frame_time) OVERRIDE {} + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {} virtual void DidLoseOutputSurface() OVERRIDE {} virtual void SetExternalDrawConstraints(const gfx::Transform& transform, diff --git a/cc/test/scheduler_test_common.cc b/cc/test/scheduler_test_common.cc index c812056..3b35a54 100644 --- a/cc/test/scheduler_test_common.cc +++ b/cc/test/scheduler_test_common.cc @@ -8,7 +8,9 @@ namespace cc { -void FakeTimeSourceClient::OnTimerTick() { tick_called_ = true; } +void FakeTimeSourceClient::OnTimerTick() { + tick_called_ = true; +} base::TimeTicks FakeDelayBasedTimeSource::Now() const { return now_; } diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index e4ca7e4..fe7589b 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -1072,8 +1072,8 @@ void LayerTreeHostImpl::SetNeedsRedrawRect(gfx::Rect damage_rect) { client_->SetNeedsRedrawRectOnImplThread(damage_rect); } -void LayerTreeHostImpl::BeginFrame(base::TimeTicks frame_time) { - client_->BeginFrameOnImplThread(frame_time); +void LayerTreeHostImpl::BeginFrame(const BeginFrameArgs& args) { + client_->BeginFrameOnImplThread(args); } void LayerTreeHostImpl::OnSwapBuffersComplete( @@ -1526,7 +1526,7 @@ bool LayerTreeHostImpl::DoInitializeRenderer( int max_frames_pending = output_surface->capabilities().max_frames_pending; if (max_frames_pending <= 0) - max_frames_pending = FrameRateController::DEFAULT_MAX_FRAMES_PENDING; + max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING; output_surface->SetMaxFramesPending(max_frames_pending); output_surface_ = output_surface.Pass(); diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index a5019ae..015a2f2 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -19,6 +19,7 @@ #include "cc/input/top_controls_manager_client.h" #include "cc/layers/layer_lists.h" #include "cc/layers/render_pass_sink.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/output_surface_client.h" #include "cc/output/renderer.h" #include "cc/quads/render_pass.h" @@ -54,7 +55,7 @@ class LayerTreeHostImplClient { scoped_refptr offscreen_context_provider) = 0; virtual void DidLoseOutputSurfaceOnImplThread() = 0; virtual void OnSwapBuffersCompleteOnImplThread() = 0; - virtual void BeginFrameOnImplThread(base::TimeTicks frame_time) = 0; + virtual void BeginFrameOnImplThread(const BeginFrameArgs& args) = 0; virtual void OnCanDrawStateChanged(bool can_draw) = 0; virtual void OnHasPendingTreeStateChanged(bool has_pending_tree) = 0; virtual void SetNeedsRedrawOnImplThread() = 0; @@ -201,7 +202,7 @@ class CC_EXPORT LayerTreeHostImpl virtual bool DeferredInitialize( scoped_refptr offscreen_context_provider) OVERRIDE; virtual void SetNeedsRedrawRect(gfx::Rect rect) OVERRIDE; - virtual void BeginFrame(base::TimeTicks frame_time) + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) OVERRIDE; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index b8b320c..e292026 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -22,6 +22,7 @@ #include "cc/layers/texture_layer_impl.h" #include "cc/layers/tiled_layer_impl.h" #include "cc/layers/video_layer_impl.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/compositor_frame_ack.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/output/gl_renderer.h" @@ -95,7 +96,7 @@ class LayerTreeHostImplTest : public testing::Test, } virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {} virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {} - virtual void BeginFrameOnImplThread(base::TimeTicks frame_time) + virtual void BeginFrameOnImplThread(const BeginFrameArgs& args) OVERRIDE {} virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE { on_can_draw_state_changed_called_ = true; diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index f4d245b..0efcaaa 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -15,6 +15,7 @@ #include "cc/layers/layer_impl.h" #include "cc/layers/picture_layer.h" #include "cc/layers/scrollbar_layer.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/output/output_surface.h" diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 9d995ba..0ed3798 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h @@ -9,6 +9,7 @@ #include "base/time.h" #include "cc/animation/animation_events.h" +#include "cc/output/begin_frame_args.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/proxy.h" @@ -51,7 +52,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { scoped_refptr offscreen_context_provider) OVERRIDE; virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE; virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {} - virtual void BeginFrameOnImplThread(base::TimeTicks frame_time) + virtual void BeginFrameOnImplThread(const BeginFrameArgs& args) OVERRIDE {} virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE; virtual void OnHasPendingTreeStateChanged(bool have_pending_tree) OVERRIDE; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index a7c4086..b307c9e 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -362,10 +362,10 @@ void ThreadProxy::SetNeedsBeginFrameOnImplThread(bool enable) { layer_tree_host_impl_->SetNeedsBeginFrame(enable); } -void ThreadProxy::BeginFrameOnImplThread(base::TimeTicks frame_time) { +void ThreadProxy::BeginFrameOnImplThread(const BeginFrameArgs& args) { DCHECK(IsImplThread()); TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread"); - scheduler_on_impl_thread_->BeginFrame(frame_time); + scheduler_on_impl_thread_->BeginFrame(args); } void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h index db3a502..4f26d35 100644 --- a/cc/trees/thread_proxy.h +++ b/cc/trees/thread_proxy.h @@ -68,7 +68,7 @@ class ThreadProxy : public Proxy, scoped_refptr offscreen_context_provider) OVERRIDE; virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE; virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE; - virtual void BeginFrameOnImplThread(base::TimeTicks frame_time) OVERRIDE; + virtual void BeginFrameOnImplThread(const BeginFrameArgs& args) OVERRIDE; virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE; virtual void OnHasPendingTreeStateChanged(bool has_pending_tree) OVERRIDE; virtual void SetNeedsRedrawOnImplThread() OVERRIDE; diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index f3d2bb0..8beebeb 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc @@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "cc/layers/layer.h" +#include "cc/output/begin_frame_args.h" #include "content/browser/android/interstitial_page_delegate_android.h" #include "content/browser/android/load_url_params.h" #include "content/browser/android/media_player_manager_impl.h" @@ -77,6 +78,10 @@ namespace content { namespace { +const unsigned int kDefaultVSyncIntervalMicros = 16666u; +// TODO(brianderson): Use adaptive draw-time estimation. +const float kDefaultBrowserCompositeVSyncFraction = 1.0f / 3; + const void* kContentViewUserDataKey = &kContentViewUserDataKey; int GetRenderProcessIdFromRenderViewHost(RenderViewHost* host) { @@ -158,6 +163,10 @@ ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, web_contents_(static_cast(web_contents)), root_layer_(cc::Layer::Create()), tab_crashed_(false), + vsync_interval_(base::TimeDelta::FromMicroseconds( + kDefaultVSyncIntervalMicros)), + expected_browser_composite_time_(base::TimeDelta::FromMicroseconds( + kDefaultVSyncIntervalMicros * kDefaultBrowserCompositeVSyncFraction)), view_android_(view_android), window_android_(window_android) { CHECK(web_contents) << @@ -701,7 +710,7 @@ void ContentViewCoreImpl::LoadUrl( tab_crashed_ = false; } -void ContentViewCoreImpl::SetVSyncNotificationEnabled(bool enabled) { +void ContentViewCoreImpl::SetNeedsBeginFrame(bool enabled) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef obj = java_ref_.get(env); if (obj.is_null()) @@ -1223,6 +1232,11 @@ void ContentViewCoreImpl::UpdateVSyncParameters(JNIEnv* env, jobject /* obj */, host->UpdateVSyncParameters( base::TimeTicks::FromInternalValue(timebase_micros), base::TimeDelta::FromMicroseconds(interval_micros)); + + vsync_interval_ = + base::TimeDelta::FromMicroseconds(interval_micros); + expected_browser_composite_time_ = + vsync_interval_ * kDefaultBrowserCompositeVSyncFraction; } void ContentViewCoreImpl::OnVSync(JNIEnv* env, jobject /* obj */, @@ -1231,8 +1245,13 @@ void ContentViewCoreImpl::OnVSync(JNIEnv* env, jobject /* obj */, if (!view) return; + base::TimeTicks frame_time = + base::TimeTicks::FromInternalValue(frame_time_micros); + base::TimeTicks display_time = frame_time + vsync_interval_; + base::TimeTicks deadline = display_time - expected_browser_composite_time_; + view->SendBeginFrame( - base::TimeTicks::FromInternalValue(frame_time_micros)); + cc::BeginFrameArgs::Create(frame_time, deadline, vsync_interval_)); } jboolean ContentViewCoreImpl::OnAnimate(JNIEnv* env, jobject /* obj */, diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index e8b1e4e..243c76b 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h @@ -297,7 +297,7 @@ class ContentViewCoreImpl : public ContentViewCore, void AttachLayer(scoped_refptr layer); void RemoveLayer(scoped_refptr layer); - void SetVSyncNotificationEnabled(bool enabled); + void SetNeedsBeginFrame(bool enabled); void SetNeedsAnimate(); private: @@ -349,6 +349,10 @@ class ContentViewCoreImpl : public ContentViewCore, // Device scale factor. float dpi_scale_; + // Variables used to keep track of frame timestamps and deadlines. + base::TimeDelta vsync_interval_; + base::TimeDelta expected_browser_composite_time_; + // The Android view that can be used to add and remove decoration layers // like AutofillPopup. ui::ViewAndroid* view_android_; diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc index 30f5d0e..ec8e6a3 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/time.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "cc/output/context_provider.h" @@ -90,6 +91,7 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( did_swap_buffer_(false), current_sw_canvas_(NULL) { capabilities_.deferred_gl_initialization = true; + capabilities_.adjust_deadline_for_parent = false; // Cannot call out to GetDelegate() here as the output surface is not // constructed on the correct thread. } @@ -219,7 +221,7 @@ void SynchronousCompositorOutputSurface::InvokeComposite( did_swap_buffer_ = false; SetNeedsRedrawRect(gfx::Rect(damage_size)); if (needs_begin_frame_) - BeginFrame(base::TimeTicks::Now()); + BeginFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor()); if (did_swap_buffer_) OnSwapBuffersComplete(NULL); diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index c5560e6..f3c4606 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -46,7 +46,9 @@ namespace { class DirectOutputSurface : public cc::OutputSurface { public: DirectOutputSurface(scoped_ptr context3d) - : cc::OutputSurface(context3d.Pass()) {} + : cc::OutputSurface(context3d.Pass()) { + capabilities_.adjust_deadline_for_parent = false; + } virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE { surface_size_ = size; @@ -56,6 +58,15 @@ class DirectOutputSurface : public cc::OutputSurface { } }; +// Used to override capabilities_.adjust_deadline_for_parent to false +class OutputSurfaceWithoutParent : public cc::OutputSurface { + public: + OutputSurfaceWithoutParent(scoped_ptr context3d) + : cc::OutputSurface(context3d.Pass()) { + capabilities_.adjust_deadline_for_parent = false; + } +}; + static bool g_initialized = false; static base::Thread* g_impl_thread = NULL; static bool g_use_direct_gl = false; @@ -365,8 +376,9 @@ scoped_ptr CompositorImpl::CreateOutputSurface() { LOG(ERROR) << "Failed to create 3D context for compositor."; return scoped_ptr(); } - return make_scoped_ptr(new cc::OutputSurface( - context.PassAs())); + return scoped_ptr( + new OutputSurfaceWithoutParent( + context.PassAs())); } } diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc index a4eeacd..4e27a79 100644 --- a/content/browser/renderer_host/image_transport_factory.cc +++ b/content/browser/renderer_host/image_transport_factory.cc @@ -505,6 +505,7 @@ class BrowserCompositorOutputSurface else LOG(ERROR) << "Trouble parsing --" << switches::kUIMaxFramesPending; } + capabilities_.adjust_deadline_for_parent = false; DetachFromThread(); } diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index fde211f..fffa18b 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -415,11 +415,10 @@ void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor( } void RenderWidgetHostViewAndroid::SendBeginFrame( - base::TimeTicks frame_time) { + const cc::BeginFrameArgs& args) { TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame"); if (host_) - host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), - frame_time)); + host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args)); } void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame( @@ -427,7 +426,7 @@ void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame( TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame", "enabled", enabled); if (content_view_core_) - content_view_core_->SetVSyncNotificationEnabled(enabled); + content_view_core_->SetNeedsBeginFrame(enabled); } void RenderWidgetHostViewAndroid::OnStartContentIntent( diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 82faae0..7de423e 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h @@ -16,6 +16,7 @@ #include "base/process.h" #include "cc/layers/delegated_renderer_layer_client.h" #include "cc/layers/texture_layer_client.h" +#include "cc/output/begin_frame_args.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/renderer_host/ime_adapter_android.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" @@ -192,7 +193,7 @@ class RenderWidgetHostViewAndroid void SendMouseEvent(const WebKit::WebMouseEvent& event); void SendMouseWheelEvent(const WebKit::WebMouseWheelEvent& event); void SendGestureEvent(const WebKit::WebGestureEvent& event); - void SendBeginFrame(base::TimeTicks frame_time); + void SendBeginFrame(const cc::BeginFrameArgs& args); void OnTextInputStateChanged(const ViewHostMsg_TextInputState_Params& params); void OnProcessImeBatchStateAck(bool is_begin); diff --git a/content/common/cc_messages.h b/content/common/cc_messages.h index 701b65f..f6fdce7 100644 --- a/content/common/cc_messages.h +++ b/content/common/cc_messages.h @@ -4,6 +4,7 @@ // // IPC Messages sent between compositor instances. +#include "cc/output/begin_frame_args.h" #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "cc/quads/checkerboard_draw_quad.h" @@ -212,6 +213,12 @@ IPC_STRUCT_TRAITS_BEGIN(cc::TransferableResource) IPC_STRUCT_TRAITS_MEMBER(mailbox) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(cc::BeginFrameArgs) + IPC_STRUCT_TRAITS_MEMBER(frame_time) + IPC_STRUCT_TRAITS_MEMBER(deadline) + IPC_STRUCT_TRAITS_MEMBER(interval) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(cc::CompositorFrameMetadata) IPC_STRUCT_TRAITS_MEMBER(device_scale_factor) IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset) diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 5f1f14c..f36be08 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -8,6 +8,7 @@ #include "base/process.h" #include "base/shared_memory.h" #include "base/strings/string16.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "content/common/browser_rendering_stats.h" @@ -1283,7 +1284,7 @@ IPC_MESSAGE_ROUTED0(ViewMsg_ShowImeIfNeeded) // Sent by the browser when the renderer should generate a new frame. IPC_MESSAGE_ROUTED1(ViewMsg_BeginFrame, - base::TimeTicks /* frame_time */) + cc::BeginFrameArgs /* args */) #elif defined(OS_MACOSX) // Let the RenderView know its window has changed visibility. diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc index 30fbc30..377a26f 100644 --- a/content/renderer/gpu/compositor_output_surface.cc +++ b/content/renderer/gpu/compositor_output_surface.cc @@ -138,9 +138,9 @@ void CompositorOutputSurface::SetNeedsBeginFrame(bool enable) { OutputSurface::SetNeedsBeginFrame(enable); } -void CompositorOutputSurface::OnBeginFrame(base::TimeTicks frame_time) { +void CompositorOutputSurface::OnBeginFrame(const cc::BeginFrameArgs& args) { DCHECK(CalledOnValidThread()); - BeginFrame(frame_time); + BeginFrame(args); } #endif // defined(OS_ANDROID) diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h index c1f9077..422a5250 100644 --- a/content/renderer/gpu/compositor_output_surface.h +++ b/content/renderer/gpu/compositor_output_surface.h @@ -12,6 +12,7 @@ #include "base/threading/non_thread_safe.h" #include "base/threading/platform_thread.h" #include "base/time.h" +#include "cc/output/begin_frame_args.h" #include "cc/output/output_surface.h" #include "ipc/ipc_sync_message_filter.h" @@ -87,7 +88,7 @@ class CompositorOutputSurface void OnUpdateVSyncParameters( base::TimeTicks timebase, base::TimeDelta interval); #if defined(OS_ANDROID) - void OnBeginFrame(base::TimeTicks frame_time); + void OnBeginFrame(const cc::BeginFrameArgs& args); #endif bool Send(IPC::Message* message); -- cgit v1.1