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