| 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/compositor/delegated_frame_host.h" | 5 #include "content/browser/compositor/delegated_frame_host.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "cc/output/compositor_frame.h" | 9 #include "cc/output/compositor_frame.h" |
| 10 #include "cc/output/compositor_frame_ack.h" | 10 #include "cc/output/compositor_frame_ack.h" |
| 11 #include "cc/output/copy_output_request.h" | 11 #include "cc/output/copy_output_request.h" |
| 12 #include "cc/resources/single_release_callback.h" | 12 #include "cc/resources/single_release_callback.h" |
| 13 #include "cc/resources/texture_mailbox.h" | 13 #include "cc/resources/texture_mailbox.h" |
| 14 #include "content/browser/compositor/resize_lock.h" | 14 #include "content/browser/compositor/resize_lock.h" |
| 15 #include "content/common/gpu/client/gl_helper.h" | 15 #include "content/common/gpu/client/gl_helper.h" |
| 16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 17 #include "content/public/common/content_switches.h" | 17 #include "content/public/common/content_switches.h" |
| 18 #include "media/base/video_frame.h" | 18 #include "media/base/video_frame.h" |
| 19 #include "media/base/video_util.h" | 19 #include "media/base/video_util.h" |
| 20 #include "skia/ext/image_operations.h" | 20 #include "skia/ext/image_operations.h" |
| 21 #include "ui/gfx/frame_time.h" |
| 21 | 22 |
| 22 namespace content { | 23 namespace content { |
| 23 | 24 |
| 24 //////////////////////////////////////////////////////////////////////////////// | 25 //////////////////////////////////////////////////////////////////////////////// |
| 25 // DelegatedFrameHostClient | 26 // DelegatedFrameHostClient |
| 26 | 27 |
| 27 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | 28 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { |
| 28 // On Windows and Linux, holding pointer moves will not help throttling | 29 // On Windows and Linux, holding pointer moves will not help throttling |
| 29 // resizes. | 30 // resizes. |
| 30 // TODO(piman): on Windows we need to block (nested message loop?) the | 31 // TODO(piman): on Windows we need to block (nested message loop?) the |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 // the release of the lock until we've kicked a frame with the new texture, to | 242 // the release of the lock until we've kicked a frame with the new texture, to |
| 242 // avoid resizing the UI before we have a chance to draw a "good" frame. | 243 // avoid resizing the UI before we have a chance to draw a "good" frame. |
| 243 resize_lock_->UnlockCompositor(); | 244 resize_lock_->UnlockCompositor(); |
| 244 ui::Compositor* compositor = client_->GetCompositor(); | 245 ui::Compositor* compositor = client_->GetCompositor(); |
| 245 if (compositor) { | 246 if (compositor) { |
| 246 if (!compositor->HasObserver(this)) | 247 if (!compositor->HasObserver(this)) |
| 247 compositor->AddObserver(this); | 248 compositor->AddObserver(this); |
| 248 } | 249 } |
| 249 } | 250 } |
| 250 | 251 |
| 251 void DelegatedFrameHost::DidReceiveFrameFromRenderer() { | 252 void DelegatedFrameHost::DidReceiveFrameFromRenderer( |
| 252 if (frame_subscriber() && CanCopyToVideoFrame()) { | 253 const gfx::Rect& damage_rect) { |
| 253 const base::TimeTicks present_time = base::TimeTicks::Now(); | 254 if (!frame_subscriber() || !CanCopyToVideoFrame()) |
| 254 scoped_refptr<media::VideoFrame> frame; | 255 return; |
| 255 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; | 256 |
| 256 if (frame_subscriber()->ShouldCaptureFrame(present_time, | 257 const base::TimeTicks now = gfx::FrameTime::Now(); |
| 257 &frame, &callback)) { | 258 base::TimeTicks present_time; |
| 258 CopyFromCompositingSurfaceToVideoFrame( | 259 if (vsync_timebase_.is_null() || vsync_interval_ <= base::TimeDelta()) { |
| 259 gfx::Rect(current_frame_size_in_dip_), | 260 present_time = now; |
| 260 frame, | 261 } else { |
| 261 base::Bind(callback, present_time)); | 262 const int64 intervals_elapsed = (now - vsync_timebase_) / vsync_interval_; |
| 262 } | 263 present_time = vsync_timebase_ + (intervals_elapsed + 1) * vsync_interval_; |
| 264 } |
| 265 |
| 266 scoped_refptr<media::VideoFrame> frame; |
| 267 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |
| 268 if (frame_subscriber()->ShouldCaptureFrame(damage_rect, present_time, |
| 269 &frame, &callback)) { |
| 270 CopyFromCompositingSurfaceToVideoFrame( |
| 271 gfx::Rect(current_frame_size_in_dip_), |
| 272 frame, |
| 273 base::Bind(callback, present_time)); |
| 263 } | 274 } |
| 264 } | 275 } |
| 265 | 276 |
| 266 void DelegatedFrameHost::SwapDelegatedFrame( | 277 void DelegatedFrameHost::SwapDelegatedFrame( |
| 267 uint32 output_surface_id, | 278 uint32 output_surface_id, |
| 268 scoped_ptr<cc::DelegatedFrameData> frame_data, | 279 scoped_ptr<cc::DelegatedFrameData> frame_data, |
| 269 float frame_device_scale_factor, | 280 float frame_device_scale_factor, |
| 270 const std::vector<ui::LatencyInfo>& latency_info) { | 281 const std::vector<ui::LatencyInfo>& latency_info) { |
| 271 RenderWidgetHostImpl* host = client_->GetHost(); | 282 RenderWidgetHostImpl* host = client_->GetHost(); |
| 272 DCHECK(!frame_data->render_pass_list.empty()); | 283 DCHECK(!frame_data->render_pass_list.empty()); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 for (it = skipped_latency_info_list_.begin(); | 382 for (it = skipped_latency_info_list_.begin(); |
| 372 it != skipped_latency_info_list_.end(); | 383 it != skipped_latency_info_list_.end(); |
| 373 ++it) | 384 ++it) |
| 374 compositor->SetLatencyInfo(*it); | 385 compositor->SetLatencyInfo(*it); |
| 375 skipped_latency_info_list_.clear(); | 386 skipped_latency_info_list_.clear(); |
| 376 AddOnCommitCallbackAndDisableLocks( | 387 AddOnCommitCallbackAndDisableLocks( |
| 377 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, | 388 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, |
| 378 AsWeakPtr(), | 389 AsWeakPtr(), |
| 379 output_surface_id)); | 390 output_surface_id)); |
| 380 } | 391 } |
| 381 DidReceiveFrameFromRenderer(); | 392 DidReceiveFrameFromRenderer(damage_rect); |
| 382 if (frame_provider_.get()) | 393 if (frame_provider_.get()) |
| 383 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); | 394 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); |
| 384 // Note: the frame may have been evicted immediately. | 395 // Note: the frame may have been evicted immediately. |
| 385 } | 396 } |
| 386 | 397 |
| 387 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { | 398 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { |
| 388 RenderWidgetHostImpl* host = client_->GetHost(); | 399 RenderWidgetHostImpl* host = client_->GetHost(); |
| 389 cc::CompositorFrameAck ack; | 400 cc::CompositorFrameAck ack; |
| 390 if (resource_collection_) | 401 if (resource_collection_) |
| 391 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 402 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 // A compositor lock that is part of a resize lock timed out. We | 754 // A compositor lock that is part of a resize lock timed out. We |
| 744 // should display a renderer frame. | 755 // should display a renderer frame. |
| 745 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { | 756 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { |
| 746 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; | 757 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; |
| 747 } | 758 } |
| 748 } | 759 } |
| 749 | 760 |
| 750 void DelegatedFrameHost::OnUpdateVSyncParameters( | 761 void DelegatedFrameHost::OnUpdateVSyncParameters( |
| 751 base::TimeTicks timebase, | 762 base::TimeTicks timebase, |
| 752 base::TimeDelta interval) { | 763 base::TimeDelta interval) { |
| 764 vsync_timebase_ = timebase; |
| 765 vsync_interval_ = interval; |
| 753 RenderWidgetHostImpl* host = client_->GetHost(); | 766 RenderWidgetHostImpl* host = client_->GetHost(); |
| 754 if (client_->IsVisible()) | 767 if (client_->IsVisible()) |
| 755 host->UpdateVSyncParameters(timebase, interval); | 768 host->UpdateVSyncParameters(timebase, interval); |
| 756 } | 769 } |
| 757 | 770 |
| 758 //////////////////////////////////////////////////////////////////////////////// | 771 //////////////////////////////////////////////////////////////////////////////// |
| 759 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 772 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
| 760 | 773 |
| 761 void DelegatedFrameHost::OnLostResources() { | 774 void DelegatedFrameHost::OnLostResources() { |
| 762 RenderWidgetHostImpl* host = client_->GetHost(); | 775 RenderWidgetHostImpl* host = client_->GetHost(); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 // The new_layer is the one that will be used by our Window, so that's the one | 855 // The new_layer is the one that will be used by our Window, so that's the one |
| 843 // that should keep our frame. old_layer will be returned to the | 856 // that should keep our frame. old_layer will be returned to the |
| 844 // RecreateLayer caller, and should have a copy. | 857 // RecreateLayer caller, and should have a copy. |
| 845 if (frame_provider_.get()) { | 858 if (frame_provider_.get()) { |
| 846 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 859 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
| 847 current_frame_size_in_dip_); | 860 current_frame_size_in_dip_); |
| 848 } | 861 } |
| 849 } | 862 } |
| 850 | 863 |
| 851 } // namespace content | 864 } // namespace content |
| 852 | |
| OLD | NEW |