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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_browsertest.cc

Issue 17971002: Make RenderWidgetHostViewAura::CopyFromCompositingSurface readback layer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tabcapture-aura: DidReceiveRendererFrame Created 7 years, 5 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 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 "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/message_loop/message_loop_proxy.h" 6 #include "base/message_loop/message_loop_proxy.h"
7 #include "base/path_service.h" 7 #include "base/path_service.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "content/browser/gpu/gpu_data_manager_impl.h" 9 #include "content/browser/gpu/gpu_data_manager_impl.h"
10 #include "content/browser/renderer_host/render_widget_host_impl.h" 10 #include "content/browser/renderer_host/render_widget_host_impl.h"
11 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" 11 #include "content/port/browser/render_widget_host_view_frame_subscriber.h"
12 #include "content/port/browser/render_widget_host_view_port.h" 12 #include "content/port/browser/render_widget_host_view_port.h"
13 #include "content/public/browser/compositor_util.h" 13 #include "content/public/browser/compositor_util.h"
14 #include "content/public/browser/render_view_host.h" 14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/content_paths.h" 16 #include "content/public/common/content_paths.h"
17 #include "content/public/common/content_switches.h" 17 #include "content/public/common/content_switches.h"
18 #include "content/public/test/browser_test_utils.h"
18 #include "content/shell/shell.h" 19 #include "content/shell/shell.h"
19 #include "content/test/content_browser_test.h" 20 #include "content/test/content_browser_test.h"
20 #include "content/test/content_browser_test_utils.h" 21 #include "content/test/content_browser_test_utils.h"
21 #include "media/base/video_frame.h" 22 #include "media/base/video_frame.h"
22 #include "net/base/net_util.h" 23 #include "net/base/net_util.h"
23 #include "ui/compositor/compositor_setup.h" 24 #include "ui/compositor/compositor_setup.h"
25 #include "ui/gl/gl_switches.h"
24 26
25 #if defined(OS_MACOSX) 27 #if defined(OS_MACOSX)
26 #include "ui/gl/io_surface_support_mac.h" 28 #include "ui/gl/io_surface_support_mac.h"
27 #endif 29 #endif
28 30
29 namespace content { 31 namespace content {
30 namespace { 32 namespace {
31 33
32 // Convenience macro: Short-cicuit a pass for the tests where platform support 34 // Convenience macro: Short-cicuit a pass for the tests where platform support
33 // for forced-compositing mode (or disabled-compositing mode) is lacking. 35 // for forced-compositing mode (or disabled-compositing mode) is lacking.
34 #define SET_UP_SURFACE_OR_PASS_TEST() \ 36 #define SET_UP_SURFACE_OR_PASS_TEST(wait_message) \
35 if (!SetUpSourceSurface()) { \ 37 if (!SetUpSourceSurface(wait_message)) { \
36 LOG(WARNING) \ 38 LOG(WARNING) \
37 << ("Blindly passing this test: This platform does not support " \ 39 << ("Blindly passing this test: This platform does not support " \
38 "forced compositing (or forced-disabled compositing) mode."); \ 40 "forced compositing (or forced-disabled compositing) mode."); \
39 return; \ 41 return; \
40 } 42 }
41 43
42 // Common base class for browser tests. This is subclassed twice: Once to test 44 // Common base class for browser tests. This is subclassed twice: Once to test
43 // the browser in forced-compositing mode, and once to test with compositing 45 // the browser in forced-compositing mode, and once to test with compositing
44 // mode disabled. 46 // mode disabled.
45 class RenderWidgetHostViewBrowserTest : public ContentBrowserTest { 47 class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
46 public: 48 public:
47 RenderWidgetHostViewBrowserTest() 49 RenderWidgetHostViewBrowserTest()
48 : frame_size_(400, 300), 50 : frame_size_(400, 300),
49 callback_invoke_count_(0), 51 callback_invoke_count_(0),
50 frames_captured_(0) {} 52 frames_captured_(0) {}
51 53
52 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 54 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
53 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_)); 55 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_));
54 ContentBrowserTest::SetUpInProcessBrowserTestFixture(); 56 ContentBrowserTest::SetUpInProcessBrowserTestFixture();
55 } 57 }
56 58
57 // Attempts to set up the source surface. Returns false if unsupported on the 59 // Attempts to set up the source surface. Returns false if unsupported on the
58 // current platform. 60 // current platform.
59 virtual bool SetUpSourceSurface() = 0; 61 virtual bool SetUpSourceSurface(const char* wait_message) = 0;
60 62
61 int callback_invoke_count() const { 63 int callback_invoke_count() const {
62 return callback_invoke_count_; 64 return callback_invoke_count_;
63 } 65 }
64 66
65 int frames_captured() const { 67 int frames_captured() const {
66 return frames_captured_; 68 return frames_captured_;
67 } 69 }
68 70
69 const gfx::Size& frame_size() const { 71 const gfx::Size& frame_size() const {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 bool frame_captured) { 127 bool frame_captured) {
126 ++callback_invoke_count_; 128 ++callback_invoke_count_;
127 if (frame_captured) 129 if (frame_captured)
128 ++frames_captured_; 130 ++frames_captured_;
129 if (!quit_closure.is_null()) 131 if (!quit_closure.is_null())
130 loop->PostTask(FROM_HERE, quit_closure); 132 loop->PostTask(FROM_HERE, quit_closure);
131 } 133 }
132 134
133 // Copy one frame using the CopyFromBackingStore API. 135 // Copy one frame using the CopyFromBackingStore API.
134 void RunBasicCopyFromBackingStoreTest() { 136 void RunBasicCopyFromBackingStoreTest() {
135 SET_UP_SURFACE_OR_PASS_TEST(); 137 SET_UP_SURFACE_OR_PASS_TEST(NULL);
136 138
137 // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g., 139 // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
138 // Windows), the operation will fail until the first "present" has been 140 // Windows), the operation will fail until the first "present" has been
139 // made. 141 // made.
140 int count_attempts = 0; 142 int count_attempts = 0;
141 while (true) { 143 while (true) {
142 ++count_attempts; 144 ++count_attempts;
143 base::RunLoop run_loop; 145 base::RunLoop run_loop;
144 GetRenderViewHost()->CopyFromBackingStore( 146 GetRenderViewHost()->CopyFromBackingStore(
145 gfx::Rect(), 147 gfx::Rect(),
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 193 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
192 // Note: Not appending kForceCompositingMode switch here, since not all bots 194 // Note: Not appending kForceCompositingMode switch here, since not all bots
193 // support compositing. Some bots will run with compositing on, and others 195 // support compositing. Some bots will run with compositing on, and others
194 // won't. Therefore, the call to SetUpSourceSurface() later on will detect 196 // won't. Therefore, the call to SetUpSourceSurface() later on will detect
195 // whether compositing mode is actually on or not. If not, the tests will 197 // whether compositing mode is actually on or not. If not, the tests will
196 // pass blindly, logging a warning message, since we cannot test what the 198 // pass blindly, logging a warning message, since we cannot test what the
197 // platform/implementation does not support. 199 // platform/implementation does not support.
198 RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line); 200 RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line);
199 } 201 }
200 202
201 virtual bool SetUpSourceSurface() OVERRIDE { 203 virtual GURL TestUrl() {
204 return net::FilePathToFileURL(
205 test_dir().AppendASCII("rwhv_compositing_animation.html"));
206 }
207
208 virtual bool SetUpSourceSurface(const char* wait_message) OVERRIDE {
202 if (!IsForceCompositingModeEnabled()) 209 if (!IsForceCompositingModeEnabled())
203 return false; // See comment in SetUpCommandLine(). 210 return false; // See comment in SetUpCommandLine().
204 #if defined(OS_MACOSX) 211 #if defined(OS_MACOSX)
205 CHECK(IOSurfaceSupport::Initialize()); 212 CHECK(IOSurfaceSupport::Initialize());
206 #endif 213 #endif
207 NavigateToURL(shell(), net::FilePathToFileURL( 214
208 test_dir().AppendASCII("rwhv_compositing_animation.html"))); 215 content::DOMMessageQueue message_queue;
216 NavigateToURL(shell(), TestUrl());
217 if (wait_message != NULL) {
218 std::string result(wait_message);
219 if (!message_queue.WaitForMessage(&result)) {
220 EXPECT_TRUE(false) << "WaitForMessage " << result << " failed.";
221 return false;
222 }
223 }
224
209 #if !defined(USE_AURA) 225 #if !defined(USE_AURA)
210 if (!GetRenderWidgetHost()->is_accelerated_compositing_active()) 226 if (!GetRenderWidgetHost()->is_accelerated_compositing_active())
211 return false; // Renderer did not turn on accelerated compositing. 227 return false; // Renderer did not turn on accelerated compositing.
212 #endif 228 #endif
213 229
214 // Using accelerated compositing, but a compositing surface might not be 230 // Using accelerated compositing, but a compositing surface might not be
215 // available yet. So, wait for it. 231 // available yet. So, wait for it.
216 WaitForCopySourceReady(); 232 WaitForCopySourceReady();
217 return true; 233 return true;
218 } 234 }
219 }; 235 };
220 236
221 class NonCompositingRenderWidgetHostViewBrowserTest 237 class NonCompositingRenderWidgetHostViewBrowserTest
222 : public RenderWidgetHostViewBrowserTest { 238 : public RenderWidgetHostViewBrowserTest {
223 public: 239 public:
224 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 240 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
225 // Note: Appending the kDisableAcceleratedCompositing switch here, but there 241 // Note: Appending the kDisableAcceleratedCompositing switch here, but there
226 // are some builds that only use compositing and will ignore this switch. 242 // are some builds that only use compositing and will ignore this switch.
227 // Therefore, the call to SetUpSourceSurface() later on will detect whether 243 // Therefore, the call to SetUpSourceSurface() later on will detect whether
228 // compositing mode is actually off. If it's on, the tests will pass 244 // compositing mode is actually off. If it's on, the tests will pass
229 // blindly, logging a warning message, since we cannot test what the 245 // blindly, logging a warning message, since we cannot test what the
230 // platform/implementation does not support. 246 // platform/implementation does not support.
231 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); 247 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
232 RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line); 248 RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line);
233 } 249 }
234 250
235 virtual bool SetUpSourceSurface() OVERRIDE { 251 virtual GURL TestUrl() {
252 return GURL("about:blank");
253 }
254
255 virtual bool SetUpSourceSurface(const char* wait_message) OVERRIDE {
236 if (IsForceCompositingModeEnabled()) 256 if (IsForceCompositingModeEnabled())
237 return false; // See comment in SetUpCommandLine(). 257 return false; // See comment in SetUpCommandLine().
238 NavigateToURL(shell(), GURL("about:blank")); 258
259 content::DOMMessageQueue message_queue;
260 NavigateToURL(shell(), TestUrl());
261 if (wait_message != NULL) {
262 std::string result(wait_message);
263 if (!message_queue.WaitForMessage(&result)) {
264 EXPECT_TRUE(false) << "WaitForMessage " << result << " failed.";
265 return false;
266 }
267 }
268
239 WaitForCopySourceReady(); 269 WaitForCopySourceReady();
240 // Return whether the renderer left accelerated compositing turned off. 270 // Return whether the renderer left accelerated compositing turned off.
241 return !GetRenderWidgetHost()->is_accelerated_compositing_active(); 271 return !GetRenderWidgetHost()->is_accelerated_compositing_active();
242 } 272 }
243 }; 273 };
244 274
245 class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber { 275 class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
246 public: 276 public:
247 FakeFrameSubscriber( 277 FakeFrameSubscriber(
248 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback) 278 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 // is disabled. 315 // is disabled.
286 IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest, 316 IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest,
287 CopyFromBackingStore) { 317 CopyFromBackingStore) {
288 RunBasicCopyFromBackingStoreTest(); 318 RunBasicCopyFromBackingStoreTest();
289 } 319 }
290 320
291 // Tests that the callback passed to CopyFromBackingStore is always called, 321 // Tests that the callback passed to CopyFromBackingStore is always called,
292 // even when the RenderWidgetHost is deleting in the middle of an async copy. 322 // even when the RenderWidgetHost is deleting in the middle of an async copy.
293 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, 323 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
294 CopyFromBackingStore_CallbackDespiteDelete) { 324 CopyFromBackingStore_CallbackDespiteDelete) {
295 SET_UP_SURFACE_OR_PASS_TEST(); 325 SET_UP_SURFACE_OR_PASS_TEST(NULL);
296 326
297 base::RunLoop run_loop; 327 base::RunLoop run_loop;
298 GetRenderViewHost()->CopyFromBackingStore( 328 GetRenderViewHost()->CopyFromBackingStore(
299 gfx::Rect(), 329 gfx::Rect(),
300 frame_size(), 330 frame_size(),
301 base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore, 331 base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
302 base::Unretained(this), run_loop.QuitClosure())); 332 base::Unretained(this), run_loop.QuitClosure()));
303 // Delete the surface before the callback is run. 333 // Delete the surface before the callback is run.
304 GetRenderWidgetHostViewPort()->AcceleratedSurfaceRelease(); 334 GetRenderWidgetHostViewPort()->AcceleratedSurfaceRelease();
305 run_loop.Run(); 335 run_loop.Run();
306 336
307 EXPECT_EQ(1, callback_invoke_count()); 337 EXPECT_EQ(1, callback_invoke_count());
308 } 338 }
309 339
310 // Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is 340 // Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
311 // always called, even when the RenderWidgetHost is deleting in the middle of 341 // always called, even when the RenderWidgetHost is deleting in the middle of
312 // an async copy. 342 // an async copy.
313 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, 343 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
314 CopyFromCompositingSurface_CallbackDespiteDelete) { 344 CopyFromCompositingSurface_CallbackDespiteDelete) {
315 SET_UP_SURFACE_OR_PASS_TEST(); 345 SET_UP_SURFACE_OR_PASS_TEST(NULL);
316 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort(); 346 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
317 if (!view->CanCopyToVideoFrame()) { 347 if (!view->CanCopyToVideoFrame()) {
318 LOG(WARNING) << 348 LOG(WARNING) <<
319 ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() " 349 ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
320 "not supported on this platform."); 350 "not supported on this platform.");
321 return; 351 return;
322 } 352 }
323 353
324 base::RunLoop run_loop; 354 base::RunLoop run_loop;
325 scoped_refptr<media::VideoFrame> dest = 355 scoped_refptr<media::VideoFrame> dest =
326 media::VideoFrame::CreateBlackFrame(frame_size()); 356 media::VideoFrame::CreateBlackFrame(frame_size());
327 view->CopyFromCompositingSurfaceToVideoFrame( 357 view->CopyFromCompositingSurfaceToVideoFrame(
328 gfx::Rect(view->GetViewBounds().size()), dest, base::Bind( 358 gfx::Rect(view->GetViewBounds().size()), dest, base::Bind(
329 &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface, 359 &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface,
330 base::Unretained(this), run_loop.QuitClosure())); 360 base::Unretained(this), run_loop.QuitClosure()));
331 // Delete the surface before the callback is run. 361 // Delete the surface before the callback is run.
332 view->AcceleratedSurfaceRelease(); 362 view->AcceleratedSurfaceRelease();
333 run_loop.Run(); 363 run_loop.Run();
334 364
335 EXPECT_EQ(1, callback_invoke_count()); 365 EXPECT_EQ(1, callback_invoke_count());
336 } 366 }
337 367
338 // With compositing turned off, no platforms should support the 368 // With compositing turned off, no platforms should support the
339 // CopyFromCompositingSurfaceToVideoFrame() API. 369 // CopyFromCompositingSurfaceToVideoFrame() API.
340 IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest, 370 IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest,
341 CopyFromCompositingSurfaceToVideoFrameCallbackTest) { 371 CopyFromCompositingSurfaceToVideoFrameCallbackTest) {
342 SET_UP_SURFACE_OR_PASS_TEST(); 372 SET_UP_SURFACE_OR_PASS_TEST(NULL);
343 EXPECT_FALSE(GetRenderWidgetHostViewPort()->CanCopyToVideoFrame()); 373 EXPECT_FALSE(GetRenderWidgetHostViewPort()->CanCopyToVideoFrame());
344 } 374 }
345 375
346 // Test basic frame subscription functionality. We subscribe, and then run 376 // Test basic frame subscription functionality. We subscribe, and then run
347 // until at least one DeliverFrameCallback has been invoked. 377 // until at least one DeliverFrameCallback has been invoked.
348 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, 378 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
349 FrameSubscriberTest) { 379 FrameSubscriberTest) {
350 SET_UP_SURFACE_OR_PASS_TEST(); 380 SET_UP_SURFACE_OR_PASS_TEST(NULL);
351 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort(); 381 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
352 if (!view->CanSubscribeFrame()) { 382 if (!view->CanSubscribeFrame()) {
353 LOG(WARNING) << ("Blindly passing this test: Frame subscription not " 383 LOG(WARNING) << ("Blindly passing this test: Frame subscription not "
354 "supported on this platform."); 384 "supported on this platform.");
355 return; 385 return;
356 } 386 }
357 #if defined(USE_AURA) 387 #if defined(USE_AURA)
358 if (ui::IsTestCompositorEnabled()) { 388 if (ui::IsTestCompositorEnabled()) {
359 LOG(WARNING) << ("Blindly passing this test: Aura test compositor doesn't " 389 LOG(WARNING) << ("Blindly passing this test: Aura test compositor doesn't "
360 "support frame subscription."); 390 "support frame subscription.");
(...skipping 13 matching lines...) Expand all
374 view->BeginFrameSubscription(subscriber.Pass()); 404 view->BeginFrameSubscription(subscriber.Pass());
375 run_loop.Run(); 405 run_loop.Run();
376 view->EndFrameSubscription(); 406 view->EndFrameSubscription();
377 407
378 EXPECT_LE(1, callback_invoke_count()); 408 EXPECT_LE(1, callback_invoke_count());
379 EXPECT_LE(1, frames_captured()); 409 EXPECT_LE(1, frames_captured());
380 } 410 }
381 411
382 // Test that we can copy twice from an accelerated composited page. 412 // Test that we can copy twice from an accelerated composited page.
383 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) { 413 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
384 SET_UP_SURFACE_OR_PASS_TEST(); 414 SET_UP_SURFACE_OR_PASS_TEST(NULL);
385 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort(); 415 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
386 if (!view->CanCopyToVideoFrame()) { 416 if (!view->CanCopyToVideoFrame()) {
387 LOG(WARNING) << ("Blindly passing this test: " 417 LOG(WARNING) << ("Blindly passing this test: "
388 "CopyFromCompositingSurfaceToVideoFrame() not supported " 418 "CopyFromCompositingSurfaceToVideoFrame() not supported "
389 "on this platform."); 419 "on this platform.");
390 return; 420 return;
391 } 421 }
392 422
393 base::RunLoop run_loop; 423 base::RunLoop run_loop;
394 scoped_refptr<media::VideoFrame> first_output = 424 scoped_refptr<media::VideoFrame> first_output =
(...skipping 16 matching lines...) Expand all
411 base::Unretained(this), 441 base::Unretained(this),
412 base::MessageLoopProxy::current(), 442 base::MessageLoopProxy::current(),
413 run_loop.QuitClosure(), 443 run_loop.QuitClosure(),
414 base::Time::Now())); 444 base::Time::Now()));
415 run_loop.Run(); 445 run_loop.Run();
416 446
417 EXPECT_EQ(2, callback_invoke_count()); 447 EXPECT_EQ(2, callback_invoke_count());
418 EXPECT_EQ(2, frames_captured()); 448 EXPECT_EQ(2, frames_captured());
419 } 449 }
420 450
451 class CompositingRenderWidgetHostViewBrowserTestTabCapture
452 : public CompositingRenderWidgetHostViewBrowserTest {
453 public:
454 CompositingRenderWidgetHostViewBrowserTestTabCapture()
455 : expected_copy_from_compositing_surface_result_(false),
456 allowable_error_(0),
457 test_url_("data:text/html,<!doctype html>") {}
458
459 virtual void SetUp() OVERRIDE {
460 ui::DisableTestCompositor();
461 CompositingRenderWidgetHostViewBrowserTest::SetUp();
462 }
463
464 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
465 // TODO(Hubbe): This code is very similar to some code in
466 // gpu_feature_browsertest.cc, and should really be shared in a common
467 // location.
468 if (!command_line->HasSwitch(switches::kUseGpuInTests)) {
469 CHECK(!command_line->HasSwitch(switches::kUseGL))
470 << "kUseGL must not be set by test framework code!";
471 command_line->AppendSwitchASCII(switches::kUseGL,
472 gfx::kGLImplementationOSMesaName);
473 }
474 }
475
476 void CopyFromCompositingSurfaceCallback(base::Closure quit_callback,
477 bool result,
478 const SkBitmap& bitmap) {
479 EXPECT_EQ(expected_copy_from_compositing_surface_result_, result);
480
481 const SkBitmap& expected_bitmap =
482 expected_copy_from_compositing_surface_bitmap_;
483 EXPECT_EQ(expected_bitmap.width(), bitmap.width());
484 EXPECT_EQ(expected_bitmap.height(), bitmap.height());
485 EXPECT_EQ(expected_bitmap.config(), bitmap.config());
486 SkAutoLockPixels expected_bitmap_lock(expected_bitmap);
487 SkAutoLockPixels bitmap_lock(bitmap);
488 int fails = 0;
489 for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
490 for (int j = 0; j < bitmap.height() && fails < 10; ++j) {
491 SkColor expected_color = expected_bitmap.getColor(i, j);
492 SkColor color = bitmap.getColor(i, j);
493 EXPECT_NEAR(expected_color, color, allowable_error_)
494 << "expected_color: " << std::hex << expected_color
495 << " color: " << color
496 << " Failed at " << std::dec << i << ", " << j
497 << " Failure " << ++fails;
498 }
499 }
500 EXPECT_LT(fails, 10);
501
502 quit_callback.Run();
503 }
504
505 void SetExpectedCopyFromCompositingSurfaceResult(bool result,
506 const SkBitmap& bitmap) {
507 expected_copy_from_compositing_surface_result_ = result;
508 expected_copy_from_compositing_surface_bitmap_ = bitmap;
509 }
510
511 void SetAllowableError(int amount) { allowable_error_ = amount; }
512
513 virtual GURL TestUrl() OVERRIDE {
514 return GURL(test_url_);
515 }
516
517 void SetTestUrl(std::string url) { test_url_ = url; }
518
519 private:
520 bool expected_copy_from_compositing_surface_result_;
521 SkBitmap expected_copy_from_compositing_surface_bitmap_;
522 int allowable_error_;
523 std::string test_url_;
524 };
525
526 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
527 CopyFromCompositingSurface_Origin_Unscaled) {
528 SetTestUrl("data:text/html,<!doctype html>"
529 "<div class='left'>"
530 " <div class='right'></div>"
531 "</div>"
532 "<style>"
533 "body { padding: 0; margin: 0; }"
534 ".left { position: absolute;"
535 " background: #0ff;"
536 " width: 200px;"
537 " height: 300px;"
538 "}"
539 ".right { position: absolute;"
540 " left: 200px;"
541 " background: #ff0;"
542 " width: 200px;"
543 " height: 300px;"
544 "}"
545 "</style>"
546 "<script>"
547 " domAutomationController.setAutomationId(0);"
548 " domAutomationController.send(\"DONE\");"
549 "</script>");
550
551 SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
552
553 RenderViewHost* const rwh =
554 shell()->web_contents()->GetRenderViewHost();
555 RenderWidgetHostViewPort* rwhvp =
556 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
557
558 // The page is loaded in the renderer, wait for a new frame to arrive.
559 uint32 frame = rwhvp->RendererFrameNumber();
560 RenderWidgetHostImpl::From(rwh)->ScheduleComposite();
piman 2013/07/02 01:49:09 So, ScheduleComposite early-outs if we're not in c
danakj 2013/07/03 01:08:45 I think that's okay. We already waited until we re
561 while (rwhvp->RendererFrameNumber() == frame)
562 GiveItSomeTime();
563
564 gfx::Rect bounds = gfx::Rect(400, 300);
565 EXPECT_LE(bounds.width(), rwhvp->GetViewBounds().width());
566 EXPECT_LE(bounds.height(), rwhvp->GetViewBounds().height());
567
568 gfx::Size out_size = bounds.size();
569
570 SkBitmap expected_bitmap;
571 expected_bitmap.setConfig(
572 SkBitmap::kARGB_8888_Config, out_size.width(), out_size.height());
573 expected_bitmap.allocPixels();
574 // Left half is #0ff.
575 expected_bitmap.eraseARGB(255, 0, 255, 255);
576 // Right half is #ff0.
577 {
578 SkAutoLockPixels lock(expected_bitmap);
579 for (int i = 0; i < out_size.width() / 2; ++i) {
580 for (int j = 0; j < out_size.height(); ++j) {
581 *expected_bitmap.getAddr32(out_size.width() / 2 + i, j) =
582 SkColorSetARGB(255, 255, 255, 0);
583 }
584 }
585 }
586 SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap);
587
588 base::RunLoop run_loop;
589 base::Callback<void(bool, const SkBitmap&)> callback =
590 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
591 CopyFromCompositingSurfaceCallback,
592 base::Unretained(this),
593 run_loop.QuitClosure());
594 rwhvp->CopyFromCompositingSurface(bounds, out_size, callback);
595 run_loop.Run();
596 }
597
598 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
599 CopyFromCompositingSurface_Origin_Scaled) {
600 SetTestUrl("data:text/html,<!doctype html>"
601 "<div class='left'>"
602 " <div class='right'></div>"
603 "</div>"
604 "<style>"
605 "body { padding: 0; margin: 0; }"
606 ".left { position: absolute;"
607 " background: #0ff;"
608 " width: 200px;"
609 " height: 300px;"
610 "}"
611 ".right { position: absolute;"
612 " left: 200px;"
613 " background: #ff0;"
614 " width: 200px;"
615 " height: 300px;"
616 "}"
617 "</style>"
618 "<script>"
619 " domAutomationController.setAutomationId(0);"
620 " domAutomationController.send(\"DONE\");"
621 "</script>");
622
623 SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
624
625 RenderViewHost* const rwh =
626 shell()->web_contents()->GetRenderViewHost();
627 RenderWidgetHostViewPort* rwhvp =
628 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
629
630 // The page is loaded in the renderer, wait for a new frame to arrive.
631 uint32 frame = rwhvp->RendererFrameNumber();
632 RenderWidgetHostImpl::From(rwh)->ScheduleComposite();
633 while (rwhvp->RendererFrameNumber() == frame)
634 GiveItSomeTime();
635
636 gfx::Rect bounds = gfx::Rect(400, 300);
637 EXPECT_LE(bounds.width(), rwhvp->GetViewBounds().width());
638 EXPECT_LE(bounds.height(), rwhvp->GetViewBounds().height());
639
640 // Scale the output to 200x100.
641 gfx::Size out_size(200, 100);
642
643 SkBitmap expected_bitmap;
644 expected_bitmap.setConfig(
645 SkBitmap::kARGB_8888_Config, out_size.width(), out_size.height());
646 expected_bitmap.allocPixels();
647 // Left half is #0ff.
648 expected_bitmap.eraseARGB(255, 0, 255, 255);
649 // Right half is #ff0.
650 {
651 SkAutoLockPixels lock(expected_bitmap);
652 for (int i = 0; i < out_size.width() / 2; ++i) {
653 for (int j = 0; j < out_size.height(); ++j) {
654 *expected_bitmap.getAddr32(out_size.width() / 2 + i, j) =
655 SkColorSetARGB(255, 255, 255, 0);
656 }
657 }
658 }
659 SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap);
660
661 base::RunLoop run_loop;
662 base::Callback<void(bool, const SkBitmap&)> callback =
663 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
664 CopyFromCompositingSurfaceCallback,
665 base::Unretained(this),
666 run_loop.QuitClosure());
667 rwhvp->CopyFromCompositingSurface(bounds, out_size, callback);
668 run_loop.Run();
669 }
670
671 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
672 CopyFromCompositingSurface_Cropped_Unscaled) {
673 SetTestUrl("data:text/html,<!doctype html>"
674 "<div class='left'>"
675 " <div class='right'></div>"
676 "</div>"
677 "<style>"
678 "body { padding: 0; margin: 0; }"
679 ".left { position: absolute;"
680 " background: #0ff;"
681 " width: 200px;"
682 " height: 300px;"
683 "}"
684 ".right { position: absolute;"
685 " left: 200px;"
686 " background: #ff0;"
687 " width: 200px;"
688 " height: 300px;"
689 "}"
690 "</style>"
691 "<script>"
692 " domAutomationController.setAutomationId(0);"
693 " domAutomationController.send(\"DONE\");"
694 "</script>");
695
696 SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
697
698 RenderViewHost* const rwh =
699 shell()->web_contents()->GetRenderViewHost();
700 RenderWidgetHostViewPort* rwhvp =
701 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
702
703 // The page is loaded in the renderer, wait for a new frame to arrive.
704 uint32 frame = rwhvp->RendererFrameNumber();
705 RenderWidgetHostImpl::From(rwh)->ScheduleComposite();
706 while (rwhvp->RendererFrameNumber() == frame)
707 GiveItSomeTime();
708
709 gfx::Rect bounds = gfx::Rect(400, 300);
710 EXPECT_LE(bounds.width(), rwhvp->GetViewBounds().width());
711 EXPECT_LE(bounds.height(), rwhvp->GetViewBounds().height());
712
713 // Grab 60x60 pixels from the center of the tab contents.
714 bounds = gfx::Rect(bounds.CenterPoint() - gfx::Vector2d(30, 30),
715 gfx::Size(60, 60));
716 gfx::Size out_size = bounds.size();
717
718 SkBitmap expected_bitmap;
719 expected_bitmap.setConfig(
720 SkBitmap::kARGB_8888_Config, out_size.width(), out_size.height());
721 expected_bitmap.allocPixels();
722 // Left half is #0ff.
723 expected_bitmap.eraseARGB(255, 0, 255, 255);
724 // Right half is #ff0.
725 {
726 SkAutoLockPixels lock(expected_bitmap);
727 for (int i = 0; i < out_size.width() / 2; ++i) {
728 for (int j = 0; j < out_size.height(); ++j) {
729 *expected_bitmap.getAddr32(out_size.width() / 2 + i, j) =
730 SkColorSetARGB(255, 255, 255, 0);
731 }
732 }
733 }
734 SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap);
735
736 base::RunLoop run_loop;
737 base::Callback<void(bool, const SkBitmap&)> callback =
738 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
739 CopyFromCompositingSurfaceCallback,
740 base::Unretained(this),
741 run_loop.QuitClosure());
742 rwhvp->CopyFromCompositingSurface(bounds, out_size, callback);
743 run_loop.Run();
744 }
745
746 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTestTabCapture,
747 CopyFromCompositingSurface_Cropped_Scaled) {
748 SetTestUrl("data:text/html,<!doctype html>"
749 "<div class='left'>"
750 " <div class='right'></div>"
751 "</div>"
752 "<style>"
753 "body { padding: 0; margin: 0; }"
754 ".left { position: absolute;"
755 " background: #0ff;"
756 " width: 200px;"
757 " height: 300px;"
758 "}"
759 ".right { position: absolute;"
760 " left: 200px;"
761 " background: #ff0;"
762 " width: 200px;"
763 " height: 300px;"
764 "}"
765 "</style>"
766 "<script>"
767 " domAutomationController.setAutomationId(0);"
768 " domAutomationController.send(\"DONE\");"
769 "</script>");
770
771 SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
772
773 RenderViewHost* const rwh =
774 shell()->web_contents()->GetRenderViewHost();
775 RenderWidgetHostViewPort* rwhvp =
776 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
777
778 // The page is loaded in the renderer, wait for a new frame to arrive.
779 uint32 frame = rwhvp->RendererFrameNumber();
780 RenderWidgetHostImpl::From(rwh)->ScheduleComposite();
781 while (rwhvp->RendererFrameNumber() == frame)
782 GiveItSomeTime();
783
784 gfx::Rect bounds = gfx::Rect(400, 300);
785 EXPECT_LE(bounds.width(), rwhvp->GetViewBounds().width());
786 EXPECT_LE(bounds.height(), rwhvp->GetViewBounds().height());
787
788 // Grab 60x60 pixels from the center of the tab contents.
789 bounds = gfx::Rect(bounds.CenterPoint() - gfx::Vector2d(30, 30),
790 gfx::Size(60, 60));
791
792 // Scale to 20 x 10.
793 gfx::Size out_size(20, 10);
794
795 SkBitmap expected_bitmap;
796 expected_bitmap.setConfig(
797 SkBitmap::kARGB_8888_Config, out_size.width(), out_size.height());
798 expected_bitmap.allocPixels();
799 // Left half is #0ff.
800 expected_bitmap.eraseARGB(255, 0, 255, 255);
801 // Right half is #ff0.
802 {
803 SkAutoLockPixels lock(expected_bitmap);
804 for (int i = 0; i < out_size.width() / 2; ++i) {
805 for (int j = 0; j < out_size.height(); ++j) {
806 *expected_bitmap.getAddr32(out_size.width() / 2 + i, j) =
807 SkColorSetARGB(255, 255, 255, 0);
808 }
809 }
810 }
811 SetExpectedCopyFromCompositingSurfaceResult(true, expected_bitmap);
812
813 base::RunLoop run_loop;
814 base::Callback<void(bool, const SkBitmap&)> callback =
815 base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
816 CopyFromCompositingSurfaceCallback,
817 base::Unretained(this),
818 run_loop.QuitClosure());
819 rwhvp->CopyFromCompositingSurface(bounds, out_size, callback);
820 run_loop.Run();
821 }
822
421 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 823 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
422 824
423 } // namespace 825 } // namespace
424 } // namespace content 826 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698