diff --git a/sky/shell/ui/animator.cc b/sky/shell/ui/animator.cc index ceca49942c3e9..1c57719b0f606 100644 --- a/sky/shell/ui/animator.cc +++ b/sky/shell/ui/animator.cc @@ -11,11 +11,14 @@ namespace sky { namespace shell { +const int kPipelineDepth = 2; + Animator::Animator(const Engine::Config& config, Engine* engine) : config_(config), engine_(engine), + outstanding_draw_requests_(0), + did_defer_frame_request_(false), engine_requested_frame_(false), - frame_in_progress_(false), paused_(false), weak_factory_(this) { } @@ -27,15 +30,19 @@ void Animator::RequestFrame() { if (engine_requested_frame_) return; + DCHECK(!did_defer_frame_request_); + TRACE_EVENT_ASYNC_BEGIN0("sky", "Frame request pending", this); engine_requested_frame_ = true; - if (!frame_in_progress_) { - frame_in_progress_ = true; - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr())); + if (outstanding_draw_requests_ >= kPipelineDepth) { + did_defer_frame_request_ = true; + return; } + + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr())); } void Animator::Stop() { @@ -49,31 +56,30 @@ void Animator::Start() { } void Animator::BeginFrame() { - DCHECK(frame_in_progress_); - // There could be a request in the message loop at time of cancel. - if (!engine_requested_frame_) { - frame_in_progress_ = false; + if (!engine_requested_frame_) return; - } - engine_requested_frame_ = false; TRACE_EVENT_ASYNC_END0("sky", "Frame request pending", this); engine_->BeginFrame(base::TimeTicks::Now()); + skia::RefPtr picture = engine_->Paint(); + + outstanding_draw_requests_++; + DCHECK(outstanding_draw_requests_ <= kPipelineDepth); config_.gpu_task_runner->PostTaskAndReply( FROM_HERE, - base::Bind(&GPUDelegate::Draw, config_.gpu_delegate, engine_->Paint()), + base::Bind(&GPUDelegate::Draw, config_.gpu_delegate, picture), base::Bind(&Animator::OnFrameComplete, weak_factory_.GetWeakPtr())); } void Animator::OnFrameComplete() { - DCHECK(frame_in_progress_); - frame_in_progress_ = false; + DCHECK(outstanding_draw_requests_ > 0); + --outstanding_draw_requests_; if (paused_) return; - if (engine_requested_frame_) { - frame_in_progress_ = true; + if (engine_requested_frame_ && did_defer_frame_request_) { + did_defer_frame_request_ = false; BeginFrame(); } } diff --git a/sky/shell/ui/animator.h b/sky/shell/ui/animator.h index cef6624cc6b8b..47de3ff850cde 100644 --- a/sky/shell/ui/animator.h +++ b/sky/shell/ui/animator.h @@ -27,8 +27,9 @@ class Animator { Engine::Config config_; Engine* engine_; + int outstanding_draw_requests_; + bool did_defer_frame_request_; bool engine_requested_frame_; - bool frame_in_progress_; bool paused_; base::WeakPtrFactory weak_factory_;