Dismiss autofill popup on screen orientation change.
[chromium-blink-merge.git] / cc / output / output_surface_unittest.cc
blob42cbc14eb85d97873bc77f2feff9dc851a4747b1
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/output_surface.h"
7 #include "base/test/test_simple_task_runner.h"
8 #include "cc/debug/test_context_provider.h"
9 #include "cc/debug/test_web_graphics_context_3d.h"
10 #include "cc/output/managed_memory_policy.h"
11 #include "cc/output/output_surface_client.h"
12 #include "cc/output/software_output_device.h"
13 #include "cc/test/fake_output_surface.h"
14 #include "cc/test/fake_output_surface_client.h"
15 #include "cc/test/scheduler_test_common.h"
16 #include "gpu/GLES2/gl2extchromium.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace cc {
20 namespace {
22 class TestOutputSurface : public OutputSurface {
23 public:
24 explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider)
25 : OutputSurface(context_provider) {}
27 explicit TestOutputSurface(
28 scoped_ptr<cc::SoftwareOutputDevice> software_device)
29 : OutputSurface(software_device.Pass()) {}
31 TestOutputSurface(scoped_refptr<ContextProvider> context_provider,
32 scoped_ptr<cc::SoftwareOutputDevice> software_device)
33 : OutputSurface(context_provider, software_device.Pass()) {}
35 bool InitializeNewContext3d(
36 scoped_refptr<ContextProvider> new_context_provider) {
37 return InitializeAndSetContext3d(new_context_provider,
38 scoped_refptr<ContextProvider>());
41 using OutputSurface::ReleaseGL;
43 void OnVSyncParametersChangedForTesting(base::TimeTicks timebase,
44 base::TimeDelta interval) {
45 OnVSyncParametersChanged(timebase, interval);
48 void BeginFrameForTesting() {
49 OutputSurface::BeginFrame(BeginFrameArgs::CreateExpiredForTesting());
52 void DidSwapBuffersForTesting() {
53 DidSwapBuffers();
56 int pending_swap_buffers() {
57 return pending_swap_buffers_;
60 void OnSwapBuffersCompleteForTesting() {
61 OnSwapBuffersComplete(NULL);
64 void SetAlternateRetroactiveBeginFramePeriod(base::TimeDelta period) {
65 alternate_retroactive_begin_frame_period_ = period;
68 protected:
69 virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE {
70 // For testing purposes, we check immediately rather than posting a task.
71 CheckForRetroactiveBeginFrame();
74 virtual base::TimeDelta AlternateRetroactiveBeginFramePeriod() OVERRIDE {
75 return alternate_retroactive_begin_frame_period_;
78 base::TimeDelta alternate_retroactive_begin_frame_period_;
81 TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientSuccess) {
82 TestOutputSurface output_surface(TestContextProvider::Create());
83 EXPECT_FALSE(output_surface.HasClient());
85 FakeOutputSurfaceClient client;
86 EXPECT_TRUE(output_surface.BindToClient(&client));
87 EXPECT_TRUE(output_surface.HasClient());
88 EXPECT_FALSE(client.deferred_initialize_called());
90 // Verify DidLoseOutputSurface callback is hooked up correctly.
91 EXPECT_FALSE(client.did_lose_output_surface_called());
92 output_surface.context_provider()->Context3d()->loseContextCHROMIUM(
93 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
94 EXPECT_TRUE(client.did_lose_output_surface_called());
97 TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientFailure) {
98 scoped_refptr<TestContextProvider> context_provider =
99 TestContextProvider::Create();
101 // Lose the context so BindToClient fails.
102 context_provider->TestContext3d()->set_times_make_current_succeeds(0);
104 TestOutputSurface output_surface(context_provider);
105 EXPECT_FALSE(output_surface.HasClient());
107 FakeOutputSurfaceClient client;
108 EXPECT_FALSE(output_surface.BindToClient(&client));
109 EXPECT_FALSE(output_surface.HasClient());
112 class OutputSurfaceTestInitializeNewContext3d : public ::testing::Test {
113 public:
114 OutputSurfaceTestInitializeNewContext3d()
115 : context_provider_(TestContextProvider::Create()),
116 output_surface_(
117 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice)) {}
119 protected:
120 void BindOutputSurface() {
121 EXPECT_TRUE(output_surface_.BindToClient(&client_));
122 EXPECT_TRUE(output_surface_.HasClient());
125 void InitializeNewContextExpectFail() {
126 EXPECT_FALSE(output_surface_.InitializeNewContext3d(context_provider_));
127 EXPECT_TRUE(output_surface_.HasClient());
129 EXPECT_FALSE(output_surface_.context_provider());
130 EXPECT_TRUE(output_surface_.software_device());
133 scoped_refptr<TestContextProvider> context_provider_;
134 TestOutputSurface output_surface_;
135 FakeOutputSurfaceClient client_;
138 TEST_F(OutputSurfaceTestInitializeNewContext3d, Success) {
139 BindOutputSurface();
140 EXPECT_FALSE(client_.deferred_initialize_called());
142 EXPECT_TRUE(output_surface_.InitializeNewContext3d(context_provider_));
143 EXPECT_TRUE(client_.deferred_initialize_called());
144 EXPECT_EQ(context_provider_, output_surface_.context_provider());
146 EXPECT_FALSE(client_.did_lose_output_surface_called());
147 context_provider_->Context3d()->loseContextCHROMIUM(
148 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
149 EXPECT_TRUE(client_.did_lose_output_surface_called());
151 output_surface_.ReleaseGL();
152 EXPECT_FALSE(output_surface_.context_provider());
155 TEST_F(OutputSurfaceTestInitializeNewContext3d, Context3dMakeCurrentFails) {
156 BindOutputSurface();
157 context_provider_->TestContext3d()->set_times_make_current_succeeds(0);
158 InitializeNewContextExpectFail();
161 TEST_F(OutputSurfaceTestInitializeNewContext3d, ClientDeferredInitializeFails) {
162 BindOutputSurface();
163 client_.set_deferred_initialize_result(false);
164 InitializeNewContextExpectFail();
167 TEST(OutputSurfaceTest, BeginFrameEmulation) {
168 TestOutputSurface output_surface(TestContextProvider::Create());
169 EXPECT_FALSE(output_surface.HasClient());
171 FakeOutputSurfaceClient client;
172 EXPECT_TRUE(output_surface.BindToClient(&client));
173 EXPECT_TRUE(output_surface.HasClient());
174 EXPECT_FALSE(client.deferred_initialize_called());
176 // Initialize BeginFrame emulation
177 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
178 new base::TestSimpleTaskRunner;
179 bool throttle_frame_production = true;
180 const base::TimeDelta display_refresh_interval =
181 BeginFrameArgs::DefaultInterval();
183 output_surface.InitializeBeginFrameEmulation(
184 task_runner.get(),
185 throttle_frame_production,
186 display_refresh_interval);
188 output_surface.SetMaxFramesPending(2);
189 output_surface.SetAlternateRetroactiveBeginFramePeriod(
190 base::TimeDelta::FromSeconds(-1));
192 // We should start off with 0 BeginFrames
193 EXPECT_EQ(client.begin_frame_count(), 0);
194 EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
196 // We should not have a pending task until a BeginFrame has been requested.
197 EXPECT_FALSE(task_runner->HasPendingTask());
198 output_surface.SetNeedsBeginFrame(true);
199 EXPECT_TRUE(task_runner->HasPendingTask());
201 // BeginFrame should be called on the first tick.
202 task_runner->RunPendingTasks();
203 EXPECT_EQ(client.begin_frame_count(), 1);
204 EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
206 // BeginFrame should not be called when there is a pending BeginFrame.
207 task_runner->RunPendingTasks();
208 EXPECT_EQ(client.begin_frame_count(), 1);
209 EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
211 // DidSwapBuffers should clear the pending BeginFrame.
212 output_surface.DidSwapBuffersForTesting();
213 EXPECT_EQ(client.begin_frame_count(), 1);
214 EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
215 task_runner->RunPendingTasks();
216 EXPECT_EQ(client.begin_frame_count(), 2);
217 EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
219 // BeginFrame should be throttled by pending swap buffers.
220 output_surface.DidSwapBuffersForTesting();
221 EXPECT_EQ(client.begin_frame_count(), 2);
222 EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
223 task_runner->RunPendingTasks();
224 EXPECT_EQ(client.begin_frame_count(), 2);
225 EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
227 // SwapAck should decrement pending swap buffers and unblock BeginFrame again.
228 output_surface.OnSwapBuffersCompleteForTesting();
229 EXPECT_EQ(client.begin_frame_count(), 2);
230 EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
231 task_runner->RunPendingTasks();
232 EXPECT_EQ(client.begin_frame_count(), 3);
233 EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
235 // Calling SetNeedsBeginFrame again indicates a swap did not occur but
236 // the client still wants another BeginFrame.
237 output_surface.SetNeedsBeginFrame(true);
238 task_runner->RunPendingTasks();
239 EXPECT_EQ(client.begin_frame_count(), 4);
240 EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
242 // Disabling SetNeedsBeginFrame should prevent further BeginFrames.
243 output_surface.SetNeedsBeginFrame(false);
244 task_runner->RunPendingTasks();
245 EXPECT_FALSE(task_runner->HasPendingTask());
246 EXPECT_EQ(client.begin_frame_count(), 4);
247 EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
250 TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) {
251 TestOutputSurface output_surface(TestContextProvider::Create());
252 EXPECT_FALSE(output_surface.HasClient());
254 FakeOutputSurfaceClient client;
255 EXPECT_TRUE(output_surface.BindToClient(&client));
256 EXPECT_TRUE(output_surface.HasClient());
257 EXPECT_FALSE(client.deferred_initialize_called());
259 output_surface.SetMaxFramesPending(2);
261 // Enable retroactive BeginFrames.
262 output_surface.SetAlternateRetroactiveBeginFramePeriod(
263 base::TimeDelta::FromSeconds(100000));
265 // Optimistically injected BeginFrames should be throttled if
266 // SetNeedsBeginFrame is false...
267 output_surface.SetNeedsBeginFrame(false);
268 output_surface.BeginFrameForTesting();
269 EXPECT_EQ(client.begin_frame_count(), 0);
270 // ...and retroactively triggered by a SetNeedsBeginFrame.
271 output_surface.SetNeedsBeginFrame(true);
272 EXPECT_EQ(client.begin_frame_count(), 1);
274 // Optimistically injected BeginFrames should be throttled by pending
275 // BeginFrames...
276 output_surface.BeginFrameForTesting();
277 EXPECT_EQ(client.begin_frame_count(), 1);
278 // ...and retroactively triggered by a SetNeedsBeginFrame.
279 output_surface.SetNeedsBeginFrame(true);
280 EXPECT_EQ(client.begin_frame_count(), 2);
281 // ...or retroactively triggered by a Swap.
282 output_surface.BeginFrameForTesting();
283 EXPECT_EQ(client.begin_frame_count(), 2);
284 output_surface.DidSwapBuffersForTesting();
285 EXPECT_EQ(client.begin_frame_count(), 3);
286 EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
288 // Optimistically injected BeginFrames should be by throttled by pending
289 // swap buffers...
290 output_surface.DidSwapBuffersForTesting();
291 EXPECT_EQ(client.begin_frame_count(), 3);
292 EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
293 output_surface.BeginFrameForTesting();
294 EXPECT_EQ(client.begin_frame_count(), 3);
295 // ...and retroactively triggered by OnSwapBuffersComplete
296 output_surface.OnSwapBuffersCompleteForTesting();
297 EXPECT_EQ(client.begin_frame_count(), 4);
300 TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) {
301 scoped_refptr<TestContextProvider> context_provider =
302 TestContextProvider::Create();
304 TestOutputSurface output_surface(context_provider);
305 EXPECT_FALSE(output_surface.HasClient());
307 FakeOutputSurfaceClient client;
308 EXPECT_TRUE(output_surface.BindToClient(&client));
309 EXPECT_TRUE(output_surface.HasClient());
310 EXPECT_FALSE(client.deferred_initialize_called());
312 base::TimeDelta big_interval = base::TimeDelta::FromSeconds(1000);
314 // Initialize BeginFrame emulation
315 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
316 new base::TestSimpleTaskRunner;
317 bool throttle_frame_production = true;
318 const base::TimeDelta display_refresh_interval = big_interval;
320 output_surface.InitializeBeginFrameEmulation(
321 task_runner.get(),
322 throttle_frame_production,
323 display_refresh_interval);
325 // We need to subtract an epsilon from Now() because some platforms have
326 // a slow clock.
327 output_surface.OnVSyncParametersChangedForTesting(
328 base::TimeTicks::Now() - base::TimeDelta::FromMilliseconds(1),
329 display_refresh_interval);
331 output_surface.SetMaxFramesPending(2);
332 output_surface.SetAlternateRetroactiveBeginFramePeriod(
333 base::TimeDelta::FromSeconds(-1));
335 // We should start off with 0 BeginFrames
336 EXPECT_EQ(client.begin_frame_count(), 0);
337 EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
339 // The first SetNeedsBeginFrame(true) should start a retroactive BeginFrame.
340 output_surface.SetNeedsBeginFrame(true);
341 EXPECT_TRUE(task_runner->HasPendingTask());
342 EXPECT_GT(task_runner->NextPendingTaskDelay(), big_interval / 2);
343 EXPECT_EQ(client.begin_frame_count(), 1);
345 output_surface.SetNeedsBeginFrame(false);
346 EXPECT_TRUE(task_runner->HasPendingTask());
347 EXPECT_EQ(client.begin_frame_count(), 1);
349 // The second SetNeedBeginFrame(true) should not retroactively start a
350 // BeginFrame if the timestamp would be the same as the previous BeginFrame.
351 output_surface.SetNeedsBeginFrame(true);
352 EXPECT_TRUE(task_runner->HasPendingTask());
353 EXPECT_EQ(client.begin_frame_count(), 1);
356 TEST(OutputSurfaceTest, MemoryAllocation) {
357 scoped_refptr<TestContextProvider> context_provider =
358 TestContextProvider::Create();
360 TestOutputSurface output_surface(context_provider);
362 FakeOutputSurfaceClient client;
363 EXPECT_TRUE(output_surface.BindToClient(&client));
365 ManagedMemoryPolicy policy(0);
366 policy.bytes_limit_when_visible = 1234;
367 policy.priority_cutoff_when_visible =
368 ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY;
369 policy.bytes_limit_when_not_visible = 4567;
370 policy.priority_cutoff_when_not_visible =
371 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING;
373 bool discard_backbuffer_when_not_visible = false;
375 context_provider->SetMemoryAllocation(policy,
376 discard_backbuffer_when_not_visible);
377 EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible);
378 EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY,
379 client.memory_policy().priority_cutoff_when_visible);
380 EXPECT_EQ(4567u, client.memory_policy().bytes_limit_when_not_visible);
381 EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
382 client.memory_policy().priority_cutoff_when_not_visible);
383 EXPECT_FALSE(client.discard_backbuffer_when_not_visible());
385 discard_backbuffer_when_not_visible = true;
386 context_provider->SetMemoryAllocation(policy,
387 discard_backbuffer_when_not_visible);
388 EXPECT_TRUE(client.discard_backbuffer_when_not_visible());
390 policy.priority_cutoff_when_visible =
391 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING;
392 policy.priority_cutoff_when_not_visible =
393 ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE;
394 context_provider->SetMemoryAllocation(policy,
395 discard_backbuffer_when_not_visible);
396 EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
397 client.memory_policy().priority_cutoff_when_visible);
398 EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE,
399 client.memory_policy().priority_cutoff_when_not_visible);
401 // 0 bytes limit should be ignored.
402 policy.bytes_limit_when_visible = 0;
403 context_provider->SetMemoryAllocation(policy,
404 discard_backbuffer_when_not_visible);
405 EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible);
408 } // namespace
409 } // namespace cc