OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/delegated_frame_host.h" | 5 #include "content/browser/renderer_host/delegated_frame_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
15 #include "base/time/default_tick_clock.h" | 15 #include "base/time/default_tick_clock.h" |
16 #include "cc/output/compositor_frame.h" | 16 #include "cc/output/compositor_frame.h" |
17 #include "cc/output/compositor_frame_ack.h" | |
18 #include "cc/output/copy_output_request.h" | 17 #include "cc/output/copy_output_request.h" |
19 #include "cc/resources/single_release_callback.h" | 18 #include "cc/resources/single_release_callback.h" |
20 #include "cc/resources/texture_mailbox.h" | 19 #include "cc/resources/texture_mailbox.h" |
21 #include "cc/surfaces/surface.h" | 20 #include "cc/surfaces/surface.h" |
22 #include "cc/surfaces/surface_factory.h" | 21 #include "cc/surfaces/surface_factory.h" |
23 #include "cc/surfaces/surface_hittest.h" | 22 #include "cc/surfaces/surface_hittest.h" |
24 #include "cc/surfaces/surface_manager.h" | 23 #include "cc/surfaces/surface_manager.h" |
25 #include "components/display_compositor/gl_helper.h" | 24 #include "components/display_compositor/gl_helper.h" |
26 #include "content/browser/compositor/surface_utils.h" | 25 #include "content/browser/compositor/surface_utils.h" |
27 #include "content/browser/gpu/compositor_util.h" | 26 #include "content/browser/gpu/compositor_util.h" |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 gfx::Size frame_size = root_pass->output_rect.size(); | 402 gfx::Size frame_size = root_pass->output_rect.size(); |
404 gfx::Size frame_size_in_dip = | 403 gfx::Size frame_size_in_dip = |
405 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); | 404 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
406 | 405 |
407 gfx::Rect damage_rect = root_pass->damage_rect; | 406 gfx::Rect damage_rect = root_pass->damage_rect; |
408 damage_rect.Intersect(gfx::Rect(frame_size)); | 407 damage_rect.Intersect(gfx::Rect(frame_size)); |
409 gfx::Rect damage_rect_in_dip = | 408 gfx::Rect damage_rect_in_dip = |
410 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); | 409 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); |
411 | 410 |
412 if (ShouldSkipFrame(frame_size_in_dip)) { | 411 if (ShouldSkipFrame(frame_size_in_dip)) { |
413 cc::CompositorFrameAck ack; | 412 cc::ReturnedResourceArray resources; |
414 cc::TransferableResource::ReturnResources(frame_data->resource_list, | 413 cc::TransferableResource::ReturnResources(frame_data->resource_list, |
415 &ack.resources); | 414 &resources); |
416 | 415 |
417 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), | 416 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), |
418 frame.metadata.latency_info.begin(), | 417 frame.metadata.latency_info.begin(), |
419 frame.metadata.latency_info.end()); | 418 frame.metadata.latency_info.end()); |
420 | 419 |
421 client_->DelegatedFrameHostSendCompositorSwapAck(output_surface_id, ack); | 420 client_->DelegatedFrameHostSendReclaimCompositorResources( |
| 421 output_surface_id, true /* is_swap_ack*/, resources); |
422 skipped_frames_ = true; | 422 skipped_frames_ = true; |
423 return; | 423 return; |
424 } | 424 } |
425 | 425 |
426 if (skipped_frames_) { | 426 if (skipped_frames_) { |
427 skipped_frames_ = false; | 427 skipped_frames_ = false; |
428 damage_rect = gfx::Rect(frame_size); | 428 damage_rect = gfx::Rect(frame_size); |
429 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); | 429 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); |
430 | 430 |
431 // Give the same damage rect to the compositor. | 431 // Give the same damage rect to the compositor. |
432 cc::RenderPass* root_pass = frame_data->render_pass_list.back().get(); | 432 cc::RenderPass* root_pass = frame_data->render_pass_list.back().get(); |
433 root_pass->damage_rect = damage_rect; | 433 root_pass->damage_rect = damage_rect; |
434 } | 434 } |
435 | 435 |
436 if (output_surface_id != last_output_surface_id_) { | 436 if (output_surface_id != last_output_surface_id_) { |
437 // Resource ids are scoped by the output surface. | 437 // Resource ids are scoped by the output surface. |
438 // If the originating output surface doesn't match the last one, it | 438 // If the originating output surface doesn't match the last one, it |
439 // indicates the renderer's output surface may have been recreated, in which | 439 // indicates the renderer's output surface may have been recreated, in which |
440 // case we should recreate the DelegatedRendererLayer, to avoid matching | 440 // case we should recreate the DelegatedRendererLayer, to avoid matching |
441 // resources from the old one with resources from the new one which would | 441 // resources from the old one with resources from the new one which would |
442 // have the same id. Changing the layer to showing painted content destroys | 442 // have the same id. Changing the layer to showing painted content destroys |
443 // the DelegatedRendererLayer. | 443 // the DelegatedRendererLayer. |
444 EvictDelegatedFrame(); | 444 EvictDelegatedFrame(); |
445 | 445 |
446 surface_factory_.reset(); | 446 surface_factory_.reset(); |
447 if (!surface_returned_resources_.empty()) | 447 if (!surface_returned_resources_.empty()) { |
448 SendReturnedDelegatedResources(last_output_surface_id_); | 448 SendReclaimCompositorResources(last_output_surface_id_, |
449 | 449 false /* is_swap_ack */); |
| 450 } |
450 last_output_surface_id_ = output_surface_id; | 451 last_output_surface_id_ = output_surface_id; |
451 } | 452 } |
452 bool skip_frame = false; | 453 bool skip_frame = false; |
453 pending_delegated_ack_count_++; | 454 pending_delegated_ack_count_++; |
454 | 455 |
455 background_color_ = frame.metadata.root_background_color; | 456 background_color_ = frame.metadata.root_background_color; |
456 | 457 |
457 if (frame_size.IsEmpty()) { | 458 if (frame_size.IsEmpty()) { |
458 DCHECK(frame_data->resource_list.empty()); | 459 DCHECK(frame_data->resource_list.empty()); |
459 EvictDelegatedFrame(); | 460 EvictDelegatedFrame(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 } | 496 } |
496 surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame), | 497 surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame), |
497 ack_callback); | 498 ack_callback); |
498 } | 499 } |
499 released_front_lock_ = NULL; | 500 released_front_lock_ = NULL; |
500 current_frame_size_in_dip_ = frame_size_in_dip; | 501 current_frame_size_in_dip_ = frame_size_in_dip; |
501 CheckResizeLock(); | 502 CheckResizeLock(); |
502 | 503 |
503 UpdateGutters(); | 504 UpdateGutters(); |
504 | 505 |
505 if (!damage_rect_in_dip.IsEmpty()) | 506 if (!damage_rect_in_dip.IsEmpty()) { |
506 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage( | 507 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage( |
507 damage_rect_in_dip); | 508 damage_rect_in_dip); |
| 509 } |
508 | 510 |
509 // Note that |compositor_| may be reset by SetShowSurface or | 511 // Note that |compositor_| may be reset by SetShowSurface or |
510 // SetShowDelegatedContent above. | 512 // SetShowDelegatedContent above. |
511 if (!compositor_ || skip_frame) { | 513 if (!compositor_ || skip_frame) { |
512 SendDelegatedFrameAck(output_surface_id); | 514 SendReclaimCompositorResources(output_surface_id, true /* is_swap_ack */); |
513 } else { | 515 } else { |
514 can_lock_compositor_ = NO_PENDING_COMMIT; | 516 can_lock_compositor_ = NO_PENDING_COMMIT; |
515 } | 517 } |
516 if (!surface_id_.is_null()) | 518 if (!surface_id_.is_null()) { |
517 delegated_frame_evictor_->SwappedFrame( | 519 delegated_frame_evictor_->SwappedFrame( |
518 client_->DelegatedFrameHostIsVisible()); | 520 client_->DelegatedFrameHostIsVisible()); |
| 521 } |
519 // Note: the frame may have been evicted immediately. | 522 // Note: the frame may have been evicted immediately. |
520 } | 523 } |
521 | 524 |
522 void DelegatedFrameHost::ClearDelegatedFrame() { | 525 void DelegatedFrameHost::ClearDelegatedFrame() { |
523 if (!surface_id_.is_null()) | 526 if (!surface_id_.is_null()) |
524 EvictDelegatedFrame(); | 527 EvictDelegatedFrame(); |
525 } | 528 } |
526 | 529 |
527 void DelegatedFrameHost::SendDelegatedFrameAck(uint32_t output_surface_id) { | 530 void DelegatedFrameHost::SendReclaimCompositorResources( |
528 cc::CompositorFrameAck ack; | 531 uint32_t output_surface_id, |
529 if (!surface_returned_resources_.empty()) | 532 bool is_swap_ack) { |
530 ack.resources.swap(surface_returned_resources_); | 533 client_->DelegatedFrameHostSendReclaimCompositorResources( |
531 client_->DelegatedFrameHostSendCompositorSwapAck(output_surface_id, ack); | 534 output_surface_id, is_swap_ack, surface_returned_resources_); |
532 DCHECK_GT(pending_delegated_ack_count_, 0); | 535 surface_returned_resources_.clear(); |
533 pending_delegated_ack_count_--; | 536 if (is_swap_ack) { |
| 537 DCHECK_GT(pending_delegated_ack_count_, 0); |
| 538 pending_delegated_ack_count_--; |
| 539 } |
534 } | 540 } |
535 | 541 |
536 void DelegatedFrameHost::SurfaceDrawn(uint32_t output_surface_id, | 542 void DelegatedFrameHost::SurfaceDrawn(uint32_t output_surface_id, |
537 cc::SurfaceDrawStatus drawn) { | 543 cc::SurfaceDrawStatus drawn) { |
538 SendDelegatedFrameAck(output_surface_id); | 544 SendReclaimCompositorResources(output_surface_id, true /* is_swap_ack */); |
539 } | |
540 | |
541 void DelegatedFrameHost::SendReturnedDelegatedResources( | |
542 uint32_t output_surface_id) { | |
543 cc::CompositorFrameAck ack; | |
544 DCHECK(!surface_returned_resources_.empty()); | |
545 ack.resources.swap(surface_returned_resources_); | |
546 | |
547 client_->DelegatedFrameHostSendReclaimCompositorResources(output_surface_id, | |
548 ack); | |
549 } | 545 } |
550 | 546 |
551 void DelegatedFrameHost::ReturnResources( | 547 void DelegatedFrameHost::ReturnResources( |
552 const cc::ReturnedResourceArray& resources) { | 548 const cc::ReturnedResourceArray& resources) { |
553 if (resources.empty()) | 549 if (resources.empty()) |
554 return; | 550 return; |
555 std::copy(resources.begin(), resources.end(), | 551 std::copy(resources.begin(), resources.end(), |
556 std::back_inserter(surface_returned_resources_)); | 552 std::back_inserter(surface_returned_resources_)); |
557 if (!pending_delegated_ack_count_) | 553 if (!pending_delegated_ack_count_) { |
558 SendReturnedDelegatedResources(last_output_surface_id_); | 554 SendReclaimCompositorResources(last_output_surface_id_, |
| 555 false /* is_swap_ack */); |
| 556 } |
559 } | 557 } |
560 | 558 |
561 void DelegatedFrameHost::WillDrawSurface(const cc::SurfaceId& id, | 559 void DelegatedFrameHost::WillDrawSurface(const cc::SurfaceId& id, |
562 const gfx::Rect& damage_rect) { | 560 const gfx::Rect& damage_rect) { |
563 // Frame subscribers are only interested in changes to the target surface, so | 561 // Frame subscribers are only interested in changes to the target surface, so |
564 // do not attempt capture if |damage_rect| is empty. This prevents the draws | 562 // do not attempt capture if |damage_rect| is empty. This prevents the draws |
565 // of parent surfaces from triggering extra frame captures, which can affect | 563 // of parent surfaces from triggering extra frame captures, which can affect |
566 // smoothness. | 564 // smoothness. |
567 if (id != surface_id_ || damage_rect.IsEmpty()) | 565 if (id != surface_id_ || damage_rect.IsEmpty()) |
568 return; | 566 return; |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 cc::SurfaceManager* manager = factory->GetSurfaceManager(); | 900 cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
903 new_layer->SetShowSurface( | 901 new_layer->SetShowSurface( |
904 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), | 902 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), |
905 base::Bind(&RequireCallback, base::Unretained(manager)), | 903 base::Bind(&RequireCallback, base::Unretained(manager)), |
906 current_surface_size_, current_scale_factor_, | 904 current_surface_size_, current_scale_factor_, |
907 current_frame_size_in_dip_); | 905 current_frame_size_in_dip_); |
908 } | 906 } |
909 } | 907 } |
910 | 908 |
911 } // namespace content | 909 } // namespace content |
OLD | NEW |