Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / cc / trees / single_thread_proxy.cc
blobc70e95d9ebc68cfae93df0c40ea9c263e063779c
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/single_thread_proxy.h"
7 #include "base/auto_reset.h"
8 #include "base/debug/trace_event.h"
9 #include "cc/debug/benchmark_instrumentation.h"
10 #include "cc/output/context_provider.h"
11 #include "cc/output/output_surface.h"
12 #include "cc/quads/draw_quad.h"
13 #include "cc/resources/prioritized_resource_manager.h"
14 #include "cc/resources/resource_update_controller.h"
15 #include "cc/trees/blocking_task_runner.h"
16 #include "cc/trees/layer_tree_host.h"
17 #include "cc/trees/layer_tree_host_single_thread_client.h"
18 #include "cc/trees/layer_tree_impl.h"
19 #include "ui/gfx/frame_time.h"
21 namespace cc {
23 scoped_ptr<Proxy> SingleThreadProxy::Create(
24 LayerTreeHost* layer_tree_host,
25 LayerTreeHostSingleThreadClient* client) {
26 return make_scoped_ptr(
27 new SingleThreadProxy(layer_tree_host, client)).PassAs<Proxy>();
30 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
31 LayerTreeHostSingleThreadClient* client)
32 : Proxy(NULL),
33 layer_tree_host_(layer_tree_host),
34 client_(client),
35 next_frame_is_newly_committed_frame_(false),
36 inside_draw_(false) {
37 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
38 DCHECK(Proxy::IsMainThread());
39 DCHECK(layer_tree_host);
41 // Impl-side painting not supported without threaded compositing.
42 CHECK(!layer_tree_host->settings().impl_side_painting)
43 << "Threaded compositing must be enabled to use impl-side painting.";
46 void SingleThreadProxy::Start() {
47 DebugScopedSetImplThread impl(this);
48 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
51 SingleThreadProxy::~SingleThreadProxy() {
52 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
53 DCHECK(Proxy::IsMainThread());
54 // Make sure Stop() got called or never Started.
55 DCHECK(!layer_tree_host_impl_);
58 void SingleThreadProxy::FinishAllRendering() {
59 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering");
60 DCHECK(Proxy::IsMainThread());
62 DebugScopedSetImplThread impl(this);
63 layer_tree_host_impl_->FinishAllRendering();
67 bool SingleThreadProxy::IsStarted() const {
68 DCHECK(Proxy::IsMainThread());
69 return layer_tree_host_impl_;
72 void SingleThreadProxy::SetLayerTreeHostClientReady() {
73 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
74 // Scheduling is controlled by the embedder in the single thread case, so
75 // nothing to do.
78 void SingleThreadProxy::SetVisible(bool visible) {
79 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
80 DebugScopedSetImplThread impl(this);
81 layer_tree_host_impl_->SetVisible(visible);
83 // Changing visibility could change ShouldComposite().
84 UpdateBackgroundAnimateTicking();
87 void SingleThreadProxy::CreateAndInitializeOutputSurface() {
88 TRACE_EVENT0(
89 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
90 DCHECK(Proxy::IsMainThread());
91 DCHECK(layer_tree_host_->output_surface_lost());
93 scoped_ptr<OutputSurface> output_surface =
94 layer_tree_host_->CreateOutputSurface();
96 renderer_capabilities_for_main_thread_ = RendererCapabilities();
98 bool success = !!output_surface;
99 if (success) {
100 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
101 DebugScopedSetImplThread impl(this);
102 layer_tree_host_->DeleteContentsTexturesOnImplThread(
103 layer_tree_host_impl_->resource_provider());
104 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
107 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
109 if (!success) {
110 // Force another recreation attempt to happen by requesting another commit.
111 SetNeedsCommit();
115 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
116 DCHECK(Proxy::IsMainThread());
117 DCHECK(!layer_tree_host_->output_surface_lost());
118 return renderer_capabilities_for_main_thread_;
121 void SingleThreadProxy::SetNeedsAnimate() {
122 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
123 DCHECK(Proxy::IsMainThread());
124 client_->ScheduleAnimation();
127 void SingleThreadProxy::SetNeedsUpdateLayers() {
128 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
129 DCHECK(Proxy::IsMainThread());
130 client_->ScheduleComposite();
133 void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
134 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
135 DCHECK(Proxy::IsMainThread());
136 // Commit immediately.
138 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
139 DebugScopedSetImplThread impl(this);
141 // This CapturePostTasks should be destroyed before CommitComplete() is
142 // called since that goes out to the embedder, and we want the embedder
143 // to receive its callbacks before that.
144 BlockingTaskRunner::CapturePostTasks blocked;
146 layer_tree_host_impl_->BeginCommit();
148 if (PrioritizedResourceManager* contents_texture_manager =
149 layer_tree_host_->contents_texture_manager()) {
150 contents_texture_manager->PushTexturePrioritiesToBackings();
152 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
154 scoped_ptr<ResourceUpdateController> update_controller =
155 ResourceUpdateController::Create(
156 NULL,
157 Proxy::MainThreadTaskRunner(),
158 queue.Pass(),
159 layer_tree_host_impl_->resource_provider());
160 update_controller->Finalize();
162 if (layer_tree_host_impl_->EvictedUIResourcesExist())
163 layer_tree_host_->RecreateUIResources();
165 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
167 layer_tree_host_impl_->CommitComplete();
169 #if DCHECK_IS_ON
170 // In the single-threaded case, the scale and scroll deltas should never be
171 // touched on the impl layer tree.
172 scoped_ptr<ScrollAndScaleSet> scroll_info =
173 layer_tree_host_impl_->ProcessScrollDeltas();
174 DCHECK(!scroll_info->scrolls.size());
175 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
176 #endif
178 RenderingStatsInstrumentation* stats_instrumentation =
179 layer_tree_host_->rendering_stats_instrumentation();
180 benchmark_instrumentation::IssueMainThreadRenderingStatsEvent(
181 stats_instrumentation->main_thread_rendering_stats());
182 stats_instrumentation->AccumulateAndClearMainThreadStats();
184 layer_tree_host_->CommitComplete();
185 next_frame_is_newly_committed_frame_ = true;
188 void SingleThreadProxy::SetNeedsCommit() {
189 DCHECK(Proxy::IsMainThread());
190 client_->ScheduleComposite();
193 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
194 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
195 SetNeedsRedrawRectOnImplThread(damage_rect);
196 client_->ScheduleComposite();
199 void SingleThreadProxy::SetNextCommitWaitsForActivation() {
200 // There is no activation here other than commit. So do nothing.
203 void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
206 bool SingleThreadProxy::CommitRequested() const { return false; }
208 bool SingleThreadProxy::BeginMainFrameRequested() const { return false; }
210 size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
211 return std::numeric_limits<size_t>::max();
214 void SingleThreadProxy::Stop() {
215 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
216 DCHECK(Proxy::IsMainThread());
218 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
219 DebugScopedSetImplThread impl(this);
221 BlockingTaskRunner::CapturePostTasks blocked;
222 layer_tree_host_->DeleteContentsTexturesOnImplThread(
223 layer_tree_host_impl_->resource_provider());
224 layer_tree_host_impl_.reset();
226 layer_tree_host_ = NULL;
229 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
230 TRACE_EVENT1(
231 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
232 DCHECK(Proxy::IsImplThread());
233 UpdateBackgroundAnimateTicking();
236 void SingleThreadProxy::NotifyReadyToActivate() {
237 // Thread-only feature.
238 NOTREACHED();
241 void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
242 client_->ScheduleComposite();
245 void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
246 SetNeedsRedrawOnImplThread();
249 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
250 // Thread-only/Impl-side-painting-only feature.
251 NOTREACHED();
254 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
255 const gfx::Rect& damage_rect) {
256 // TODO(brianderson): Once we move render_widget scheduling into this class,
257 // we can treat redraw requests more efficiently than CommitAndRedraw
258 // requests.
259 layer_tree_host_impl_->SetViewportDamage(damage_rect);
260 SetNeedsCommit();
263 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
264 // Impl-side painting only.
265 NOTREACHED();
268 void SingleThreadProxy::SetNeedsCommitOnImplThread() {
269 client_->ScheduleComposite();
272 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
273 scoped_ptr<AnimationEventsVector> events) {
274 TRACE_EVENT0(
275 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
276 DCHECK(Proxy::IsImplThread());
277 DebugScopedSetMainThread main(this);
278 layer_tree_host_->SetAnimationEvents(events.Pass());
281 bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
282 size_t limit_bytes,
283 int priority_cutoff) {
284 DCHECK(IsImplThread());
285 PrioritizedResourceManager* contents_texture_manager =
286 layer_tree_host_->contents_texture_manager();
288 ResourceProvider* resource_provider =
289 layer_tree_host_impl_->resource_provider();
291 if (!contents_texture_manager || !resource_provider)
292 return false;
294 return contents_texture_manager->ReduceMemoryOnImplThread(
295 limit_bytes, priority_cutoff, resource_provider);
298 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
300 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
301 DCHECK(IsImplThread());
302 renderer_capabilities_for_main_thread_ =
303 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
306 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
307 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
308 // Cause a commit so we can notice the lost context.
309 SetNeedsCommitOnImplThread();
310 client_->DidAbortSwapBuffers();
313 void SingleThreadProxy::DidSwapBuffersOnImplThread() {
314 client_->DidPostSwapBuffers();
317 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
318 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
319 client_->DidCompleteSwapBuffers();
322 // Called by the legacy scheduling path (e.g. where render_widget does the
323 // scheduling)
324 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
325 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
326 DCHECK(Proxy::IsMainThread());
327 DCHECK(!layer_tree_host_->output_surface_lost());
329 layer_tree_host_->AnimateLayers(frame_begin_time);
331 if (PrioritizedResourceManager* contents_texture_manager =
332 layer_tree_host_->contents_texture_manager()) {
333 contents_texture_manager->UnlinkAndClearEvictedBackings();
334 contents_texture_manager->SetMaxMemoryLimitBytes(
335 layer_tree_host_impl_->memory_allocation_limit_bytes());
336 contents_texture_manager->SetExternalPriorityCutoff(
337 layer_tree_host_impl_->memory_allocation_priority_cutoff());
340 scoped_ptr<ResourceUpdateQueue> queue =
341 make_scoped_ptr(new ResourceUpdateQueue);
342 layer_tree_host_->UpdateLayers(queue.get());
343 layer_tree_host_->WillCommit();
344 DoCommit(queue.Pass());
345 layer_tree_host_->DidBeginMainFrame();
347 LayerTreeHostImpl::FrameData frame;
348 if (DoComposite(&frame)) {
350 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
351 DebugScopedSetImplThread impl(this);
353 // This CapturePostTasks should be destroyed before
354 // DidCommitAndDrawFrame() is called since that goes out to the embedder,
355 // and we want the embedder to receive its callbacks before that.
356 // NOTE: This maintains consistent ordering with the ThreadProxy since
357 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
358 // there as the main thread is not blocked, so any posted tasks inside
359 // the swap buffers will execute first.
360 BlockingTaskRunner::CapturePostTasks blocked;
362 layer_tree_host_impl_->SwapBuffers(frame);
364 DidSwapFrame();
368 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
369 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
371 // The following line casts away const modifiers because it is just
372 // setting debug state. We still want the AsValue() function and its
373 // call chain to be const throughout.
374 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
376 state->Set("layer_tree_host_impl",
377 layer_tree_host_impl_->AsValue().release());
379 return state.PassAs<base::Value>();
382 void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
384 DebugScopedSetImplThread impl(this);
385 if (layer_tree_host_impl_->renderer()) {
386 DCHECK(!layer_tree_host_->output_surface_lost());
387 layer_tree_host_impl_->renderer()->DoNoOp();
392 bool SingleThreadProxy::SupportsImplScrolling() const {
393 return false;
396 bool SingleThreadProxy::ShouldComposite() const {
397 DCHECK(Proxy::IsImplThread());
398 return layer_tree_host_impl_->visible() &&
399 layer_tree_host_impl_->CanDraw();
402 void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
403 DCHECK(Proxy::IsImplThread());
404 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
405 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
408 bool SingleThreadProxy::DoComposite(
409 LayerTreeHostImpl::FrameData* frame) {
410 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
411 DCHECK(!layer_tree_host_->output_surface_lost());
413 bool lost_output_surface = false;
415 DebugScopedSetImplThread impl(this);
416 base::AutoReset<bool> mark_inside(&inside_draw_, true);
418 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
419 // frame, so can only be used when such a frame is possible. Since
420 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
421 // CanDraw() as well.
422 if (!ShouldComposite()) {
423 UpdateBackgroundAnimateTicking();
424 return false;
427 layer_tree_host_impl_->Animate(
428 layer_tree_host_impl_->CurrentFrameTimeTicks());
429 UpdateBackgroundAnimateTicking();
431 if (!layer_tree_host_impl_->IsContextLost()) {
432 layer_tree_host_impl_->PrepareToDraw(frame);
433 layer_tree_host_impl_->DrawLayers(frame);
434 layer_tree_host_impl_->DidDrawAllLayers(*frame);
436 lost_output_surface = layer_tree_host_impl_->IsContextLost();
438 bool start_ready_animations = true;
439 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
441 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
444 if (lost_output_surface) {
445 layer_tree_host_->DidLoseOutputSurface();
446 return false;
449 return true;
452 void SingleThreadProxy::DidSwapFrame() {
453 if (next_frame_is_newly_committed_frame_) {
454 next_frame_is_newly_committed_frame_ = false;
455 layer_tree_host_->DidCommitAndDrawFrame();
459 bool SingleThreadProxy::CommitPendingForTesting() { return false; }
461 } // namespace cc