Chromium Code Reviews| 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 false /* is_swap_ack */); | |
| 449 | 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()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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); |
| 508 | 509 |
| 509 // Note that |compositor_| may be reset by SetShowSurface or | 510 // Note that |compositor_| may be reset by SetShowSurface or |
| 510 // SetShowDelegatedContent above. | 511 // SetShowDelegatedContent above. |
| 511 if (!compositor_ || skip_frame) { | 512 if (!compositor_ || skip_frame) { |
| 512 SendDelegatedFrameAck(output_surface_id); | 513 SendReclaimCompositorResources(output_surface_id, false /* is_swap_ack */); |
|
piman
2016/07/13 20:59:14
this one is a swap ack.
Fady Samuel
2016/07/13 22:12:16
Done.
danakj
2016/07/13 22:15:03
Are there (can there be) tests that cover these mi
Fady Samuel
2016/07/14 02:50:10
This is now covered by RenderWidgetHostViewAuraTes
| |
| 513 } else { | 514 } else { |
| 514 can_lock_compositor_ = NO_PENDING_COMMIT; | 515 can_lock_compositor_ = NO_PENDING_COMMIT; |
| 515 } | 516 } |
| 516 if (!surface_id_.is_null()) | 517 if (!surface_id_.is_null()) |
| 517 delegated_frame_evictor_->SwappedFrame( | 518 delegated_frame_evictor_->SwappedFrame( |
| 518 client_->DelegatedFrameHostIsVisible()); | 519 client_->DelegatedFrameHostIsVisible()); |
| 519 // Note: the frame may have been evicted immediately. | 520 // Note: the frame may have been evicted immediately. |
| 520 } | 521 } |
| 521 | 522 |
| 522 void DelegatedFrameHost::ClearDelegatedFrame() { | 523 void DelegatedFrameHost::ClearDelegatedFrame() { |
| 523 if (!surface_id_.is_null()) | 524 if (!surface_id_.is_null()) |
| 524 EvictDelegatedFrame(); | 525 EvictDelegatedFrame(); |
| 525 } | 526 } |
| 526 | 527 |
| 527 void DelegatedFrameHost::SendDelegatedFrameAck(uint32_t output_surface_id) { | 528 void DelegatedFrameHost::SendReclaimCompositorResources( |
| 528 cc::CompositorFrameAck ack; | 529 uint32_t output_surface_id, |
| 529 if (!surface_returned_resources_.empty()) | 530 bool is_swap_ack) { |
| 530 ack.resources.swap(surface_returned_resources_); | 531 client_->DelegatedFrameHostSendReclaimCompositorResources( |
| 531 client_->DelegatedFrameHostSendCompositorSwapAck(output_surface_id, ack); | 532 output_surface_id, is_swap_ack, surface_returned_resources_); |
| 533 surface_returned_resources_.clear(); | |
| 532 DCHECK_GT(pending_delegated_ack_count_, 0); | 534 DCHECK_GT(pending_delegated_ack_count_, 0); |
| 533 pending_delegated_ack_count_--; | 535 pending_delegated_ack_count_--; |
|
piman
2016/07/13 20:59:14
this (the DCHECK and the decrement) should only ha
Fady Samuel
2016/07/13 22:12:16
Done.
Fady Samuel
2016/07/14 02:50:10
This is now covered by RenderWidgetHostViewAuraTes
| |
| 534 } | 536 } |
| 535 | 537 |
| 536 void DelegatedFrameHost::SurfaceDrawn(uint32_t output_surface_id, | 538 void DelegatedFrameHost::SurfaceDrawn(uint32_t output_surface_id, |
| 537 cc::SurfaceDrawStatus drawn) { | 539 cc::SurfaceDrawStatus drawn) { |
| 538 SendDelegatedFrameAck(output_surface_id); | 540 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 } | 541 } |
| 550 | 542 |
| 551 void DelegatedFrameHost::ReturnResources( | 543 void DelegatedFrameHost::ReturnResources( |
| 552 const cc::ReturnedResourceArray& resources) { | 544 const cc::ReturnedResourceArray& resources) { |
| 553 if (resources.empty()) | 545 if (resources.empty()) |
| 554 return; | 546 return; |
| 555 std::copy(resources.begin(), resources.end(), | 547 std::copy(resources.begin(), resources.end(), |
| 556 std::back_inserter(surface_returned_resources_)); | 548 std::back_inserter(surface_returned_resources_)); |
| 557 if (!pending_delegated_ack_count_) | 549 if (!pending_delegated_ack_count_) |
| 558 SendReturnedDelegatedResources(last_output_surface_id_); | 550 SendReclaimCompositorResources(last_output_surface_id_, |
| 551 false /* is_swap_ack */); | |
| 559 } | 552 } |
| 560 | 553 |
| 561 void DelegatedFrameHost::WillDrawSurface(const cc::SurfaceId& id, | 554 void DelegatedFrameHost::WillDrawSurface(const cc::SurfaceId& id, |
| 562 const gfx::Rect& damage_rect) { | 555 const gfx::Rect& damage_rect) { |
| 563 // Frame subscribers are only interested in changes to the target surface, so | 556 // 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 | 557 // 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 | 558 // of parent surfaces from triggering extra frame captures, which can affect |
| 566 // smoothness. | 559 // smoothness. |
| 567 if (id != surface_id_ || damage_rect.IsEmpty()) | 560 if (id != surface_id_ || damage_rect.IsEmpty()) |
| 568 return; | 561 return; |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 902 cc::SurfaceManager* manager = factory->GetSurfaceManager(); | 895 cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
| 903 new_layer->SetShowSurface( | 896 new_layer->SetShowSurface( |
| 904 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), | 897 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), |
| 905 base::Bind(&RequireCallback, base::Unretained(manager)), | 898 base::Bind(&RequireCallback, base::Unretained(manager)), |
| 906 current_surface_size_, current_scale_factor_, | 899 current_surface_size_, current_scale_factor_, |
| 907 current_frame_size_in_dip_); | 900 current_frame_size_in_dip_); |
| 908 } | 901 } |
| 909 } | 902 } |
| 910 | 903 |
| 911 } // namespace content | 904 } // namespace content |
| OLD | NEW |