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/base/switches.h" | 16 #include "cc/base/switches.h" |
17 #include "cc/output/compositor_frame.h" | 17 #include "cc/output/compositor_frame.h" |
18 #include "cc/output/copy_output_request.h" | 18 #include "cc/output/copy_output_request.h" |
19 #include "cc/resources/single_release_callback.h" | 19 #include "cc/resources/single_release_callback.h" |
20 #include "cc/resources/texture_mailbox.h" | 20 #include "cc/resources/texture_mailbox.h" |
21 #include "cc/surfaces/compositor_frame_sink_support.h" | |
21 #include "cc/surfaces/surface.h" | 22 #include "cc/surfaces/surface.h" |
22 #include "cc/surfaces/surface_factory.h" | 23 #include "cc/surfaces/surface_factory.h" |
23 #include "cc/surfaces/surface_hittest.h" | 24 #include "cc/surfaces/surface_hittest.h" |
24 #include "cc/surfaces/surface_manager.h" | 25 #include "cc/surfaces/surface_manager.h" |
25 #include "components/display_compositor/gl_helper.h" | 26 #include "components/display_compositor/gl_helper.h" |
26 #include "content/browser/compositor/surface_utils.h" | 27 #include "content/browser/compositor/surface_utils.h" |
27 #include "content/browser/gpu/compositor_util.h" | 28 #include "content/browser/gpu/compositor_util.h" |
28 #include "content/browser/renderer_host/render_widget_host_view_frame_subscriber .h" | 29 #include "content/browser/renderer_host/render_widget_host_view_frame_subscriber .h" |
29 #include "content/browser/renderer_host/resize_lock.h" | 30 #include "content/browser/renderer_host/resize_lock.h" |
30 #include "content/public/common/content_switches.h" | 31 #include "content/public/common/content_switches.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
41 //////////////////////////////////////////////////////////////////////////////// | 42 //////////////////////////////////////////////////////////////////////////////// |
42 // DelegatedFrameHost | 43 // DelegatedFrameHost |
43 | 44 |
44 DelegatedFrameHost::DelegatedFrameHost(const cc::FrameSinkId& frame_sink_id, | 45 DelegatedFrameHost::DelegatedFrameHost(const cc::FrameSinkId& frame_sink_id, |
45 DelegatedFrameHostClient* client) | 46 DelegatedFrameHostClient* client) |
46 : frame_sink_id_(frame_sink_id), | 47 : frame_sink_id_(frame_sink_id), |
47 client_(client), | 48 client_(client), |
48 compositor_(nullptr), | 49 compositor_(nullptr), |
49 tick_clock_(new base::DefaultTickClock()), | 50 tick_clock_(new base::DefaultTickClock()), |
50 last_compositor_frame_sink_id_(0), | 51 last_compositor_frame_sink_id_(0), |
51 pending_delegated_ack_count_(0), | |
52 skipped_frames_(false), | 52 skipped_frames_(false), |
53 background_color_(SK_ColorRED), | 53 background_color_(SK_ColorRED), |
54 current_scale_factor_(1.f), | 54 current_scale_factor_(1.f), |
55 can_lock_compositor_(YES_CAN_LOCK), | 55 can_lock_compositor_(YES_CAN_LOCK), |
56 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 56 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
57 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 57 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
58 factory->GetContextFactory()->AddObserver(this); | 58 factory->GetContextFactory()->AddObserver(this); |
59 id_allocator_.reset(new cc::SurfaceIdAllocator()); | 59 id_allocator_.reset(new cc::SurfaceIdAllocator()); |
60 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( | 60 factory->GetContextFactoryPrivate()->GetSurfaceManager()->RegisterFrameSinkId( |
61 frame_sink_id_); | 61 frame_sink_id_); |
62 factory->GetContextFactoryPrivate() | 62 support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>( |
Fady Samuel
2017/02/23 18:32:40
Maybe we can move creating a support to a helper m
Saman Sami
2017/02/23 18:34:40
Acknowledged.
| |
63 ->GetSurfaceManager() | 63 this, factory->GetContextFactoryPrivate()->GetSurfaceManager(), |
64 ->RegisterSurfaceFactoryClient(frame_sink_id_, this); | 64 frame_sink_id_, false /* is_root */, |
65 surface_factory_ = base::MakeUnique<cc::SurfaceFactory>( | 65 false /* handles_frame_sink_id_invalidation */, |
66 frame_sink_id_, factory->GetContextFactoryPrivate()->GetSurfaceManager(), | 66 true /* needs_sync_points */); |
67 this); | 67 begin_frame_source_ = base::MakeUnique<cc::ExternalBeginFrameSource>(this); |
68 client_->SetBeginFrameSource(begin_frame_source_.get()); | |
68 } | 69 } |
69 | 70 |
70 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { | 71 void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { |
71 delegated_frame_evictor_->SetVisible(true); | 72 delegated_frame_evictor_->SetVisible(true); |
72 | 73 |
73 if (!local_surface_id_.is_valid() && !released_front_lock_.get()) { | 74 if (!local_surface_id_.is_valid() && !released_front_lock_.get()) { |
74 if (compositor_) | 75 if (compositor_) |
75 released_front_lock_ = compositor_->GetCompositorLock(); | 76 released_front_lock_ = compositor_->GetCompositorLock(); |
76 } | 77 } |
77 | 78 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 subscriber_texture->target())); | 372 subscriber_texture->target())); |
372 } | 373 } |
373 | 374 |
374 if (local_surface_id_.is_valid()) { | 375 if (local_surface_id_.is_valid()) { |
375 // To avoid unnecessary composites, go directly to the Surface rather than | 376 // To avoid unnecessary composites, go directly to the Surface rather than |
376 // through RequestCopyOfOutput (which goes through the browser | 377 // through RequestCopyOfOutput (which goes through the browser |
377 // compositor). | 378 // compositor). |
378 if (!request_copy_of_output_callback_for_testing_.is_null()) | 379 if (!request_copy_of_output_callback_for_testing_.is_null()) |
379 request_copy_of_output_callback_for_testing_.Run(std::move(request)); | 380 request_copy_of_output_callback_for_testing_.Run(std::move(request)); |
380 else | 381 else |
381 surface_factory_->RequestCopyOfSurface(std::move(request)); | 382 support_->RequestCopyOfSurface(std::move(request)); |
382 } else { | 383 } else { |
383 request->set_area(gfx::Rect(current_frame_size_in_dip_)); | 384 request->set_area(gfx::Rect(current_frame_size_in_dip_)); |
384 RequestCopyOfOutput(std::move(request)); | 385 RequestCopyOfOutput(std::move(request)); |
385 } | 386 } |
386 } | 387 } |
387 | 388 |
388 void DelegatedFrameHost::SwapDelegatedFrame(uint32_t compositor_frame_sink_id, | 389 void DelegatedFrameHost::SwapDelegatedFrame(uint32_t compositor_frame_sink_id, |
389 cc::CompositorFrame frame) { | 390 cc::CompositorFrame frame) { |
390 #if defined(OS_CHROMEOS) | 391 #if defined(OS_CHROMEOS) |
391 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); | 392 DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 | 432 |
432 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { | 433 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { |
433 // Resource ids are scoped by the output surface. | 434 // Resource ids are scoped by the output surface. |
434 // If the originating output surface doesn't match the last one, it | 435 // If the originating output surface doesn't match the last one, it |
435 // indicates the renderer's output surface may have been recreated, in which | 436 // indicates the renderer's output surface may have been recreated, in which |
436 // case we should recreate the DelegatedRendererLayer, to avoid matching | 437 // case we should recreate the DelegatedRendererLayer, to avoid matching |
437 // resources from the old one with resources from the new one which would | 438 // resources from the old one with resources from the new one which would |
438 // have the same id. Changing the layer to showing painted content destroys | 439 // have the same id. Changing the layer to showing painted content destroys |
439 // the DelegatedRendererLayer. | 440 // the DelegatedRendererLayer. |
440 EvictDelegatedFrame(); | 441 EvictDelegatedFrame(); |
441 surface_factory_->Reset(); | 442 DCHECK(support_); |
442 surface_returned_resources_.clear(); | 443 support_.reset(); |
444 support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>( | |
445 this, | |
446 ImageTransportFactory::GetInstance() | |
447 ->GetContextFactoryPrivate() | |
448 ->GetSurfaceManager(), | |
449 frame_sink_id_, false /* is_root */, | |
450 false /* handles_frame_sink_id_invalidation */, | |
451 true /* needs_sync_points */); | |
452 if (compositor_) { | |
453 compositor_->RemoveFrameSink(frame_sink_id_); | |
Fady Samuel
2017/02/23 18:32:40
Remind me why you remove the FrameSink first and t
Saman Sami
2017/02/23 18:34:40
The link already exists. We need to remove and re-
| |
454 compositor_->AddFrameSink(frame_sink_id_); | |
455 } | |
456 if (needs_begin_frame_) | |
457 support_->SetNeedsBeginFrame(true); | |
443 last_compositor_frame_sink_id_ = compositor_frame_sink_id; | 458 last_compositor_frame_sink_id_ = compositor_frame_sink_id; |
444 } | 459 } |
460 | |
445 bool skip_frame = false; | 461 bool skip_frame = false; |
446 pending_delegated_ack_count_++; | |
447 | 462 |
448 background_color_ = frame.metadata.root_background_color; | 463 background_color_ = frame.metadata.root_background_color; |
449 | 464 |
450 if (frame_size.IsEmpty()) { | 465 if (frame_size.IsEmpty()) { |
451 DCHECK(frame.resource_list.empty()); | 466 DCHECK(frame.resource_list.empty()); |
452 EvictDelegatedFrame(); | 467 EvictDelegatedFrame(); |
453 } else { | 468 } else { |
454 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 469 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
455 cc::SurfaceManager* manager = | 470 cc::SurfaceManager* manager = |
456 factory->GetContextFactoryPrivate()->GetSurfaceManager(); | 471 factory->GetContextFactoryPrivate()->GetSurfaceManager(); |
(...skipping 11 matching lines...) Expand all Loading... | |
468 frame.metadata.latency_info.begin(), | 483 frame.metadata.latency_info.begin(), |
469 frame.metadata.latency_info.end()); | 484 frame.metadata.latency_info.end()); |
470 frame.metadata.latency_info.clear(); | 485 frame.metadata.latency_info.clear(); |
471 } else { | 486 } else { |
472 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), | 487 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), |
473 skipped_latency_info_list_.begin(), | 488 skipped_latency_info_list_.begin(), |
474 skipped_latency_info_list_.end()); | 489 skipped_latency_info_list_.end()); |
475 skipped_latency_info_list_.clear(); | 490 skipped_latency_info_list_.clear(); |
476 } | 491 } |
477 | 492 |
478 cc::SurfaceFactory::DrawCallback ack_callback; | 493 support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)); |
479 if (!skip_frame) { | 494 |
480 ack_callback = base::Bind(&DelegatedFrameHost::SurfaceDrawn, AsWeakPtr(), | |
481 compositor_frame_sink_id); | |
482 } | |
483 surface_factory_->SubmitCompositorFrame(local_surface_id_, std::move(frame), | |
484 ack_callback); | |
485 if (allocated_new_local_surface_id) { | 495 if (allocated_new_local_surface_id) { |
486 // manager must outlive compositors using it. | 496 // manager must outlive compositors using it. |
487 cc::SurfaceId surface_id(frame_sink_id_, local_surface_id_); | 497 cc::SurfaceId surface_id(frame_sink_id_, local_surface_id_); |
488 cc::SurfaceInfo surface_info(surface_id, frame_device_scale_factor, | 498 cc::SurfaceInfo surface_info(surface_id, frame_device_scale_factor, |
489 frame_size); | 499 frame_size); |
490 client_->DelegatedFrameHostGetLayer()->SetShowSurface( | 500 client_->DelegatedFrameHostGetLayer()->SetShowSurface( |
491 surface_info, manager->reference_factory()); | 501 surface_info, manager->reference_factory()); |
492 current_surface_size_ = frame_size; | 502 current_surface_size_ = frame_size; |
493 current_scale_factor_ = frame_device_scale_factor; | 503 current_scale_factor_ = frame_device_scale_factor; |
494 } | 504 } |
495 } | 505 } |
496 released_front_lock_ = NULL; | 506 released_front_lock_ = NULL; |
497 current_frame_size_in_dip_ = frame_size_in_dip; | 507 current_frame_size_in_dip_ = frame_size_in_dip; |
498 CheckResizeLock(); | 508 CheckResizeLock(); |
499 | 509 |
500 UpdateGutters(); | 510 UpdateGutters(); |
501 | 511 |
502 if (!damage_rect_in_dip.IsEmpty()) { | 512 if (!damage_rect_in_dip.IsEmpty()) { |
503 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage( | 513 client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage( |
504 damage_rect_in_dip); | 514 damage_rect_in_dip); |
505 } | 515 } |
506 | 516 |
507 if (skip_frame) { | |
508 SendReclaimCompositorResources(compositor_frame_sink_id, | |
509 true /* is_swap_ack */); | |
510 } | |
511 | |
512 if (compositor_ && !skip_frame) | 517 if (compositor_ && !skip_frame) |
513 can_lock_compositor_ = NO_PENDING_COMMIT; | 518 can_lock_compositor_ = NO_PENDING_COMMIT; |
514 | 519 |
515 if (local_surface_id_.is_valid()) { | 520 if (local_surface_id_.is_valid()) { |
516 delegated_frame_evictor_->SwappedFrame( | 521 delegated_frame_evictor_->SwappedFrame( |
517 client_->DelegatedFrameHostIsVisible()); | 522 client_->DelegatedFrameHostIsVisible()); |
518 } | 523 } |
519 // Note: the frame may have been evicted immediately. | 524 // Note: the frame may have been evicted immediately. |
520 } | 525 } |
521 | 526 |
522 void DelegatedFrameHost::ClearDelegatedFrame() { | 527 void DelegatedFrameHost::ClearDelegatedFrame() { |
523 if (local_surface_id_.is_valid()) | 528 if (local_surface_id_.is_valid()) |
524 EvictDelegatedFrame(); | 529 EvictDelegatedFrame(); |
525 } | 530 } |
526 | 531 |
527 void DelegatedFrameHost::SendReclaimCompositorResources( | 532 void DelegatedFrameHost::DidReceiveCompositorFrameAck() { |
528 uint32_t compositor_frame_sink_id, | 533 LOG(ERROR) << "Ack"; |
529 bool is_swap_ack) { | |
530 client_->DelegatedFrameHostSendReclaimCompositorResources( | 534 client_->DelegatedFrameHostSendReclaimCompositorResources( |
531 compositor_frame_sink_id, is_swap_ack, surface_returned_resources_); | 535 last_compositor_frame_sink_id_, true /* is_swap_ack */, |
532 surface_returned_resources_.clear(); | 536 cc::ReturnedResourceArray()); |
533 if (is_swap_ack) { | |
534 DCHECK_GT(pending_delegated_ack_count_, 0); | |
535 pending_delegated_ack_count_--; | |
536 } | |
537 } | 537 } |
538 | 538 |
539 void DelegatedFrameHost::SurfaceDrawn(uint32_t compositor_frame_sink_id) { | 539 void DelegatedFrameHost::ReclaimResources( |
540 SendReclaimCompositorResources(compositor_frame_sink_id, | |
541 true /* is_swap_ack */); | |
542 } | |
543 | |
544 void DelegatedFrameHost::ReturnResources( | |
545 const cc::ReturnedResourceArray& resources) { | 540 const cc::ReturnedResourceArray& resources) { |
546 if (resources.empty()) | 541 LOG(ERROR) << resources.size(); |
547 return; | 542 client_->DelegatedFrameHostSendReclaimCompositorResources( |
548 std::copy(resources.begin(), resources.end(), | 543 last_compositor_frame_sink_id_, false /* is_swap_ack */, resources); |
549 std::back_inserter(surface_returned_resources_)); | |
550 if (!pending_delegated_ack_count_) { | |
551 SendReclaimCompositorResources(last_compositor_frame_sink_id_, | |
552 false /* is_swap_ack */); | |
553 } | |
554 } | 544 } |
555 | 545 |
556 void DelegatedFrameHost::WillDrawSurface(const cc::LocalSurfaceId& id, | 546 void DelegatedFrameHost::WillDrawSurface(const cc::LocalSurfaceId& id, |
557 const gfx::Rect& damage_rect) { | 547 const gfx::Rect& damage_rect) { |
558 // Frame subscribers are only interested in changes to the target surface, so | 548 // Frame subscribers are only interested in changes to the target surface, so |
559 // do not attempt capture if |damage_rect| is empty. This prevents the draws | 549 // do not attempt capture if |damage_rect| is empty. This prevents the draws |
560 // of parent surfaces from triggering extra frame captures, which can affect | 550 // of parent surfaces from triggering extra frame captures, which can affect |
561 // smoothness. | 551 // smoothness. |
562 if (id != local_surface_id_ || damage_rect.IsEmpty()) | 552 if (id != local_surface_id_ || damage_rect.IsEmpty()) |
563 return; | 553 return; |
564 AttemptFrameSubscriberCapture(damage_rect); | 554 AttemptFrameSubscriberCapture(damage_rect); |
565 } | 555 } |
566 | 556 |
567 void DelegatedFrameHost::SetBeginFrameSource( | 557 void DelegatedFrameHost::OnBeginFrame(const cc::BeginFrameArgs& args) { |
568 cc::BeginFrameSource* begin_frame_source) { | 558 begin_frame_source_->OnBeginFrame(args); |
569 client_->SetBeginFrameSource(begin_frame_source); | |
570 } | 559 } |
571 | 560 |
572 void DelegatedFrameHost::EvictDelegatedFrame() { | 561 void DelegatedFrameHost::EvictDelegatedFrame() { |
573 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); | 562 client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); |
574 if (local_surface_id_.is_valid()) { | 563 if (local_surface_id_.is_valid()) { |
575 surface_factory_->EvictSurface(); | 564 support_->EvictFrame(); |
576 local_surface_id_ = cc::LocalSurfaceId(); | 565 local_surface_id_ = cc::LocalSurfaceId(); |
577 } | 566 } |
578 delegated_frame_evictor_->DiscardedFrame(); | 567 delegated_frame_evictor_->DiscardedFrame(); |
579 UpdateGutters(); | 568 UpdateGutters(); |
580 } | 569 } |
581 | 570 |
582 // static | 571 // static |
583 void DelegatedFrameHost::ReturnSubscriberTexture( | 572 void DelegatedFrameHost::ReturnSubscriberTexture( |
584 base::WeakPtr<DelegatedFrameHost> dfh, | 573 base::WeakPtr<DelegatedFrameHost> dfh, |
585 scoped_refptr<OwnedMailbox> subscriber_texture, | 574 scoped_refptr<OwnedMailbox> subscriber_texture, |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
799 yuv_readback_pipeline_.reset(); | 788 yuv_readback_pipeline_.reset(); |
800 } | 789 } |
801 | 790 |
802 //////////////////////////////////////////////////////////////////////////////// | 791 //////////////////////////////////////////////////////////////////////////////// |
803 // DelegatedFrameHost, private: | 792 // DelegatedFrameHost, private: |
804 | 793 |
805 DelegatedFrameHost::~DelegatedFrameHost() { | 794 DelegatedFrameHost::~DelegatedFrameHost() { |
806 DCHECK(!compositor_); | 795 DCHECK(!compositor_); |
807 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 796 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
808 factory->GetContextFactory()->RemoveObserver(this); | 797 factory->GetContextFactory()->RemoveObserver(this); |
809 surface_factory_->EvictSurface(); | 798 |
810 factory->GetContextFactoryPrivate() | 799 begin_frame_source_.reset(); |
811 ->GetSurfaceManager() | 800 support_.reset(); |
812 ->UnregisterSurfaceFactoryClient(frame_sink_id_); | 801 |
813 factory->GetContextFactoryPrivate() | 802 factory->GetContextFactoryPrivate() |
814 ->GetSurfaceManager() | 803 ->GetSurfaceManager() |
815 ->InvalidateFrameSinkId(frame_sink_id_); | 804 ->InvalidateFrameSinkId(frame_sink_id_); |
816 | 805 |
817 DCHECK(!vsync_manager_.get()); | 806 DCHECK(!vsync_manager_.get()); |
818 } | 807 } |
819 | 808 |
820 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { | 809 void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) { |
821 DCHECK(!compositor_); | 810 DCHECK(!compositor_); |
822 if (!compositor) | 811 if (!compositor) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput( | 850 client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput( |
862 std::move(request)); | 851 std::move(request)); |
863 } | 852 } |
864 } | 853 } |
865 | 854 |
866 void DelegatedFrameHost::UnlockResources() { | 855 void DelegatedFrameHost::UnlockResources() { |
867 DCHECK(local_surface_id_.is_valid()); | 856 DCHECK(local_surface_id_.is_valid()); |
868 delegated_frame_evictor_->UnlockFrame(); | 857 delegated_frame_evictor_->UnlockFrame(); |
869 } | 858 } |
870 | 859 |
860 void DelegatedFrameHost::OnNeedsBeginFrames(bool needs_begin_frames) { | |
861 needs_begin_frame_ = needs_begin_frames; | |
862 support_->SetNeedsBeginFrame(needs_begin_frames); | |
863 } | |
864 | |
865 void DelegatedFrameHost::OnDidFinishFrame(const cc::BeginFrameAck& ack) {} | |
866 | |
871 } // namespace content | 867 } // namespace content |
OLD | NEW |