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.
7 #include "CCFrameRateController.h"
9 #include "CCDelayBasedTimeSource.h"
10 #include "CCTimeSource.h"
11 #include "TraceEvent.h"
12 #include <wtf/CurrentTime.h>
16 // This will be the maximum number of pending frames unless
17 // CCFrameRateController::setMaxFramesPending is called.
18 const int defaultMaxFramesPending
= 2;
24 class CCFrameRateControllerTimeSourceAdapter
: public CCTimeSourceClient
{
26 static PassOwnPtr
<CCFrameRateControllerTimeSourceAdapter
> create(CCFrameRateController
* frameRateController
)
28 return adoptPtr(new CCFrameRateControllerTimeSourceAdapter(frameRateController
));
30 virtual ~CCFrameRateControllerTimeSourceAdapter() { }
32 virtual void onTimerTick() OVERRIDE
{ m_frameRateController
->onTimerTick(); }
34 explicit CCFrameRateControllerTimeSourceAdapter(CCFrameRateController
* frameRateController
)
35 : m_frameRateController(frameRateController
) { }
37 CCFrameRateController
* m_frameRateController
;
40 CCFrameRateController::CCFrameRateController(PassRefPtr
<CCTimeSource
> timer
)
42 , m_numFramesPending(0)
43 , m_maxFramesPending(defaultMaxFramesPending
)
46 , m_swapBuffersCompleteSupported(true)
47 , m_isTimeSourceThrottling(true)
49 m_timeSourceClientAdapter
= CCFrameRateControllerTimeSourceAdapter::create(this);
50 m_timeSource
->setClient(m_timeSourceClientAdapter
.get());
53 CCFrameRateController::CCFrameRateController(CCThread
* thread
)
55 , m_numFramesPending(0)
56 , m_maxFramesPending(defaultMaxFramesPending
)
58 , m_swapBuffersCompleteSupported(true)
59 , m_isTimeSourceThrottling(false)
61 m_manualTicker
= adoptPtr(new CCTimer(thread
, this));
64 CCFrameRateController::~CCFrameRateController()
66 if (m_isTimeSourceThrottling
)
67 m_timeSource
->setActive(false);
70 void CCFrameRateController::setActive(bool active
)
72 if (m_active
== active
)
74 TRACE_EVENT1("cc", "CCFrameRateController::setActive", "active", active
);
77 if (m_isTimeSourceThrottling
)
78 m_timeSource
->setActive(active
);
83 m_manualTicker
->stop();
87 void CCFrameRateController::setMaxFramesPending(int maxFramesPending
)
89 ASSERT(maxFramesPending
> 0);
90 m_maxFramesPending
= maxFramesPending
;
93 void CCFrameRateController::setTimebaseAndInterval(double timebase
, double intervalSeconds
)
95 if (m_isTimeSourceThrottling
)
96 m_timeSource
->setTimebaseAndInterval(timebase
, intervalSeconds
);
99 void CCFrameRateController::setSwapBuffersCompleteSupported(bool supported
)
101 m_swapBuffersCompleteSupported
= supported
;
104 void CCFrameRateController::onTimerTick()
108 // Don't forward the tick if we have too many frames in flight.
109 if (m_numFramesPending
>= m_maxFramesPending
) {
110 TRACE_EVENT0("cc", "CCFrameRateController::onTimerTickButMaxFramesPending");
115 m_client
->vsyncTick();
117 if (m_swapBuffersCompleteSupported
&& !m_isTimeSourceThrottling
&& m_numFramesPending
< m_maxFramesPending
)
121 void CCFrameRateController::postManualTick()
124 m_manualTicker
->startOneShot(0);
127 void CCFrameRateController::onTimerFired()
132 void CCFrameRateController::didBeginFrame()
134 if (m_swapBuffersCompleteSupported
)
135 m_numFramesPending
++;
136 else if (!m_isTimeSourceThrottling
)
140 void CCFrameRateController::didFinishFrame()
142 ASSERT(m_swapBuffersCompleteSupported
);
144 m_numFramesPending
--;
145 if (!m_isTimeSourceThrottling
)
149 void CCFrameRateController::didAbortAllPendingFrames()
151 m_numFramesPending
= 0;
154 double CCFrameRateController::nextTickTimeIfActivated()
156 if (m_isTimeSourceThrottling
)
157 return m_timeSource
->nextTickTimeIfActivated();
159 return monotonicallyIncreasingTime();