OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 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/scheduler/frame_rate_controller.h" | 5 #include "cc/scheduler/frame_rate_controller.h" |
6 | 6 |
7 #include "cc/test/scheduler_test_common.h" | 7 #include "cc/test/scheduler_test_common.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 | 9 |
10 namespace cc { | 10 namespace cc { |
11 namespace { | 11 namespace { |
12 | 12 |
13 class FakeFrameRateControllerClient : public cc::FrameRateControllerClient { | 13 class FakeFrameRateControllerClient : public cc::FrameRateControllerClient { |
14 public: | 14 public: |
15 FakeFrameRateControllerClient() { Reset(); } | 15 FakeFrameRateControllerClient() { Reset(); } |
16 | 16 |
17 void Reset() { vsync_ticked_ = false; } | 17 void Reset() { began_frame_ = false; } |
18 bool VSyncTicked() const { return vsync_ticked_; } | 18 bool BeganFrame() const { return began_frame_; } |
19 | 19 |
20 virtual void VSyncTick(bool throttled) OVERRIDE { | 20 virtual void BeginFrame(bool throttled) OVERRIDE { |
21 vsync_ticked_ = !throttled; | 21 began_frame_ = !throttled; |
22 } | 22 } |
23 | 23 |
24 protected: | 24 protected: |
25 bool vsync_ticked_; | 25 bool began_frame_; |
26 }; | 26 }; |
27 | 27 |
28 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { | 28 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { |
29 FakeThread thread; | 29 FakeThread thread; |
30 FakeFrameRateControllerClient client; | 30 FakeFrameRateControllerClient client; |
31 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( | 31 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( |
32 base::Time::kMicrosecondsPerSecond / 60); | 32 base::Time::kMicrosecondsPerSecond / 60); |
33 scoped_refptr<FakeDelayBasedTimeSource> time_source = | 33 scoped_refptr<FakeDelayBasedTimeSource> time_source = |
34 FakeDelayBasedTimeSource::Create(interval, &thread); | 34 FakeDelayBasedTimeSource::Create(interval, &thread); |
35 FrameRateController controller(time_source); | 35 FrameRateController controller(time_source); |
36 | 36 |
37 controller.SetClient(&client); | 37 controller.SetClient(&client); |
38 controller.SetActive(true); | 38 controller.SetActive(true); |
39 | 39 |
40 base::TimeTicks elapsed; // Muck around with time a bit | 40 base::TimeTicks elapsed; // Muck around with time a bit |
41 | 41 |
42 // Trigger one frame, make sure the vsync callback is called | 42 // Trigger one frame, make sure the BeginFrame callback is called |
43 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 43 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); |
44 time_source->SetNow(elapsed); | 44 time_source->SetNow(elapsed); |
45 thread.RunPendingTask(); | 45 thread.RunPendingTask(); |
46 EXPECT_TRUE(client.VSyncTicked()); | 46 EXPECT_TRUE(client.BeganFrame()); |
47 client.Reset(); | 47 client.Reset(); |
48 | 48 |
49 // Tell the controller we drew | 49 // Tell the controller we drew |
50 controller.DidBeginFrame(); | 50 controller.DidSwapBuffers(); |
51 | 51 |
52 // Tell the controller the frame ended 5ms later | 52 // Tell the controller the frame ended 5ms later |
53 time_source->SetNow(time_source->Now() + | 53 time_source->SetNow(time_source->Now() + |
54 base::TimeDelta::FromMilliseconds(5)); | 54 base::TimeDelta::FromMilliseconds(5)); |
55 controller.DidFinishFrame(); | 55 controller.DidSwapBuffersComplete(); |
56 | 56 |
57 // Trigger another frame, make sure vsync runs again | 57 // Trigger another frame, make sure BeginFrame runs again |
58 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 58 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); |
59 // Sanity check that previous code didn't move time backward. | 59 // Sanity check that previous code didn't move time backward. |
60 EXPECT_GE(elapsed, time_source->Now()); | 60 EXPECT_GE(elapsed, time_source->Now()); |
61 time_source->SetNow(elapsed); | 61 time_source->SetNow(elapsed); |
62 thread.RunPendingTask(); | 62 thread.RunPendingTask(); |
63 EXPECT_TRUE(client.VSyncTicked()); | 63 EXPECT_TRUE(client.BeganFrame()); |
64 } | 64 } |
65 | 65 |
66 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { | 66 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { |
67 FakeThread thread; | 67 FakeThread thread; |
68 FakeFrameRateControllerClient client; | 68 FakeFrameRateControllerClient client; |
69 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( | 69 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( |
70 base::Time::kMicrosecondsPerSecond / 60); | 70 base::Time::kMicrosecondsPerSecond / 60); |
71 scoped_refptr<FakeDelayBasedTimeSource> time_source = | 71 scoped_refptr<FakeDelayBasedTimeSource> time_source = |
72 FakeDelayBasedTimeSource::Create(interval, &thread); | 72 FakeDelayBasedTimeSource::Create(interval, &thread); |
73 FrameRateController controller(time_source); | 73 FrameRateController controller(time_source); |
74 | 74 |
75 controller.SetClient(&client); | 75 controller.SetClient(&client); |
76 controller.SetActive(true); | 76 controller.SetActive(true); |
77 controller.SetMaxFramesPending(2); | 77 controller.SetMaxFramesPending(2); |
78 | 78 |
79 base::TimeTicks elapsed; // Muck around with time a bit | 79 base::TimeTicks elapsed; // Muck around with time a bit |
80 | 80 |
81 // Trigger one frame, make sure the vsync callback is called | 81 // Trigger one frame, make sure the BeginFrame callback is called |
82 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 82 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); |
83 time_source->SetNow(elapsed); | 83 time_source->SetNow(elapsed); |
84 thread.RunPendingTask(); | 84 thread.RunPendingTask(); |
85 EXPECT_TRUE(client.VSyncTicked()); | 85 EXPECT_TRUE(client.BeganFrame()); |
86 client.Reset(); | 86 client.Reset(); |
87 | 87 |
88 // Tell the controller we drew | 88 // Tell the controller we drew |
89 controller.DidBeginFrame(); | 89 controller.DidSwapBuffers(); |
90 | 90 |
91 // Trigger another frame, make sure vsync callback runs again | 91 // Trigger another frame, make sure BeginFrame callback runs again |
92 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 92 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); |
93 // Sanity check that previous code didn't move time backward. | 93 // Sanity check that previous code didn't move time backward. |
94 EXPECT_GE(elapsed, time_source->Now()); | 94 EXPECT_GE(elapsed, time_source->Now()); |
95 time_source->SetNow(elapsed); | 95 time_source->SetNow(elapsed); |
96 thread.RunPendingTask(); | 96 thread.RunPendingTask(); |
97 EXPECT_TRUE(client.VSyncTicked()); | 97 EXPECT_TRUE(client.BeganFrame()); |
98 client.Reset(); | 98 client.Reset(); |
99 | 99 |
100 // Tell the controller we drew, again. | 100 // Tell the controller we drew, again. |
101 controller.DidBeginFrame(); | 101 controller.DidSwapBuffers(); |
102 | 102 |
103 // Trigger another frame. Since two frames are pending, we should not draw. | 103 // Trigger another frame. Since two frames are pending, we should not draw. |
104 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 104 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); |
105 // Sanity check that previous code didn't move time backward. | 105 // Sanity check that previous code didn't move time backward. |
106 EXPECT_GE(elapsed, time_source->Now()); | 106 EXPECT_GE(elapsed, time_source->Now()); |
107 time_source->SetNow(elapsed); | 107 time_source->SetNow(elapsed); |
108 thread.RunPendingTask(); | 108 thread.RunPendingTask(); |
109 EXPECT_FALSE(client.VSyncTicked()); | 109 EXPECT_FALSE(client.BeganFrame()); |
110 | 110 |
111 // Tell the controller the first frame ended 5ms later | 111 // Tell the controller the first frame ended 5ms later |
112 time_source->SetNow(time_source->Now() + | 112 time_source->SetNow(time_source->Now() + |
113 base::TimeDelta::FromMilliseconds(5)); | 113 base::TimeDelta::FromMilliseconds(5)); |
114 controller.DidFinishFrame(); | 114 controller.DidSwapBuffersComplete(); |
115 | 115 |
116 // Tick should not have been called | 116 // Tick should not have been called |
117 EXPECT_FALSE(client.VSyncTicked()); | 117 EXPECT_FALSE(client.BeganFrame()); |
118 | 118 |
119 // Trigger yet another frame. Since one frames is pending, another vsync | 119 // Trigger yet another frame. Since one frames is pending, another |
120 // callback should run. | 120 // BeginFrame callback should run. |
121 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 121 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); |
122 // Sanity check that previous code didn't move time backward. | 122 // Sanity check that previous code didn't move time backward. |
123 EXPECT_GE(elapsed, time_source->Now()); | 123 EXPECT_GE(elapsed, time_source->Now()); |
124 time_source->SetNow(elapsed); | 124 time_source->SetNow(elapsed); |
125 thread.RunPendingTask(); | 125 thread.RunPendingTask(); |
126 EXPECT_TRUE(client.VSyncTicked()); | 126 EXPECT_TRUE(client.BeganFrame()); |
127 } | 127 } |
128 | 128 |
129 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) { | 129 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) { |
130 FakeThread thread; | 130 FakeThread thread; |
131 FakeFrameRateControllerClient client; | 131 FakeFrameRateControllerClient client; |
132 FrameRateController controller(&thread); | 132 FrameRateController controller(&thread); |
133 | 133 |
134 controller.SetClient(&client); | 134 controller.SetClient(&client); |
135 controller.SetMaxFramesPending(2); | 135 controller.SetMaxFramesPending(2); |
136 | 136 |
137 // SetActive triggers 1st frame, make sure the vsync callback is called | 137 // SetActive triggers 1st frame, make sure the BeginFrame callback |
| 138 // is called |
138 controller.SetActive(true); | 139 controller.SetActive(true); |
139 thread.RunPendingTask(); | 140 thread.RunPendingTask(); |
140 EXPECT_TRUE(client.VSyncTicked()); | 141 EXPECT_TRUE(client.BeganFrame()); |
141 client.Reset(); | 142 client.Reset(); |
142 | 143 |
143 // Even if we don't call DidBeginFrame, FrameRateController should | 144 // Even if we don't call DidSwapBuffers, FrameRateController should |
144 // still attempt to vsync tick multiple times until it does result in | 145 // still attempt to tick multiple times until it does result in |
145 // a DidBeginFrame. | 146 // a DidSwapBuffers. |
146 thread.RunPendingTask(); | 147 thread.RunPendingTask(); |
147 EXPECT_TRUE(client.VSyncTicked()); | 148 EXPECT_TRUE(client.BeganFrame()); |
148 client.Reset(); | 149 client.Reset(); |
149 | 150 |
150 thread.RunPendingTask(); | 151 thread.RunPendingTask(); |
151 EXPECT_TRUE(client.VSyncTicked()); | 152 EXPECT_TRUE(client.BeganFrame()); |
152 client.Reset(); | 153 client.Reset(); |
153 | 154 |
154 // DidBeginFrame triggers 2nd frame, make sure the vsync callback is called | 155 // DidSwapBuffers triggers 2nd frame, make sure the BeginFrame callback is |
155 controller.DidBeginFrame(); | 156 // called |
| 157 controller.DidSwapBuffers(); |
156 thread.RunPendingTask(); | 158 thread.RunPendingTask(); |
157 EXPECT_TRUE(client.VSyncTicked()); | 159 EXPECT_TRUE(client.BeganFrame()); |
158 client.Reset(); | 160 client.Reset(); |
159 | 161 |
160 // DidBeginFrame triggers 3rd frame (> max_frames_pending), | 162 // DidSwapBuffers triggers 3rd frame (> max_frames_pending), |
161 // make sure the vsync callback is NOT called | 163 // make sure the BeginFrame callback is NOT called |
162 controller.DidBeginFrame(); | 164 controller.DidSwapBuffers(); |
163 thread.RunPendingTask(); | 165 thread.RunPendingTask(); |
164 EXPECT_FALSE(client.VSyncTicked()); | 166 EXPECT_FALSE(client.BeganFrame()); |
165 client.Reset(); | 167 client.Reset(); |
166 | 168 |
167 // Make sure there is no pending task since we can't do anything until we | 169 // Make sure there is no pending task since we can't do anything until we |
168 // receive a DidFinishFrame anyway. | 170 // receive a DidSwapBuffersComplete anyway. |
169 EXPECT_FALSE(thread.HasPendingTask()); | 171 EXPECT_FALSE(thread.HasPendingTask()); |
170 | 172 |
171 // DidFinishFrame triggers a frame, make sure the vsync callback is called | 173 // DidSwapBuffersComplete triggers a frame, make sure the BeginFrame |
172 controller.DidFinishFrame(); | 174 // callback is called |
| 175 controller.DidSwapBuffersComplete(); |
173 thread.RunPendingTask(); | 176 thread.RunPendingTask(); |
174 EXPECT_TRUE(client.VSyncTicked()); | 177 EXPECT_TRUE(client.BeganFrame()); |
175 } | 178 } |
176 | 179 |
177 } // namespace | 180 } // namespace |
178 } // namespace cc | 181 } // namespace cc |
OLD | NEW |