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 209 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 for (it = skipped_latency_info_list_.begin(); | 406 for (it = skipped_latency_info_list_.begin(); |
396 it != skipped_latency_info_list_.end(); | 407 it != skipped_latency_info_list_.end(); |
397 ++it) | 408 ++it) |
398 compositor->SetLatencyInfo(*it); | 409 compositor->SetLatencyInfo(*it); |
399 skipped_latency_info_list_.clear(); | 410 skipped_latency_info_list_.clear(); |
400 AddOnCommitCallbackAndDisableLocks( | 411 AddOnCommitCallbackAndDisableLocks( |
401 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, | 412 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, |
402 AsWeakPtr(), | 413 AsWeakPtr(), |
403 output_surface_id)); | 414 output_surface_id)); |
404 } | 415 } |
405 DidReceiveFrameFromRenderer(); | 416 DidReceiveFrameFromRenderer(damage_rect); |
406 if (frame_provider_.get() || !surface_id_.is_null()) | 417 if (frame_provider_.get() || !surface_id_.is_null()) |
407 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); | 418 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); |
408 // Note: the frame may have been evicted immediately. | 419 // Note: the frame may have been evicted immediately. |
409 } | 420 } |
410 | 421 |
411 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { | 422 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { |
412 RenderWidgetHostImpl* host = client_->GetHost(); | 423 RenderWidgetHostImpl* host = client_->GetHost(); |
413 cc::CompositorFrameAck ack; | 424 cc::CompositorFrameAck ack; |
414 if (!surface_returned_resources_.empty()) | 425 if (!surface_returned_resources_.empty()) |
415 ack.resources.swap(surface_returned_resources_); | 426 ack.resources.swap(surface_returned_resources_); |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 // A compositor lock that is part of a resize lock timed out. We | 799 // A compositor lock that is part of a resize lock timed out. We |
789 // should display a renderer frame. | 800 // should display a renderer frame. |
790 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { | 801 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { |
791 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; | 802 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; |
792 } | 803 } |
793 } | 804 } |
794 | 805 |
795 void DelegatedFrameHost::OnUpdateVSyncParameters( | 806 void DelegatedFrameHost::OnUpdateVSyncParameters( |
796 base::TimeTicks timebase, | 807 base::TimeTicks timebase, |
797 base::TimeDelta interval) { | 808 base::TimeDelta interval) { |
| 809 vsync_timebase_ = timebase; |
| 810 vsync_interval_ = interval; |
798 RenderWidgetHostImpl* host = client_->GetHost(); | 811 RenderWidgetHostImpl* host = client_->GetHost(); |
799 if (client_->IsVisible()) | 812 if (client_->IsVisible()) |
800 host->UpdateVSyncParameters(timebase, interval); | 813 host->UpdateVSyncParameters(timebase, interval); |
801 } | 814 } |
802 | 815 |
803 //////////////////////////////////////////////////////////////////////////////// | 816 //////////////////////////////////////////////////////////////////////////////// |
804 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 817 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
805 | 818 |
806 void DelegatedFrameHost::OnLostResources() { | 819 void DelegatedFrameHost::OnLostResources() { |
807 RenderWidgetHostImpl* host = client_->GetHost(); | 820 RenderWidgetHostImpl* host = client_->GetHost(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 if (frame_provider_.get()) { | 905 if (frame_provider_.get()) { |
893 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 906 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
894 current_frame_size_in_dip_); | 907 current_frame_size_in_dip_); |
895 } | 908 } |
896 if (!surface_id_.is_null()) { | 909 if (!surface_id_.is_null()) { |
897 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); | 910 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); |
898 } | 911 } |
899 } | 912 } |
900 | 913 |
901 } // namespace content | 914 } // namespace content |
902 | |
OLD | NEW |