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/ui_base_switches.h"
31 #include "ui/gfx/size_conversions.h"
32 #include "ui/gfx/switches.h"
33 #include "ui/gl/gl_switches.h"
35 #if defined(OS_MACOSX)
36 #include "ui/gl/io_surface_support_mac.h"
40 #include "base/win/windows_version.h"
41 #include "ui/gfx/win/dpi.h"
47 // Convenience macro: Short-circuit a pass for the tests where platform support
48 // for forced-compositing mode (or disabled-compositing mode) is lacking.
49 #define SET_UP_SURFACE_OR_PASS_TEST(wait_message) \
50 if (!SetUpSourceSurface(wait_message)) { \
52 << ("Blindly passing this test: This platform does not support " \
53 "forced compositing (or forced-disabled compositing) mode."); \
57 // Convenience macro: Short-circuit a pass for platforms where setting up
59 #define PASS_TEST_IF_SCALE_FACTOR_NOT_SUPPORTED(factor) \
60 if (ui::GetScaleForScaleFactor( \
61 GetScaleFactorForView(GetRenderWidgetHostView())) != factor) { \
62 LOG(WARNING) << "Blindly passing this test: failed to set up " \
63 "scale factor: " << factor; \
67 // Common base class for browser tests. This is subclassed twice: Once to test
68 // the browser in forced-compositing mode, and once to test with compositing
70 class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
72 RenderWidgetHostViewBrowserTest()
73 : frame_size_(400, 300),
74 callback_invoke_count_(0),
75 frames_captured_(0) {}
77 virtual void SetUpOnMainThread() OVERRIDE {
78 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_));
81 // Attempts to set up the source surface. Returns false if unsupported on the
83 virtual bool SetUpSourceSurface(const char* wait_message) = 0;
85 int callback_invoke_count() const {
86 return callback_invoke_count_;
89 int frames_captured() const {
90 return frames_captured_;
93 const gfx::Size& frame_size() const {
97 const base::FilePath& test_dir() const {
101 RenderViewHost* GetRenderViewHost() const {
102 RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
107 RenderWidgetHostImpl* GetRenderWidgetHost() const {
108 RenderWidgetHostImpl* const rwh = RenderWidgetHostImpl::From(
109 shell()->web_contents()->GetRenderWidgetHostView()->
110 GetRenderWidgetHost());
115 RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
116 return static_cast<RenderWidgetHostViewBase*>(
117 GetRenderViewHost()->GetView());
120 // Callback when using CopyFromBackingStore() API.
121 void FinishCopyFromBackingStore(const base::Closure& quit_closure,
123 const SkBitmap& bitmap) {
124 ++callback_invoke_count_;
125 if (frame_captured) {
127 EXPECT_FALSE(bitmap.empty());
129 if (!quit_closure.is_null())
133 // Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
134 void FinishCopyFromCompositingSurface(const base::Closure& quit_closure,
135 bool frame_captured) {
136 ++callback_invoke_count_;
139 if (!quit_closure.is_null())
143 // Callback when using frame subscriber API.
144 void FrameDelivered(const scoped_refptr<base::MessageLoopProxy>& loop,
145 base::Closure quit_closure,
146 base::TimeTicks timestamp,
147 bool frame_captured) {
148 ++callback_invoke_count_;
151 if (!quit_closure.is_null())
152 loop->PostTask(FROM_HERE, quit_closure);
155 // Copy one frame using the CopyFromBackingStore API.
156 void RunBasicCopyFromBackingStoreTest() {
157 SET_UP_SURFACE_OR_PASS_TEST(NULL);
159 // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
160 // Windows), the operation will fail until the first "present" has been
162 int count_attempts = 0;
165 base::RunLoop run_loop;
166 GetRenderViewHost()->CopyFromBackingStore(
170 &RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
171 base::Unretained(this),
172 run_loop.QuitClosure()),
173 SkBitmap::kARGB_8888_Config);
176 if (frames_captured())
182 EXPECT_EQ(count_attempts, callback_invoke_count());
183 EXPECT_EQ(1, frames_captured());
187 // Waits until the source is available for copying.
188 void WaitForCopySourceReady() {
189 while (!GetRenderWidgetHostView()->IsSurfaceAvailableForCopy())
193 // Run the current message loop for a short time without unwinding the current
195 static void GiveItSomeTime() {
196 base::RunLoop run_loop;
197 base::MessageLoop::current()->PostDelayedTask(
199 run_loop.QuitClosure(),
200 base::TimeDelta::FromMilliseconds(10));
205 const gfx::Size frame_size_;
206 base::FilePath test_dir_;
207 int callback_invoke_count_;
208 int frames_captured_;
211 enum CompositingMode {
213 SOFTWARE_COMPOSITING,
216 class CompositingRenderWidgetHostViewBrowserTest
217 : public RenderWidgetHostViewBrowserTest,
218 public testing::WithParamInterface<CompositingMode> {
220 explicit CompositingRenderWidgetHostViewBrowserTest()
221 : compositing_mode_(GetParam()) {}
223 virtual void SetUp() OVERRIDE {
224 if (compositing_mode_ == SOFTWARE_COMPOSITING)
225 UseSoftwareCompositing();
226 RenderWidgetHostViewBrowserTest::SetUp();
229 virtual GURL TestUrl() {
230 return net::FilePathToFileURL(
231 test_dir().AppendASCII("rwhv_compositing_animation.html"));
234 virtual bool SetUpSourceSurface(const char* wait_message) OVERRIDE {
235 #if defined(OS_MACOSX)
236 CHECK(IOSurfaceSupport::Initialize());
239 content::DOMMessageQueue message_queue;
240 NavigateToURL(shell(), TestUrl());
241 if (wait_message != NULL) {
242 std::string result(wait_message);
243 if (!message_queue.WaitForMessage(&result)) {
244 EXPECT_TRUE(false) << "WaitForMessage " << result << " failed.";
249 #if !defined(USE_AURA)
250 if (!GetRenderWidgetHost()->is_accelerated_compositing_active())
251 return false; // Renderer did not turn on accelerated compositing.
254 // Using accelerated compositing, but a compositing surface might not be
255 // available yet. So, wait for it.
256 WaitForCopySourceReady();
261 const CompositingMode compositing_mode_;
263 DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewBrowserTest);
266 class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
269 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback)
270 : callback_(callback) {
273 virtual bool ShouldCaptureFrame(base::TimeTicks present_time,
274 scoped_refptr<media::VideoFrame>* storage,
275 DeliverFrameCallback* callback) OVERRIDE {
276 // Only allow one frame capture to be made. Otherwise, the compositor could
277 // start multiple captures, unbounded, and eventually its own limiter logic
278 // will begin invoking |callback| with a |false| result. This flakes out
279 // the unit tests, since they receive a "failed" callback before the later
280 // "success" callbacks.
281 if (callback_.is_null())
283 *storage = media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100));
284 *callback = callback_;
290 DeliverFrameCallback callback_;
293 // Disable tests for Android and IOS as these platforms have incomplete
295 #if !defined(OS_ANDROID) && !defined(OS_IOS)
297 // The CopyFromBackingStore() API should work on all platforms when compositing
299 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
300 CopyFromBackingStore) {
301 RunBasicCopyFromBackingStoreTest();
304 // Tests that the callback passed to CopyFromBackingStore is always called,
305 // even when the RenderWidgetHost is deleting in the middle of an async copy.
306 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
307 CopyFromBackingStore_CallbackDespiteDelete) {
308 SET_UP_SURFACE_OR_PASS_TEST(NULL);
310 base::RunLoop run_loop;
311 GetRenderViewHost()->CopyFromBackingStore(
314 base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
315 base::Unretained(this),
316 run_loop.QuitClosure()),
317 SkBitmap::kARGB_8888_Config);
318 // Delete the surface before the callback is run.
319 GetRenderWidgetHostView()->AcceleratedSurfaceRelease();
322 EXPECT_EQ(1, callback_invoke_count());
325 // Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
326 // always called, even when the RenderWidgetHost is deleting in the middle of
329 // Test is flaky on Win. http://crbug.com/276783
330 #if defined(OS_WIN) || (defined(OS_CHROMEOS) && !defined(NDEBUG))
331 #define MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete \
332 DISABLED_CopyFromCompositingSurface_CallbackDespiteDelete
334 #define MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete \
335 CopyFromCompositingSurface_CallbackDespiteDelete
337 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
338 MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete) {
339 SET_UP_SURFACE_OR_PASS_TEST(NULL);
340 RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
341 if (!view->CanCopyToVideoFrame()) {
343 ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
344 "not supported on this platform.");
348 base::RunLoop run_loop;
349 scoped_refptr<media::VideoFrame> dest =
350 media::VideoFrame::CreateBlackFrame(frame_size());
351 view->CopyFromCompositingSurfaceToVideoFrame(
352 gfx::Rect(view->GetViewBounds().size()), dest, base::Bind(
353 &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface,
354 base::Unretained(this), run_loop.QuitClosure()));
355 // Delete the surface before the callback is run.
356 view->AcceleratedSurfaceRelease();
359 EXPECT_EQ(1, callback_invoke_count());
362 // Test basic frame subscription functionality. We subscribe, and then run
363 // until at least one DeliverFrameCallback has been invoked.
364 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
365 FrameSubscriberTest) {
366 SET_UP_SURFACE_OR_PASS_TEST(NULL);
367 RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
368 if (!view->CanSubscribeFrame()) {
369 LOG(WARNING) << ("Blindly passing this test: Frame subscription not "
370 "supported on this platform.");
374 base::RunLoop run_loop;
375 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
376 new FakeFrameSubscriber(
377 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
378 base::Unretained(this),
379 base::MessageLoopProxy::current(),
380 run_loop.QuitClosure())));
381 view->BeginFrameSubscription(subscriber.Pass());
383 view->EndFrameSubscription();
385 EXPECT_LE(1, callback_invoke_count());
386 EXPECT_LE(1, frames_captured());
389 // Test that we can copy twice from an accelerated composited page.
390 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
391 SET_UP_SURFACE_OR_PASS_TEST(NULL);
392 RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
393 if (!view->CanCopyToVideoFrame()) {
394 LOG(WARNING) << ("Blindly passing this test: "
395 "CopyFromCompositingSurfaceToVideoFrame() not supported "
396 "on this platform.");
400 base::RunLoop run_loop;
401 scoped_refptr<media::VideoFrame> first_output =
402 media::VideoFrame::CreateBlackFrame(frame_size());
403 ASSERT_TRUE(first_output.get());
404 scoped_refptr<media::VideoFrame> second_output =
405 media::VideoFrame::CreateBlackFrame(frame_size());
406 ASSERT_TRUE(second_output.get());
407 view->CopyFromCompositingSurfaceToVideoFrame(
408 gfx::Rect(view->GetViewBounds().size()),
410 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
411 base::Unretained(this),
412 base::MessageLoopProxy::current(),
414 base::TimeTicks::Now()));
415 view->CopyFromCompositingSurfaceToVideoFrame(
416 gfx::Rect(view->GetViewBounds().size()),
418 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
419 base::Unretained(this),
420 base::MessageLoopProxy::current(),
421 run_loop.QuitClosure(),
422 base::TimeTicks::Now()));
425 EXPECT_EQ(2, callback_invoke_count());
426 EXPECT_EQ(2, frames_captured());
429 class CompositingRenderWidgetHostViewBrowserTestTabCapture
430 : public CompositingRenderWidgetHostViewBrowserTest {
432 CompositingRenderWidgetHostViewBrowserTestTabCapture()
433 : expected_copy_from_compositing_surface_result_(false),
435 test_url_("data:text/html,<!doctype html>") {}
437 virtual void SetUp() OVERRIDE {
439 CompositingRenderWidgetHostViewBrowserTest::SetUp();
442 void CopyFromCompositingSurfaceCallback(base::Closure quit_callback,
444 const SkBitmap& bitmap) {
445 EXPECT_EQ(expected_copy_from_compositing_surface_result_, result);
451 const SkBitmap& expected_bitmap =
452 expected_copy_from_compositing_surface_bitmap_;
453 EXPECT_EQ(expected_bitmap.width(), bitmap.width());
454 EXPECT_EQ(expected_bitmap.height(), bitmap.height());
455 EXPECT_EQ(expected_bitmap.config(), bitmap.config());
456 SkAutoLockPixels expected_bitmap_lock(expected_bitmap);
457 SkAutoLockPixels bitmap_lock(bitmap);
459 for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
460 for (int j = 0; j < bitmap.height() && fails < 10; ++j) {
461 if (!exclude_rect_.IsEmpty() && exclude_rect_.Contains(i, j))
464 SkColor expected_color = expected_bitmap.getColor(i, j);
465 SkColor color = bitmap.getColor(i, j);
466 int expected_alpha = SkColorGetA(expected_color);
467 int alpha = SkColorGetA(color);
468 int expected_red = SkColorGetR(expected_color);
469 int red = SkColorGetR(color);
470 int expected_green = SkColorGetG(expected_color);
471 int green = SkColorGetG(color);
472 int expected_blue = SkColorGetB(expected_color);
473 int blue = SkColorGetB(color);
474 EXPECT_NEAR(expected_alpha, alpha, allowable_error_)
475 << "expected_color: " << std::hex << expected_color
476 << " color: " << color
477 << " Failed at " << std::dec << i << ", " << j
478 << " Failure " << ++fails;
479 EXPECT_NEAR(expected_red, red, allowable_error_)
480 << "expected_color: " << std::hex << expected_color
481 << " color: " << color
482 << " Failed at " << std::dec << i << ", " << j
483 << " Failure " << ++fails;
484 EXPECT_NEAR(expected_green, green, allowable_error_)
485 << "expected_color: " << std::hex << expected_color
486 << " color: " << color
487 << " Failed at " << std::dec << i << ", " << j
488 << " Failure " << ++fails;
489 EXPECT_NEAR(expected_blue, blue, allowable_error_)
490 << "expected_color: " << std::hex << expected_color
491 << " color: " << color
492 << " Failed at " << std::dec << i << ", " << j
493 << " Failure " << ++fails;
496 EXPECT_LT(fails, 10);
501 void CopyFromCompositingSurfaceCallbackForVideo(
502 scoped_refptr<media::VideoFrame> video_frame,
503 base::Closure quit_callback,
505 EXPECT_EQ(expected_copy_from_compositing_surface_result_, result);
511 media::SkCanvasVideoRenderer video_renderer;
514 bitmap.allocPixels(SkImageInfo::Make(video_frame->visible_rect().width(),
515 video_frame->visible_rect().height(),
516 kPMColor_SkColorType,
517 kOpaque_SkAlphaType));
518 bitmap.allocPixels();
519 SkCanvas canvas(bitmap);
521 video_renderer.Paint(video_frame.get(),
523 video_frame->visible_rect(),
526 CopyFromCompositingSurfaceCallback(quit_callback,
531 void SetExpectedCopyFromCompositingSurfaceResult(bool result,
532 const SkBitmap& bitmap) {
533 expected_copy_from_compositing_surface_result_ = result;
534 expected_copy_from_compositing_surface_bitmap_ = bitmap;
537 void SetAllowableError(int amount) { allowable_error_ = amount; }
538 void SetExcludeRect(gfx::Rect exclude) { exclude_rect_ = exclude; }
540 virtual GURL TestUrl() OVERRIDE {
541 return GURL(test_url_);
544 void SetTestUrl(std::string url) { test_url_ = url; }
546 // Loads a page two boxes side-by-side, each half the width of
547 // |html_rect_size|, and with different background colors. The test then
548 // copies from |copy_rect| region of the page into a bitmap of size
549 // |output_size|, and compares that with a bitmap of size
550 // |expected_bitmap_size|.
551 // Note that |output_size| may not have the same size as |copy_rect| (e.g.
552 // when the output is scaled). Also note that |expected_bitmap_size| may not
553 // be the same as |output_size| (e.g. when the device scale factor is not 1).
554 void PerformTestWithLeftRightRects(const gfx::Size& html_rect_size,
555 const gfx::Rect& copy_rect,
556 const gfx::Size& output_size,
557 const gfx::Size& expected_bitmap_size,
559 const gfx::Size box_size(html_rect_size.width() / 2,
560 html_rect_size.height());
561 SetTestUrl(base::StringPrintf(
562 "data:text/html,<!doctype html>"
564 " <div class='right'></div>"
567 "body { padding: 0; margin: 0; }"
568 ".left { position: absolute;"
573 ".right { position: absolute;"
581 " domAutomationController.setAutomationId(0);"
582 " domAutomationController.send(\"DONE\");"
590 SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
591 if (!ShouldContinueAfterTestURLLoad())
594 RenderWidgetHostViewBase* rwhvp = GetRenderWidgetHostView();
595 if (video_frame && !rwhvp->CanCopyToVideoFrame()) {
596 // This should only happen on Mac when using the software compositor.
597 // Otherwise, raise an error. This can be removed when Mac is moved to a
598 // browser compositor.
599 // http://crbug.com/314190
600 #if defined(OS_MACOSX)
601 if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) {
602 LOG(WARNING) << ("Blindly passing this test because copying to "
603 "video frames is not supported on this platform.");
610 // The page is loaded in the renderer, wait for a new frame to arrive.
611 uint32 frame = rwhvp->RendererFrameNumber();
612 while (!GetRenderWidgetHost()->ScheduleComposite())
614 while (rwhvp->RendererFrameNumber() == frame)
617 SkBitmap expected_bitmap;
618 SetupLeftRightBitmap(expected_bitmap_size, &expected_bitmap);
619 SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap);
621 base::RunLoop run_loop;
623 // Allow pixel differences as long as we have the right idea.
624 SetAllowableError(0x10);
625 // Exclude the middle two columns which are blended between the two sides.
627 gfx::Rect(output_size.width() / 2 - 1, 0, 2, output_size.height()));
629 scoped_refptr<media::VideoFrame> video_frame =
630 media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
631 expected_bitmap_size,
632 gfx::Rect(expected_bitmap_size),
633 expected_bitmap_size,
636 base::Callback<void(bool success)> callback =
637 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
638 CopyFromCompositingSurfaceCallbackForVideo,
639 base::Unretained(this),
641 run_loop.QuitClosure());
642 rwhvp->CopyFromCompositingSurfaceToVideoFrame(copy_rect,
646 #if defined(USE_AURA)
647 if (!content::GpuDataManager::GetInstance()
648 ->CanUseGpuBrowserCompositor()) {
649 // Skia rendering can cause color differences, particularly in the
650 // middle two columns.
651 SetAllowableError(2);
653 gfx::Rect(output_size.width() / 2 - 1, 0, 2, output_size.height()));
657 base::Callback<void(bool, const SkBitmap&)> callback =
658 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
659 CopyFromCompositingSurfaceCallback,
660 base::Unretained(this),
661 run_loop.QuitClosure());
662 rwhvp->CopyFromCompositingSurface(copy_rect,
665 SkBitmap::kARGB_8888_Config);
670 // Sets up |bitmap| to have size |copy_size|. It floods the left half with
671 // #0ff and the right half with #ff0.
672 void SetupLeftRightBitmap(const gfx::Size& copy_size, SkBitmap* bitmap) {
674 SkBitmap::kARGB_8888_Config, copy_size.width(), copy_size.height());
675 bitmap->allocPixels();
676 // Left half is #0ff.
677 bitmap->eraseARGB(255, 0, 255, 255);
678 // Right half is #ff0.
680 SkAutoLockPixels lock(*bitmap);
681 for (int i = 0; i < copy_size.width() / 2; ++i) {
682 for (int j = 0; j < copy_size.height(); ++j) {
683 *(bitmap->getAddr32(copy_size.width() / 2 + i, j)) =
684 SkColorSetARGB(255, 255, 255, 0);
691 virtual bool ShouldContinueAfterTestURLLoad() {
696 bool expected_copy_from_compositing_surface_result_;
697 SkBitmap expected_copy_from_compositing_surface_bitmap_;
698 int allowable_error_;
699 gfx::Rect exclude_rect_;
700 std::string test_url_;
703 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
704 CopyFromCompositingSurface_Origin_Unscaled) {
705 gfx::Rect copy_rect(400, 300);
706 gfx::Size output_size = copy_rect.size();
707 gfx::Size expected_bitmap_size = output_size;
708 gfx::Size html_rect_size(400, 300);
709 bool video_frame = false;
710 PerformTestWithLeftRightRects(html_rect_size,
713 expected_bitmap_size,
717 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
718 CopyFromCompositingSurface_Origin_Scaled) {
719 gfx::Rect copy_rect(400, 300);
720 gfx::Size output_size(200, 100);
721 gfx::Size expected_bitmap_size = output_size;
722 gfx::Size html_rect_size(400, 300);
723 bool video_frame = false;
724 PerformTestWithLeftRightRects(html_rect_size,
727 expected_bitmap_size,
731 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
732 CopyFromCompositingSurface_Cropped_Unscaled) {
733 // Grab 60x60 pixels from the center of the tab contents.
734 gfx::Rect copy_rect(400, 300);
735 copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
737 gfx::Size output_size = copy_rect.size();
738 gfx::Size expected_bitmap_size = output_size;
739 gfx::Size html_rect_size(400, 300);
740 bool video_frame = false;
741 PerformTestWithLeftRightRects(html_rect_size,
744 expected_bitmap_size,
748 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
749 CopyFromCompositingSurface_Cropped_Scaled) {
750 // Grab 60x60 pixels from the center of the tab contents.
751 gfx::Rect copy_rect(400, 300);
752 copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
754 gfx::Size output_size(20, 10);
755 gfx::Size expected_bitmap_size = output_size;
756 gfx::Size html_rect_size(400, 300);
757 bool video_frame = false;
758 PerformTestWithLeftRightRects(html_rect_size,
761 expected_bitmap_size,
765 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
766 CopyFromCompositingSurface_ForVideoFrame) {
767 // Grab 90x60 pixels from the center of the tab contents.
768 gfx::Rect copy_rect(400, 300);
769 copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
771 gfx::Size output_size = copy_rect.size();
772 gfx::Size expected_bitmap_size = output_size;
773 gfx::Size html_rect_size(400, 300);
774 bool video_frame = true;
775 PerformTestWithLeftRightRects(html_rect_size,
778 expected_bitmap_size,
782 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
783 CopyFromCompositingSurface_ForVideoFrame_Scaled) {
784 // Grab 90x60 pixels from the center of the tab contents.
785 gfx::Rect copy_rect(400, 300);
786 copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
788 // Scale to 30 x 20 (preserve aspect ratio).
789 gfx::Size output_size(30, 20);
790 gfx::Size expected_bitmap_size = output_size;
791 gfx::Size html_rect_size(400, 300);
792 bool video_frame = true;
793 PerformTestWithLeftRightRects(html_rect_size,
796 expected_bitmap_size,
800 class CompositingRenderWidgetHostViewTabCaptureHighDPI
801 : public CompositingRenderWidgetHostViewBrowserTestTabCapture {
803 CompositingRenderWidgetHostViewTabCaptureHighDPI() : kScale(2.f) {}
805 virtual void SetUpOnMainThread() OVERRIDE {
806 CommandLine* cmd = CommandLine::ForCurrentProcess();
807 cmd->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
808 base::StringPrintf("%f", scale()));
810 gfx::ForceHighDPISupportForTesting(scale());
811 gfx::EnableHighDPISupport();
815 float scale() const { return kScale; }
818 virtual bool ShouldContinueAfterTestURLLoad() OVERRIDE {
819 PASS_TEST_IF_SCALE_FACTOR_NOT_SUPPORTED(scale());
825 DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewTabCaptureHighDPI);
828 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewTabCaptureHighDPI,
829 CopyFromCompositingSurface) {
830 gfx::Rect copy_rect(200, 150);
831 gfx::Size output_size = copy_rect.size();
832 gfx::Size expected_bitmap_size =
833 gfx::ToFlooredSize(gfx::ScaleSize(output_size, scale(), scale()));
834 gfx::Size html_rect_size(200, 150);
835 bool video_frame = false;
836 PerformTestWithLeftRightRects(html_rect_size,
839 expected_bitmap_size,
843 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewTabCaptureHighDPI,
844 CopyFromCompositingSurfaceVideoFrame) {
845 gfx::Size html_rect_size(200, 150);
846 // Grab 90x60 pixels from the center of the tab contents.
847 gfx::Rect copy_rect =
848 gfx::Rect(gfx::Rect(html_rect_size).CenterPoint() - gfx::Vector2d(45, 30),
850 gfx::Size output_size = copy_rect.size();
851 gfx::Size expected_bitmap_size =
852 gfx::ToFlooredSize(gfx::ScaleSize(output_size, scale(), scale()));
853 bool video_frame = true;
854 PerformTestWithLeftRightRects(html_rect_size,
857 expected_bitmap_size,
861 #if !defined(USE_AURA) && !defined(OS_MACOSX)
862 // TODO(danakj): Remove this case when GTK linux is no more and move the
863 // values inline to testing::Values() below.
864 static const CompositingMode kAllCompositingModes[] = {GL_COMPOSITING};
866 static const CompositingMode kAllCompositingModes[] = {GL_COMPOSITING,
867 SOFTWARE_COMPOSITING};
870 INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing,
871 CompositingRenderWidgetHostViewBrowserTest,
872 testing::ValuesIn(kAllCompositingModes));
873 INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing,
874 CompositingRenderWidgetHostViewBrowserTestTabCapture,
875 testing::ValuesIn(kAllCompositingModes));
876 INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing,
877 CompositingRenderWidgetHostViewTabCaptureHighDPI,
878 testing::ValuesIn(kAllCompositingModes));
880 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
883 } // namespace content