OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/compositor_impl_android.h" | 5 #include "content/browser/renderer_host/compositor_impl_android.h" |
6 | 6 |
7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
9 | 9 |
10 #include "base/android/jni_android.h" | 10 #include "base/android/jni_android.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 #include "third_party/khronos/GLES2/gl2ext.h" | 62 #include "third_party/khronos/GLES2/gl2ext.h" |
63 #include "third_party/skia/include/core/SkMallocPixelRef.h" | 63 #include "third_party/skia/include/core/SkMallocPixelRef.h" |
64 #include "ui/android/window_android.h" | 64 #include "ui/android/window_android.h" |
65 #include "ui/gfx/android/device_display_info.h" | 65 #include "ui/gfx/android/device_display_info.h" |
66 #include "ui/gfx/swap_result.h" | 66 #include "ui/gfx/swap_result.h" |
67 | 67 |
68 namespace content { | 68 namespace content { |
69 | 69 |
70 namespace { | 70 namespace { |
71 | 71 |
| 72 const unsigned int kMaxUiSwapBuffers = 1U; |
72 const unsigned int kMaxDisplaySwapBuffers = 1U; | 73 const unsigned int kMaxDisplaySwapBuffers = 1U; |
73 | 74 |
74 // Used to override capabilities_.adjust_deadline_for_parent to false | 75 // Used to override capabilities_.adjust_deadline_for_parent to false |
75 class OutputSurfaceWithoutParent : public cc::OutputSurface, | 76 class OutputSurfaceWithoutParent : public cc::OutputSurface, |
76 public CompositorImpl::VSyncObserver { | 77 public CompositorImpl::VSyncObserver { |
77 public: | 78 public: |
78 OutputSurfaceWithoutParent( | 79 OutputSurfaceWithoutParent( |
79 CompositorImpl* compositor, | 80 CompositorImpl* compositor, |
80 const scoped_refptr<ContextProviderCommandBuffer>& context_provider, | 81 const scoped_refptr<ContextProviderCommandBuffer>& context_provider, |
81 const base::Callback<void(gpu::Capabilities)>& | 82 const base::Callback<void(gpu::Capabilities)>& |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 DCHECK(command_buffer_proxy); | 135 DCHECK(command_buffer_proxy); |
135 return command_buffer_proxy; | 136 return command_buffer_proxy; |
136 } | 137 } |
137 | 138 |
138 void OnSwapBuffersCompleted(const std::vector<ui::LatencyInfo>& latency_info, | 139 void OnSwapBuffersCompleted(const std::vector<ui::LatencyInfo>& latency_info, |
139 gfx::SwapResult result) { | 140 gfx::SwapResult result) { |
140 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info); | 141 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info); |
141 OutputSurface::OnSwapBuffersComplete(); | 142 OutputSurface::OnSwapBuffersComplete(); |
142 } | 143 } |
143 | 144 |
144 void OnVSync(base::TimeTicks timebase, base::TimeDelta interval) override { | 145 void OnUpdateVSyncParameters(base::TimeTicks timebase, |
| 146 base::TimeDelta interval) override { |
145 CommitVSyncParameters(timebase, interval); | 147 CommitVSyncParameters(timebase, interval); |
146 } | 148 } |
147 | 149 |
148 CompositorImpl* compositor_; | 150 CompositorImpl* compositor_; |
149 base::Callback<void(gpu::Capabilities)> populate_gpu_capabilities_callback_; | 151 base::Callback<void(gpu::Capabilities)> populate_gpu_capabilities_callback_; |
150 base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&, | 152 base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&, |
151 gfx::SwapResult)> | 153 gfx::SwapResult)> |
152 swap_buffers_completion_callback_; | 154 swap_buffers_completion_callback_; |
153 scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator_; | 155 scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator_; |
154 }; | 156 }; |
155 | 157 |
156 class ExternalBeginFrameSource : public cc::BeginFrameSourceBase, | |
157 public CompositorImpl::VSyncObserver { | |
158 public: | |
159 ExternalBeginFrameSource(CompositorImpl* compositor) | |
160 : compositor_(compositor) { | |
161 compositor_->AddObserver(this); | |
162 } | |
163 | |
164 ~ExternalBeginFrameSource() override { | |
165 compositor_->RemoveObserver(this); | |
166 } | |
167 | |
168 // cc::BeginFrameSourceBase implementation: | |
169 void OnNeedsBeginFramesChange( | |
170 bool needs_begin_frames) override { | |
171 compositor_->OnNeedsBeginFramesChange(needs_begin_frames); | |
172 } | |
173 | |
174 // CompositorImpl::VSyncObserver implementation: | |
175 void OnVSync(base::TimeTicks frame_time, | |
176 base::TimeDelta vsync_period) override { | |
177 CallOnBeginFrame(cc::BeginFrameArgs::Create( | |
178 BEGINFRAME_FROM_HERE, frame_time, base::TimeTicks::Now(), vsync_period, | |
179 cc::BeginFrameArgs::NORMAL)); | |
180 } | |
181 | |
182 private: | |
183 CompositorImpl* compositor_; | |
184 }; | |
185 | |
186 static bool g_initialized = false; | 158 static bool g_initialized = false; |
187 | 159 |
188 bool g_use_surface_manager = false; | 160 bool g_use_surface_manager = false; |
189 base::LazyInstance<cc::SurfaceManager> g_surface_manager = | 161 base::LazyInstance<cc::SurfaceManager> g_surface_manager = |
190 LAZY_INSTANCE_INITIALIZER; | 162 LAZY_INSTANCE_INITIALIZER; |
191 | 163 |
192 int g_surface_id_namespace = 0; | 164 int g_surface_id_namespace = 0; |
193 | 165 |
194 class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner { | 166 class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner { |
195 public: | 167 public: |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 : root_layer_(cc::Layer::Create(Compositor::LayerSettings())), | 230 : root_layer_(cc::Layer::Create(Compositor::LayerSettings())), |
259 resource_manager_(root_window), | 231 resource_manager_(root_window), |
260 surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator() | 232 surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator() |
261 : nullptr), | 233 : nullptr), |
262 has_transparent_background_(false), | 234 has_transparent_background_(false), |
263 device_scale_factor_(1), | 235 device_scale_factor_(1), |
264 window_(NULL), | 236 window_(NULL), |
265 surface_id_(0), | 237 surface_id_(0), |
266 client_(client), | 238 client_(client), |
267 root_window_(root_window), | 239 root_window_(root_window), |
| 240 did_post_swapbuffers_(false), |
| 241 ignore_schedule_composite_(false), |
| 242 needs_composite_(false), |
268 needs_animate_(false), | 243 needs_animate_(false), |
| 244 will_composite_immediately_(false), |
| 245 composite_on_vsync_trigger_(DO_NOT_COMPOSITE), |
269 pending_swapbuffers_(0U), | 246 pending_swapbuffers_(0U), |
270 num_successive_context_creation_failures_(0), | 247 num_successive_context_creation_failures_(0), |
271 output_surface_request_pending_(false), | 248 output_surface_request_pending_(false), |
272 needs_begin_frames_(false), | |
273 weak_factory_(this) { | 249 weak_factory_(this) { |
274 DCHECK(client); | 250 DCHECK(client); |
275 DCHECK(root_window); | 251 DCHECK(root_window); |
276 root_window->AttachCompositor(this); | 252 root_window->AttachCompositor(this); |
277 CreateLayerTreeHost(); | 253 CreateLayerTreeHost(); |
278 resource_manager_.Init(host_.get()); | 254 resource_manager_.Init(host_.get()); |
279 } | 255 } |
280 | 256 |
281 CompositorImpl::~CompositorImpl() { | 257 CompositorImpl::~CompositorImpl() { |
282 root_window_->DetachCompositor(); | 258 root_window_->DetachCompositor(); |
283 // Clean-up any surface references. | 259 // Clean-up any surface references. |
284 SetSurface(NULL); | 260 SetSurface(NULL); |
285 } | 261 } |
286 | 262 |
| 263 void CompositorImpl::PostComposite(CompositingTrigger trigger) { |
| 264 DCHECK(host_->visible()); |
| 265 DCHECK(needs_composite_); |
| 266 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); |
| 267 |
| 268 if (will_composite_immediately_ || |
| 269 (trigger == COMPOSITE_EVENTUALLY && WillComposite())) { |
| 270 // We will already composite soon enough. |
| 271 DCHECK(WillComposite()); |
| 272 return; |
| 273 } |
| 274 |
| 275 if (DidCompositeThisFrame()) { |
| 276 DCHECK(!WillCompositeThisFrame()); |
| 277 if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) { |
| 278 composite_on_vsync_trigger_ = trigger; |
| 279 root_window_->RequestVSyncUpdate(); |
| 280 } |
| 281 DCHECK(WillComposite()); |
| 282 return; |
| 283 } |
| 284 |
| 285 base::TimeDelta delay; |
| 286 if (trigger == COMPOSITE_IMMEDIATELY) { |
| 287 will_composite_immediately_ = true; |
| 288 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; |
| 289 } else { |
| 290 DCHECK(!WillComposite()); |
| 291 const base::TimeDelta estimated_composite_time = vsync_period_ / 4; |
| 292 const base::TimeTicks now = base::TimeTicks::Now(); |
| 293 |
| 294 if (!last_vsync_.is_null() && (now - last_vsync_) < vsync_period_) { |
| 295 base::TimeTicks next_composite = |
| 296 last_vsync_ + vsync_period_ - estimated_composite_time; |
| 297 if (next_composite < now) { |
| 298 // It's too late, we will reschedule composite as needed on the next |
| 299 // vsync. |
| 300 composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY; |
| 301 root_window_->RequestVSyncUpdate(); |
| 302 DCHECK(WillComposite()); |
| 303 return; |
| 304 } |
| 305 |
| 306 delay = next_composite - now; |
| 307 } |
| 308 } |
| 309 TRACE_EVENT2("cc,benchmark", "CompositorImpl::PostComposite", |
| 310 "trigger", trigger, |
| 311 "delay", delay.InMillisecondsF()); |
| 312 |
| 313 DCHECK(composite_on_vsync_trigger_ == DO_NOT_COMPOSITE); |
| 314 if (current_composite_task_) |
| 315 current_composite_task_->Cancel(); |
| 316 |
| 317 // Unretained because we cancel the task on shutdown. |
| 318 current_composite_task_.reset(new base::CancelableClosure( |
| 319 base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger))); |
| 320 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 321 FROM_HERE, current_composite_task_->callback(), delay); |
| 322 } |
| 323 |
| 324 void CompositorImpl::Composite(CompositingTrigger trigger) { |
| 325 if (trigger == COMPOSITE_IMMEDIATELY) |
| 326 will_composite_immediately_ = false; |
| 327 |
| 328 DCHECK(host_->visible()); |
| 329 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); |
| 330 DCHECK(needs_composite_); |
| 331 DCHECK(!DidCompositeThisFrame()); |
| 332 |
| 333 DCHECK_LE(pending_swapbuffers_, kMaxUiSwapBuffers); |
| 334 // Swap Ack accounting is unreliable if the OutputSurface was lost. |
| 335 // In that case still attempt to composite, which will cause creation of a |
| 336 // new OutputSurface and reset pending_swapbuffers_. |
| 337 if (pending_swapbuffers_ == kMaxUiSwapBuffers && |
| 338 !host_->output_surface_lost()) { |
| 339 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit"); |
| 340 return; |
| 341 } |
| 342 |
| 343 // Reset state before Layout+Composite since that might create more |
| 344 // requests to Composite that we need to respect. |
| 345 needs_composite_ = false; |
| 346 |
| 347 // Only allow compositing once per vsync. |
| 348 current_composite_task_->Cancel(); |
| 349 DCHECK(DidCompositeThisFrame() && !WillComposite()); |
| 350 |
| 351 const base::TimeTicks frame_time = base::TimeTicks::Now(); |
| 352 if (needs_animate_) { |
| 353 base::AutoReset<bool> auto_reset_ignore_schedule( |
| 354 &ignore_schedule_composite_, true); |
| 355 needs_animate_ = false; |
| 356 root_window_->Animate(frame_time); |
| 357 } |
| 358 |
| 359 did_post_swapbuffers_ = false; |
| 360 host_->Composite(frame_time); |
| 361 if (did_post_swapbuffers_) |
| 362 pending_swapbuffers_++; |
| 363 |
| 364 // Need to track vsync to avoid compositing more than once per frame. |
| 365 root_window_->RequestVSyncUpdate(); |
| 366 } |
| 367 |
287 ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() { | 368 ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() { |
288 return *this; | 369 return *this; |
289 } | 370 } |
290 | 371 |
291 ui::ResourceManager& CompositorImpl::GetResourceManager() { | 372 ui::ResourceManager& CompositorImpl::GetResourceManager() { |
292 return resource_manager_; | 373 return resource_manager_; |
293 } | 374 } |
294 | 375 |
295 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { | 376 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { |
296 if (subroot_layer_.get()) { | 377 if (subroot_layer_.get()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 gfx::GLSurfaceHandle(surface_id_, gfx::NATIVE_DIRECT)); | 418 gfx::GLSurfaceHandle(surface_id_, gfx::NATIVE_DIRECT)); |
338 // Register first, SetVisible() might create an OutputSurface. | 419 // Register first, SetVisible() might create an OutputSurface. |
339 RegisterViewSurface(surface_id_, j_surface.obj()); | 420 RegisterViewSurface(surface_id_, j_surface.obj()); |
340 SetVisible(true); | 421 SetVisible(true); |
341 ANativeWindow_release(window); | 422 ANativeWindow_release(window); |
342 } | 423 } |
343 } | 424 } |
344 | 425 |
345 void CompositorImpl::CreateLayerTreeHost() { | 426 void CompositorImpl::CreateLayerTreeHost() { |
346 DCHECK(!host_); | 427 DCHECK(!host_); |
| 428 DCHECK(!WillCompositeThisFrame()); |
| 429 |
| 430 // Just in case, since we immediately hide the LTH in this function, |
| 431 // and we do not want to end up with a pending Composite task when the |
| 432 // host is hidden. |
| 433 base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_, |
| 434 true); |
347 | 435 |
348 cc::LayerTreeSettings settings; | 436 cc::LayerTreeSettings settings; |
349 settings.renderer_settings.refresh_rate = 60.0; | 437 settings.renderer_settings.refresh_rate = 60.0; |
350 settings.renderer_settings.allow_antialiasing = false; | 438 settings.renderer_settings.allow_antialiasing = false; |
351 settings.renderer_settings.highp_threshold_min = 2048; | 439 settings.renderer_settings.highp_threshold_min = 2048; |
352 settings.use_zero_copy = true; | 440 settings.use_zero_copy = true; |
353 settings.use_external_begin_frame_source = true; | |
354 | 441 |
355 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 442 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
356 settings.initial_debug_state.SetRecordRenderingStats( | 443 settings.initial_debug_state.SetRecordRenderingStats( |
357 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); | 444 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); |
358 if (command_line->HasSwitch(cc::switches::kDisableCompositorPropertyTrees)) | 445 if (command_line->HasSwitch(cc::switches::kDisableCompositorPropertyTrees)) |
359 settings.use_property_trees = false; | 446 settings.use_property_trees = false; |
360 settings.single_thread_proxy_scheduler = true; | 447 // TODO(enne): Update this this compositor to use the scheduler. |
| 448 settings.single_thread_proxy_scheduler = false; |
361 | 449 |
362 settings.use_compositor_animation_timelines = !command_line->HasSwitch( | 450 settings.use_compositor_animation_timelines = !command_line->HasSwitch( |
363 switches::kDisableAndroidCompositorAnimationTimelines); | 451 switches::kDisableAndroidCompositorAnimationTimelines); |
364 | 452 |
365 cc::LayerTreeHost::InitParams params; | 453 cc::LayerTreeHost::InitParams params; |
366 params.client = this; | 454 params.client = this; |
367 params.shared_bitmap_manager = HostSharedBitmapManager::current(); | 455 params.shared_bitmap_manager = HostSharedBitmapManager::current(); |
368 params.gpu_memory_buffer_manager = BrowserGpuMemoryBufferManager::current(); | 456 params.gpu_memory_buffer_manager = BrowserGpuMemoryBufferManager::current(); |
369 params.task_graph_runner = g_task_graph_runner.Pointer(); | 457 params.task_graph_runner = g_task_graph_runner.Pointer(); |
370 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); | 458 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); |
371 params.settings = &settings; | 459 params.settings = &settings; |
372 params.external_begin_frame_source.reset(new ExternalBeginFrameSource(this)); | |
373 host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); | 460 host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); |
374 DCHECK(!host_->visible()); | 461 DCHECK(!host_->visible()); |
375 host_->SetRootLayer(root_layer_); | 462 host_->SetRootLayer(root_layer_); |
376 host_->SetViewportSize(size_); | 463 host_->SetViewportSize(size_); |
377 host_->set_has_transparent_background(has_transparent_background_); | 464 host_->set_has_transparent_background(has_transparent_background_); |
378 host_->SetDeviceScaleFactor(device_scale_factor_); | 465 host_->SetDeviceScaleFactor(device_scale_factor_); |
379 | 466 |
380 if (needs_animate_) | 467 if (needs_animate_) |
381 host_->SetNeedsAnimate(); | 468 host_->SetNeedsAnimate(); |
382 } | 469 } |
383 | 470 |
384 void CompositorImpl::SetVisible(bool visible) { | 471 void CompositorImpl::SetVisible(bool visible) { |
385 TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible); | 472 TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible); |
386 if (!visible) { | 473 if (!visible) { |
387 DCHECK(host_->visible()); | 474 DCHECK(host_->visible()); |
| 475 // Look for any layers that were attached to the root for readback |
| 476 // and are waiting for Composite() to happen. |
| 477 bool readback_pending = false; |
| 478 for (size_t i = 0; i < root_layer_->children().size(); ++i) { |
| 479 if (root_layer_->children()[i]->HasCopyRequest()) { |
| 480 readback_pending = true; |
| 481 break; |
| 482 } |
| 483 } |
| 484 if (readback_pending) { |
| 485 base::AutoReset<bool> auto_reset_ignore_schedule( |
| 486 &ignore_schedule_composite_, true); |
| 487 host_->Composite(base::TimeTicks::Now()); |
| 488 } |
| 489 if (WillComposite()) |
| 490 CancelComposite(); |
388 host_->SetVisible(false); | 491 host_->SetVisible(false); |
389 if (!host_->output_surface_lost()) | 492 if (!host_->output_surface_lost()) |
390 host_->ReleaseOutputSurface(); | 493 host_->ReleaseOutputSurface(); |
391 pending_swapbuffers_ = 0; | 494 pending_swapbuffers_ = 0; |
| 495 needs_composite_ = false; |
| 496 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; |
392 establish_gpu_channel_timeout_.Stop(); | 497 establish_gpu_channel_timeout_.Stop(); |
393 display_client_.reset(); | 498 display_client_.reset(); |
| 499 if (current_composite_task_) { |
| 500 current_composite_task_->Cancel(); |
| 501 current_composite_task_.reset(); |
| 502 } |
394 } else { | 503 } else { |
395 host_->SetVisible(true); | 504 host_->SetVisible(true); |
396 if (output_surface_request_pending_) | 505 if (output_surface_request_pending_) |
397 RequestNewOutputSurface(); | 506 RequestNewOutputSurface(); |
| 507 SetNeedsComposite(); |
398 } | 508 } |
399 } | 509 } |
400 | 510 |
401 void CompositorImpl::setDeviceScaleFactor(float factor) { | 511 void CompositorImpl::setDeviceScaleFactor(float factor) { |
402 device_scale_factor_ = factor; | 512 device_scale_factor_ = factor; |
403 if (host_) | 513 if (host_) |
404 host_->SetDeviceScaleFactor(factor); | 514 host_->SetDeviceScaleFactor(factor); |
405 } | 515 } |
406 | 516 |
407 void CompositorImpl::SetWindowBounds(const gfx::Size& size) { | 517 void CompositorImpl::SetWindowBounds(const gfx::Size& size) { |
(...skipping 10 matching lines...) Expand all Loading... |
418 | 528 |
419 void CompositorImpl::SetHasTransparentBackground(bool flag) { | 529 void CompositorImpl::SetHasTransparentBackground(bool flag) { |
420 has_transparent_background_ = flag; | 530 has_transparent_background_ = flag; |
421 if (host_) | 531 if (host_) |
422 host_->set_has_transparent_background(flag); | 532 host_->set_has_transparent_background(flag); |
423 } | 533 } |
424 | 534 |
425 void CompositorImpl::SetNeedsComposite() { | 535 void CompositorImpl::SetNeedsComposite() { |
426 if (!host_->visible()) | 536 if (!host_->visible()) |
427 return; | 537 return; |
428 host_->SetNeedsAnimate(); | 538 DCHECK(!needs_composite_ || WillComposite()); |
| 539 |
| 540 needs_composite_ = true; |
| 541 PostComposite(COMPOSITE_IMMEDIATELY); |
429 } | 542 } |
430 | 543 |
431 static scoped_ptr<WebGraphicsContext3DCommandBufferImpl> | 544 static scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
432 CreateGpuProcessViewContext( | 545 CreateGpuProcessViewContext( |
433 const scoped_refptr<GpuChannelHost>& gpu_channel_host, | 546 const scoped_refptr<GpuChannelHost>& gpu_channel_host, |
434 const blink::WebGraphicsContext3D::Attributes attributes, | 547 const blink::WebGraphicsContext3D::Attributes attributes, |
435 int surface_id) { | 548 int surface_id) { |
436 GURL url("chrome://gpu/Compositor::createContext3D"); | 549 GURL url("chrome://gpu/Compositor::createContext3D"); |
437 static const size_t kBytesPerPixel = 4; | 550 static const size_t kBytesPerPixel = 4; |
438 gfx::DeviceDisplayInfo display_info; | 551 gfx::DeviceDisplayInfo display_info; |
(...skipping 13 matching lines...) Expand all Loading... |
452 new WebGraphicsContext3DCommandBufferImpl(surface_id, | 565 new WebGraphicsContext3DCommandBufferImpl(surface_id, |
453 url, | 566 url, |
454 gpu_channel_host.get(), | 567 gpu_channel_host.get(), |
455 attributes, | 568 attributes, |
456 lose_context_when_out_of_memory, | 569 lose_context_when_out_of_memory, |
457 limits, | 570 limits, |
458 NULL)); | 571 NULL)); |
459 } | 572 } |
460 | 573 |
461 void CompositorImpl::UpdateLayerTreeHost() { | 574 void CompositorImpl::UpdateLayerTreeHost() { |
| 575 base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_, |
| 576 true); |
462 client_->UpdateLayerTreeHost(); | 577 client_->UpdateLayerTreeHost(); |
463 if (needs_animate_) { | |
464 needs_animate_ = false; | |
465 root_window_->Animate(base::TimeTicks::Now()); | |
466 } | |
467 } | 578 } |
468 | 579 |
469 void CompositorImpl::OnGpuChannelEstablished() { | 580 void CompositorImpl::OnGpuChannelEstablished() { |
470 establish_gpu_channel_timeout_.Stop(); | 581 establish_gpu_channel_timeout_.Stop(); |
471 CreateOutputSurface(); | 582 CreateOutputSurface(); |
472 } | 583 } |
473 | 584 |
474 void CompositorImpl::OnGpuChannelTimeout() { | 585 void CompositorImpl::OnGpuChannelTimeout() { |
475 LOG(FATAL) << "Timed out waiting for GPU channel."; | 586 LOG(FATAL) << "Timed out waiting for GPU channel."; |
476 } | 587 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 } | 697 } |
587 | 698 |
588 void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) { | 699 void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) { |
589 host_->DeleteUIResource(resource_id); | 700 host_->DeleteUIResource(resource_id); |
590 } | 701 } |
591 | 702 |
592 bool CompositorImpl::SupportsETC1NonPowerOfTwo() const { | 703 bool CompositorImpl::SupportsETC1NonPowerOfTwo() const { |
593 return gpu_capabilities_.texture_format_etc1_npot; | 704 return gpu_capabilities_.texture_format_etc1_npot; |
594 } | 705 } |
595 | 706 |
| 707 void CompositorImpl::ScheduleComposite() { |
| 708 if (ignore_schedule_composite_ || !host_->visible()) |
| 709 return; |
| 710 |
| 711 DCHECK(!needs_composite_ || WillComposite()); |
| 712 needs_composite_ = true; |
| 713 // We currently expect layer tree invalidations at most once per frame |
| 714 // during normal operation and therefore try to composite immediately |
| 715 // to minimize latency. |
| 716 PostComposite(COMPOSITE_IMMEDIATELY); |
| 717 } |
| 718 |
| 719 void CompositorImpl::ScheduleAnimation() { |
| 720 needs_animate_ = true; |
| 721 |
| 722 if (!host_->visible()) |
| 723 return; |
| 724 |
| 725 if (needs_composite_) { |
| 726 DCHECK(WillComposite()); |
| 727 return; |
| 728 } |
| 729 |
| 730 TRACE_EVENT0("cc", "CompositorImpl::ScheduleAnimation"); |
| 731 needs_composite_ = true; |
| 732 PostComposite(COMPOSITE_EVENTUALLY); |
| 733 } |
| 734 |
596 void CompositorImpl::DidPostSwapBuffers() { | 735 void CompositorImpl::DidPostSwapBuffers() { |
597 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); | 736 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); |
598 pending_swapbuffers_++; | 737 did_post_swapbuffers_ = true; |
599 } | 738 } |
600 | 739 |
601 void CompositorImpl::DidCompleteSwapBuffers() { | 740 void CompositorImpl::DidCompleteSwapBuffers() { |
602 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers"); | 741 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers"); |
603 DCHECK_GT(pending_swapbuffers_, 0U); | 742 DCHECK_GT(pending_swapbuffers_, 0U); |
604 pending_swapbuffers_--; | 743 if (pending_swapbuffers_-- == kMaxUiSwapBuffers && needs_composite_) |
| 744 PostComposite(COMPOSITE_IMMEDIATELY); |
605 client_->OnSwapBuffersCompleted(pending_swapbuffers_); | 745 client_->OnSwapBuffersCompleted(pending_swapbuffers_); |
606 } | 746 } |
607 | 747 |
608 void CompositorImpl::DidAbortSwapBuffers() { | 748 void CompositorImpl::DidAbortSwapBuffers() { |
609 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers"); | 749 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers"); |
610 // This really gets called only once from | 750 // This really gets called only once from |
611 // SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the | 751 // SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the |
612 // context was lost. | 752 // context was lost. |
613 if (host_->visible()) | 753 ScheduleComposite(); |
614 host_->SetNeedsCommit(); | |
615 client_->OnSwapBuffersCompleted(0); | 754 client_->OnSwapBuffersCompleted(0); |
616 } | 755 } |
617 | 756 |
618 void CompositorImpl::DidCommit() { | 757 void CompositorImpl::DidCommit() { |
619 root_window_->OnCompositingDidCommit(); | 758 root_window_->OnCompositingDidCommit(); |
620 } | 759 } |
621 | 760 |
622 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { | 761 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { |
623 root_layer_->AddChild(layer); | 762 root_layer_->AddChild(layer); |
624 } | 763 } |
625 | 764 |
626 void CompositorImpl::RequestCopyOfOutputOnRootLayer( | 765 void CompositorImpl::RequestCopyOfOutputOnRootLayer( |
627 scoped_ptr<cc::CopyOutputRequest> request) { | 766 scoped_ptr<cc::CopyOutputRequest> request) { |
628 root_layer_->RequestCopyOfOutput(request.Pass()); | 767 root_layer_->RequestCopyOfOutput(request.Pass()); |
629 } | 768 } |
630 | 769 |
631 void CompositorImpl::OnVSync(base::TimeTicks frame_time, | 770 void CompositorImpl::OnVSync(base::TimeTicks frame_time, |
632 base::TimeDelta vsync_period) { | 771 base::TimeDelta vsync_period) { |
| 772 vsync_period_ = vsync_period; |
| 773 last_vsync_ = frame_time; |
| 774 |
| 775 if (WillCompositeThisFrame()) { |
| 776 // We somehow missed the last vsync interval, so reschedule for deadline. |
| 777 // We cannot schedule immediately, or will get us out-of-phase with new |
| 778 // renderer frames. |
| 779 CancelComposite(); |
| 780 composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY; |
| 781 } else { |
| 782 current_composite_task_.reset(); |
| 783 } |
| 784 |
| 785 DCHECK(!DidCompositeThisFrame() && !WillCompositeThisFrame()); |
| 786 if (composite_on_vsync_trigger_ != DO_NOT_COMPOSITE) { |
| 787 CompositingTrigger trigger = composite_on_vsync_trigger_; |
| 788 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; |
| 789 PostComposite(trigger); |
| 790 } |
| 791 |
633 FOR_EACH_OBSERVER(VSyncObserver, observer_list_, | 792 FOR_EACH_OBSERVER(VSyncObserver, observer_list_, |
634 OnVSync(frame_time, vsync_period)); | 793 OnUpdateVSyncParameters(frame_time, vsync_period)); |
635 if (needs_begin_frames_) | |
636 root_window_->RequestVSyncUpdate(); | |
637 } | |
638 | |
639 void CompositorImpl::OnNeedsBeginFramesChange(bool needs_begin_frames) { | |
640 if (needs_begin_frames_ == needs_begin_frames) | |
641 return; | |
642 | |
643 needs_begin_frames_ = needs_begin_frames; | |
644 if (needs_begin_frames_) | |
645 root_window_->RequestVSyncUpdate(); | |
646 } | 794 } |
647 | 795 |
648 void CompositorImpl::SetNeedsAnimate() { | 796 void CompositorImpl::SetNeedsAnimate() { |
649 needs_animate_ = true; | 797 needs_animate_ = true; |
650 if (!host_->visible()) | 798 if (!host_->visible()) |
651 return; | 799 return; |
652 | 800 |
653 host_->SetNeedsAnimate(); | 801 host_->SetNeedsAnimate(); |
654 } | 802 } |
655 | 803 |
656 } // namespace content | 804 } // namespace content |
OLD | NEW |