Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Unified Diff: cc/trees/thread_proxy.cc

Issue 16871016: cc: Use BeginFrameArgs (Closed) Base URL: http://git.chromium.org/chromium/src.git@bfargs2
Patch Set: Add an --enable-deadline-scheduler commandline flag. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/trees/thread_proxy.cc
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 31a497ab267419fb189fadd24095c8e57df86438..912e244a0fa6b498a76252f7988e117f81e007ca 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -77,6 +77,7 @@ ThreadProxy::ThreadProxy(
manage_tiles_pending_(false),
weak_factory_on_impl_thread_(this),
weak_factory_(this),
+ frame_did_draw_(false),
begin_frame_sent_to_main_thread_completion_event_on_impl_thread_(NULL),
readback_request_on_impl_thread_(NULL),
commit_completion_event_on_impl_thread_(NULL),
@@ -123,19 +124,27 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
return false;
}
- // Perform a synchronous commit.
+ // Perform a synchronous commit with an associated readback.
+ ReadbackRequest request;
+ request.rect = rect;
+ request.pixels = pixels;
{
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
CompletionEvent begin_frame_sent_to_main_thread_completion;
Proxy::ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&ThreadProxy::ForceCommitOnImplThread,
+ base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
impl_thread_weak_ptr_,
- &begin_frame_sent_to_main_thread_completion));
+ &begin_frame_sent_to_main_thread_completion,
+ &request));
begin_frame_sent_to_main_thread_completion.Wait();
}
in_composite_and_readback_ = true;
+ // This is the forced commit.
+ // Note: The Impl thread also queues a separate BeginFrameOnMainThread on the
+ // main thread, which will be called after this CompositeAndReadback
+ // completes, to replace the forced commit.
BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>());
in_composite_and_readback_ = false;
@@ -143,48 +152,35 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
// that it made.
can_cancel_commit_ = false;
- // Perform a synchronous readback.
- ReadbackRequest request;
- request.rect = rect;
- request.pixels = pixels;
- {
- DebugScopedSetMainThreadBlocked main_thread_blocked(this);
- Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::RequestReadbackOnImplThread,
- impl_thread_weak_ptr_,
- &request));
- request.completion.Wait();
- }
+ request.completion.Wait();
return request.success;
}
-void ThreadProxy::ForceCommitOnImplThread(CompletionEvent* completion) {
- TRACE_EVENT0("cc", "ThreadProxy::ForceCommitOnImplThread");
+void ThreadProxy::ForceCommitForReadbackOnImplThread(
+ CompletionEvent* begin_frame_sent_completion,
+ ReadbackRequest* request) {
+ TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
DCHECK(IsImplThread());
DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_);
-
- scheduler_on_impl_thread_->SetNeedsForcedCommit();
- if (scheduler_on_impl_thread_->CommitPending()) {
- completion->Signal();
- return;
- }
-
- begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = completion;
-}
-
-void ThreadProxy::RequestReadbackOnImplThread(ReadbackRequest* request) {
- DCHECK(Proxy::IsImplThread());
DCHECK(!readback_request_on_impl_thread_);
+
if (!layer_tree_host_impl_) {
+ begin_frame_sent_completion->Signal();
request->success = false;
request->completion.Signal();
return;
}
readback_request_on_impl_thread_ = request;
- scheduler_on_impl_thread_->SetNeedsRedraw();
- scheduler_on_impl_thread_->SetNeedsForcedRedraw();
+
+ scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback();
+ if (scheduler_on_impl_thread_->CommitPending()) {
+ begin_frame_sent_completion->Signal();
+ return;
+ }
+
+ begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ =
+ begin_frame_sent_completion;
}
void ThreadProxy::FinishAllRendering() {
@@ -393,14 +389,35 @@ void ThreadProxy::SetNeedsBeginFrameOnImplThread(bool enable) {
TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrameOnImplThread",
"enable", enable);
layer_tree_host_impl_->SetNeedsBeginFrame(enable);
+ layer_tree_host_impl_->UpdateBackgroundAnimateTicking(!enable);
}
void ThreadProxy::BeginFrameOnImplThread(const BeginFrameArgs& args) {
DCHECK(IsImplThread());
TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread");
+
+ base::TimeTicks monotonic_time =
+ layer_tree_host_impl_->CurrentFrameTimeTicks();
+ base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime();
+ if (layer_tree_host_impl_->active_tree()->root_layer())
+ layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time);
+
+ // Reinitialize for the current frame.
+ frame_did_draw_ = false;
+
scheduler_on_impl_thread_->BeginFrame(args);
}
+void ThreadProxy::DidBeginFrameDeadlineOnImplThread() {
+ // Do not start animations if we skip drawing the frame to avoid
+ // checkerboarding.
+ if (layer_tree_host_impl_->active_tree()->root_layer()) {
+ layer_tree_host_impl_->UpdateAnimationState(
+ frame_did_draw_ || !layer_tree_host_impl_->CanDraw());
+ }
+ layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
+}
+
void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
DCHECK(IsImplThread());
TRACE_EVENT1(
@@ -410,11 +427,20 @@ void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
!scheduler_on_impl_thread_->WillDrawIfNeeded());
}
+void ThreadProxy::NotifyReadyToActivate() {
+ TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate");
+ scheduler_on_impl_thread_->NotifyReadyToActivate();
+}
+
void ThreadProxy::OnHasPendingTreeStateChanged(bool has_pending_tree) {
DCHECK(IsImplThread());
TRACE_EVENT1("cc", "ThreadProxy::OnHasPendingTreeStateChanged",
"has_pending_tree", has_pending_tree);
- scheduler_on_impl_thread_->SetHasPendingTree(has_pending_tree);
+ scheduler_on_impl_thread_->SetHasTrees(
+ has_pending_tree,
+ layer_tree_host_impl_->active_tree()
+ ? !layer_tree_host_impl_->active_tree()->root_layer()
+ : true);
}
void ThreadProxy::SetNeedsCommitOnImplThread() {
@@ -668,6 +694,7 @@ void ThreadProxy::ScheduledActionSendBeginFrameToMainThread() {
TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginFrameToMainThread");
scoped_ptr<BeginFrameAndCommitState> begin_frame_state(
new BeginFrameAndCommitState);
+
begin_frame_state->monotonic_frame_begin_time =
layer_tree_host_impl_->CurrentPhysicalTimeTicks();
begin_frame_state->scroll_info =
@@ -676,6 +703,7 @@ void ThreadProxy::ScheduledActionSendBeginFrameToMainThread() {
if (!layer_tree_host_impl_->settings().impl_side_painting) {
DCHECK_GT(layer_tree_host_impl_->memory_allocation_limit_bytes(), 0u);
}
+
begin_frame_state->memory_allocation_limit_bytes =
layer_tree_host_impl_->memory_allocation_limit_bytes();
Proxy::MainThreadTaskRunner()->PostTask(
@@ -851,8 +879,6 @@ void ThreadProxy::StartCommitOnImplThread(
CompletionEvent* completion,
ResourceUpdateQueue* raw_queue,
scoped_refptr<cc::ContextProvider> offscreen_context_provider) {
- scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
-
TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
DCHECK(!commit_completion_event_on_impl_thread_);
DCHECK(IsImplThread() && IsMainThreadBlocked());
@@ -862,9 +888,12 @@ void ThreadProxy::StartCommitOnImplThread(
if (!layer_tree_host_impl_) {
TRACE_EVENT0("cc", "EarlyOut_NoLayerTree");
completion->Signal();
+
return;
}
+ scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
+
if (offscreen_context_provider.get())
offscreen_context_provider->BindToCurrentThread();
layer_tree_host_impl_->resource_provider()->
@@ -931,9 +960,6 @@ void ThreadProxy::ScheduledActionCommit() {
SetInputThrottledUntilCommitOnImplThread(false);
- layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
- !scheduler_on_impl_thread_->WillDrawIfNeeded());
-
next_frame_is_newly_committed_frame_on_impl_thread_ = true;
if (layer_tree_host_->settings().impl_side_painting &&
@@ -955,6 +981,10 @@ void ThreadProxy::ScheduledActionCommit() {
begin_frame_to_commit_duration_history_.InsertSample(
commit_complete_time_ - begin_frame_sent_to_main_thread_time_);
+ // The commit may have added animations, requiring us to start
+ // background ticking.
+ layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
+ !scheduler_on_impl_thread_->WillDrawIfNeeded());
// SetVisible kicks off the next scheduler action, so this must be last.
scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
}
@@ -965,10 +995,10 @@ void ThreadProxy::ScheduledActionUpdateVisibleTiles() {
layer_tree_host_impl_->UpdateVisibleTiles();
}
-void ThreadProxy::ScheduledActionActivatePendingTreeIfNeeded() {
+void ThreadProxy::ScheduledActionActivatePendingTree() {
DCHECK(IsImplThread());
- TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTreeIfNeeded");
- layer_tree_host_impl_->ActivatePendingTreeIfNeeded();
+ TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree");
+ layer_tree_host_impl_->ActivatePendingTree();
}
void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
@@ -979,12 +1009,13 @@ void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
main_thread_weak_ptr_));
}
-ScheduledActionDrawAndSwapResult
-ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
- TRACE_EVENT1(
- "cc", "ThreadProxy::ScheduledActionDrawAndSwap", "forced", forced_draw);
+DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawSwapReadbackInternal(
+ bool forced_draw,
+ bool swap_requested,
+ bool readback_requested) {
+ TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawSwapReadback");
- ScheduledActionDrawAndSwapResult result;
+ DrawSwapReadbackResult result;
result.did_draw = false;
result.did_swap = false;
DCHECK(IsImplThread());
@@ -996,19 +1027,6 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
if (!layer_tree_host_impl_->renderer())
return result;
- base::TimeTicks monotonic_time =
- layer_tree_host_impl_->CurrentFrameTimeTicks();
- base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime();
-
- // TODO(enne): This should probably happen post-animate.
- if (layer_tree_host_impl_->pending_tree()) {
- layer_tree_host_impl_->ActivatePendingTreeIfNeeded();
- if (layer_tree_host_impl_->pending_tree())
- layer_tree_host_impl_->pending_tree()->UpdateDrawProperties();
- }
- layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time);
- layer_tree_host_impl_->UpdateBackgroundAnimateTicking(false);
-
base::TimeTicks start_time = base::TimeTicks::HighResNow();
base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
base::AutoReset<bool> mark_inside(&inside_draw_, true);
@@ -1024,12 +1042,12 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
// DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
// CanDraw() as well.
- bool drawing_for_readback = !!readback_request_on_impl_thread_;
+ bool drawing_for_readback =
+ readback_requested && !!readback_request_on_impl_thread_;
bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
LayerTreeHostImpl::FrameData frame;
bool draw_frame = false;
- bool start_ready_animations = true;
if (layer_tree_host_impl_->CanDraw() &&
(!drawing_for_readback || can_do_readback)) {
@@ -1038,15 +1056,13 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
if (drawing_for_readback)
readback_rect = readback_request_on_impl_thread_->rect;
- // Do not start animations if we skip drawing the frame to avoid
- // checkerboarding.
if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) ||
forced_draw)
draw_frame = true;
- else
- start_ready_animations = false;
}
+ frame_did_draw_ = draw_frame;
+
if (draw_frame) {
layer_tree_host_impl_->DrawLayers(
&frame,
@@ -1055,20 +1071,18 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
}
layer_tree_host_impl_->DidDrawAllLayers(frame);
- layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
-
// Check for a pending CompositeAndReadback.
- if (readback_request_on_impl_thread_) {
- readback_request_on_impl_thread_->success = false;
+ if (drawing_for_readback) {
+ result.did_readback = false;
if (draw_frame) {
layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels,
readback_request_on_impl_thread_->rect);
- readback_request_on_impl_thread_->success =
- !layer_tree_host_impl_->IsContextLost();
+ result.did_readback = !layer_tree_host_impl_->IsContextLost();
}
+ readback_request_on_impl_thread_->success = result.did_readback;
readback_request_on_impl_thread_->completion.Signal();
readback_request_on_impl_thread_ = NULL;
- } else if (draw_frame) {
+ } else if (draw_frame && swap_requested) {
result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
if (frame.contains_incomplete_tile)
@@ -1161,21 +1175,34 @@ void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
texture_acquisition_completion_event_on_impl_thread_ = NULL;
}
-ScheduledActionDrawAndSwapResult
-ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
- return ScheduledActionDrawAndSwapInternal(false);
+DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
+ bool forced_draw = false;
+ bool swap_requested = true;
+ bool readback_requested = false;
+ return ScheduledActionDrawSwapReadbackInternal(
+ forced_draw, swap_requested, readback_requested);
+}
+
+DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
+ bool forced_draw = true;
+ bool swap_requested = true;
+ bool readback_requested = false;
+ return ScheduledActionDrawSwapReadbackInternal(
+ forced_draw, swap_requested, readback_requested);
}
-ScheduledActionDrawAndSwapResult
-ThreadProxy::ScheduledActionDrawAndSwapForced() {
- return ScheduledActionDrawAndSwapInternal(true);
+DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
+ bool forced_draw = true;
+ bool swap_requested = false;
+ bool readback_requested = true;
+ return ScheduledActionDrawSwapReadbackInternal(
+ forced_draw, swap_requested, readback_requested);
}
void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
if (current_resource_update_controller_on_impl_thread_)
- current_resource_update_controller_on_impl_thread_
- ->PerformMoreUpdates(time);
- layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
+ current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
+ time);
}
base::TimeDelta ThreadProxy::DrawDurationEstimate() {
@@ -1196,6 +1223,14 @@ base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
kCommitAndActivationDurationEstimationPercentile);
}
+void ThreadProxy::PostBeginFrameDeadline(const base::Closure& closure,
+ base::TimeTicks deadline) {
+ base::TimeDelta delta = deadline - base::TimeTicks::Now();
+ if (delta <= base::TimeDelta())
+ delta = base::TimeDelta();
+ Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
+}
+
void ThreadProxy::ReadyToFinalizeTextureUpdates() {
DCHECK(IsImplThread());
scheduler_on_impl_thread_->FinishCommit();
@@ -1266,6 +1301,8 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
const LayerTreeSettings& settings = layer_tree_host_->settings();
SchedulerSettings scheduler_settings;
+ scheduler_settings.deadline_scheduling_enabled =
+ settings.deadline_scheduling_enabled;
scheduler_settings.impl_side_painting = settings.impl_side_painting;
scheduler_settings.timeout_and_draw_when_animation_checkerboards =
settings.timeout_and_draw_when_animation_checkerboards;
@@ -1273,6 +1310,7 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
settings.using_synchronous_renderer_compositor;
scheduler_settings.throttle_frame_production =
settings.throttle_frame_production;
+ scheduler_settings.use_begin_frame_workaround_for_crbug_249806 = true;
scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings);
scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());

Powered by Google App Engine
This is Rietveld 408576698