| 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() { m_vsyncTicked = false; } | 17 void reset() { m_vsyncTicked = false; } |
| 18 bool vsyncTicked() const { return m_vsyncTicked; } | 18 bool vsyncTicked() const { return m_vsyncTicked; } |
| 19 | 19 |
| 20 virtual void vsyncTick(bool throttled) OVERRIDE { | 20 virtual void VsyncTick(bool throttled) OVERRIDE { |
| 21 m_vsyncTicked = !throttled; | 21 m_vsyncTicked = !throttled; |
| 22 } | 22 } |
| 23 | 23 |
| 24 protected: | 24 protected: |
| 25 bool m_vsyncTicked; | 25 bool m_vsyncTicked; |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 | 28 |
| 29 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) | 29 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) |
| 30 { | 30 { |
| 31 FakeThread thread; | 31 FakeThread thread; |
| 32 FakeFrameRateControllerClient client; | 32 FakeFrameRateControllerClient client; |
| 33 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(base::Time::kMi
crosecondsPerSecond / 60); | 33 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(base::Time::kMi
crosecondsPerSecond / 60); |
| 34 scoped_refptr<FakeDelayBasedTimeSource> timeSource = FakeDelayBasedTimeSourc
e::create(interval, &thread); | 34 scoped_refptr<FakeDelayBasedTimeSource> timeSource = FakeDelayBasedTimeSourc
e::create(interval, &thread); |
| 35 FrameRateController controller(timeSource); | 35 FrameRateController controller(timeSource); |
| 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 vsync callback is called |
| 43 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); | 43 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); |
| 44 timeSource->setNow(elapsed); | 44 timeSource->setNow(elapsed); |
| 45 thread.runPendingTask(); | 45 thread.runPendingTask(); |
| 46 EXPECT_TRUE(client.vsyncTicked()); | 46 EXPECT_TRUE(client.vsyncTicked()); |
| 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.DidBeginFrame(); |
| 51 | 51 |
| 52 // Tell the controller the frame ended 5ms later | 52 // Tell the controller the frame ended 5ms later |
| 53 timeSource->setNow(timeSource->now() + base::TimeDelta::FromMilliseconds(5))
; | 53 timeSource->setNow(timeSource->now() + base::TimeDelta::FromMilliseconds(5))
; |
| 54 controller.didFinishFrame(); | 54 controller.DidFinishFrame(); |
| 55 | 55 |
| 56 // Trigger another frame, make sure vsync runs again | 56 // Trigger another frame, make sure vsync runs again |
| 57 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); | 57 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); |
| 58 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. | 58 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. |
| 59 timeSource->setNow(elapsed); | 59 timeSource->setNow(elapsed); |
| 60 thread.runPendingTask(); | 60 thread.runPendingTask(); |
| 61 EXPECT_TRUE(client.vsyncTicked()); | 61 EXPECT_TRUE(client.vsyncTicked()); |
| 62 } | 62 } |
| 63 | 63 |
| 64 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) | 64 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) |
| 65 { | 65 { |
| 66 FakeThread thread; | 66 FakeThread thread; |
| 67 FakeFrameRateControllerClient client; | 67 FakeFrameRateControllerClient client; |
| 68 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(base::Time::kMi
crosecondsPerSecond / 60); | 68 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(base::Time::kMi
crosecondsPerSecond / 60); |
| 69 scoped_refptr<FakeDelayBasedTimeSource> timeSource = FakeDelayBasedTimeSourc
e::create(interval, &thread); | 69 scoped_refptr<FakeDelayBasedTimeSource> timeSource = FakeDelayBasedTimeSourc
e::create(interval, &thread); |
| 70 FrameRateController controller(timeSource); | 70 FrameRateController controller(timeSource); |
| 71 | 71 |
| 72 controller.setClient(&client); | 72 controller.SetClient(&client); |
| 73 controller.setActive(true); | 73 controller.SetActive(true); |
| 74 controller.setMaxFramesPending(2); | 74 controller.SetMaxFramesPending(2); |
| 75 | 75 |
| 76 base::TimeTicks elapsed; // Muck around with time a bit | 76 base::TimeTicks elapsed; // Muck around with time a bit |
| 77 | 77 |
| 78 // Trigger one frame, make sure the vsync callback is called | 78 // Trigger one frame, make sure the vsync callback is called |
| 79 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); | 79 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); |
| 80 timeSource->setNow(elapsed); | 80 timeSource->setNow(elapsed); |
| 81 thread.runPendingTask(); | 81 thread.runPendingTask(); |
| 82 EXPECT_TRUE(client.vsyncTicked()); | 82 EXPECT_TRUE(client.vsyncTicked()); |
| 83 client.reset(); | 83 client.reset(); |
| 84 | 84 |
| 85 // Tell the controller we drew | 85 // Tell the controller we drew |
| 86 controller.didBeginFrame(); | 86 controller.DidBeginFrame(); |
| 87 | 87 |
| 88 // Trigger another frame, make sure vsync callback runs again | 88 // Trigger another frame, make sure vsync callback runs again |
| 89 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); | 89 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); |
| 90 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. | 90 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. |
| 91 timeSource->setNow(elapsed); | 91 timeSource->setNow(elapsed); |
| 92 thread.runPendingTask(); | 92 thread.runPendingTask(); |
| 93 EXPECT_TRUE(client.vsyncTicked()); | 93 EXPECT_TRUE(client.vsyncTicked()); |
| 94 client.reset(); | 94 client.reset(); |
| 95 | 95 |
| 96 // Tell the controller we drew, again. | 96 // Tell the controller we drew, again. |
| 97 controller.didBeginFrame(); | 97 controller.DidBeginFrame(); |
| 98 | 98 |
| 99 // Trigger another frame. Since two frames are pending, we should not draw. | 99 // Trigger another frame. Since two frames are pending, we should not draw. |
| 100 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); | 100 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); |
| 101 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. | 101 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. |
| 102 timeSource->setNow(elapsed); | 102 timeSource->setNow(elapsed); |
| 103 thread.runPendingTask(); | 103 thread.runPendingTask(); |
| 104 EXPECT_FALSE(client.vsyncTicked()); | 104 EXPECT_FALSE(client.vsyncTicked()); |
| 105 | 105 |
| 106 // Tell the controller the first frame ended 5ms later | 106 // Tell the controller the first frame ended 5ms later |
| 107 timeSource->setNow(timeSource->now() + base::TimeDelta::FromMilliseconds(5))
; | 107 timeSource->setNow(timeSource->now() + base::TimeDelta::FromMilliseconds(5))
; |
| 108 controller.didFinishFrame(); | 108 controller.DidFinishFrame(); |
| 109 | 109 |
| 110 // Tick should not have been called | 110 // Tick should not have been called |
| 111 EXPECT_FALSE(client.vsyncTicked()); | 111 EXPECT_FALSE(client.vsyncTicked()); |
| 112 | 112 |
| 113 // Trigger yet another frame. Since one frames is pending, another vsync cal
lback should run. | 113 // Trigger yet another frame. Since one frames is pending, another vsync cal
lback should run. |
| 114 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); | 114 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs()); |
| 115 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. | 115 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous cod
e didn't move time backward. |
| 116 timeSource->setNow(elapsed); | 116 timeSource->setNow(elapsed); |
| 117 thread.runPendingTask(); | 117 thread.runPendingTask(); |
| 118 EXPECT_TRUE(client.vsyncTicked()); | 118 EXPECT_TRUE(client.vsyncTicked()); |
| 119 } | 119 } |
| 120 | 120 |
| 121 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) | 121 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) |
| 122 { | 122 { |
| 123 FakeThread thread; | 123 FakeThread thread; |
| 124 FakeFrameRateControllerClient client; | 124 FakeFrameRateControllerClient client; |
| 125 FrameRateController controller(&thread); | 125 FrameRateController controller(&thread); |
| 126 | 126 |
| 127 controller.setClient(&client); | 127 controller.SetClient(&client); |
| 128 controller.setMaxFramesPending(2); | 128 controller.SetMaxFramesPending(2); |
| 129 | 129 |
| 130 // setActive triggers 1st frame, make sure the vsync callback is called | 130 // setActive triggers 1st frame, make sure the vsync callback is called |
| 131 controller.setActive(true); | 131 controller.SetActive(true); |
| 132 thread.runPendingTask(); | 132 thread.runPendingTask(); |
| 133 EXPECT_TRUE(client.vsyncTicked()); | 133 EXPECT_TRUE(client.vsyncTicked()); |
| 134 client.reset(); | 134 client.reset(); |
| 135 | 135 |
| 136 // Even if we don't call didBeginFrame, FrameRateController should | 136 // Even if we don't call didBeginFrame, FrameRateController should |
| 137 // still attempt to vsync tick multiple times until it does result in | 137 // still attempt to vsync tick multiple times until it does result in |
| 138 // a didBeginFrame. | 138 // a didBeginFrame. |
| 139 thread.runPendingTask(); | 139 thread.runPendingTask(); |
| 140 EXPECT_TRUE(client.vsyncTicked()); | 140 EXPECT_TRUE(client.vsyncTicked()); |
| 141 client.reset(); | 141 client.reset(); |
| 142 | 142 |
| 143 thread.runPendingTask(); | 143 thread.runPendingTask(); |
| 144 EXPECT_TRUE(client.vsyncTicked()); | 144 EXPECT_TRUE(client.vsyncTicked()); |
| 145 client.reset(); | 145 client.reset(); |
| 146 | 146 |
| 147 // didBeginFrame triggers 2nd frame, make sure the vsync callback is called | 147 // didBeginFrame triggers 2nd frame, make sure the vsync callback is called |
| 148 controller.didBeginFrame(); | 148 controller.DidBeginFrame(); |
| 149 thread.runPendingTask(); | 149 thread.runPendingTask(); |
| 150 EXPECT_TRUE(client.vsyncTicked()); | 150 EXPECT_TRUE(client.vsyncTicked()); |
| 151 client.reset(); | 151 client.reset(); |
| 152 | 152 |
| 153 // didBeginFrame triggers 3rd frame (> maxFramesPending), make sure the vsyn
c callback is NOT called | 153 // didBeginFrame triggers 3rd frame (> maxFramesPending), make sure the vsyn
c callback is NOT called |
| 154 controller.didBeginFrame(); | 154 controller.DidBeginFrame(); |
| 155 thread.runPendingTask(); | 155 thread.runPendingTask(); |
| 156 EXPECT_FALSE(client.vsyncTicked()); | 156 EXPECT_FALSE(client.vsyncTicked()); |
| 157 client.reset(); | 157 client.reset(); |
| 158 | 158 |
| 159 // Make sure there is no pending task since we can't do anything until we re
ceive a didFinishFrame anyway. | 159 // Make sure there is no pending task since we can't do anything until we re
ceive a didFinishFrame anyway. |
| 160 EXPECT_FALSE(thread.hasPendingTask()); | 160 EXPECT_FALSE(thread.hasPendingTask()); |
| 161 | 161 |
| 162 // didFinishFrame triggers a frame, make sure the vsync callback is called | 162 // didFinishFrame triggers a frame, make sure the vsync callback is called |
| 163 controller.didFinishFrame(); | 163 controller.DidFinishFrame(); |
| 164 thread.runPendingTask(); | 164 thread.runPendingTask(); |
| 165 EXPECT_TRUE(client.vsyncTicked()); | 165 EXPECT_TRUE(client.vsyncTicked()); |
| 166 } | 166 } |
| 167 | 167 |
| 168 } // namespace | 168 } // namespace |
| 169 } // namespace cc | 169 } // namespace cc |
| OLD | NEW |