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

Unified 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: More clean-up. Fixes for Aura. Disabled tests for Android and IOS platforms. Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/renderer_host/render_widget_host_view_browsertest.cc
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 2235486de06d10e9c562f9f8a73b9eebf561fc14..75718aad56c551bd0c28b979cf61d0ab631c07c6 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -13,69 +13,132 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_paths.h"
+#include "content/public/common/content_switches.h"
#include "content/shell/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
#include "media/base/video_frame.h"
#include "net/base/net_util.h"
-#include "skia/ext/platform_canvas.h"
#include "ui/compositor/compositor_setup.h"
#if defined(OS_MACOSX)
#include "ui/surface/io_surface_support_mac.h"
#endif
namespace content {
+namespace {
+// Common base class for browser tests. This is subclassed twice: Once to test
+// the browser in forced-compositing mode, and once to test with compositing
+// mode disabled.
class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
public:
- RenderWidgetHostViewBrowserTest() : finish_called_(false), size_(400, 300) {}
+ RenderWidgetHostViewBrowserTest()
+ : frame_size_(400, 300),
+ callback_invoke_count_(0),
+ frames_captured_(0) {}
virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
+ ui::DisableTestCompositor();
ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_));
}
- virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
- ui::DisableTestCompositor();
+ // Overridden in subclasses to source either a compositing surface or a
+ // backing store.
+ virtual void SetUpSourceSurface() = 0;
+ virtual bool IsCopySourceReady() = 0;
+
+ int callback_invoke_count() const {
+ return callback_invoke_count_;
}
- bool CheckAcceleratedCompositingActive() {
- RenderWidgetHostImpl* impl =
- RenderWidgetHostImpl::From(
- shell()->web_contents()->GetRenderWidgetHostView()->
- GetRenderWidgetHost());
- return impl->is_accelerated_compositing_active();
+ int frames_captured() const {
+ return frames_captured_;
}
- bool CheckCompositingSurface() {
-#if defined(OS_WIN)
- if (!GpuDataManagerImpl::GetInstance()->IsUsingAcceleratedSurface())
- return false;
-#endif
+ const gfx::Size& frame_size() const {
+ return frame_size_;
+ }
- RenderViewHost* const rwh =
- shell()->web_contents()->GetRenderViewHost();
- RenderWidgetHostViewPort* rwhvp =
- static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
- bool ret = !rwhvp->GetCompositingSurface().is_null();
-#if defined(OS_MACOSX)
- ret &= rwhvp->HasAcceleratedSurface(gfx::Size());
-#endif
- return ret;
+ const base::FilePath& test_dir() const {
+ return test_dir_;
}
- bool SetupCompositingSurface() {
-#if defined(OS_MACOSX)
- if (!IOSurfaceSupport::Initialize())
- return false;
-#endif
- NavigateToURL(shell(), net::FilePathToFileURL(
- test_dir_.AppendASCII("rwhv_compositing_animation.html")));
- if (!CheckAcceleratedCompositingActive())
- return false;
+ RenderViewHost* GetRenderViewHost() const {
+ RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
+ CHECK(rvh);
+ return rvh;
+ }
- // The page is now accelerated composited but a compositing surface might
- // not be available immediately so wait for it.
- while (!CheckCompositingSurface()) {
+ RenderWidgetHostImpl* GetRenderWidgetHost() const {
+ RenderWidgetHostImpl* const rwh = RenderWidgetHostImpl::From(
+ shell()->web_contents()->GetRenderWidgetHostView()->
+ GetRenderWidgetHost());
+ CHECK(rwh);
+ return rwh;
+ }
+
+ RenderWidgetHostViewPort* GetRenderWidgetHostViewPort() const {
+ RenderWidgetHostViewPort* const view =
+ RenderWidgetHostViewPort::FromRWHV(GetRenderViewHost()->GetView());
+ CHECK(view);
+ return view;
+ }
+
+ // Callback when using CopyFromBackingStore() API.
+ void FinishCopyFromBackingStore(const base::Closure& quit_closure,
+ bool frame_captured,
+ const SkBitmap& bitmap) {
+ ++callback_invoke_count_;
+ if (frame_captured) {
+ ++frames_captured_;
+ EXPECT_FALSE(bitmap.empty());
+ }
+ if (!quit_closure.is_null())
+ quit_closure.Run();
+ }
+
+ // Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
+ void FinishCopyFromCompositingSurface(const base::Closure& quit_closure,
+ bool frame_captured) {
+ ++callback_invoke_count_;
+ if (frame_captured)
+ ++frames_captured_;
+ if (!quit_closure.is_null())
+ quit_closure.Run();
+ }
+
+ // Callback when using frame subscriber API.
+ void FrameDelivered(const scoped_refptr<base::MessageLoopProxy>& loop,
+ base::Closure quit_closure,
+ base::Time timestamp,
+ bool frame_captured) {
+ ++callback_invoke_count_;
+ if (frame_captured)
+ ++frames_captured_;
+ if (!quit_closure.is_null())
+ loop->PostTask(FROM_HERE, quit_closure);
+ }
+
+ // Copy one frame using the CopyFromBackingStore API.
+ void RunBasicCopyFromBackingStoreTest() {
+ SetUpSourceSurface();
+
+ base::RunLoop run_loop;
+ GetRenderViewHost()->CopyFromBackingStore(
+ gfx::Rect(),
+ frame_size(),
+ base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
+ base::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+
+ EXPECT_EQ(1, callback_invoke_count());
+ EXPECT_EQ(1, frames_captured());
+ }
+
+ protected:
+ // Waits until the source is available for copying.
+ void WaitForCopySourceReady() {
+ while (!IsCopySourceReady()) {
base::RunLoop run_loop;
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
@@ -83,39 +146,72 @@ class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
base::TimeDelta::FromMilliseconds(10));
run_loop.Run();
}
- return true;
}
- bool SetupNonCompositing() {
+ private:
+ const gfx::Size frame_size_;
+ base::FilePath test_dir_;
+ int callback_invoke_count_;
+ int frames_captured_;
+};
+
+class RenderWidgetHostViewBrowserTest_Compositing
Ken Russell (switch to Gerrit) 2013/04/30 23:23:02 The "_" here and in the subclass below doesn't rea
miu 2013/05/01 00:19:36 Done. Was concerned about what people might try i
+ : public RenderWidgetHostViewBrowserTest {
+ public:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kForceCompositingMode);
+ }
+
+ virtual void SetUpSourceSurface() OVERRIDE {
+#if defined(OS_MACOSX)
+ ASSERT_TRUE(IOSurfaceSupport::Initialize());
+#endif
NavigateToURL(shell(), net::FilePathToFileURL(
- test_dir_.AppendASCII("rwhv_compositing_static.html")));
- return !CheckCompositingSurface();
+ test_dir().AppendASCII("rwhv_compositing_animation.html")));
+#if !defined(USE_AURA)
+ ASSERT_TRUE(GetRenderWidgetHost()->is_accelerated_compositing_active());
+#endif
+
+ // The page is now accelerated composited but a compositing surface might
+ // not be available immediately so wait for it.
+ WaitForCopySourceReady();
}
- void FinishCopyFromBackingStore(bool expected_result,
- const base::Closure& quit_closure,
- bool result,
- const SkBitmap& bitmap) {
- quit_closure.Run();
- EXPECT_EQ(expected_result, result);
- if (expected_result)
- EXPECT_FALSE(bitmap.empty());
- finish_called_ = true;
+ virtual bool IsCopySourceReady() OVERRIDE {
+#if defined(OS_WIN)
+ if (!GpuDataManagerImpl::GetInstance()->IsUsingAcceleratedSurface())
+ return false;
+#endif
+
+ RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
+ bool ret = !view->GetCompositingSurface().is_null();
+#if defined(OS_MACOSX)
+ ret &= view->HasAcceleratedSurface(gfx::Size());
+#endif
+ return ret;
+ }
+};
+
+class RenderWidgetHostViewBrowserTest_NonCompositing
+ : public RenderWidgetHostViewBrowserTest {
+ public:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
}
- void FinishCopyFromCompositingSurface(bool expected_result,
- const base::Closure& quit_closure,
- bool result) {
- if (!quit_closure.is_null())
- quit_closure.Run();
- EXPECT_EQ(expected_result, result);
- finish_called_ = true;
+ virtual void SetUpSourceSurface() OVERRIDE {
+ // Assumption: Browser-internal pages will cause RenderWidget to turn off
+ // compositing.
Ken Russell (switch to Gerrit) 2013/04/30 23:23:02 Wasn't the point of the subclass to avoid these as
miu 2013/05/01 00:19:36 Ah! A should have removed the comment. The comma
+ NavigateToURL(shell(), GURL("about:blank"));
+ WaitForCopySourceReady();
}
- protected:
- base::FilePath test_dir_;
- bool finish_called_;
- gfx::Size size_;
+ virtual bool IsCopySourceReady() OVERRIDE {
+ // Note: Passing false to GetBackingStore() asks for the backing store
+ // without forcing its creation. We want to the browser to create it via
+ // its normal mechanism.
+ return GetRenderWidgetHost()->GetBackingStore(false) != NULL;
Ken Russell (switch to Gerrit) 2013/04/30 23:23:02 Do you want to make assertions that the composited
miu 2013/05/01 00:19:36 Good point. Done.
+ }
};
class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
@@ -146,177 +242,142 @@ class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
DeliverFrameCallback callback_;
};
-#if defined(OS_MACOSX) || defined(OS_WIN)
+// Disable tests for Android and IOS as these platforms have incomplete
+// implementation.
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
-static void DeliverFrameFunc(const scoped_refptr<base::MessageLoopProxy>& loop,
- base::Closure quit_closure,
- bool* frame_captured_out,
- base::Time timestamp,
- bool frame_captured) {
- *frame_captured_out = frame_captured;
- if (!quit_closure.is_null())
- loop->PostTask(FROM_HERE, quit_closure);
+// The CopyFromBackingStore() API should work on all platforms when compositing
+// is enabled.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest_Compositing,
+ CopyFromBackingStore) {
+ RunBasicCopyFromBackingStoreTest();
}
-#endif
+// The CopyFromBackingStore() API should work on all platforms when compositing
+// is disabled.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest_NonCompositing,
+ CopyFromBackingStore) {
+ RunBasicCopyFromBackingStoreTest();
+}
-#if defined(OS_MACOSX)
-// Tests that the callback passed to CopyFromBackingStore is always called, even
-// when the RenderWidgetHost is deleting in the middle of an async copy.
-IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest,
- MacAsyncCopyFromBackingStoreCallbackTest) {
- if (!SetupCompositingSurface()) {
- LOG(WARNING) << "Accelerated compositing not running.";
- return;
- }
+// Tests that the callback passed to CopyFromBackingStore is always called,
+// even when the RenderWidgetHost is deleting in the middle of an async copy.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest_Compositing,
+ CopyFromBackingStore_CallbackDespiteDelete) {
+ SetUpSourceSurface();
base::RunLoop run_loop;
- RenderViewHost* const rwh =
- shell()->web_contents()->GetRenderViewHost();
- RenderWidgetHostViewPort* rwhvp =
- static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
-
- rwh->CopyFromBackingStore(
+ GetRenderViewHost()->CopyFromBackingStore(
gfx::Rect(),
- size_,
+ frame_size(),
base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
- base::Unretained(this), false, run_loop.QuitClosure()));
-
- // Delete the surface before the callback is run. This is synchronous until
- // we get to the copy_timer_, so we will always end up in the destructor
- // before the timer fires.
- rwhvp->AcceleratedSurfaceRelease();
+ base::Unretained(this), run_loop.QuitClosure()));
+ // Delete the surface before the callback is run.
+ GetRenderWidgetHostViewPort()->AcceleratedSurfaceRelease();
run_loop.Run();
- EXPECT_TRUE(finish_called_);
+ EXPECT_EQ(1, callback_invoke_count());
}
// Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
// always called, even when the RenderWidgetHost is deleting in the middle of
// an async copy.
-IN_PROC_BROWSER_TEST_F(
- RenderWidgetHostViewBrowserTest,
- MacAsyncCopyFromCompositingSurfaceToVideoFrameCallbackTest) {
- if (!SetupCompositingSurface()) {
- LOG(WARNING) << "Accelerated compositing not running.";
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest_Compositing,
+ CopyFromCompositingSurface_CallbackDespiteDelete) {
+ SetUpSourceSurface();
+ RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
+ if (!view->CanCopyToVideoFrame()) {
+ LOG(WARNING) << ("CopyFromCompositingSurfaceToVideoFrame() not supported "
+ "on this platform.");
return;
}
base::RunLoop run_loop;
- RenderViewHost* const rwh =
- shell()->web_contents()->GetRenderViewHost();
- RenderWidgetHostViewPort* rwhvp =
- static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
-
scoped_refptr<media::VideoFrame> dest =
- media::VideoFrame::CreateBlackFrame(size_);
- rwhvp->CopyFromCompositingSurfaceToVideoFrame(
- gfx::Rect(rwhvp->GetViewBounds().size()), dest, base::Bind(
+ media::VideoFrame::CreateBlackFrame(frame_size());
+ view->CopyFromCompositingSurfaceToVideoFrame(
+ gfx::Rect(view->GetViewBounds().size()), dest, base::Bind(
&RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface,
- base::Unretained(this), false, run_loop.QuitClosure()));
-
- // Delete the surface before the callback is run. This is synchronous until
- // we get to the copy_timer_, so we will always end up in the destructor
- // before the timer fires.
- rwhvp->AcceleratedSurfaceRelease();
+ base::Unretained(this), run_loop.QuitClosure()));
+ // Delete the surface before the callback is run.
+ view->AcceleratedSurfaceRelease();
run_loop.Run();
- ASSERT_TRUE(finish_called_);
+ EXPECT_EQ(1, callback_invoke_count());
}
-#endif
-
-#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(OS_MACOSX)
-IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest,
- FrameSubscriberTest) {
- if (!SetupCompositingSurface()) {
- LOG(WARNING) << "Accelerated compositing not running.";
- return;
- }
- base::RunLoop run_loop;
- RenderWidgetHostViewPort* view = RenderWidgetHostViewPort::FromRWHV(
- shell()->web_contents()->GetRenderViewHost()->GetView());
- ASSERT_TRUE(view);
+// With compositing turned off, no platforms should support the
+// CopyFromCompositingSurfaceToVideoFrame() API.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest_NonCompositing,
+ CopyFromCompositingSurfaceToVideoFrameCallbackTest) {
+ SetUpSourceSurface();
+ EXPECT_FALSE(GetRenderWidgetHostViewPort()->CanCopyToVideoFrame());
+}
+// Test basic frame subscription functionality. We subscribe, and then run
+// until at least one DeliverFrameCallback has been invoked.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest_Compositing,
+ FrameSubscriberTest) {
+ SetUpSourceSurface();
+ RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
if (!view->CanSubscribeFrame()) {
- LOG(WARNING) << "Frame subscription no supported on this platform.";
+ LOG(WARNING) << "Frame subscription not supported on this platform.";
return;
ncarter (slow) 2013/05/01 00:04:32 I expect this will happen on XP.
}
- bool frame_captured = false;
+ base::RunLoop run_loop;
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
- new FakeFrameSubscriber(base::Bind(&DeliverFrameFunc,
- base::MessageLoopProxy::current(),
- run_loop.QuitClosure(),
- &frame_captured)));
+ new FakeFrameSubscriber(
+ base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
+ base::Unretained(this),
+ base::MessageLoopProxy::current(),
+ run_loop.QuitClosure())));
view->BeginFrameSubscription(subscriber.Pass());
run_loop.Run();
view->EndFrameSubscription();
- EXPECT_TRUE(frame_captured);
-}
-// Test copying from backing store when page is non-accelerated-composited.
-// Flaky. http://crbug.com/224351
-#if defined(OS_MACOSX) || defined(OS_WIN)
-#define MAYBE_CopyFromBackingStore DISABLED_CopyFromBackingStore
-#else
-#define MAYBE_CopyFromBackingStore CopyFromBackingStore
-#endif
-IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest,
- MAYBE_CopyFromBackingStore) {
- SetupNonCompositing();
- base::RunLoop run_loop;
-
- shell()->web_contents()->GetRenderViewHost()->CopyFromBackingStore(
- gfx::Rect(),
- size_,
- base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
- base::Unretained(this), true, run_loop.QuitClosure()));
- run_loop.Run();
-
- EXPECT_TRUE(finish_called_);
+ EXPECT_LE(1, callback_invoke_count());
+ EXPECT_LE(1, frames_captured());
}
-#endif
-#if defined(OS_MACOSX)
// Test that we can copy twice from an accelerated composited page.
-// This test is only running on Mac because this is the only platform that
-// we can reliably detect that accelerated surface is in use.
-IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest, CopyTwice) {
- if (!SetupCompositingSurface()) {
- LOG(WARNING) << "Accelerated compositing not running.";
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest_Compositing, CopyTwice) {
+ SetUpSourceSurface();
+ RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
+ if (!view->CanCopyToVideoFrame()) {
+ LOG(WARNING) << ("CopyFromCompositingSurfaceToVideoFrame() not supported "
+ "on this platform.");
ncarter (slow) 2013/05/01 00:04:32 I expect this will happen on XP.
return;
}
base::RunLoop run_loop;
- RenderViewHost* const rwh =
- shell()->web_contents()->GetRenderViewHost();
- RenderWidgetHostViewPort* rwhvp =
- static_cast<RenderWidgetHostViewPort*>(rwh->GetView());
- scoped_refptr<media::VideoFrame> dest =
- media::VideoFrame::CreateBlackFrame(size_);
-
- bool first_frame_captured = false;
- bool second_frame_captured = false;
- rwhvp->CopyFromCompositingSurfaceToVideoFrame(
- gfx::Rect(rwhvp->GetViewBounds().size()), dest,
- base::Bind(&DeliverFrameFunc,
+ scoped_refptr<media::VideoFrame> first_output =
+ media::VideoFrame::CreateBlackFrame(frame_size());
+ ASSERT_TRUE(first_output);
+ scoped_refptr<media::VideoFrame> second_output =
+ media::VideoFrame::CreateBlackFrame(frame_size());
+ ASSERT_TRUE(second_output);
+ view->CopyFromCompositingSurfaceToVideoFrame(
+ gfx::Rect(view->GetViewBounds().size()), first_output,
+ base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
+ base::Unretained(this),
base::MessageLoopProxy::current(),
base::Closure(),
- &first_frame_captured,
base::Time::Now()));
- rwhvp->CopyFromCompositingSurfaceToVideoFrame(
- gfx::Rect(rwhvp->GetViewBounds().size()), dest,
- base::Bind(&DeliverFrameFunc,
+ view->CopyFromCompositingSurfaceToVideoFrame(
+ gfx::Rect(view->GetViewBounds().size()), second_output,
+ base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
+ base::Unretained(this),
base::MessageLoopProxy::current(),
run_loop.QuitClosure(),
- &second_frame_captured,
base::Time::Now()));
run_loop.Run();
- EXPECT_TRUE(first_frame_captured);
- EXPECT_TRUE(second_frame_captured);
+ EXPECT_EQ(2, callback_invoke_count());
+ EXPECT_EQ(2, frames_captured());
}
-#endif
+#endif // !defined(OS_ANDROID) && !defined(OS_IOS)
+
+} // namespace
} // namespace content
« 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