1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/command_line.h"
6 #include "base/message_loop/message_loop_proxy.h"
7 #include "base/path_service.h"
8 #include "base/run_loop.h"
9 #include "content/browser/gpu/compositor_util.h"
10 #include "content/browser/gpu/gpu_data_manager_impl.h"
11 #include "content/browser/renderer_host/dip_util.h"
12 #include "content/browser/renderer_host/render_widget_host_impl.h"
13 #include "content/browser/renderer_host/render_widget_host_view_base.h"
14 #include "content/public/browser/gpu_data_manager.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/common/content_paths.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/common/url_constants.h"
21 #include "content/public/test/browser_test_utils.h"
22 #include "content/public/test/content_browser_test.h"
23 #include "content/public/test/content_browser_test_utils.h"
24 #include "content/shell/browser/shell.h"
25 #include "media/base/video_frame.h"
26 #include "media/filters/skcanvas_video_renderer.h"
27 #include "net/base/filename_util.h"
28 #include "third_party/skia/include/core/SkBitmap.h"
29 #include "third_party/skia/include/core/SkCanvas.h"
30 #include "ui/base/layout.h"
31 #include "ui/base/ui_base_switches.h"
32 #include "ui/gfx/geometry/size_conversions.h"
33 #include "ui/gfx/switches.h"
34 #include "ui/gl/gl_switches.h"
37 #include "base/win/windows_version.h"
38 #include "ui/gfx/win/dpi.h"
44 // Convenience macro: Short-circuit a pass for the tests where platform support
45 // for forced-compositing mode (or disabled-compositing mode) is lacking.
46 #define SET_UP_SURFACE_OR_PASS_TEST(wait_message) \
47 if (!SetUpSourceSurface(wait_message)) { \
49 << ("Blindly passing this test: This platform does not support " \
50 "forced compositing (or forced-disabled compositing) mode."); \
54 // Common base class for browser tests. This is subclassed twice: Once to test
55 // the browser in forced-compositing mode, and once to test with compositing
57 class RenderWidgetHostViewBrowserTest
: public ContentBrowserTest
{
59 RenderWidgetHostViewBrowserTest()
60 : frame_size_(400, 300),
61 callback_invoke_count_(0),
62 frames_captured_(0) {}
64 virtual void SetUpOnMainThread() OVERRIDE
{
65 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA
, &test_dir_
));
68 // Attempts to set up the source surface. Returns false if unsupported on the
70 virtual bool SetUpSourceSurface(const char* wait_message
) = 0;
72 int callback_invoke_count() const {
73 return callback_invoke_count_
;
76 int frames_captured() const {
77 return frames_captured_
;
80 const gfx::Size
& frame_size() const {
84 const base::FilePath
& test_dir() const {
88 RenderViewHost
* GetRenderViewHost() const {
89 RenderViewHost
* const rvh
= shell()->web_contents()->GetRenderViewHost();
94 RenderWidgetHostImpl
* GetRenderWidgetHost() const {
95 RenderWidgetHostImpl
* const rwh
= RenderWidgetHostImpl::From(
96 shell()->web_contents()->GetRenderWidgetHostView()->
97 GetRenderWidgetHost());
102 RenderWidgetHostViewBase
* GetRenderWidgetHostView() const {
103 return static_cast<RenderWidgetHostViewBase
*>(
104 GetRenderViewHost()->GetView());
107 // Callback when using CopyFromBackingStore() API.
108 void FinishCopyFromBackingStore(const base::Closure
& quit_closure
,
110 const SkBitmap
& bitmap
) {
111 ++callback_invoke_count_
;
112 if (frame_captured
) {
114 EXPECT_FALSE(bitmap
.empty());
116 if (!quit_closure
.is_null())
120 // Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
121 void FinishCopyFromCompositingSurface(const base::Closure
& quit_closure
,
122 bool frame_captured
) {
123 ++callback_invoke_count_
;
126 if (!quit_closure
.is_null())
130 // Callback when using frame subscriber API.
131 void FrameDelivered(const scoped_refptr
<base::MessageLoopProxy
>& loop
,
132 base::Closure quit_closure
,
133 base::TimeTicks timestamp
,
134 bool frame_captured
) {
135 ++callback_invoke_count_
;
138 if (!quit_closure
.is_null())
139 loop
->PostTask(FROM_HERE
, quit_closure
);
142 // Copy one frame using the CopyFromBackingStore API.
143 void RunBasicCopyFromBackingStoreTest() {
144 SET_UP_SURFACE_OR_PASS_TEST(NULL
);
146 // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
147 // Windows), the operation will fail until the first "present" has been
149 int count_attempts
= 0;
152 base::RunLoop run_loop
;
153 GetRenderViewHost()->CopyFromBackingStore(
157 &RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore
,
158 base::Unretained(this),
159 run_loop
.QuitClosure()),
163 if (frames_captured())
169 EXPECT_EQ(count_attempts
, callback_invoke_count());
170 EXPECT_EQ(1, frames_captured());
174 // Waits until the source is available for copying.
175 void WaitForCopySourceReady() {
176 while (!GetRenderWidgetHostView()->IsSurfaceAvailableForCopy())
180 // Run the current message loop for a short time without unwinding the current
182 static void GiveItSomeTime() {
183 base::RunLoop run_loop
;
184 base::MessageLoop::current()->PostDelayedTask(
186 run_loop
.QuitClosure(),
187 base::TimeDelta::FromMilliseconds(10));
192 const gfx::Size frame_size_
;
193 base::FilePath test_dir_
;
194 int callback_invoke_count_
;
195 int frames_captured_
;
198 enum CompositingMode
{
200 SOFTWARE_COMPOSITING
,
203 class CompositingRenderWidgetHostViewBrowserTest
204 : public RenderWidgetHostViewBrowserTest
,
205 public testing::WithParamInterface
<CompositingMode
> {
207 explicit CompositingRenderWidgetHostViewBrowserTest()
208 : compositing_mode_(GetParam()) {}
210 virtual void SetUp() OVERRIDE
{
211 if (compositing_mode_
== SOFTWARE_COMPOSITING
)
212 UseSoftwareCompositing();
213 RenderWidgetHostViewBrowserTest::SetUp();
216 virtual GURL
TestUrl() {
217 return net::FilePathToFileURL(
218 test_dir().AppendASCII("rwhv_compositing_animation.html"));
221 virtual bool SetUpSourceSurface(const char* wait_message
) OVERRIDE
{
222 content::DOMMessageQueue message_queue
;
223 NavigateToURL(shell(), TestUrl());
224 if (wait_message
!= NULL
) {
225 std::string
result(wait_message
);
226 if (!message_queue
.WaitForMessage(&result
)) {
227 EXPECT_TRUE(false) << "WaitForMessage " << result
<< " failed.";
232 // A frame might not be available yet. So, wait for it.
233 WaitForCopySourceReady();
238 const CompositingMode compositing_mode_
;
240 DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewBrowserTest
);
243 class FakeFrameSubscriber
: public RenderWidgetHostViewFrameSubscriber
{
246 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback
)
247 : callback_(callback
) {
250 virtual bool ShouldCaptureFrame(const gfx::Rect
& damage_rect
,
251 base::TimeTicks present_time
,
252 scoped_refptr
<media::VideoFrame
>* storage
,
253 DeliverFrameCallback
* callback
) OVERRIDE
{
254 // Only allow one frame capture to be made. Otherwise, the compositor could
255 // start multiple captures, unbounded, and eventually its own limiter logic
256 // will begin invoking |callback| with a |false| result. This flakes out
257 // the unit tests, since they receive a "failed" callback before the later
258 // "success" callbacks.
259 if (callback_
.is_null())
261 *storage
= media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100));
262 *callback
= callback_
;
268 DeliverFrameCallback callback_
;
271 // Disable tests for Android and IOS as these platforms have incomplete
273 #if !defined(OS_ANDROID) && !defined(OS_IOS)
275 // The CopyFromBackingStore() API should work on all platforms when compositing
277 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest
,
278 CopyFromBackingStore
) {
279 RunBasicCopyFromBackingStoreTest();
282 // Tests that the callback passed to CopyFromBackingStore is always called,
283 // even when the RenderWidgetHost is deleting in the middle of an async copy.
284 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest
,
285 CopyFromBackingStore_CallbackDespiteDelete
) {
286 SET_UP_SURFACE_OR_PASS_TEST(NULL
);
288 base::RunLoop run_loop
;
289 GetRenderViewHost()->CopyFromBackingStore(
292 base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore
,
293 base::Unretained(this),
294 run_loop
.QuitClosure()),
296 // Delete the surface before the callback is run.
297 GetRenderWidgetHostView()->AcceleratedSurfaceRelease();
300 EXPECT_EQ(1, callback_invoke_count());
303 // Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
304 // always called, even when the RenderWidgetHost is deleting in the middle of
307 // Test is flaky on Win. http://crbug.com/276783
308 #if defined(OS_WIN) || (defined(OS_CHROMEOS) && !defined(NDEBUG))
309 #define MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete \
310 DISABLED_CopyFromCompositingSurface_CallbackDespiteDelete
312 #define MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete \
313 CopyFromCompositingSurface_CallbackDespiteDelete
315 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest
,
316 MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete
) {
317 SET_UP_SURFACE_OR_PASS_TEST(NULL
);
318 RenderWidgetHostViewBase
* const view
= GetRenderWidgetHostView();
319 if (!view
->CanCopyToVideoFrame()) {
321 ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
322 "not supported on this platform.");
326 base::RunLoop run_loop
;
327 scoped_refptr
<media::VideoFrame
> dest
=
328 media::VideoFrame::CreateBlackFrame(frame_size());
329 view
->CopyFromCompositingSurfaceToVideoFrame(
330 gfx::Rect(view
->GetViewBounds().size()), dest
, base::Bind(
331 &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface
,
332 base::Unretained(this), run_loop
.QuitClosure()));
333 // Delete the surface before the callback is run.
334 view
->AcceleratedSurfaceRelease();
337 EXPECT_EQ(1, callback_invoke_count());
340 // Test basic frame subscription functionality. We subscribe, and then run
341 // until at least one DeliverFrameCallback has been invoked.
342 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest
,
343 FrameSubscriberTest
) {
344 SET_UP_SURFACE_OR_PASS_TEST(NULL
);
345 RenderWidgetHostViewBase
* const view
= GetRenderWidgetHostView();
346 if (!view
->CanSubscribeFrame()) {
347 LOG(WARNING
) << ("Blindly passing this test: Frame subscription not "
348 "supported on this platform.");
352 base::RunLoop run_loop
;
353 scoped_ptr
<RenderWidgetHostViewFrameSubscriber
> subscriber(
354 new FakeFrameSubscriber(
355 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered
,
356 base::Unretained(this),
357 base::MessageLoopProxy::current(),
358 run_loop
.QuitClosure())));
359 view
->BeginFrameSubscription(subscriber
.Pass());
361 view
->EndFrameSubscription();
363 EXPECT_LE(1, callback_invoke_count());
364 EXPECT_LE(1, frames_captured());
367 // Test that we can copy twice from an accelerated composited page.
368 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest
, CopyTwice
) {
369 SET_UP_SURFACE_OR_PASS_TEST(NULL
);
370 RenderWidgetHostViewBase
* const view
= GetRenderWidgetHostView();
371 if (!view
->CanCopyToVideoFrame()) {
372 LOG(WARNING
) << ("Blindly passing this test: "
373 "CopyFromCompositingSurfaceToVideoFrame() not supported "
374 "on this platform.");
378 base::RunLoop run_loop
;
379 scoped_refptr
<media::VideoFrame
> first_output
=
380 media::VideoFrame::CreateBlackFrame(frame_size());
381 ASSERT_TRUE(first_output
.get());
382 scoped_refptr
<media::VideoFrame
> second_output
=
383 media::VideoFrame::CreateBlackFrame(frame_size());
384 ASSERT_TRUE(second_output
.get());
385 view
->CopyFromCompositingSurfaceToVideoFrame(
386 gfx::Rect(view
->GetViewBounds().size()),
388 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered
,
389 base::Unretained(this),
390 base::MessageLoopProxy::current(),
392 base::TimeTicks::Now()));
393 view
->CopyFromCompositingSurfaceToVideoFrame(
394 gfx::Rect(view
->GetViewBounds().size()),
396 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered
,
397 base::Unretained(this),
398 base::MessageLoopProxy::current(),
399 run_loop
.QuitClosure(),
400 base::TimeTicks::Now()));
403 EXPECT_EQ(2, callback_invoke_count());
404 EXPECT_EQ(2, frames_captured());
407 class CompositingRenderWidgetHostViewBrowserTestTabCapture
408 : public CompositingRenderWidgetHostViewBrowserTest
{
410 CompositingRenderWidgetHostViewBrowserTestTabCapture()
411 : expected_copy_from_compositing_surface_result_(false),
413 test_url_("data:text/html,<!doctype html>") {}
415 virtual void SetUp() OVERRIDE
{
417 CompositingRenderWidgetHostViewBrowserTest::SetUp();
420 void CopyFromCompositingSurfaceCallback(base::Closure quit_callback
,
422 const SkBitmap
& bitmap
) {
423 EXPECT_EQ(expected_copy_from_compositing_surface_result_
, result
);
429 const SkBitmap
& expected_bitmap
=
430 expected_copy_from_compositing_surface_bitmap_
;
431 EXPECT_EQ(expected_bitmap
.width(), bitmap
.width());
432 EXPECT_EQ(expected_bitmap
.height(), bitmap
.height());
433 EXPECT_EQ(expected_bitmap
.colorType(), bitmap
.colorType());
434 SkAutoLockPixels
expected_bitmap_lock(expected_bitmap
);
435 SkAutoLockPixels
bitmap_lock(bitmap
);
437 for (int i
= 0; i
< bitmap
.width() && fails
< 10; ++i
) {
438 for (int j
= 0; j
< bitmap
.height() && fails
< 10; ++j
) {
439 if (!exclude_rect_
.IsEmpty() && exclude_rect_
.Contains(i
, j
))
442 SkColor expected_color
= expected_bitmap
.getColor(i
, j
);
443 SkColor color
= bitmap
.getColor(i
, j
);
444 int expected_alpha
= SkColorGetA(expected_color
);
445 int alpha
= SkColorGetA(color
);
446 int expected_red
= SkColorGetR(expected_color
);
447 int red
= SkColorGetR(color
);
448 int expected_green
= SkColorGetG(expected_color
);
449 int green
= SkColorGetG(color
);
450 int expected_blue
= SkColorGetB(expected_color
);
451 int blue
= SkColorGetB(color
);
452 EXPECT_NEAR(expected_alpha
, alpha
, allowable_error_
)
453 << "expected_color: " << std::hex
<< expected_color
454 << " color: " << color
455 << " Failed at " << std::dec
<< i
<< ", " << j
456 << " Failure " << ++fails
;
457 EXPECT_NEAR(expected_red
, red
, allowable_error_
)
458 << "expected_color: " << std::hex
<< expected_color
459 << " color: " << color
460 << " Failed at " << std::dec
<< i
<< ", " << j
461 << " Failure " << ++fails
;
462 EXPECT_NEAR(expected_green
, green
, allowable_error_
)
463 << "expected_color: " << std::hex
<< expected_color
464 << " color: " << color
465 << " Failed at " << std::dec
<< i
<< ", " << j
466 << " Failure " << ++fails
;
467 EXPECT_NEAR(expected_blue
, blue
, allowable_error_
)
468 << "expected_color: " << std::hex
<< expected_color
469 << " color: " << color
470 << " Failed at " << std::dec
<< i
<< ", " << j
471 << " Failure " << ++fails
;
474 EXPECT_LT(fails
, 10);
479 void CopyFromCompositingSurfaceCallbackForVideo(
480 scoped_refptr
<media::VideoFrame
> video_frame
,
481 base::Closure quit_callback
,
483 EXPECT_EQ(expected_copy_from_compositing_surface_result_
, result
);
489 media::SkCanvasVideoRenderer video_renderer
;
492 bitmap
.allocN32Pixels(video_frame
->visible_rect().width(),
493 video_frame
->visible_rect().height());
494 // Don't clear the canvas because drawing a video frame by Src mode.
495 SkCanvas
canvas(bitmap
);
496 video_renderer
.Copy(video_frame
.get(), &canvas
);
498 CopyFromCompositingSurfaceCallback(quit_callback
,
503 void SetExpectedCopyFromCompositingSurfaceResult(bool result
,
504 const SkBitmap
& bitmap
) {
505 expected_copy_from_compositing_surface_result_
= result
;
506 expected_copy_from_compositing_surface_bitmap_
= bitmap
;
509 void SetAllowableError(int amount
) { allowable_error_
= amount
; }
510 void SetExcludeRect(gfx::Rect exclude
) { exclude_rect_
= exclude
; }
512 virtual GURL
TestUrl() OVERRIDE
{
513 return GURL(test_url_
);
516 void SetTestUrl(std::string url
) { test_url_
= url
; }
518 // Loads a page two boxes side-by-side, each half the width of
519 // |html_rect_size|, and with different background colors. The test then
520 // copies from |copy_rect| region of the page into a bitmap of size
521 // |output_size|, and examines the resulting bitmap/VideoFrame.
522 // Note that |output_size| may not have the same size as |copy_rect| (e.g.
523 // when the output is scaled).
524 void PerformTestWithLeftRightRects(const gfx::Size
& html_rect_size
,
525 const gfx::Rect
& copy_rect
,
526 const gfx::Size
& output_size
,
528 const gfx::Size
box_size(html_rect_size
.width() / 2,
529 html_rect_size
.height());
530 SetTestUrl(base::StringPrintf(
531 "data:text/html,<!doctype html>"
533 " <div class='right'></div>"
536 "body { padding: 0; margin: 0; }"
537 ".left { position: absolute;"
542 ".right { position: absolute;"
550 " domAutomationController.setAutomationId(0);"
551 " domAutomationController.send(\"DONE\");"
559 SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
560 if (!ShouldContinueAfterTestURLLoad())
563 RenderWidgetHostViewBase
* rwhvp
= GetRenderWidgetHostView();
564 if (video_frame
&& !rwhvp
->CanCopyToVideoFrame()) {
565 // This should only happen on Mac when using the software compositor.
566 // Otherwise, raise an error. This can be removed when Mac is moved to a
567 // browser compositor.
568 // http://crbug.com/314190
569 #if defined(OS_MACOSX)
570 if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL
)) {
571 LOG(WARNING
) << ("Blindly passing this test because copying to "
572 "video frames is not supported on this platform.");
579 // The page is loaded in the renderer, wait for a new frame to arrive.
580 uint32 frame
= rwhvp
->RendererFrameNumber();
581 while (!GetRenderWidgetHost()->ScheduleComposite())
583 while (rwhvp
->RendererFrameNumber() == frame
)
586 SkBitmap expected_bitmap
;
587 SetupLeftRightBitmap(output_size
, &expected_bitmap
);
588 SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap
);
590 base::RunLoop run_loop
;
592 // Allow pixel differences as long as we have the right idea.
593 SetAllowableError(0x10);
594 // Exclude the middle two columns which are blended between the two sides.
596 gfx::Rect(output_size
.width() / 2 - 1, 0, 2, output_size
.height()));
598 scoped_refptr
<media::VideoFrame
> video_frame
=
599 media::VideoFrame::CreateFrame(media::VideoFrame::YV12
,
601 gfx::Rect(output_size
),
605 base::Callback
<void(bool success
)> callback
=
606 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
607 CopyFromCompositingSurfaceCallbackForVideo
,
608 base::Unretained(this),
610 run_loop
.QuitClosure());
611 rwhvp
->CopyFromCompositingSurfaceToVideoFrame(copy_rect
,
615 if (IsDelegatedRendererEnabled()) {
616 if (!content::GpuDataManager::GetInstance()
617 ->CanUseGpuBrowserCompositor()) {
618 // Skia rendering can cause color differences, particularly in the
619 // middle two columns.
620 SetAllowableError(2);
621 SetExcludeRect(gfx::Rect(
622 output_size
.width() / 2 - 1, 0, 2, output_size
.height()));
626 base::Callback
<void(bool, const SkBitmap
&)> callback
=
627 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
628 CopyFromCompositingSurfaceCallback
,
629 base::Unretained(this),
630 run_loop
.QuitClosure());
631 rwhvp
->CopyFromCompositingSurface(copy_rect
,
639 // Sets up |bitmap| to have size |copy_size|. It floods the left half with
640 // #0ff and the right half with #ff0.
641 void SetupLeftRightBitmap(const gfx::Size
& copy_size
, SkBitmap
* bitmap
) {
642 bitmap
->allocN32Pixels(copy_size
.width(), copy_size
.height());
643 // Left half is #0ff.
644 bitmap
->eraseARGB(255, 0, 255, 255);
645 // Right half is #ff0.
647 SkAutoLockPixels
lock(*bitmap
);
648 for (int i
= 0; i
< copy_size
.width() / 2; ++i
) {
649 for (int j
= 0; j
< copy_size
.height(); ++j
) {
650 *(bitmap
->getAddr32(copy_size
.width() / 2 + i
, j
)) =
651 SkColorSetARGB(255, 255, 255, 0);
658 virtual bool ShouldContinueAfterTestURLLoad() {
663 bool expected_copy_from_compositing_surface_result_
;
664 SkBitmap expected_copy_from_compositing_surface_bitmap_
;
665 int allowable_error_
;
666 gfx::Rect exclude_rect_
;
667 std::string test_url_
;
670 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture
,
671 CopyFromCompositingSurface_Origin_Unscaled
) {
672 gfx::Rect
copy_rect(400, 300);
673 gfx::Size output_size
= copy_rect
.size();
674 gfx::Size
html_rect_size(400, 300);
675 bool video_frame
= false;
676 PerformTestWithLeftRightRects(html_rect_size
,
682 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture
,
683 CopyFromCompositingSurface_Origin_Scaled
) {
684 gfx::Rect
copy_rect(400, 300);
685 gfx::Size
output_size(200, 100);
686 gfx::Size
html_rect_size(400, 300);
687 bool video_frame
= false;
688 PerformTestWithLeftRightRects(html_rect_size
,
694 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture
,
695 CopyFromCompositingSurface_Cropped_Unscaled
) {
696 // Grab 60x60 pixels from the center of the tab contents.
697 gfx::Rect
copy_rect(400, 300);
698 copy_rect
= gfx::Rect(copy_rect
.CenterPoint() - gfx::Vector2d(30, 30),
700 gfx::Size output_size
= copy_rect
.size();
701 gfx::Size
html_rect_size(400, 300);
702 bool video_frame
= false;
703 PerformTestWithLeftRightRects(html_rect_size
,
709 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture
,
710 CopyFromCompositingSurface_Cropped_Scaled
) {
711 // Grab 60x60 pixels from the center of the tab contents.
712 gfx::Rect
copy_rect(400, 300);
713 copy_rect
= gfx::Rect(copy_rect
.CenterPoint() - gfx::Vector2d(30, 30),
715 gfx::Size
output_size(20, 10);
716 gfx::Size
html_rect_size(400, 300);
717 bool video_frame
= false;
718 PerformTestWithLeftRightRects(html_rect_size
,
724 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture
,
725 CopyFromCompositingSurface_ForVideoFrame
) {
726 // Grab 90x60 pixels from the center of the tab contents.
727 gfx::Rect
copy_rect(400, 300);
728 copy_rect
= gfx::Rect(copy_rect
.CenterPoint() - gfx::Vector2d(45, 30),
730 gfx::Size output_size
= copy_rect
.size();
731 gfx::Size
html_rect_size(400, 300);
732 bool video_frame
= true;
733 PerformTestWithLeftRightRects(html_rect_size
,
739 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture
,
740 CopyFromCompositingSurface_ForVideoFrame_Scaled
) {
741 // Grab 90x60 pixels from the center of the tab contents.
742 gfx::Rect
copy_rect(400, 300);
743 copy_rect
= gfx::Rect(copy_rect
.CenterPoint() - gfx::Vector2d(45, 30),
745 // Scale to 30 x 20 (preserve aspect ratio).
746 gfx::Size
output_size(30, 20);
747 gfx::Size
html_rect_size(400, 300);
748 bool video_frame
= true;
749 PerformTestWithLeftRightRects(html_rect_size
,
755 class CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
756 : public CompositingRenderWidgetHostViewBrowserTestTabCapture
{
758 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI() {}
761 virtual void SetUpCommandLine(base::CommandLine
* cmd
) OVERRIDE
{
762 CompositingRenderWidgetHostViewBrowserTestTabCapture::SetUpCommandLine(cmd
);
763 cmd
->AppendSwitchASCII(switches::kForceDeviceScaleFactor
,
764 base::StringPrintf("%f", scale()));
767 virtual bool ShouldContinueAfterTestURLLoad() OVERRIDE
{
768 // Short-circuit a pass for platforms where setting up high-DPI fails.
769 const float actual_scale_factor
=
770 GetScaleFactorForView(GetRenderWidgetHostView());
771 if (actual_scale_factor
!= scale()) {
772 LOG(WARNING
) << "Blindly passing this test; unable to force device scale "
773 << "factor: seems to be " << actual_scale_factor
774 << " but expected " << scale();
777 VLOG(1) << ("Successfully forced device scale factor. Moving forward with "
782 static float scale() { return 2.0f
; }
785 DISALLOW_COPY_AND_ASSIGN(
786 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
);
789 // ImageSkia (related to ResourceBundle) implementation crashes the process on
790 // Windows when this content_browsertest forces a device scale factor.
791 // http://crbug.com/399349
793 // These tests are flaky on ChromeOS builders. See http://crbug.com/406018.
794 #if defined(OS_WIN) || defined(OS_CHROMEOS)
795 #define MAYBE_CopyToBitmap_EntireRegion DISABLED_CopyToBitmap_EntireRegion
796 #define MAYBE_CopyToBitmap_CenterRegion DISABLED_CopyToBitmap_CenterRegion
797 #define MAYBE_CopyToBitmap_ScaledResult DISABLED_CopyToBitmap_ScaledResult
798 #define MAYBE_CopyToVideoFrame_EntireRegion \
799 DISABLED_CopyToVideoFrame_EntireRegion
800 #define MAYBE_CopyToVideoFrame_CenterRegion \
801 DISABLED_CopyToVideoFrame_CenterRegion
802 #define MAYBE_CopyToVideoFrame_ScaledResult \
803 DISABLED_CopyToVideoFrame_ScaledResult
805 #define MAYBE_CopyToBitmap_EntireRegion CopyToBitmap_EntireRegion
806 #define MAYBE_CopyToBitmap_CenterRegion CopyToBitmap_CenterRegion
807 #define MAYBE_CopyToBitmap_ScaledResult CopyToBitmap_ScaledResult
808 #define MAYBE_CopyToVideoFrame_EntireRegion CopyToVideoFrame_EntireRegion
809 #define MAYBE_CopyToVideoFrame_CenterRegion CopyToVideoFrame_CenterRegion
810 #define MAYBE_CopyToVideoFrame_ScaledResult CopyToVideoFrame_ScaledResult
813 IN_PROC_BROWSER_TEST_P(
814 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
,
815 MAYBE_CopyToBitmap_EntireRegion
) {
816 gfx::Size
html_rect_size(200, 150);
817 gfx::Rect
copy_rect(200, 150);
818 // Scale the output size so that, internally, scaling is not occurring.
819 gfx::Size output_size
=
820 gfx::ToRoundedSize(gfx::ScaleSize(copy_rect
.size(), scale()));
821 bool video_frame
= false;
822 PerformTestWithLeftRightRects(html_rect_size
,
828 IN_PROC_BROWSER_TEST_P(
829 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
,
830 MAYBE_CopyToBitmap_CenterRegion
) {
831 gfx::Size
html_rect_size(200, 150);
832 // Grab 90x60 pixels from the center of the tab contents.
833 gfx::Rect copy_rect
=
834 gfx::Rect(gfx::Rect(html_rect_size
).CenterPoint() - gfx::Vector2d(45, 30),
836 // Scale the output size so that, internally, scaling is not occurring.
837 gfx::Size output_size
=
838 gfx::ToRoundedSize(gfx::ScaleSize(copy_rect
.size(), scale()));
839 bool video_frame
= false;
840 PerformTestWithLeftRightRects(html_rect_size
,
846 IN_PROC_BROWSER_TEST_P(
847 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
,
848 MAYBE_CopyToBitmap_ScaledResult
) {
849 gfx::Size
html_rect_size(200, 100);
850 gfx::Rect
copy_rect(200, 100);
851 // Output is being down-scaled since output_size is in phyiscal pixels.
852 gfx::Size
output_size(200, 100);
853 bool video_frame
= false;
854 PerformTestWithLeftRightRects(html_rect_size
,
860 IN_PROC_BROWSER_TEST_P(
861 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
,
862 MAYBE_CopyToVideoFrame_EntireRegion
) {
863 gfx::Size
html_rect_size(200, 150);
864 gfx::Rect
copy_rect(200, 150);
865 // Scale the output size so that, internally, scaling is not occurring.
866 gfx::Size output_size
=
867 gfx::ToRoundedSize(gfx::ScaleSize(copy_rect
.size(), scale()));
868 bool video_frame
= true;
869 PerformTestWithLeftRightRects(html_rect_size
,
875 IN_PROC_BROWSER_TEST_P(
876 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
,
877 MAYBE_CopyToVideoFrame_CenterRegion
) {
878 gfx::Size
html_rect_size(200, 150);
879 // Grab 90x60 pixels from the center of the tab contents.
880 gfx::Rect copy_rect
=
881 gfx::Rect(gfx::Rect(html_rect_size
).CenterPoint() - gfx::Vector2d(45, 30),
883 // Scale the output size so that, internally, scaling is not occurring.
884 gfx::Size output_size
=
885 gfx::ToRoundedSize(gfx::ScaleSize(copy_rect
.size(), scale()));
886 bool video_frame
= true;
887 PerformTestWithLeftRightRects(html_rect_size
,
893 IN_PROC_BROWSER_TEST_P(
894 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
,
895 MAYBE_CopyToVideoFrame_ScaledResult
) {
896 gfx::Size
html_rect_size(200, 100);
897 gfx::Rect
copy_rect(200, 100);
898 // Output is being down-scaled since output_size is in phyiscal pixels.
899 gfx::Size
output_size(200, 100);
900 bool video_frame
= true;
901 PerformTestWithLeftRightRects(html_rect_size
,
907 INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing
,
908 CompositingRenderWidgetHostViewBrowserTest
,
909 testing::Values(GL_COMPOSITING
, SOFTWARE_COMPOSITING
));
910 INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing
,
911 CompositingRenderWidgetHostViewBrowserTestTabCapture
,
912 testing::Values(GL_COMPOSITING
, SOFTWARE_COMPOSITING
));
913 INSTANTIATE_TEST_CASE_P(
914 GLAndSoftwareCompositing
,
915 CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
,
916 testing::Values(GL_COMPOSITING
, SOFTWARE_COMPOSITING
));
918 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
921 } // namespace content