#include "cc/quads/draw_quad.h"
#include "cc/resources/prioritized_resource_manager.h"
#include "cc/scheduler/delay_based_time_source.h"
-#include "cc/scheduler/frame_rate_controller.h"
#include "cc/scheduler/scheduler.h"
#include "cc/trees/blocking_task_runner.h"
#include "cc/trees/layer_tree_host.h"
animate_requested(false),
commit_requested(false),
commit_request_sent_to_impl_thread(false),
- created_offscreen_context_provider(false),
started(false),
- textures_acquired(true),
in_composite_and_readback(false),
manage_tiles_pending(false),
can_cancel_commit(true),
readback_request(NULL),
commit_completion_event(NULL),
completion_event_for_commit_held_on_tree_activation(NULL),
- texture_acquisition_completion_event(NULL),
next_frame_is_newly_committed_frame(false),
inside_draw(false),
input_throttled_until_commit(false),
animations_frozen_until_next_draw(false),
+ did_commit_after_animating(false),
renew_tree_priority_pending(false),
- weak_factory(proxy) {}
+ weak_factory(proxy) {
+}
ThreadProxy::CompositorThreadOnly::~CompositorThreadOnly() {}
RendererCapabilities capabilities;
bool success = !!output_surface;
- if (!success) {
- OnOutputSurfaceInitializeAttempted(false, capabilities);
- return;
- }
-
- scoped_refptr<ContextProvider> offscreen_context_provider;
- if (main().created_offscreen_context_provider) {
- offscreen_context_provider =
- layer_tree_host()->client()->OffscreenContextProvider();
- success = !!offscreen_context_provider.get();
- if (!success) {
- OnOutputSurfaceInitializeAttempted(false, capabilities);
- return;
- }
- }
-
- success = false;
- {
+ if (success) {
// Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
// of that call are pushed into the success and capabilities local
// variables.
impl_thread_weak_ptr_,
&completion,
base::Passed(&output_surface),
- offscreen_context_provider,
&success,
&capabilities));
completion.Wait();
}
+ main().renderer_capabilities_main_thread_copy = capabilities;
+ layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
- OnOutputSurfaceInitializeAttempted(success, capabilities);
+ if (success) {
+ main().output_surface_creation_callback.Cancel();
+ } else if (!main().output_surface_creation_callback.IsCancelled()) {
+ Proxy::MainThreadTaskRunner()->PostTask(
+ FROM_HERE, main().output_surface_creation_callback.callback());
+ }
}
void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
main().renderer_capabilities_main_thread_copy = capabilities;
}
-void ThreadProxy::OnOutputSurfaceInitializeAttempted(
- bool success,
- const RendererCapabilities& capabilities) {
- DCHECK(IsMainThread());
- DCHECK(layer_tree_host());
-
- if (success) {
- main().renderer_capabilities_main_thread_copy = capabilities;
- }
-
- LayerTreeHost::CreateResult result =
- layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
- if (result == LayerTreeHost::CreateFailedButTryAgain) {
- if (!main().output_surface_creation_callback.callback().is_null()) {
- Proxy::MainThreadTaskRunner()->PostTask(
- FROM_HERE, main().output_surface_creation_callback.callback());
- }
- } else {
- main().output_surface_creation_callback.Cancel();
- }
-}
-
void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
DCHECK(IsMainThread());
if (main().commit_request_sent_to_impl_thread)
DCHECK(IsImplThread());
if (!impl().layer_tree_host_impl->IsContextLost())
return;
- if (ContextProvider* offscreen_contexts =
- impl().layer_tree_host_impl->offscreen_context_provider())
- offscreen_contexts->VerifyContexts();
impl().scheduler->DidLoseOutputSurface();
}
-void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
- TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread");
+void ThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
+ base::TimeDelta interval) {
+ impl().scheduler->CommitVSyncParameters(timebase, interval);
+}
+
+void ThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
+ impl().scheduler->SetEstimatedParentDrawTime(draw_time);
+}
+
+void ThreadProxy::SetMaxSwapsPendingOnImplThread(int max) {
+ impl().scheduler->SetMaxSwapsPending(max);
+}
+
+void ThreadProxy::DidSwapBuffersOnImplThread() {
+ impl().scheduler->DidSwapBuffers();
+}
+
+void ThreadProxy::DidSwapBuffersCompleteOnImplThread() {
+ TRACE_EVENT0("cc", "ThreadProxy::DidSwapBuffersCompleteOnImplThread");
DCHECK(IsImplThread());
+ impl().scheduler->DidSwapBuffersComplete();
Proxy::MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
}
-void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
- TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame", "enable", enable);
- DCHECK(IsImplThread());
- impl().layer_tree_host_impl->SetNeedsBeginImplFrame(enable);
+void ThreadProxy::SetNeedsBeginFrame(bool enable) {
+ TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrame", "enable", enable);
+ impl().layer_tree_host_impl->SetNeedsBeginFrame(enable);
UpdateBackgroundAnimateTicking();
}
-void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
- TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
- DCHECK(IsImplThread());
-
- // Sample the frame time now. This time will be used for updating animations
- // when we draw.
- impl().layer_tree_host_impl->UpdateCurrentFrameTime();
+void ThreadProxy::BeginFrame(const BeginFrameArgs& args) {
+ impl().scheduler->BeginFrame(args);
+}
- impl().scheduler->BeginImplFrame(args);
+void ThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
+ impl().layer_tree_host_impl->WillBeginImplFrame(args);
}
void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
impl().scheduler->SetNeedsRedraw();
}
+void ThreadProxy::SetNeedsAnimateOnImplThread() {
+ TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimateOnImplThread");
+ DCHECK(IsImplThread());
+ impl().scheduler->SetNeedsAnimate();
+}
+
void ThreadProxy::SetNeedsManageTilesOnImplThread() {
DCHECK(IsImplThread());
impl().scheduler->SetNeedsManageTiles();
completion->Signal();
}
+void ThreadProxy::SetDebugState(const LayerTreeDebugState& debug_state) {
+ Proxy::ImplThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&ThreadProxy::SetDebugStateOnImplThread,
+ impl_thread_weak_ptr_,
+ debug_state));
+}
+
+void ThreadProxy::SetDebugStateOnImplThread(
+ const LayerTreeDebugState& debug_state) {
+ DCHECK(IsImplThread());
+ impl().scheduler->SetContinuousPainting(debug_state.continuous_painting);
+}
+
void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread");
DCHECK(IsImplThread());
bool updated = layer_tree_host()->UpdateLayers(queue.get());
- // Once single buffered layers are committed, they cannot be modified until
- // they are drawn by the impl thread.
- main().textures_acquired = false;
-
layer_tree_host()->WillCommit();
// Before calling animate, we set main().animate_requested to false. If it is
return;
}
- scoped_refptr<ContextProvider> offscreen_context_provider;
- if (main().renderer_capabilities_main_thread_copy.using_offscreen_context3d &&
- layer_tree_host()->needs_offscreen_context()) {
- offscreen_context_provider =
- layer_tree_host()->client()->OffscreenContextProvider();
- if (offscreen_context_provider.get())
- main().created_offscreen_context_provider = true;
- }
-
// Notify the impl thread that the main thread is ready to commit. This will
// begin the commit process, which is blocking from the main thread's
// point of view, but asynchronously performed on the impl thread,
base::Bind(&ThreadProxy::StartCommitOnImplThread,
impl_thread_weak_ptr_,
&completion,
- queue.release(),
- offscreen_context_provider));
+ queue.release()));
completion.Wait();
RenderingStatsInstrumentation* stats_instrumentation =
layer_tree_host()->DidBeginMainFrame();
}
-void ThreadProxy::StartCommitOnImplThread(
- CompletionEvent* completion,
- ResourceUpdateQueue* raw_queue,
- scoped_refptr<ContextProvider> offscreen_context_provider) {
+void ThreadProxy::StartCommitOnImplThread(CompletionEvent* completion,
+ ResourceUpdateQueue* raw_queue) {
TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
DCHECK(!impl().commit_completion_event);
DCHECK(IsImplThread() && IsMainThreadBlocked());
scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
- if (offscreen_context_provider.get())
- offscreen_context_provider->BindToCurrentThread();
- impl().layer_tree_host_impl->SetOffscreenContextProvider(
- offscreen_context_provider);
-
if (impl().contents_texture_manager) {
DCHECK_EQ(impl().contents_texture_manager,
blocked_main().contents_texture_manager());
impl().scheduler->BeginMainFrameAborted(did_handle);
}
+void ThreadProxy::ScheduledActionAnimate() {
+ TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionAnimate");
+ DCHECK(IsImplThread());
+
+ if (!impl().animations_frozen_until_next_draw) {
+ impl().animation_time =
+ impl().layer_tree_host_impl->CurrentFrameTimeTicks();
+ }
+ impl().layer_tree_host_impl->Animate(impl().animation_time);
+ impl().did_commit_after_animating = false;
+}
+
void ThreadProxy::ScheduledActionCommit() {
TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
DCHECK(IsImplThread());
impl().current_resource_update_controller.reset();
if (impl().animations_frozen_until_next_draw) {
- impl().animation_freeze_time =
- std::max(impl().animation_freeze_time,
- blocked_main().last_monotonic_frame_begin_time);
+ impl().animation_time = std::max(
+ impl().animation_time, blocked_main().last_monotonic_frame_begin_time);
}
+ impl().did_commit_after_animating = true;
blocked_main().main_thread_inside_commit = true;
impl().layer_tree_host_impl->BeginCommit();
impl().next_frame_is_newly_committed_frame = true;
impl().timing_history.DidCommit();
-
- // SetVisible kicks off the next scheduler action, so this must be last.
- impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
}
void ThreadProxy::ScheduledActionUpdateVisibleTiles() {
base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
base::AutoReset<bool> mark_inside(&impl().inside_draw, true);
- // Advance our animations.
- base::TimeTicks monotonic_time;
- if (impl().animations_frozen_until_next_draw)
- monotonic_time = impl().animation_freeze_time;
- else
- monotonic_time = impl().layer_tree_host_impl->CurrentFrameTimeTicks();
+ if (impl().did_commit_after_animating) {
+ impl().layer_tree_host_impl->Animate(impl().animation_time);
+ impl().did_commit_after_animating = false;
+ }
- // TODO(enne): This should probably happen post-animate.
if (impl().layer_tree_host_impl->pending_tree())
impl().layer_tree_host_impl->pending_tree()->UpdateDrawProperties();
- impl().layer_tree_host_impl->Animate(monotonic_time);
// This method is called on a forced draw, regardless of whether we are able
// to produce a frame, as the calling site on main thread is blocked until its
// checkerboarding will be displayed when we force a draw. To avoid this,
// we freeze animations until we successfully draw.
impl().animations_frozen_until_next_draw = true;
- impl().animation_freeze_time = monotonic_time;
} else {
DCHECK_NE(DrawSwapReadbackResult::DRAW_SUCCESS, result.draw_result);
}
impl().readback_request = NULL;
} else if (draw_frame) {
DCHECK(swap_requested);
- result.did_swap = impl().layer_tree_host_impl->SwapBuffers(frame);
+ result.did_request_swap = impl().layer_tree_host_impl->SwapBuffers(frame);
// We don't know if we have incomplete tiles if we didn't actually swap.
- if (result.did_swap) {
+ if (result.did_request_swap) {
DCHECK(!frame.has_no_damage);
SetSwapUsedIncompleteTileOnImplThread(frame.contains_incomplete_tile);
}
return result;
}
-void ThreadProxy::AcquireLayerTextures() {
- // Called when the main thread needs to modify a layer texture that is used
- // directly by the compositor.
- // This method will block until the next compositor draw if there is a
- // previously committed frame that is still undrawn. This is necessary to
- // ensure that the main thread does not monopolize access to the textures.
- DCHECK(IsMainThread());
-
- if (main().textures_acquired)
- return;
-
- TRACE_EVENT0("cc", "ThreadProxy::AcquireLayerTextures");
- DebugScopedSetMainThreadBlocked main_thread_blocked(this);
- CompletionEvent completion;
- Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread,
- impl_thread_weak_ptr_,
- &completion));
- // Block until it is safe to write to layer textures from the main thread.
- completion.Wait();
-
- main().textures_acquired = true;
- main().can_cancel_commit = false;
-}
-
-void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread(
- CompletionEvent* completion) {
- DCHECK(IsImplThread());
- DCHECK(!impl().texture_acquisition_completion_event);
-
- impl().texture_acquisition_completion_event = completion;
- impl().scheduler->SetMainThreadNeedsLayerTextures();
-}
-
-void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
- DCHECK(impl().texture_acquisition_completion_event);
- impl().texture_acquisition_completion_event->Signal();
- impl().texture_acquisition_completion_event = NULL;
-}
-
void ThreadProxy::ScheduledActionManageTiles() {
TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionManageTiles");
DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting);
layer_tree_host()->CreateLayerTreeHostImpl(this);
const LayerTreeSettings& settings = layer_tree_host()->settings();
SchedulerSettings scheduler_settings;
+ scheduler_settings.begin_frame_scheduling_enabled =
+ settings.begin_frame_scheduling_enabled;
scheduler_settings.main_frame_before_draw_enabled =
settings.main_frame_before_draw_enabled;
scheduler_settings.main_frame_before_activation_enabled =
void ThreadProxy::InitializeOutputSurfaceOnImplThread(
CompletionEvent* completion,
scoped_ptr<OutputSurface> output_surface,
- scoped_refptr<ContextProvider> offscreen_context_provider,
bool* success,
RendererCapabilities* capabilities) {
TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
.layer_tree_host_impl->GetRendererCapabilities()
.MainThreadCapabilities();
impl().scheduler->DidCreateAndInitializeOutputSurface();
- } else if (offscreen_context_provider.get()) {
- if (offscreen_context_provider->BindToCurrentThread())
- offscreen_context_provider->VerifyContexts();
- offscreen_context_provider = NULL;
}
- impl().layer_tree_host_impl->SetOffscreenContextProvider(
- offscreen_context_provider);
-
completion->Signal();
}
layer_tree_host()->DeleteContentsTexturesOnImplThread(
impl().layer_tree_host_impl->resource_provider());
impl().current_resource_update_controller.reset();
- impl().layer_tree_host_impl->SetNeedsBeginImplFrame(false);
+ impl().layer_tree_host_impl->SetNeedsBeginFrame(false);
impl().scheduler.reset();
impl().layer_tree_host_impl.reset();
impl().weak_factory.InvalidateWeakPtrs();
DCHECK(IsImplThread());
bool smoothness_takes_priority =
impl().layer_tree_host_impl->pinch_gesture_active() ||
- impl().layer_tree_host_impl->IsCurrentlyScrolling() ||
- impl().layer_tree_host_impl->page_scale_animation_active();
+ impl().layer_tree_host_impl->page_scale_animation_active() ||
+ (impl().layer_tree_host_impl->IsCurrentlyScrolling() &&
+ !impl().layer_tree_host_impl->scroll_affects_scroll_handler());
base::TimeTicks now = impl().layer_tree_host_impl->CurrentFrameTimeTicks();
RenewTreePriority();
}
-void ThreadProxy::RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) {
- Proxy::ImplThreadTaskRunner()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread,
- impl_thread_weak_ptr_),
- delay);
-}
-
-void ThreadProxy::StartScrollbarAnimationOnImplThread() {
- impl().layer_tree_host_impl->StartScrollbarAnimation();
+void ThreadProxy::PostDelayedScrollbarFadeOnImplThread(
+ const base::Closure& start_fade,
+ base::TimeDelta delay) {
+ Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, start_fade, delay);
}
void ThreadProxy::DidActivatePendingTree() {