| 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 "cc/surfaces/surface_factory.h" | 14 #include "cc/surfaces/surface_factory.h" |
| 15 #include "content/browser/compositor/resize_lock.h" | 15 #include "content/browser/compositor/resize_lock.h" |
| 16 #include "content/common/gpu/client/gl_helper.h" | 16 #include "content/common/gpu/client/gl_helper.h" |
| 17 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 17 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 18 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
| 19 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
| 20 #include "media/base/video_util.h" | 20 #include "media/base/video_util.h" |
| 21 #include "skia/ext/image_operations.h" | 21 #include "skia/ext/image_operations.h" |
| 22 #include "ui/gfx/frame_time.h" |
| 22 | 23 |
| 23 namespace content { | 24 namespace content { |
| 24 | 25 |
| 25 //////////////////////////////////////////////////////////////////////////////// | 26 //////////////////////////////////////////////////////////////////////////////// |
| 26 // DelegatedFrameHostClient | 27 // DelegatedFrameHostClient |
| 27 | 28 |
| 28 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | 29 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { |
| 29 // On Windows and Linux, holding pointer moves will not help throttling | 30 // On Windows and Linux, holding pointer moves will not help throttling |
| 30 // resizes. | 31 // resizes. |
| 31 // TODO(piman): on Windows we need to block (nested message loop?) the | 32 // TODO(piman): on Windows we need to block (nested message loop?) the |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 // the release of the lock until we've kicked a frame with the new texture, to | 241 // the release of the lock until we've kicked a frame with the new texture, to |
| 241 // avoid resizing the UI before we have a chance to draw a "good" frame. | 242 // avoid resizing the UI before we have a chance to draw a "good" frame. |
| 242 resize_lock_->UnlockCompositor(); | 243 resize_lock_->UnlockCompositor(); |
| 243 ui::Compositor* compositor = client_->GetCompositor(); | 244 ui::Compositor* compositor = client_->GetCompositor(); |
| 244 if (compositor) { | 245 if (compositor) { |
| 245 if (!compositor->HasObserver(this)) | 246 if (!compositor->HasObserver(this)) |
| 246 compositor->AddObserver(this); | 247 compositor->AddObserver(this); |
| 247 } | 248 } |
| 248 } | 249 } |
| 249 | 250 |
| 250 void DelegatedFrameHost::DidReceiveFrameFromRenderer() { | 251 void DelegatedFrameHost::DidReceiveFrameFromRenderer( |
| 251 if (frame_subscriber() && CanCopyToVideoFrame()) { | 252 const gfx::Rect& damage_rect) { |
| 252 const base::TimeTicks present_time = base::TimeTicks::Now(); | 253 if (!frame_subscriber() || !CanCopyToVideoFrame()) |
| 253 scoped_refptr<media::VideoFrame> frame; | 254 return; |
| 254 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; | 255 |
| 255 if (frame_subscriber()->ShouldCaptureFrame(present_time, | 256 const base::TimeTicks now = gfx::FrameTime::Now(); |
| 256 &frame, &callback)) { | 257 base::TimeTicks present_time; |
| 257 CopyFromCompositingSurfaceToVideoFrame( | 258 if (vsync_timebase_.is_null() || vsync_interval_ <= base::TimeDelta()) { |
| 258 gfx::Rect(current_frame_size_in_dip_), | 259 present_time = now; |
| 259 frame, | 260 } else { |
| 260 base::Bind(callback, present_time)); | 261 const int64 intervals_elapsed = (now - vsync_timebase_) / vsync_interval_; |
| 261 } | 262 present_time = vsync_timebase_ + (intervals_elapsed + 1) * vsync_interval_; |
| 263 } |
| 264 |
| 265 scoped_refptr<media::VideoFrame> frame; |
| 266 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |
| 267 if (frame_subscriber()->ShouldCaptureFrame(damage_rect, present_time, |
| 268 &frame, &callback)) { |
| 269 CopyFromCompositingSurfaceToVideoFrame( |
| 270 gfx::Rect(current_frame_size_in_dip_), |
| 271 frame, |
| 272 base::Bind(callback, present_time)); |
| 262 } | 273 } |
| 263 } | 274 } |
| 264 | 275 |
| 265 void DelegatedFrameHost::SwapDelegatedFrame( | 276 void DelegatedFrameHost::SwapDelegatedFrame( |
| 266 uint32 output_surface_id, | 277 uint32 output_surface_id, |
| 267 scoped_ptr<cc::DelegatedFrameData> frame_data, | 278 scoped_ptr<cc::DelegatedFrameData> frame_data, |
| 268 float frame_device_scale_factor, | 279 float frame_device_scale_factor, |
| 269 const std::vector<ui::LatencyInfo>& latency_info) { | 280 const std::vector<ui::LatencyInfo>& latency_info) { |
| 270 RenderWidgetHostImpl* host = client_->GetHost(); | 281 RenderWidgetHostImpl* host = client_->GetHost(); |
| 271 DCHECK(!frame_data->render_pass_list.empty()); | 282 DCHECK(!frame_data->render_pass_list.empty()); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 for (it = skipped_latency_info_list_.begin(); | 405 for (it = skipped_latency_info_list_.begin(); |
| 395 it != skipped_latency_info_list_.end(); | 406 it != skipped_latency_info_list_.end(); |
| 396 ++it) | 407 ++it) |
| 397 compositor->SetLatencyInfo(*it); | 408 compositor->SetLatencyInfo(*it); |
| 398 skipped_latency_info_list_.clear(); | 409 skipped_latency_info_list_.clear(); |
| 399 AddOnCommitCallbackAndDisableLocks( | 410 AddOnCommitCallbackAndDisableLocks( |
| 400 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, | 411 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, |
| 401 AsWeakPtr(), | 412 AsWeakPtr(), |
| 402 output_surface_id)); | 413 output_surface_id)); |
| 403 } | 414 } |
| 404 DidReceiveFrameFromRenderer(); | 415 DidReceiveFrameFromRenderer(damage_rect); |
| 405 if (frame_provider_.get() || !surface_id_.is_null()) | 416 if (frame_provider_.get() || !surface_id_.is_null()) |
| 406 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); | 417 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); |
| 407 // Note: the frame may have been evicted immediately. | 418 // Note: the frame may have been evicted immediately. |
| 408 } | 419 } |
| 409 | 420 |
| 410 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { | 421 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { |
| 411 RenderWidgetHostImpl* host = client_->GetHost(); | 422 RenderWidgetHostImpl* host = client_->GetHost(); |
| 412 cc::CompositorFrameAck ack; | 423 cc::CompositorFrameAck ack; |
| 413 if (!surface_returned_resources_.empty()) | 424 if (!surface_returned_resources_.empty()) |
| 414 ack.resources.swap(surface_returned_resources_); | 425 ack.resources.swap(surface_returned_resources_); |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 // A compositor lock that is part of a resize lock timed out. We | 798 // A compositor lock that is part of a resize lock timed out. We |
| 788 // should display a renderer frame. | 799 // should display a renderer frame. |
| 789 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { | 800 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { |
| 790 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; | 801 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; |
| 791 } | 802 } |
| 792 } | 803 } |
| 793 | 804 |
| 794 void DelegatedFrameHost::OnUpdateVSyncParameters( | 805 void DelegatedFrameHost::OnUpdateVSyncParameters( |
| 795 base::TimeTicks timebase, | 806 base::TimeTicks timebase, |
| 796 base::TimeDelta interval) { | 807 base::TimeDelta interval) { |
| 808 vsync_timebase_ = timebase; |
| 809 vsync_interval_ = interval; |
| 797 RenderWidgetHostImpl* host = client_->GetHost(); | 810 RenderWidgetHostImpl* host = client_->GetHost(); |
| 798 if (client_->IsVisible()) | 811 if (client_->IsVisible()) |
| 799 host->UpdateVSyncParameters(timebase, interval); | 812 host->UpdateVSyncParameters(timebase, interval); |
| 800 } | 813 } |
| 801 | 814 |
| 802 //////////////////////////////////////////////////////////////////////////////// | 815 //////////////////////////////////////////////////////////////////////////////// |
| 803 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 816 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
| 804 | 817 |
| 805 void DelegatedFrameHost::OnLostResources() { | 818 void DelegatedFrameHost::OnLostResources() { |
| 806 RenderWidgetHostImpl* host = client_->GetHost(); | 819 RenderWidgetHostImpl* host = client_->GetHost(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 if (frame_provider_.get()) { | 904 if (frame_provider_.get()) { |
| 892 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 905 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
| 893 current_frame_size_in_dip_); | 906 current_frame_size_in_dip_); |
| 894 } | 907 } |
| 895 if (!surface_id_.is_null()) { | 908 if (!surface_id_.is_null()) { |
| 896 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); | 909 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); |
| 897 } | 910 } |
| 898 } | 911 } |
| 899 | 912 |
| 900 } // namespace content | 913 } // namespace content |
| 901 | |
| OLD | NEW |