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

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

Issue 14495016: Fix flaky test: RenderWidgetHostViewBrowserTest.CopyFromBackingStore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Improve comment regarding compositing mode maybe being tested. Created 7 years, 7 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_proxy.h" 6 #include "base/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/render_view_host.h" 14 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/content_paths.h" 16 #include "content/public/common/content_paths.h"
17 #include "content/public/common/content_switches.h"
16 #include "content/shell/shell.h" 18 #include "content/shell/shell.h"
17 #include "content/test/content_browser_test.h" 19 #include "content/test/content_browser_test.h"
18 #include "content/test/content_browser_test_utils.h" 20 #include "content/test/content_browser_test_utils.h"
19 #include "media/base/video_frame.h" 21 #include "media/base/video_frame.h"
20 #include "net/base/net_util.h" 22 #include "net/base/net_util.h"
21 #include "skia/ext/platform_canvas.h"
22 #include "ui/compositor/compositor_setup.h" 23 #include "ui/compositor/compositor_setup.h"
23 #if defined(OS_MACOSX) 24 #if defined(OS_MACOSX)
24 #include "ui/surface/io_surface_support_mac.h" 25 #include "ui/surface/io_surface_support_mac.h"
25 #endif 26 #endif
26 27
27 namespace content { 28 namespace content {
28 29 namespace {
30
31 // Convenience macro: Short-cicuit a pass for the tests where platform support
32 // for forced-compositing mode (or disabled-compositing mode) is lacking.
33 #define SET_UP_SURFACE_OR_PASS_TEST() \
34 if (!SetUpSourceSurface()) { \
35 LOG(WARNING) \
36 << ("Blindly passing this test: This platform does not support " \
37 "forced compositing (or forced-disabled compositing) mode."); \
38 return; \
39 }
40
41 // Common base class for browser tests. This is subclassed twice: Once to test
42 // the browser in forced-compositing mode, and once to test with compositing
43 // mode disabled.
29 class RenderWidgetHostViewBrowserTest : public ContentBrowserTest { 44 class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
30 public: 45 public:
31 RenderWidgetHostViewBrowserTest() : finish_called_(false), size_(400, 300) {} 46 RenderWidgetHostViewBrowserTest()
47 : frame_size_(400, 300),
48 callback_invoke_count_(0),
49 frames_captured_(0) {}
32 50
33 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 51 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
34 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_)); 52 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_));
35 } 53 ContentBrowserTest::SetUpInProcessBrowserTestFixture();
36 54 }
55
56 // Attempts to set up the source surface. Returns false if unsupported on the
57 // current platform.
58 virtual bool SetUpSourceSurface() = 0;
59
60 int callback_invoke_count() const {
61 return callback_invoke_count_;
62 }
63
64 int frames_captured() const {
65 return frames_captured_;
66 }
67
68 const gfx::Size& frame_size() const {
69 return frame_size_;
70 }
71
72 const base::FilePath& test_dir() const {
73 return test_dir_;
74 }
75
76 RenderViewHost* GetRenderViewHost() const {
77 RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
78 CHECK(rvh);
79 return rvh;
80 }
81
82 RenderWidgetHostImpl* GetRenderWidgetHost() const {
83 RenderWidgetHostImpl* const rwh = RenderWidgetHostImpl::From(
84 shell()->web_contents()->GetRenderWidgetHostView()->
85 GetRenderWidgetHost());
86 CHECK(rwh);
87 return rwh;
88 }
89
90 RenderWidgetHostViewPort* GetRenderWidgetHostViewPort() const {
91 RenderWidgetHostViewPort* const view =
92 RenderWidgetHostViewPort::FromRWHV(GetRenderViewHost()->GetView());
93 CHECK(view);
94 return view;
95 }
96
97 // Callback when using CopyFromBackingStore() API.
98 void FinishCopyFromBackingStore(const base::Closure& quit_closure,
99 bool frame_captured,
100 const SkBitmap& bitmap) {
101 ++callback_invoke_count_;
102 if (frame_captured) {
103 ++frames_captured_;
104 EXPECT_FALSE(bitmap.empty());
105 }
106 if (!quit_closure.is_null())
107 quit_closure.Run();
108 }
109
110 // Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
111 void FinishCopyFromCompositingSurface(const base::Closure& quit_closure,
112 bool frame_captured) {
113 ++callback_invoke_count_;
114 if (frame_captured)
115 ++frames_captured_;
116 if (!quit_closure.is_null())
117 quit_closure.Run();
118 }
119
120 // Callback when using frame subscriber API.
121 void FrameDelivered(const scoped_refptr<base::MessageLoopProxy>& loop,
122 base::Closure quit_closure,
123 base::Time timestamp,
124 bool frame_captured) {
125 ++callback_invoke_count_;
126 if (frame_captured)
127 ++frames_captured_;
128 if (!quit_closure.is_null())
129 loop->PostTask(FROM_HERE, quit_closure);
130 }
131
132 // Copy one frame using the CopyFromBackingStore API.
133 void RunBasicCopyFromBackingStoreTest() {
134 SET_UP_SURFACE_OR_PASS_TEST();
135
136 // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
137 // Windows), the operation will fail until the first "present" has been
138 // made.
139 int count_attempts = 0;
140 while (true) {
141 ++count_attempts;
142 base::RunLoop run_loop;
143 GetRenderViewHost()->CopyFromBackingStore(
144 gfx::Rect(),
145 frame_size(),
146 base::Bind(
147 &RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
148 base::Unretained(this),
149 run_loop.QuitClosure()));
150 run_loop.Run();
151
152 if (frames_captured())
153 break;
154 else
155 GiveItSomeTime();
156 }
157
158 EXPECT_EQ(count_attempts, callback_invoke_count());
159 EXPECT_EQ(1, frames_captured());
160 }
161
162 protected:
163 // Waits until the source is available for copying.
164 void WaitForCopySourceReady() {
165 while (!GetRenderWidgetHostViewPort()->IsSurfaceAvailableForCopy())
166 GiveItSomeTime();
167 }
168
169 // Run the current message loop for a short time without unwinding the current
170 // call stack.
171 static void GiveItSomeTime() {
172 base::RunLoop run_loop;
173 MessageLoop::current()->PostDelayedTask(
174 FROM_HERE,
175 run_loop.QuitClosure(),
176 base::TimeDelta::FromMilliseconds(10));
177 run_loop.Run();
178 }
179
180 private:
181 const gfx::Size frame_size_;
182 base::FilePath test_dir_;
183 int callback_invoke_count_;
184 int frames_captured_;
185 };
186
187 class CompositingRenderWidgetHostViewBrowserTest
188 : public RenderWidgetHostViewBrowserTest {
189 public:
37 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 190 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
38 ui::DisableTestCompositor(); 191 // Note: Not appending kForceCompositingMode switch here, since not all bots
39 } 192 // support compositing. Some bots will run with compositing on, and others
40 193 // won't. Therefore, the call to SetUpSourceSurface() later on will detect
41 bool CheckAcceleratedCompositingActive() { 194 // whether compositing mode is actually on or not. If not, the tests will
42 RenderWidgetHostImpl* impl = 195 // pass blindly, logging a warning message, since we cannot test what the
43 RenderWidgetHostImpl::From( 196 // platform/implementation does not support.
44 shell()->web_contents()->GetRenderWidgetHostView()-> 197 RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line);
45 GetRenderWidgetHost()); 198 }
46 return impl->is_accelerated_compositing_active(); 199
47 } 200 virtual bool SetUpSourceSurface() OVERRIDE {
48 201 if (!IsForceCompositingModeEnabled())
49 bool CheckCompositingSurface() { 202 return false; // See comment in SetUpCommandLine().
50 #if defined(OS_WIN)
51 if (!GpuDataManagerImpl::GetInstance()->IsUsingAcceleratedSurface())
52 return false;
53 #endif
54
55 RenderViewHost* const rwh =
56 shell()->web_contents()->GetRenderViewHost();
57 RenderWidgetHostViewPort* rwhvp =
58 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
59 bool ret = !rwhvp->GetCompositingSurface().is_null();
60 #if defined(OS_MACOSX) 203 #if defined(OS_MACOSX)
61 ret &= rwhvp->HasAcceleratedSurface(gfx::Size()); 204 CHECK(IOSurfaceSupport::Initialize());
62 #endif
63 return ret;
64 }
65
66 bool SetupCompositingSurface() {
67 #if defined(OS_MACOSX)
68 if (!IOSurfaceSupport::Initialize())
69 return false;
70 #endif 205 #endif
71 NavigateToURL(shell(), net::FilePathToFileURL( 206 NavigateToURL(shell(), net::FilePathToFileURL(
72 test_dir_.AppendASCII("rwhv_compositing_animation.html"))); 207 test_dir().AppendASCII("rwhv_compositing_animation.html")));
73 if (!CheckAcceleratedCompositingActive()) 208 #if !defined(USE_AURA)
74 return false; 209 if (!GetRenderWidgetHost()->is_accelerated_compositing_active())
75 210 return false; // Renderer did not turn on accelerated compositing.
76 // The page is now accelerated composited but a compositing surface might 211 #endif
77 // not be available immediately so wait for it. 212
78 while (!CheckCompositingSurface()) { 213 // Using accelerated compositing, but a compositing surface might not be
79 base::RunLoop run_loop; 214 // available yet. So, wait for it.
80 base::MessageLoop::current()->PostDelayedTask( 215 WaitForCopySourceReady();
81 FROM_HERE,
82 run_loop.QuitClosure(),
83 base::TimeDelta::FromMilliseconds(10));
84 run_loop.Run();
85 }
86 return true; 216 return true;
87 } 217 }
88
89 bool SetupNonCompositing() {
90 NavigateToURL(shell(), net::FilePathToFileURL(
91 test_dir_.AppendASCII("rwhv_compositing_static.html")));
92 return !CheckCompositingSurface();
93 }
94
95 void FinishCopyFromBackingStore(bool expected_result,
96 const base::Closure& quit_closure,
97 bool result,
98 const SkBitmap& bitmap) {
99 quit_closure.Run();
100 EXPECT_EQ(expected_result, result);
101 if (expected_result)
102 EXPECT_FALSE(bitmap.empty());
103 finish_called_ = true;
104 }
105
106 void FinishCopyFromCompositingSurface(bool expected_result,
107 const base::Closure& quit_closure,
108 bool result) {
109 if (!quit_closure.is_null())
110 quit_closure.Run();
111 EXPECT_EQ(expected_result, result);
112 finish_called_ = true;
113 }
114
115 protected:
116 base::FilePath test_dir_;
117 bool finish_called_;
118 gfx::Size size_;
119 }; 218 };
120 219
220 class NonCompositingRenderWidgetHostViewBrowserTest
221 : public RenderWidgetHostViewBrowserTest {
222 public:
223 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
224 // Note: Appending the kDisableAcceleratedCompositing switch here, but there
225 // are some builds that only use compositing and will ignore this switch.
226 // Therefore, the call to SetUpSourceSurface() later on will detect whether
227 // compositing mode is actually off. If it's on, the tests will pass
228 // blindly, logging a warning message, since we cannot test what the
229 // platform/implementation does not support.
230 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
231 RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line);
232 }
233
234 virtual bool SetUpSourceSurface() OVERRIDE {
235 if (IsForceCompositingModeEnabled())
236 return false; // See comment in SetUpCommandLine().
237 NavigateToURL(shell(), GURL("about:blank"));
238 WaitForCopySourceReady();
239 // Return whether the renderer left accelerated compositing turned off.
240 return !GetRenderWidgetHost()->is_accelerated_compositing_active();
241 }
242 };
243
121 class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber { 244 class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
122 public: 245 public:
123 FakeFrameSubscriber( 246 FakeFrameSubscriber(
124 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback) 247 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback)
125 : callback_(callback) { 248 : callback_(callback) {
126 } 249 }
127 250
128 virtual bool ShouldCaptureFrame( 251 virtual bool ShouldCaptureFrame(
129 base::Time present_time, 252 base::Time present_time,
130 scoped_refptr<media::VideoFrame>* storage, 253 scoped_refptr<media::VideoFrame>* storage,
131 DeliverFrameCallback* callback) OVERRIDE { 254 DeliverFrameCallback* callback) OVERRIDE {
132 // Only allow one frame capture to be made. Otherwise, the compositor could 255 // Only allow one frame capture to be made. Otherwise, the compositor could
133 // start multiple captures, unbounded, and eventually its own limiter logic 256 // start multiple captures, unbounded, and eventually its own limiter logic
134 // will begin invoking |callback| with a |false| result. This flakes out 257 // will begin invoking |callback| with a |false| result. This flakes out
135 // the unit tests, since they receive a "failed" callback before the later 258 // the unit tests, since they receive a "failed" callback before the later
136 // "success" callbacks. 259 // "success" callbacks.
137 if (callback_.is_null()) 260 if (callback_.is_null())
138 return false; 261 return false;
139 *storage = media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100)); 262 *storage = media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100));
140 *callback = callback_; 263 *callback = callback_;
141 callback_.Reset(); 264 callback_.Reset();
142 return true; 265 return true;
143 } 266 }
144 267
145 private: 268 private:
146 DeliverFrameCallback callback_; 269 DeliverFrameCallback callback_;
147 }; 270 };
148 271
149 #if defined(OS_MACOSX) || defined(OS_WIN) 272 // Disable tests for Android and IOS as these platforms have incomplete
273 // implementation.
274 #if !defined(OS_ANDROID) && !defined(OS_IOS)
150 275
151 static void DeliverFrameFunc(const scoped_refptr<base::MessageLoopProxy>& loop, 276 // The CopyFromBackingStore() API should work on all platforms when compositing
152 base::Closure quit_closure, 277 // is enabled.
153 bool* frame_captured_out, 278 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
154 base::Time timestamp, 279 CopyFromBackingStore) {
155 bool frame_captured) { 280 RunBasicCopyFromBackingStoreTest();
156 *frame_captured_out = frame_captured;
157 if (!quit_closure.is_null())
158 loop->PostTask(FROM_HERE, quit_closure);
159 } 281 }
160 282
161 #endif 283 // The CopyFromBackingStore() API should work on all platforms when compositing
284 // is disabled.
285 IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest,
286 CopyFromBackingStore) {
287 RunBasicCopyFromBackingStoreTest();
288 }
162 289
163 #if defined(OS_MACOSX) 290 // Tests that the callback passed to CopyFromBackingStore is always called,
164 // Tests that the callback passed to CopyFromBackingStore is always called, even 291 // even when the RenderWidgetHost is deleting in the middle of an async copy.
165 // when the RenderWidgetHost is deleting in the middle of an async copy. 292 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
166 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, 293 CopyFromBackingStore_CallbackDespiteDelete) {
167 MacAsyncCopyFromBackingStoreCallbackTest) { 294 SET_UP_SURFACE_OR_PASS_TEST();
168 if (!SetupCompositingSurface()) {
169 LOG(WARNING) << "Accelerated compositing not running.";
170 return;
171 }
172 295
173 base::RunLoop run_loop; 296 base::RunLoop run_loop;
174 RenderViewHost* const rwh = 297 GetRenderViewHost()->CopyFromBackingStore(
175 shell()->web_contents()->GetRenderViewHost();
176 RenderWidgetHostViewPort* rwhvp =
177 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
178
179 rwh->CopyFromBackingStore(
180 gfx::Rect(), 298 gfx::Rect(),
181 size_, 299 frame_size(),
182 base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore, 300 base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
183 base::Unretained(this), false, run_loop.QuitClosure())); 301 base::Unretained(this), run_loop.QuitClosure()));
184 302 // Delete the surface before the callback is run.
185 // Delete the surface before the callback is run. This is synchronous until 303 GetRenderWidgetHostViewPort()->AcceleratedSurfaceRelease();
186 // we get to the copy_timer_, so we will always end up in the destructor
187 // before the timer fires.
188 rwhvp->AcceleratedSurfaceRelease();
189 run_loop.Run(); 304 run_loop.Run();
190 305
191 EXPECT_TRUE(finish_called_); 306 EXPECT_EQ(1, callback_invoke_count());
192 } 307 }
193 308
194 // Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is 309 // Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
195 // always called, even when the RenderWidgetHost is deleting in the middle of 310 // always called, even when the RenderWidgetHost is deleting in the middle of
196 // an async copy. 311 // an async copy.
197 IN_PROC_BROWSER_TEST_F( 312 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
198 RenderWidgetHostViewBrowserTest, 313 CopyFromCompositingSurface_CallbackDespiteDelete) {
199 MacAsyncCopyFromCompositingSurfaceToVideoFrameCallbackTest) { 314 SET_UP_SURFACE_OR_PASS_TEST();
200 if (!SetupCompositingSurface()) { 315 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
201 LOG(WARNING) << "Accelerated compositing not running."; 316 if (!view->CanCopyToVideoFrame()) {
317 LOG(WARNING) <<
318 ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
319 "not supported on this platform.");
202 return; 320 return;
203 } 321 }
204 322
205 base::RunLoop run_loop; 323 base::RunLoop run_loop;
206 RenderViewHost* const rwh =
207 shell()->web_contents()->GetRenderViewHost();
208 RenderWidgetHostViewPort* rwhvp =
209 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
210
211 scoped_refptr<media::VideoFrame> dest = 324 scoped_refptr<media::VideoFrame> dest =
212 media::VideoFrame::CreateBlackFrame(size_); 325 media::VideoFrame::CreateBlackFrame(frame_size());
213 rwhvp->CopyFromCompositingSurfaceToVideoFrame( 326 view->CopyFromCompositingSurfaceToVideoFrame(
214 gfx::Rect(rwhvp->GetViewBounds().size()), dest, base::Bind( 327 gfx::Rect(view->GetViewBounds().size()), dest, base::Bind(
215 &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface, 328 &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface,
216 base::Unretained(this), false, run_loop.QuitClosure())); 329 base::Unretained(this), run_loop.QuitClosure()));
217 330 // Delete the surface before the callback is run.
218 // Delete the surface before the callback is run. This is synchronous until 331 view->AcceleratedSurfaceRelease();
219 // we get to the copy_timer_, so we will always end up in the destructor
220 // before the timer fires.
221 rwhvp->AcceleratedSurfaceRelease();
222 run_loop.Run(); 332 run_loop.Run();
223 333
224 ASSERT_TRUE(finish_called_); 334 EXPECT_EQ(1, callback_invoke_count());
225 } 335 }
336
337 // With compositing turned off, no platforms should support the
338 // CopyFromCompositingSurfaceToVideoFrame() API.
339 IN_PROC_BROWSER_TEST_F(NonCompositingRenderWidgetHostViewBrowserTest,
340 CopyFromCompositingSurfaceToVideoFrameCallbackTest) {
341 SET_UP_SURFACE_OR_PASS_TEST();
342 EXPECT_FALSE(GetRenderWidgetHostViewPort()->CanCopyToVideoFrame());
343 }
344
345 // Test basic frame subscription functionality. We subscribe, and then run
346 // until at least one DeliverFrameCallback has been invoked.
347 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest,
348 FrameSubscriberTest) {
349 SET_UP_SURFACE_OR_PASS_TEST();
350 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
351 if (!view->CanSubscribeFrame()) {
352 LOG(WARNING) << ("Blindly passing this test: Frame subscription not "
353 "supported on this platform.");
354 return;
355 }
356 #if defined(USE_AURA)
357 if (ui::IsTestCompositorEnabled()) {
358 LOG(WARNING) << ("Blindly passing this test: Aura test compositor doesn't "
359 "support frame subscription.");
360 // TODO(miu): Aura test compositor should support frame subscription for
361 // testing. http://crbug.com/240572
362 return;
363 }
226 #endif 364 #endif
227 365
228 #if (defined(OS_WIN) && !defined(USE_AURA)) || defined(OS_MACOSX) 366 base::RunLoop run_loop;
229 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, 367 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
230 FrameSubscriberTest) { 368 new FakeFrameSubscriber(
231 if (!SetupCompositingSurface()) { 369 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
232 LOG(WARNING) << "Accelerated compositing not running."; 370 base::Unretained(this),
371 base::MessageLoopProxy::current(),
372 run_loop.QuitClosure())));
373 view->BeginFrameSubscription(subscriber.Pass());
374 run_loop.Run();
375 view->EndFrameSubscription();
376
377 EXPECT_LE(1, callback_invoke_count());
378 EXPECT_LE(1, frames_captured());
379 }
380
381 // Test that we can copy twice from an accelerated composited page.
382 IN_PROC_BROWSER_TEST_F(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
383 SET_UP_SURFACE_OR_PASS_TEST();
384 RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
385 if (!view->CanCopyToVideoFrame()) {
386 LOG(WARNING) << ("Blindly passing this test: "
387 "CopyFromCompositingSurfaceToVideoFrame() not supported "
388 "on this platform.");
233 return; 389 return;
234 } 390 }
235 391
236 base::RunLoop run_loop; 392 base::RunLoop run_loop;
237 RenderWidgetHostViewPort* view = RenderWidgetHostViewPort::FromRWHV( 393 scoped_refptr<media::VideoFrame> first_output =
238 shell()->web_contents()->GetRenderViewHost()->GetView()); 394 media::VideoFrame::CreateBlackFrame(frame_size());
239 ASSERT_TRUE(view); 395 ASSERT_TRUE(first_output);
240 396 scoped_refptr<media::VideoFrame> second_output =
241 if (!view->CanSubscribeFrame()) { 397 media::VideoFrame::CreateBlackFrame(frame_size());
242 LOG(WARNING) << "Frame subscription no supported on this platform."; 398 ASSERT_TRUE(second_output);
243 return; 399 view->CopyFromCompositingSurfaceToVideoFrame(
244 } 400 gfx::Rect(view->GetViewBounds().size()), first_output,
245 401 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
246 bool frame_captured = false; 402 base::Unretained(this),
247 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
248 new FakeFrameSubscriber(base::Bind(&DeliverFrameFunc,
249 base::MessageLoopProxy::current(),
250 run_loop.QuitClosure(),
251 &frame_captured)));
252 view->BeginFrameSubscription(subscriber.Pass());
253 run_loop.Run();
254 view->EndFrameSubscription();
255 EXPECT_TRUE(frame_captured);
256 }
257
258 // Test copying from backing store when page is non-accelerated-composited.
259 // Flaky. http://crbug.com/224351
260 #if defined(OS_MACOSX) || defined(OS_WIN)
261 #define MAYBE_CopyFromBackingStore DISABLED_CopyFromBackingStore
262 #else
263 #define MAYBE_CopyFromBackingStore CopyFromBackingStore
264 #endif
265 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest,
266 MAYBE_CopyFromBackingStore) {
267 SetupNonCompositing();
268 base::RunLoop run_loop;
269
270 shell()->web_contents()->GetRenderViewHost()->CopyFromBackingStore(
271 gfx::Rect(),
272 size_,
273 base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
274 base::Unretained(this), true, run_loop.QuitClosure()));
275 run_loop.Run();
276
277 EXPECT_TRUE(finish_called_);
278 }
279 #endif
280
281 #if defined(OS_MACOSX)
282 // Test that we can copy twice from an accelerated composited page.
283 // This test is only running on Mac because this is the only platform that
284 // we can reliably detect that accelerated surface is in use.
285 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, CopyTwice) {
286 if (!SetupCompositingSurface()) {
287 LOG(WARNING) << "Accelerated compositing not running.";
288 return;
289 }
290
291 base::RunLoop run_loop;
292 RenderViewHost* const rwh =
293 shell()->web_contents()->GetRenderViewHost();
294 RenderWidgetHostViewPort* rwhvp =
295 static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
296 scoped_refptr<media::VideoFrame> dest =
297 media::VideoFrame::CreateBlackFrame(size_);
298
299 bool first_frame_captured = false;
300 bool second_frame_captured = false;
301 rwhvp->CopyFromCompositingSurfaceToVideoFrame(
302 gfx::Rect(rwhvp->GetViewBounds().size()), dest,
303 base::Bind(&DeliverFrameFunc,
304 base::MessageLoopProxy::current(), 403 base::MessageLoopProxy::current(),
305 base::Closure(), 404 base::Closure(),
306 &first_frame_captured,
307 base::Time::Now())); 405 base::Time::Now()));
308 rwhvp->CopyFromCompositingSurfaceToVideoFrame( 406 view->CopyFromCompositingSurfaceToVideoFrame(
309 gfx::Rect(rwhvp->GetViewBounds().size()), dest, 407 gfx::Rect(view->GetViewBounds().size()), second_output,
310 base::Bind(&DeliverFrameFunc, 408 base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
409 base::Unretained(this),
311 base::MessageLoopProxy::current(), 410 base::MessageLoopProxy::current(),
312 run_loop.QuitClosure(), 411 run_loop.QuitClosure(),
313 &second_frame_captured,
314 base::Time::Now())); 412 base::Time::Now()));
315 run_loop.Run(); 413 run_loop.Run();
316 414
317 EXPECT_TRUE(first_frame_captured); 415 EXPECT_EQ(2, callback_invoke_count());
318 EXPECT_TRUE(second_frame_captured); 416 EXPECT_EQ(2, frames_captured());
319 } 417 }
320 #endif
321 418
419 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
420
421 } // namespace
322 } // namespace content 422 } // namespace content
OLDNEW
« no previous file with comments | « build/android/pylib/gtest/test_runner.py ('k') | content/test/data/rwhv_compositing_static.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698