Refactor WebsiteSettings to operate on a SecurityInfo
[chromium-blink-merge.git] / content / renderer / gpu / render_widget_compositor_unittest.cc
blobf1d7ec3246d68ee95bfec01143c81f0ca9270d34
1 // Copyright 2014 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 "content/renderer/gpu/render_widget_compositor.h"
7 #include "base/location.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "cc/output/begin_frame_args.h"
11 #include "cc/test/failure_output_surface.h"
12 #include "cc/trees/layer_tree_host.h"
13 #include "components/scheduler/renderer/renderer_scheduler.h"
14 #include "content/public/test/mock_render_thread.h"
15 #include "content/renderer/render_widget.h"
16 #include "content/test/fake_compositor_dependencies.h"
17 #include "content/test/fake_renderer_scheduler.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
22 using testing::AllOf;
23 using testing::Field;
25 namespace content {
26 namespace {
28 class MockWebWidget : public blink::WebWidget {
29 public:
30 MOCK_METHOD1(beginFrame, void(const blink::WebBeginFrameArgs& args));
33 class TestRenderWidget : public RenderWidget {
34 public:
35 explicit TestRenderWidget(CompositorDependencies* compositor_deps)
36 : RenderWidget(compositor_deps,
37 blink::WebPopupTypeNone,
38 blink::WebScreenInfo(),
39 true,
40 false,
41 false) {
42 webwidget_ = &mock_webwidget_;
45 MockWebWidget mock_webwidget_;
47 protected:
48 ~TestRenderWidget() override { webwidget_ = NULL; }
50 DISALLOW_COPY_AND_ASSIGN(TestRenderWidget);
53 class RenderWidgetCompositorTest : public testing::Test {
54 public:
55 RenderWidgetCompositorTest()
56 : compositor_deps_(new FakeCompositorDependencies),
57 render_widget_(new TestRenderWidget(compositor_deps_.get())),
58 render_widget_compositor_(
59 RenderWidgetCompositor::Create(render_widget_.get(),
60 compositor_deps_.get())) {}
61 ~RenderWidgetCompositorTest() override {}
63 protected:
64 base::MessageLoop loop_;
65 MockRenderThread render_thread_;
66 scoped_ptr<FakeCompositorDependencies> compositor_deps_;
67 scoped_refptr<TestRenderWidget> render_widget_;
68 scoped_ptr<RenderWidgetCompositor> render_widget_compositor_;
70 private:
71 DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositorTest);
74 TEST_F(RenderWidgetCompositorTest, BeginMainFrame) {
75 base::TimeTicks frame_time(base::TimeTicks() +
76 base::TimeDelta::FromSeconds(1));
77 base::TimeTicks deadline(base::TimeTicks() + base::TimeDelta::FromSeconds(2));
78 base::TimeDelta interval(base::TimeDelta::FromSeconds(3));
79 cc::BeginFrameArgs args(
80 cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
81 interval, cc::BeginFrameArgs::NORMAL));
83 EXPECT_CALL(render_widget_->mock_webwidget_,
84 beginFrame(AllOf(
85 Field(&blink::WebBeginFrameArgs::lastFrameTimeMonotonic, 1),
86 Field(&blink::WebBeginFrameArgs::deadline, 2),
87 Field(&blink::WebBeginFrameArgs::interval, 3))));
89 render_widget_compositor_->BeginMainFrame(args);
92 class RenderWidgetCompositorOutputSurface;
94 class RenderWidgetOutputSurface : public TestRenderWidget {
95 public:
96 explicit RenderWidgetOutputSurface(CompositorDependencies* compositor_deps)
97 : TestRenderWidget(compositor_deps), compositor_(NULL) {}
98 void SetCompositor(RenderWidgetCompositorOutputSurface* compositor);
100 scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback) override;
102 protected:
103 ~RenderWidgetOutputSurface() override {}
105 private:
106 RenderWidgetCompositorOutputSurface* compositor_;
108 DISALLOW_COPY_AND_ASSIGN(RenderWidgetOutputSurface);
111 // Verify that failing to create an output surface will cause the compositor
112 // to attempt to repeatedly create another output surface. After enough
113 // failures, verify that it attempts to create a fallback output surface.
114 // The use null output surface parameter allows testing whether failures
115 // from RenderWidget (couldn't create an output surface) vs failures from
116 // the compositor (couldn't bind the output surface) are handled identically.
117 class RenderWidgetCompositorOutputSurface : public RenderWidgetCompositor {
118 public:
119 RenderWidgetCompositorOutputSurface(RenderWidget* widget,
120 CompositorDependencies* compositor_deps)
121 : RenderWidgetCompositor(widget, compositor_deps),
122 num_failures_before_success_(0),
123 expected_successes_(0),
124 expected_fallback_successes_(0),
125 expected_requests_(0),
126 num_requests_(0),
127 num_requests_since_last_success_(0),
128 num_successes_(0),
129 num_fallback_successes_(0),
130 num_failures_(0),
131 last_create_was_fallback_(false),
132 use_null_output_surface_(true) {}
134 using RenderWidgetCompositor::Initialize;
136 scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback) {
137 EXPECT_EQ(num_requests_since_last_success_ >
138 OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK,
139 fallback);
140 last_create_was_fallback_ = fallback;
141 bool success = num_failures_ >= num_failures_before_success_;
142 if (success) {
143 scoped_ptr<cc::TestWebGraphicsContext3D> context =
144 cc::TestWebGraphicsContext3D::Create();
145 // Image support required for synchronous compositing.
146 context->set_support_image(true);
147 // Create delegating surface so that max_pending_frames = 1.
148 return cc::FakeOutputSurface::CreateDelegating3d(context.Pass());
150 return use_null_output_surface_
151 ? nullptr
152 : make_scoped_ptr(new cc::FailureOutputSurface(true));
155 // Force a new output surface to be created.
156 void SynchronousComposite() {
157 layer_tree_host()->DidLoseOutputSurface();
159 base::TimeTicks some_time;
160 layer_tree_host()->Composite(some_time);
163 void RequestNewOutputSurface() override {
164 ++num_requests_;
165 ++num_requests_since_last_success_;
166 RenderWidgetCompositor::RequestNewOutputSurface();
169 void DidInitializeOutputSurface() override {
170 if (last_create_was_fallback_)
171 ++num_fallback_successes_;
172 else
173 ++num_successes_;
175 if (num_requests_ == expected_requests_) {
176 EndTest();
177 } else {
178 num_requests_since_last_success_ = 0;
179 RenderWidgetCompositor::DidInitializeOutputSurface();
180 // Post the synchronous composite task so that it is not called
181 // reentrantly as a part of RequestNewOutputSurface.
182 base::ThreadTaskRunnerHandle::Get()->PostTask(
183 FROM_HERE,
184 base::Bind(&RenderWidgetCompositorOutputSurface::SynchronousComposite,
185 base::Unretained(this)));
189 void DidFailToInitializeOutputSurface() override {
190 ++num_failures_;
191 if (num_requests_ == expected_requests_) {
192 EndTest();
193 return;
196 RenderWidgetCompositor::DidFailToInitializeOutputSurface();
199 void SetUp(bool use_null_output_surface,
200 int num_failures_before_success,
201 int expected_successes,
202 int expected_fallback_succeses) {
203 use_null_output_surface_ = use_null_output_surface;
204 num_failures_before_success_ = num_failures_before_success;
205 expected_successes_ = expected_successes;
206 expected_fallback_successes_ = expected_fallback_succeses;
207 expected_requests_ = num_failures_before_success_ + expected_successes_ +
208 expected_fallback_successes_;
211 void EndTest() { base::MessageLoop::current()->Quit(); }
213 void AfterTest() {
214 EXPECT_EQ(num_failures_before_success_, num_failures_);
215 EXPECT_EQ(expected_successes_, num_successes_);
216 EXPECT_EQ(expected_fallback_successes_, num_fallback_successes_);
217 EXPECT_EQ(expected_requests_, num_requests_);
220 private:
221 int num_failures_before_success_;
222 int expected_successes_;
223 int expected_fallback_successes_;
224 int expected_requests_;
225 int num_requests_;
226 int num_requests_since_last_success_;
227 int num_successes_;
228 int num_fallback_successes_;
229 int num_failures_;
230 bool last_create_was_fallback_;
231 bool use_null_output_surface_;
233 DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositorOutputSurface);
236 class RenderWidgetCompositorOutputSurfaceTest : public testing::Test {
237 public:
238 RenderWidgetCompositorOutputSurfaceTest()
239 : compositor_deps_(new FakeCompositorDependencies),
240 render_widget_(new RenderWidgetOutputSurface(compositor_deps_.get())) {
241 render_widget_compositor_.reset(new RenderWidgetCompositorOutputSurface(
242 render_widget_.get(), compositor_deps_.get()));
243 render_widget_compositor_->Initialize();
244 render_widget_->SetCompositor(render_widget_compositor_.get());
247 void RunTest(bool use_null_output_surface,
248 int num_failures_before_success,
249 int expected_successes,
250 int expected_fallback_succeses) {
251 render_widget_compositor_->SetUp(
252 use_null_output_surface, num_failures_before_success,
253 expected_successes, expected_fallback_succeses);
254 render_widget_compositor_->StartCompositor();
255 base::ThreadTaskRunnerHandle::Get()->PostTask(
256 FROM_HERE,
257 base::Bind(&RenderWidgetCompositorOutputSurface::SynchronousComposite,
258 base::Unretained(render_widget_compositor_.get())));
259 base::MessageLoop::current()->Run();
260 render_widget_compositor_->AfterTest();
263 protected:
264 base::MessageLoop ye_olde_message_loope_;
265 MockRenderThread render_thread_;
266 scoped_ptr<FakeCompositorDependencies> compositor_deps_;
267 scoped_refptr<RenderWidgetOutputSurface> render_widget_;
268 scoped_ptr<RenderWidgetCompositorOutputSurface> render_widget_compositor_;
270 private:
271 DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositorOutputSurfaceTest);
274 scoped_ptr<cc::OutputSurface> RenderWidgetOutputSurface::CreateOutputSurface(
275 bool fallback) {
276 return compositor_->CreateOutputSurface(fallback);
279 void RenderWidgetOutputSurface::SetCompositor(
280 RenderWidgetCompositorOutputSurface* compositor) {
281 compositor_ = compositor;
284 TEST_F(RenderWidgetCompositorOutputSurfaceTest, SucceedOnce) {
285 RunTest(false, 0, 1, 0);
288 TEST_F(RenderWidgetCompositorOutputSurfaceTest, SucceedTwice) {
289 RunTest(false, 0, 2, 0);
292 TEST_F(RenderWidgetCompositorOutputSurfaceTest, FailOnceNull) {
293 static_assert(
294 RenderWidgetCompositor::OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK >= 2,
295 "Adjust the values of this test if this fails");
296 RunTest(true, 1, 1, 0);
299 TEST_F(RenderWidgetCompositorOutputSurfaceTest, FailOnceBind) {
300 static_assert(
301 RenderWidgetCompositor::OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK >= 2,
302 "Adjust the values of this test if this fails");
303 RunTest(false, 1, 1, 0);
306 TEST_F(RenderWidgetCompositorOutputSurfaceTest, FallbackSuccessNull) {
307 RunTest(true, RenderWidgetCompositor::OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK,
308 0, 1);
311 TEST_F(RenderWidgetCompositorOutputSurfaceTest, FallbackSuccessBind) {
312 RunTest(false, RenderWidgetCompositor::OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK,
313 0, 1);
316 TEST_F(RenderWidgetCompositorOutputSurfaceTest, FallbackSuccessNormalSuccess) {
317 // The first success is a fallback, but the next should not be a fallback.
318 RunTest(false, RenderWidgetCompositor::OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK,
319 1, 1);
322 } // namespace
323 } // namespace content