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

Side by Side Diff: cc/output/output_surface_unittest.cc

Issue 221833009: cc: Move scheduling logic out of OutputSurface (Closed) Base URL: http://git.chromium.org/chromium/src.git@swapAck2Sched11
Patch Set: rebase; sami's comments Created 6 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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 "cc/output/output_surface.h" 5 #include "cc/output/output_surface.h"
6 6
7 #include "base/test/test_simple_task_runner.h" 7 #include "base/test/test_simple_task_runner.h"
8 #include "cc/output/managed_memory_policy.h" 8 #include "cc/output/managed_memory_policy.h"
9 #include "cc/output/output_surface_client.h" 9 #include "cc/output/output_surface_client.h"
10 #include "cc/output/software_output_device.h" 10 #include "cc/output/software_output_device.h"
11 #include "cc/test/fake_output_surface.h" 11 #include "cc/test/fake_output_surface.h"
12 #include "cc/test/fake_output_surface_client.h" 12 #include "cc/test/fake_output_surface_client.h"
13 #include "cc/test/scheduler_test_common.h" 13 #include "cc/test/scheduler_test_common.h"
14 #include "cc/test/test_context_provider.h" 14 #include "cc/test/test_context_provider.h"
15 #include "cc/test/test_web_graphics_context_3d.h" 15 #include "cc/test/test_web_graphics_context_3d.h"
16 #include "gpu/GLES2/gl2extchromium.h" 16 #include "gpu/GLES2/gl2extchromium.h"
17 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/gfx/frame_time.h" 18 #include "ui/gfx/frame_time.h"
19 19
20 namespace cc { 20 namespace cc {
21 namespace { 21 namespace {
22 22
23 class TestOutputSurface : public OutputSurface { 23 class TestOutputSurface : public OutputSurface {
24 public: 24 public:
25 explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider) 25 explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider)
26 : OutputSurface(context_provider), 26 : OutputSurface(context_provider) {}
27 retroactive_begin_frame_deadline_enabled_(false),
28 override_retroactive_period_(false) {}
29 27
30 explicit TestOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) 28 explicit TestOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
31 : OutputSurface(software_device.Pass()), 29 : OutputSurface(software_device.Pass()) {}
32 retroactive_begin_frame_deadline_enabled_(false),
33 override_retroactive_period_(false) {}
34 30
35 TestOutputSurface(scoped_refptr<ContextProvider> context_provider, 31 TestOutputSurface(scoped_refptr<ContextProvider> context_provider,
36 scoped_ptr<SoftwareOutputDevice> software_device) 32 scoped_ptr<SoftwareOutputDevice> software_device)
37 : OutputSurface(context_provider, software_device.Pass()), 33 : OutputSurface(context_provider, software_device.Pass()) {}
38 retroactive_begin_frame_deadline_enabled_(false),
39 override_retroactive_period_(false) {}
40 34
41 bool InitializeNewContext3d( 35 bool InitializeNewContext3d(
42 scoped_refptr<ContextProvider> new_context_provider) { 36 scoped_refptr<ContextProvider> new_context_provider) {
43 return InitializeAndSetContext3d(new_context_provider, 37 return InitializeAndSetContext3d(new_context_provider,
44 scoped_refptr<ContextProvider>()); 38 scoped_refptr<ContextProvider>());
45 } 39 }
46 40
47 using OutputSurface::ReleaseGL; 41 using OutputSurface::ReleaseGL;
48 42
49 void CommitVSyncParametersForTesting(base::TimeTicks timebase, 43 void CommitVSyncParametersForTesting(base::TimeTicks timebase,
50 base::TimeDelta interval) { 44 base::TimeDelta interval) {
51 CommitVSyncParameters(timebase, interval); 45 CommitVSyncParameters(timebase, interval);
52 } 46 }
53 47
54 void BeginFrameForTesting() { 48 void BeginFrameForTesting() {
55 OutputSurface::BeginFrame(BeginFrameArgs::CreateExpiredForTesting()); 49 client_->BeginFrame(BeginFrameArgs::CreateExpiredForTesting());
56 } 50 }
57 51
58 void DidSwapBuffersForTesting() { 52 void DidSwapBuffersForTesting() { client_->DidSwapBuffers(); }
59 DidSwapBuffers();
60 }
61 53
62 void OnSwapBuffersCompleteForTesting() { 54 void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); }
63 OnSwapBuffersComplete();
64 }
65
66 void EnableRetroactiveBeginFrameDeadline(bool enable,
67 bool override_retroactive_period,
68 base::TimeDelta period_override) {
69 retroactive_begin_frame_deadline_enabled_ = enable;
70 override_retroactive_period_ = override_retroactive_period;
71 retroactive_period_override_ = period_override;
72 }
73 55
74 protected: 56 protected:
75 virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE {
76 // For testing purposes, we check immediately rather than posting a task.
77 CheckForRetroactiveBeginFrame();
78 }
79
80 virtual base::TimeTicks RetroactiveBeginFrameDeadline() OVERRIDE {
81 if (retroactive_begin_frame_deadline_enabled_) {
82 if (override_retroactive_period_) {
83 return skipped_begin_frame_args_.frame_time +
84 retroactive_period_override_;
85 } else {
86 return OutputSurface::RetroactiveBeginFrameDeadline();
87 }
88 }
89 return base::TimeTicks();
90 }
91
92 bool retroactive_begin_frame_deadline_enabled_;
93 bool override_retroactive_period_;
94 base::TimeDelta retroactive_period_override_;
95 }; 57 };
96 58
97 class TestSoftwareOutputDevice : public SoftwareOutputDevice { 59 class TestSoftwareOutputDevice : public SoftwareOutputDevice {
98 public: 60 public:
99 TestSoftwareOutputDevice(); 61 TestSoftwareOutputDevice();
100 virtual ~TestSoftwareOutputDevice(); 62 virtual ~TestSoftwareOutputDevice();
101 63
102 // Overriden from cc:SoftwareOutputDevice 64 // Overriden from cc:SoftwareOutputDevice
103 virtual void DiscardBackbuffer() OVERRIDE; 65 virtual void DiscardBackbuffer() OVERRIDE;
104 virtual void EnsureBackbuffer() OVERRIDE; 66 virtual void EnsureBackbuffer() OVERRIDE;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 context_provider_->UnboundTestContext3d()->set_context_lost(true); 171 context_provider_->UnboundTestContext3d()->set_context_lost(true);
210 InitializeNewContextExpectFail(); 172 InitializeNewContextExpectFail();
211 } 173 }
212 174
213 TEST_F(OutputSurfaceTestInitializeNewContext3d, ClientDeferredInitializeFails) { 175 TEST_F(OutputSurfaceTestInitializeNewContext3d, ClientDeferredInitializeFails) {
214 BindOutputSurface(); 176 BindOutputSurface();
215 client_.set_deferred_initialize_result(false); 177 client_.set_deferred_initialize_result(false);
216 InitializeNewContextExpectFail(); 178 InitializeNewContextExpectFail();
217 } 179 }
218 180
219 TEST(OutputSurfaceTest, BeginFrameEmulation) {
220 TestOutputSurface output_surface(TestContextProvider::Create());
221 EXPECT_FALSE(output_surface.HasClient());
222
223 FakeOutputSurfaceClient client;
224 EXPECT_TRUE(output_surface.BindToClient(&client));
225 EXPECT_TRUE(output_surface.HasClient());
226 EXPECT_FALSE(client.deferred_initialize_called());
227
228 // Initialize BeginFrame emulation
229 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
230 new base::TestSimpleTaskRunner;
231 const base::TimeDelta display_refresh_interval =
232 BeginFrameArgs::DefaultInterval();
233
234 output_surface.InitializeBeginFrameEmulation(task_runner.get(),
235 display_refresh_interval);
236
237 output_surface.EnableRetroactiveBeginFrameDeadline(
238 false, false, base::TimeDelta());
239
240 // We should start off with 0 BeginFrames
241 EXPECT_EQ(client.begin_frame_count(), 0);
242
243 // We should not have a pending task until a BeginFrame has been
244 // requested.
245 EXPECT_FALSE(task_runner->HasPendingTask());
246 output_surface.SetNeedsBeginFrame(true);
247 EXPECT_TRUE(task_runner->HasPendingTask());
248
249 // BeginFrame should be called on the first tick.
250 task_runner->RunPendingTasks();
251 EXPECT_EQ(client.begin_frame_count(), 1);
252
253 // BeginFrame should not be called when there is a pending BeginFrame.
254 task_runner->RunPendingTasks();
255 EXPECT_EQ(client.begin_frame_count(), 1);
256 // SetNeedsBeginFrame should clear the pending BeginFrame after
257 // a SwapBuffers.
258 output_surface.DidSwapBuffersForTesting();
259 output_surface.SetNeedsBeginFrame(true);
260 EXPECT_EQ(client.begin_frame_count(), 1);
261 task_runner->RunPendingTasks();
262 EXPECT_EQ(client.begin_frame_count(), 2);
263
264 // Calling SetNeedsBeginFrame again indicates a swap did not occur but
265 // the client still wants another BeginFrame.
266 output_surface.SetNeedsBeginFrame(true);
267 task_runner->RunPendingTasks();
268 EXPECT_EQ(client.begin_frame_count(), 3);
269
270 // Disabling SetNeedsBeginFrame should prevent further BeginFrames.
271 output_surface.SetNeedsBeginFrame(false);
272 task_runner->RunPendingTasks();
273 EXPECT_FALSE(task_runner->HasPendingTask());
274 EXPECT_EQ(client.begin_frame_count(), 3);
275 }
276
277 TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) {
278 TestOutputSurface output_surface(TestContextProvider::Create());
279 EXPECT_FALSE(output_surface.HasClient());
280
281 FakeOutputSurfaceClient client;
282 EXPECT_TRUE(output_surface.BindToClient(&client));
283 EXPECT_TRUE(output_surface.HasClient());
284 EXPECT_FALSE(client.deferred_initialize_called());
285
286 output_surface.EnableRetroactiveBeginFrameDeadline(
287 true, false, base::TimeDelta());
288
289 // Optimistically injected BeginFrames should be throttled if
290 // SetNeedsBeginFrame is false...
291 output_surface.SetNeedsBeginFrame(false);
292 output_surface.BeginFrameForTesting();
293 EXPECT_EQ(client.begin_frame_count(), 0);
294 // ...and retroactively triggered by a SetNeedsBeginFrame.
295 output_surface.SetNeedsBeginFrame(true);
296 EXPECT_EQ(client.begin_frame_count(), 1);
297
298 // Optimistically injected BeginFrames should be throttled by pending
299 // BeginFrames...
300 output_surface.BeginFrameForTesting();
301 EXPECT_EQ(client.begin_frame_count(), 1);
302 // ...and retroactively triggered by a SetNeedsBeginFrame.
303 output_surface.SetNeedsBeginFrame(true);
304 EXPECT_EQ(client.begin_frame_count(), 2);
305 // ...or retroactively triggered by a Swap.
306 output_surface.BeginFrameForTesting();
307 EXPECT_EQ(client.begin_frame_count(), 2);
308 output_surface.DidSwapBuffersForTesting();
309 output_surface.SetNeedsBeginFrame(true);
310 EXPECT_EQ(client.begin_frame_count(), 3);
311 }
312
313 TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) {
314 scoped_refptr<TestContextProvider> context_provider =
315 TestContextProvider::Create();
316
317 TestOutputSurface output_surface(context_provider);
318 EXPECT_FALSE(output_surface.HasClient());
319
320 FakeOutputSurfaceClient client;
321 EXPECT_TRUE(output_surface.BindToClient(&client));
322 EXPECT_TRUE(output_surface.HasClient());
323 EXPECT_FALSE(client.deferred_initialize_called());
324
325 base::TimeDelta big_interval = base::TimeDelta::FromSeconds(10);
326
327 // Initialize BeginFrame emulation
328 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
329 new base::TestSimpleTaskRunner;
330 const base::TimeDelta display_refresh_interval = big_interval;
331
332 output_surface.InitializeBeginFrameEmulation(task_runner.get(),
333 display_refresh_interval);
334
335 // We need to subtract an epsilon from Now() because some platforms have
336 // a slow clock.
337 output_surface.CommitVSyncParametersForTesting(
338 gfx::FrameTime::Now() - base::TimeDelta::FromSeconds(1), big_interval);
339
340 output_surface.EnableRetroactiveBeginFrameDeadline(true, true, big_interval);
341
342 // We should start off with 0 BeginFrames
343 EXPECT_EQ(client.begin_frame_count(), 0);
344
345 // The first SetNeedsBeginFrame(true) should start a retroactive
346 // BeginFrame.
347 EXPECT_FALSE(task_runner->HasPendingTask());
348 output_surface.SetNeedsBeginFrame(true);
349 EXPECT_TRUE(task_runner->HasPendingTask());
350 EXPECT_GT(task_runner->NextPendingTaskDelay(), big_interval / 2);
351 EXPECT_EQ(client.begin_frame_count(), 1);
352
353 output_surface.SetNeedsBeginFrame(false);
354 EXPECT_TRUE(task_runner->HasPendingTask());
355 EXPECT_EQ(client.begin_frame_count(), 1);
356
357 // The second SetNeedBeginFrame(true) should not retroactively start a
358 // BeginFrame if the timestamp would be the same as the previous
359 // BeginFrame.
360 output_surface.SetNeedsBeginFrame(true);
361 EXPECT_TRUE(task_runner->HasPendingTask());
362 EXPECT_EQ(client.begin_frame_count(), 1);
363 }
364
365 TEST(OutputSurfaceTest, MemoryAllocation) { 181 TEST(OutputSurfaceTest, MemoryAllocation) {
366 scoped_refptr<TestContextProvider> context_provider = 182 scoped_refptr<TestContextProvider> context_provider =
367 TestContextProvider::Create(); 183 TestContextProvider::Create();
368 184
369 TestOutputSurface output_surface(context_provider); 185 TestOutputSurface output_surface(context_provider);
370 186
371 FakeOutputSurfaceClient client; 187 FakeOutputSurfaceClient client;
372 EXPECT_TRUE(output_surface.BindToClient(&client)); 188 EXPECT_TRUE(output_surface.BindToClient(&client));
373 189
374 ManagedMemoryPolicy policy(0); 190 ManagedMemoryPolicy policy(0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count()); 225 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count());
410 EXPECT_EQ(0, software_output_device->discard_backbuffer_count()); 226 EXPECT_EQ(0, software_output_device->discard_backbuffer_count());
411 output_surface.DiscardBackbuffer(); 227 output_surface.DiscardBackbuffer();
412 228
413 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count()); 229 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count());
414 EXPECT_EQ(1, software_output_device->discard_backbuffer_count()); 230 EXPECT_EQ(1, software_output_device->discard_backbuffer_count());
415 } 231 }
416 232
417 } // namespace 233 } // namespace
418 } // namespace cc 234 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698