Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: content/browser/media/capture/web_contents_video_capture_device.cc

Issue 461443003: Account for DIP when setting the preferred size for tab capture. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add gfx::Screen and gfx::Display fakes for unit test runs on non-Mac platforms. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | content/browser/media/capture/web_contents_video_capture_device_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // Implementation notes: This needs to work on a variety of hardware 5 // Implementation notes: This needs to work on a variety of hardware
6 // configurations where the speed of the CPU and GPU greatly affect overall 6 // configurations where the speed of the CPU and GPU greatly affect overall
7 // performance. Spanning several threads, the process of capturing has been 7 // performance. Spanning several threads, the process of capturing has been
8 // split up into four conceptual stages: 8 // split up into four conceptual stages:
9 // 9 //
10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's 10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #include "content/public/browser/notification_types.h" 73 #include "content/public/browser/notification_types.h"
74 #include "content/public/browser/render_view_host.h" 74 #include "content/public/browser/render_view_host.h"
75 #include "content/public/browser/render_widget_host_view.h" 75 #include "content/public/browser/render_widget_host_view.h"
76 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" 76 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
77 #include "content/public/browser/web_contents_observer.h" 77 #include "content/public/browser/web_contents_observer.h"
78 #include "media/base/video_util.h" 78 #include "media/base/video_util.h"
79 #include "media/video/capture/video_capture_types.h" 79 #include "media/video/capture/video_capture_types.h"
80 #include "skia/ext/image_operations.h" 80 #include "skia/ext/image_operations.h"
81 #include "third_party/skia/include/core/SkBitmap.h" 81 #include "third_party/skia/include/core/SkBitmap.h"
82 #include "third_party/skia/include/core/SkColor.h" 82 #include "third_party/skia/include/core/SkColor.h"
83 #include "ui/gfx/display.h"
84 #include "ui/gfx/geometry/size.h"
85 #include "ui/gfx/geometry/size_conversions.h"
86 #include "ui/gfx/screen.h"
83 87
84 namespace content { 88 namespace content {
85 89
86 namespace { 90 namespace {
87 91
88 // Compute a letterbox region, aligned to even coordinates. 92 // Compute a letterbox region, aligned to even coordinates.
89 gfx::Rect ComputeYV12LetterboxRegion(const gfx::Size& frame_size, 93 gfx::Rect ComputeYV12LetterboxRegion(const gfx::Size& frame_size,
90 const gfx::Size& content_size) { 94 const gfx::Size& content_size) {
91 95
92 gfx::Rect result = media::ComputeLetterboxRegion(gfx::Rect(frame_size), 96 gfx::Rect result = media::ComputeLetterboxRegion(gfx::Rect(frame_size),
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 270
267 virtual void DidNavigateMainFrame( 271 virtual void DidNavigateMainFrame(
268 const LoadCommittedDetails& details, 272 const LoadCommittedDetails& details,
269 const FrameNavigateParams& params) OVERRIDE { 273 const FrameNavigateParams& params) OVERRIDE {
270 RenewFrameSubscription(); 274 RenewFrameSubscription();
271 } 275 }
272 276
273 virtual void WebContentsDestroyed() OVERRIDE; 277 virtual void WebContentsDestroyed() OVERRIDE;
274 278
275 private: 279 private:
280 // Computes the preferred size of the target RenderWidget for optimal capture.
281 gfx::Size ComputeOptimalTargetSize() const;
282
276 // Starts observing the web contents, returning false if lookup fails. 283 // Starts observing the web contents, returning false if lookup fails.
277 bool StartObservingWebContents(); 284 bool StartObservingWebContents();
278 285
279 // Helper function to determine the view that we are currently tracking. 286 // Helper function to determine the view that we are currently tracking.
280 RenderWidgetHost* GetTarget(); 287 RenderWidgetHost* GetTarget() const;
281 288
282 // Response callback for RenderWidgetHost::CopyFromBackingStore(). 289 // Response callback for RenderWidgetHost::CopyFromBackingStore().
283 void DidCopyFromBackingStore( 290 void DidCopyFromBackingStore(
284 const base::TimeTicks& start_time, 291 const base::TimeTicks& start_time,
285 const scoped_refptr<media::VideoFrame>& target, 292 const scoped_refptr<media::VideoFrame>& target,
286 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& 293 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
287 deliver_frame_cb, 294 deliver_frame_cb,
288 bool success, 295 bool success,
289 const SkBitmap& bitmap); 296 const SkBitmap& bitmap);
290 297
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 fitted_size, // Size here is a request not always honored. 675 fitted_size, // Size here is a request not always honored.
669 base::Bind(&WebContentsCaptureMachine::DidCopyFromBackingStore, 676 base::Bind(&WebContentsCaptureMachine::DidCopyFromBackingStore,
670 weak_ptr_factory_.GetWeakPtr(), 677 weak_ptr_factory_.GetWeakPtr(),
671 start_time, 678 start_time,
672 target, 679 target,
673 deliver_frame_cb), 680 deliver_frame_cb),
674 kN32_SkColorType); 681 kN32_SkColorType);
675 } 682 }
676 } 683 }
677 684
685 gfx::Size WebContentsCaptureMachine::ComputeOptimalTargetSize() const {
686 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
687
688 gfx::Size optimal_size = oracle_proxy_->GetCaptureSize();
689
690 // If the ratio between physical and logical pixels is greater than 1:1,
691 // shrink |optimal_size| by that amount. Then, when external code resizes the
692 // render widget to the "preferred size," the widget will be physically
693 // rendered at the exact capture size, thereby eliminating unnecessary scaling
694 // operations in the graphics pipeline.
695 RenderWidgetHost* const rwh = GetTarget();
696 RenderWidgetHostView* const rwhv = rwh ? rwh->GetView() : NULL;
697 if (rwhv) {
698 const gfx::NativeView view = rwhv->GetNativeView();
699 gfx::Screen* const screen = gfx::Screen::GetScreenFor(view);
700 if (screen->IsDIPEnabled()) {
701 const gfx::Display display = screen->GetDisplayNearestWindow(view);
702 const float scale = display.device_scale_factor();
703 if (scale > 1.0f) {
704 const gfx::Size shrunk_size(
705 gfx::ToFlooredSize(gfx::ScaleSize(optimal_size, 1.0f / scale)));
706 if (shrunk_size.width() > 0 && shrunk_size.height() > 0)
707 optimal_size = shrunk_size;
708 }
709 }
710 }
711
712 VLOG(1) << "Computed optimal target size: " << optimal_size.ToString();
713 return optimal_size;
714 }
715
678 bool WebContentsCaptureMachine::StartObservingWebContents() { 716 bool WebContentsCaptureMachine::StartObservingWebContents() {
717 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
718
679 // Look-up the RenderFrameHost and, from that, the WebContents that wraps it. 719 // Look-up the RenderFrameHost and, from that, the WebContents that wraps it.
680 // If successful, begin observing the WebContents instance. 720 // If successful, begin observing the WebContents instance.
681 // 721 //
682 // Why this can be unsuccessful: The request for mirroring originates in a 722 // Why this can be unsuccessful: The request for mirroring originates in a
683 // render process, and this request is based on the current main RenderFrame 723 // render process, and this request is based on the current main RenderFrame
684 // associated with a tab. However, by the time we get up-and-running here, 724 // associated with a tab. However, by the time we get up-and-running here,
685 // there have been multiple back-and-forth IPCs between processes, as well as 725 // there have been multiple back-and-forth IPCs between processes, as well as
686 // a bit of indirection across threads. It's easily possible that, in the 726 // a bit of indirection across threads. It's easily possible that, in the
687 // meantime, the original RenderFrame may have gone away. 727 // meantime, the original RenderFrame may have gone away.
688 Observe(WebContents::FromRenderFrameHost(RenderFrameHost::FromID( 728 Observe(WebContents::FromRenderFrameHost(RenderFrameHost::FromID(
689 initial_render_process_id_, initial_main_render_frame_id_))); 729 initial_render_process_id_, initial_main_render_frame_id_)));
690 DVLOG_IF(1, !web_contents()) 730 DVLOG_IF(1, !web_contents())
691 << "Could not find WebContents associated with main RenderFrameHost " 731 << "Could not find WebContents associated with main RenderFrameHost "
692 << "referenced by render_process_id=" << initial_render_process_id_ 732 << "referenced by render_process_id=" << initial_render_process_id_
693 << ", routing_id=" << initial_main_render_frame_id_; 733 << ", routing_id=" << initial_main_render_frame_id_;
694 734
695 WebContentsImpl* contents = static_cast<WebContentsImpl*>(web_contents()); 735 WebContentsImpl* contents = static_cast<WebContentsImpl*>(web_contents());
696 if (contents) { 736 if (contents) {
697 contents->IncrementCapturerCount(oracle_proxy_->GetCaptureSize()); 737 contents->IncrementCapturerCount(ComputeOptimalTargetSize());
698 fullscreen_widget_id_ = contents->GetFullscreenWidgetRoutingID(); 738 fullscreen_widget_id_ = contents->GetFullscreenWidgetRoutingID();
699 RenewFrameSubscription(); 739 RenewFrameSubscription();
700 return true; 740 return true;
701 } 741 }
702 return false; 742 return false;
703 } 743 }
704 744
705 void WebContentsCaptureMachine::WebContentsDestroyed() { 745 void WebContentsCaptureMachine::WebContentsDestroyed() {
706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 746 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
707 747
708 subscription_.reset(); 748 subscription_.reset();
709 web_contents()->DecrementCapturerCount(); 749 web_contents()->DecrementCapturerCount();
710 oracle_proxy_->ReportError("WebContentsDestroyed()"); 750 oracle_proxy_->ReportError("WebContentsDestroyed()");
711 } 751 }
712 752
713 RenderWidgetHost* WebContentsCaptureMachine::GetTarget() { 753 RenderWidgetHost* WebContentsCaptureMachine::GetTarget() const {
714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 754 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
715 if (!web_contents()) 755 if (!web_contents())
716 return NULL; 756 return NULL;
717 757
718 RenderWidgetHost* rwh = NULL; 758 RenderWidgetHost* rwh = NULL;
719 if (fullscreen_widget_id_ != MSG_ROUTING_NONE) { 759 if (fullscreen_widget_id_ != MSG_ROUTING_NONE) {
720 RenderProcessHost* process = web_contents()->GetRenderProcessHost(); 760 RenderProcessHost* process = web_contents()->GetRenderProcessHost();
721 if (process) 761 if (process)
722 rwh = RenderWidgetHost::FromID(process->GetID(), fullscreen_widget_id_); 762 rwh = RenderWidgetHost::FromID(process->GetID(), fullscreen_widget_id_);
723 } else { 763 } else {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 scoped_ptr<Client> client) { 856 scoped_ptr<Client> client) {
817 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 857 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
818 core_->AllocateAndStart(params, client.Pass()); 858 core_->AllocateAndStart(params, client.Pass());
819 } 859 }
820 860
821 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { 861 void WebContentsVideoCaptureDevice::StopAndDeAllocate() {
822 core_->StopAndDeAllocate(); 862 core_->StopAndDeAllocate();
823 } 863 }
824 864
825 } // namespace content 865 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/media/capture/web_contents_video_capture_device_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698