Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / cc / scheduler / frame_rate_controller_unittest.cc
1 // Copyright 2011 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.
4
5 #include "cc/scheduler/frame_rate_controller.h"
6
7 #include "base/test/test_simple_task_runner.h"
8 #include "cc/test/scheduler_test_common.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace cc {
12 namespace {
13
14 class FakeFrameRateControllerClient : public FrameRateControllerClient {
15  public:
16   FakeFrameRateControllerClient() { Reset(); }
17
18   void Reset() { frame_count_ = 0; }
19   bool BeganFrame() const { return frame_count_ > 0; }
20   int frame_count() const { return frame_count_; }
21
22   virtual void FrameRateControllerTick(
23       bool throttled, const BeginFrameArgs& args) OVERRIDE {
24     frame_count_ += throttled ? 0 : 1;
25   }
26
27  protected:
28   int frame_count_;
29 };
30
31 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) {
32   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
33       new base::TestSimpleTaskRunner;
34   FakeFrameRateControllerClient client;
35   base::TimeDelta interval = base::TimeDelta::FromMicroseconds(
36       base::Time::kMicrosecondsPerSecond / 60);
37   scoped_refptr<FakeDelayBasedTimeSource> time_source =
38       FakeDelayBasedTimeSource::Create(interval, task_runner.get());
39   FrameRateController controller(time_source);
40
41   controller.SetClient(&client);
42   controller.SetActive(true);
43
44   base::TimeTicks elapsed;  // Muck around with time a bit
45
46   // Trigger one frame, make sure the BeginFrame callback is called
47   elapsed += task_runner->NextPendingTaskDelay();
48   time_source->SetNow(elapsed);
49   task_runner->RunPendingTasks();
50   EXPECT_TRUE(client.BeganFrame());
51   client.Reset();
52
53   // Tell the controller we drew
54   controller.DidSwapBuffers();
55
56   // Tell the controller the frame ended 5ms later
57   time_source->SetNow(time_source->Now() +
58                       base::TimeDelta::FromMilliseconds(5));
59   controller.DidSwapBuffersComplete();
60
61   // Trigger another frame, make sure BeginFrame runs again
62   elapsed += task_runner->NextPendingTaskDelay();
63   // Sanity check that previous code didn't move time backward.
64   EXPECT_GE(elapsed, time_source->Now());
65   time_source->SetNow(elapsed);
66   task_runner->RunPendingTasks();
67   EXPECT_TRUE(client.BeganFrame());
68 }
69
70 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) {
71   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
72       new base::TestSimpleTaskRunner;
73   FakeFrameRateControllerClient client;
74   base::TimeDelta interval = base::TimeDelta::FromMicroseconds(
75       base::Time::kMicrosecondsPerSecond / 60);
76   scoped_refptr<FakeDelayBasedTimeSource> time_source =
77       FakeDelayBasedTimeSource::Create(interval, task_runner.get());
78   FrameRateController controller(time_source);
79
80   controller.SetClient(&client);
81   controller.SetActive(true);
82   controller.SetMaxSwapsPending(2);
83
84   base::TimeTicks elapsed;  // Muck around with time a bit
85
86   // Trigger one frame, make sure the BeginFrame callback is called
87   elapsed += task_runner->NextPendingTaskDelay();
88   time_source->SetNow(elapsed);
89   task_runner->RunPendingTasks();
90   EXPECT_TRUE(client.BeganFrame());
91   client.Reset();
92
93   // Tell the controller we drew
94   controller.DidSwapBuffers();
95
96   // Trigger another frame, make sure BeginFrame callback runs again
97   elapsed += task_runner->NextPendingTaskDelay();
98   // Sanity check that previous code didn't move time backward.
99   EXPECT_GE(elapsed, time_source->Now());
100   time_source->SetNow(elapsed);
101   task_runner->RunPendingTasks();
102   EXPECT_TRUE(client.BeganFrame());
103   client.Reset();
104
105   // Tell the controller we drew, again.
106   controller.DidSwapBuffers();
107
108   // Trigger another frame. Since two frames are pending, we should not draw.
109   elapsed += task_runner->NextPendingTaskDelay();
110   // Sanity check that previous code didn't move time backward.
111   EXPECT_GE(elapsed, time_source->Now());
112   time_source->SetNow(elapsed);
113   task_runner->RunPendingTasks();
114   EXPECT_FALSE(client.BeganFrame());
115
116   // Tell the controller the first frame ended 5ms later
117   time_source->SetNow(time_source->Now() +
118                       base::TimeDelta::FromMilliseconds(5));
119   controller.DidSwapBuffersComplete();
120
121   // Tick should not have been called
122   EXPECT_FALSE(client.BeganFrame());
123
124   // Trigger yet another frame. Since one frames is pending, another
125   // BeginFrame callback should run.
126   elapsed += task_runner->NextPendingTaskDelay();
127   // Sanity check that previous code didn't move time backward.
128   EXPECT_GE(elapsed, time_source->Now());
129   time_source->SetNow(elapsed);
130   task_runner->RunPendingTasks();
131   EXPECT_TRUE(client.BeganFrame());
132 }
133
134 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) {
135   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
136       new base::TestSimpleTaskRunner;
137   FakeFrameRateControllerClient client;
138   FrameRateController controller(task_runner.get());
139
140   controller.SetClient(&client);
141   controller.SetMaxSwapsPending(2);
142
143   // SetActive triggers 1st frame, make sure the BeginFrame callback
144   // is called
145   controller.SetActive(true);
146   task_runner->RunPendingTasks();
147   EXPECT_TRUE(client.BeganFrame());
148   client.Reset();
149
150   // Even if we don't call DidSwapBuffers, FrameRateController should
151   // still attempt to tick multiple times until it does result in
152   // a DidSwapBuffers.
153   task_runner->RunPendingTasks();
154   EXPECT_TRUE(client.BeganFrame());
155   client.Reset();
156
157   task_runner->RunPendingTasks();
158   EXPECT_TRUE(client.BeganFrame());
159   client.Reset();
160
161   // DidSwapBuffers triggers 2nd frame, make sure the BeginFrame callback is
162   // called
163   controller.DidSwapBuffers();
164   task_runner->RunPendingTasks();
165   EXPECT_TRUE(client.BeganFrame());
166   client.Reset();
167
168   // DidSwapBuffers triggers 3rd frame (> max_frames_pending),
169   // make sure the BeginFrame callback is NOT called
170   controller.DidSwapBuffers();
171   task_runner->RunPendingTasks();
172   EXPECT_FALSE(client.BeganFrame());
173   client.Reset();
174
175   // Make sure there is no pending task since we can't do anything until we
176   // receive a DidSwapBuffersComplete anyway.
177   EXPECT_FALSE(task_runner->HasPendingTask());
178
179   // DidSwapBuffersComplete triggers a frame, make sure the BeginFrame
180   // callback is called
181   controller.DidSwapBuffersComplete();
182   task_runner->RunPendingTasks();
183   EXPECT_TRUE(client.BeganFrame());
184 }
185
186 TEST(FrameRateControllerTest, TestFrameThrottling_NoDoubleTicking) {
187   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
188       new base::TestSimpleTaskRunner;
189   FakeFrameRateControllerClient client;
190   FrameRateController controller(task_runner.get());
191   controller.SetClient(&client);
192
193   // SetActive triggers 1st frame and queues another tick task since the time
194   // source isn't throttling.
195   controller.SetActive(true);
196   task_runner->RunPendingTasks();
197   EXPECT_TRUE(client.BeganFrame());
198   client.Reset();
199   EXPECT_TRUE(task_runner->HasPendingTask());
200
201   // Simulate a frame swap. This shouldn't queue a second tick task.
202   controller.DidSwapBuffers();
203   controller.DidSwapBuffersComplete();
204
205   // The client should only be ticked once.
206   task_runner->RunPendingTasks();
207   EXPECT_EQ(1, client.frame_count());
208 }
209
210 }  // namespace
211 }  // namespace cc