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

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; add comment about race 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
« no previous file with comments | « cc/output/output_surface_client.h ('k') | cc/scheduler/frame_rate_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 } 38 }
45 39
46 using OutputSurface::ReleaseGL; 40 using OutputSurface::ReleaseGL;
47 41
48 void CommitVSyncParametersForTesting(base::TimeTicks timebase, 42 void CommitVSyncParametersForTesting(base::TimeTicks timebase,
49 base::TimeDelta interval) { 43 base::TimeDelta interval) {
50 CommitVSyncParameters(timebase, interval); 44 CommitVSyncParameters(timebase, interval);
51 } 45 }
52 46
53 void BeginFrameForTesting() { 47 void BeginFrameForTesting() {
54 OutputSurface::BeginFrame(BeginFrameArgs::CreateExpiredForTesting()); 48 client_->BeginFrame(BeginFrameArgs::CreateExpiredForTesting());
55 } 49 }
56 50
57 void DidSwapBuffersForTesting() { 51 void DidSwapBuffersForTesting() { client_->DidSwapBuffers(); }
58 DidSwapBuffers();
59 }
60 52
61 void OnSwapBuffersCompleteForTesting() { 53 void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); }
62 OnSwapBuffersComplete();
63 }
64
65 void EnableRetroactiveBeginFrameDeadline(bool enable,
66 bool override_retroactive_period,
67 base::TimeDelta period_override) {
68 retroactive_begin_frame_deadline_enabled_ = enable;
69 override_retroactive_period_ = override_retroactive_period;
70 retroactive_period_override_ = period_override;
71 }
72 54
73 protected: 55 protected:
74 virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE {
75 // For testing purposes, we check immediately rather than posting a task.
76 CheckForRetroactiveBeginFrame();
77 }
78
79 virtual base::TimeTicks RetroactiveBeginFrameDeadline() OVERRIDE {
80 if (retroactive_begin_frame_deadline_enabled_) {
81 if (override_retroactive_period_) {
82 return skipped_begin_frame_args_.frame_time +
83 retroactive_period_override_;
84 } else {
85 return OutputSurface::RetroactiveBeginFrameDeadline();
86 }
87 }
88 return base::TimeTicks();
89 }
90
91 bool retroactive_begin_frame_deadline_enabled_;
92 bool override_retroactive_period_;
93 base::TimeDelta retroactive_period_override_;
94 }; 56 };
95 57
96 class TestSoftwareOutputDevice : public SoftwareOutputDevice { 58 class TestSoftwareOutputDevice : public SoftwareOutputDevice {
97 public: 59 public:
98 TestSoftwareOutputDevice(); 60 TestSoftwareOutputDevice();
99 virtual ~TestSoftwareOutputDevice(); 61 virtual ~TestSoftwareOutputDevice();
100 62
101 // Overriden from cc:SoftwareOutputDevice 63 // Overriden from cc:SoftwareOutputDevice
102 virtual void DiscardBackbuffer() OVERRIDE; 64 virtual void DiscardBackbuffer() OVERRIDE;
103 virtual void EnsureBackbuffer() OVERRIDE; 65 virtual void EnsureBackbuffer() OVERRIDE;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 EXPECT_FALSE(output_surface_.context_provider()); 164 EXPECT_FALSE(output_surface_.context_provider());
203 } 165 }
204 166
205 TEST_F(OutputSurfaceTestInitializeNewContext3d, Context3dMakeCurrentFails) { 167 TEST_F(OutputSurfaceTestInitializeNewContext3d, Context3dMakeCurrentFails) {
206 BindOutputSurface(); 168 BindOutputSurface();
207 169
208 context_provider_->UnboundTestContext3d()->set_context_lost(true); 170 context_provider_->UnboundTestContext3d()->set_context_lost(true);
209 InitializeNewContextExpectFail(); 171 InitializeNewContextExpectFail();
210 } 172 }
211 173
212 TEST(OutputSurfaceTest, BeginFrameEmulation) {
213 TestOutputSurface output_surface(TestContextProvider::Create());
214 EXPECT_FALSE(output_surface.HasClient());
215
216 FakeOutputSurfaceClient client;
217 EXPECT_TRUE(output_surface.BindToClient(&client));
218 EXPECT_TRUE(output_surface.HasClient());
219 EXPECT_FALSE(client.deferred_initialize_called());
220
221 // Initialize BeginFrame emulation
222 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
223 new base::TestSimpleTaskRunner;
224 const base::TimeDelta display_refresh_interval =
225 BeginFrameArgs::DefaultInterval();
226
227 output_surface.InitializeBeginFrameEmulation(task_runner.get(),
228 display_refresh_interval);
229
230 output_surface.EnableRetroactiveBeginFrameDeadline(
231 false, false, base::TimeDelta());
232
233 // We should start off with 0 BeginFrames
234 EXPECT_EQ(client.begin_frame_count(), 0);
235
236 // We should not have a pending task until a BeginFrame has been
237 // requested.
238 EXPECT_FALSE(task_runner->HasPendingTask());
239 output_surface.SetNeedsBeginFrame(true);
240 EXPECT_TRUE(task_runner->HasPendingTask());
241
242 // BeginFrame should be called on the first tick.
243 task_runner->RunPendingTasks();
244 EXPECT_EQ(client.begin_frame_count(), 1);
245
246 // BeginFrame should not be called when there is a pending BeginFrame.
247 task_runner->RunPendingTasks();
248 EXPECT_EQ(client.begin_frame_count(), 1);
249 // SetNeedsBeginFrame should clear the pending BeginFrame after
250 // a SwapBuffers.
251 output_surface.DidSwapBuffersForTesting();
252 output_surface.SetNeedsBeginFrame(true);
253 EXPECT_EQ(client.begin_frame_count(), 1);
254 task_runner->RunPendingTasks();
255 EXPECT_EQ(client.begin_frame_count(), 2);
256
257 // Calling SetNeedsBeginFrame again indicates a swap did not occur but
258 // the client still wants another BeginFrame.
259 output_surface.SetNeedsBeginFrame(true);
260 task_runner->RunPendingTasks();
261 EXPECT_EQ(client.begin_frame_count(), 3);
262
263 // Disabling SetNeedsBeginFrame should prevent further BeginFrames.
264 output_surface.SetNeedsBeginFrame(false);
265 task_runner->RunPendingTasks();
266 EXPECT_FALSE(task_runner->HasPendingTask());
267 EXPECT_EQ(client.begin_frame_count(), 3);
268 }
269
270 TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) {
271 TestOutputSurface output_surface(TestContextProvider::Create());
272 EXPECT_FALSE(output_surface.HasClient());
273
274 FakeOutputSurfaceClient client;
275 EXPECT_TRUE(output_surface.BindToClient(&client));
276 EXPECT_TRUE(output_surface.HasClient());
277 EXPECT_FALSE(client.deferred_initialize_called());
278
279 output_surface.EnableRetroactiveBeginFrameDeadline(
280 true, false, base::TimeDelta());
281
282 // Optimistically injected BeginFrames should be throttled if
283 // SetNeedsBeginFrame is false...
284 output_surface.SetNeedsBeginFrame(false);
285 output_surface.BeginFrameForTesting();
286 EXPECT_EQ(client.begin_frame_count(), 0);
287 // ...and retroactively triggered by a SetNeedsBeginFrame.
288 output_surface.SetNeedsBeginFrame(true);
289 EXPECT_EQ(client.begin_frame_count(), 1);
290
291 // Optimistically injected BeginFrames should be throttled by pending
292 // BeginFrames...
293 output_surface.BeginFrameForTesting();
294 EXPECT_EQ(client.begin_frame_count(), 1);
295 // ...and retroactively triggered by a SetNeedsBeginFrame.
296 output_surface.SetNeedsBeginFrame(true);
297 EXPECT_EQ(client.begin_frame_count(), 2);
298 // ...or retroactively triggered by a Swap.
299 output_surface.BeginFrameForTesting();
300 EXPECT_EQ(client.begin_frame_count(), 2);
301 output_surface.DidSwapBuffersForTesting();
302 output_surface.SetNeedsBeginFrame(true);
303 EXPECT_EQ(client.begin_frame_count(), 3);
304 }
305
306 TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) {
307 scoped_refptr<TestContextProvider> context_provider =
308 TestContextProvider::Create();
309
310 TestOutputSurface output_surface(context_provider);
311 EXPECT_FALSE(output_surface.HasClient());
312
313 FakeOutputSurfaceClient client;
314 EXPECT_TRUE(output_surface.BindToClient(&client));
315 EXPECT_TRUE(output_surface.HasClient());
316 EXPECT_FALSE(client.deferred_initialize_called());
317
318 base::TimeDelta big_interval = base::TimeDelta::FromSeconds(10);
319
320 // Initialize BeginFrame emulation
321 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
322 new base::TestSimpleTaskRunner;
323 const base::TimeDelta display_refresh_interval = big_interval;
324
325 output_surface.InitializeBeginFrameEmulation(task_runner.get(),
326 display_refresh_interval);
327
328 // We need to subtract an epsilon from Now() because some platforms have
329 // a slow clock.
330 output_surface.CommitVSyncParametersForTesting(
331 gfx::FrameTime::Now() - base::TimeDelta::FromSeconds(1), big_interval);
332
333 output_surface.EnableRetroactiveBeginFrameDeadline(true, true, big_interval);
334
335 // We should start off with 0 BeginFrames
336 EXPECT_EQ(client.begin_frame_count(), 0);
337
338 // The first SetNeedsBeginFrame(true) should start a retroactive
339 // BeginFrame.
340 EXPECT_FALSE(task_runner->HasPendingTask());
341 output_surface.SetNeedsBeginFrame(true);
342 EXPECT_TRUE(task_runner->HasPendingTask());
343 EXPECT_GT(task_runner->NextPendingTaskDelay(), big_interval / 2);
344 EXPECT_EQ(client.begin_frame_count(), 1);
345
346 output_surface.SetNeedsBeginFrame(false);
347 EXPECT_TRUE(task_runner->HasPendingTask());
348 EXPECT_EQ(client.begin_frame_count(), 1);
349
350 // The second SetNeedBeginFrame(true) should not retroactively start a
351 // BeginFrame if the timestamp would be the same as the previous
352 // BeginFrame.
353 output_surface.SetNeedsBeginFrame(true);
354 EXPECT_TRUE(task_runner->HasPendingTask());
355 EXPECT_EQ(client.begin_frame_count(), 1);
356 }
357
358 TEST(OutputSurfaceTest, MemoryAllocation) { 174 TEST(OutputSurfaceTest, MemoryAllocation) {
359 scoped_refptr<TestContextProvider> context_provider = 175 scoped_refptr<TestContextProvider> context_provider =
360 TestContextProvider::Create(); 176 TestContextProvider::Create();
361 177
362 TestOutputSurface output_surface(context_provider); 178 TestOutputSurface output_surface(context_provider);
363 179
364 FakeOutputSurfaceClient client; 180 FakeOutputSurfaceClient client;
365 EXPECT_TRUE(output_surface.BindToClient(&client)); 181 EXPECT_TRUE(output_surface.BindToClient(&client));
366 182
367 ManagedMemoryPolicy policy(0); 183 ManagedMemoryPolicy policy(0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count()); 218 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count());
403 EXPECT_EQ(0, software_output_device->discard_backbuffer_count()); 219 EXPECT_EQ(0, software_output_device->discard_backbuffer_count());
404 output_surface.DiscardBackbuffer(); 220 output_surface.DiscardBackbuffer();
405 221
406 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count()); 222 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count());
407 EXPECT_EQ(1, software_output_device->discard_backbuffer_count()); 223 EXPECT_EQ(1, software_output_device->discard_backbuffer_count());
408 } 224 }
409 225
410 } // namespace 226 } // namespace
411 } // namespace cc 227 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/output_surface_client.h ('k') | cc/scheduler/frame_rate_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698