am f89dac47: Merge "Tweak RT-animator scheduling" into lmp-mr1-dev

* commit 'f89dac472366c547e535dfafa8df25bd2d031833':
  Tweak RT-animator scheduling
This commit is contained in:
John Reck
2014-12-19 23:15:12 +00:00
committed by Android Git Automerger
4 changed files with 22 additions and 15 deletions

View File

@ -40,7 +40,7 @@ namespace renderthread {
static const size_t EVENT_BUFFER_SIZE = 100; static const size_t EVENT_BUFFER_SIZE = 100;
// Slight delay to give the UI time to push us a new frame before we replay // Slight delay to give the UI time to push us a new frame before we replay
static const int DISPATCH_FRAME_CALLBACKS_DELAY = 4; static const nsecs_t DISPATCH_FRAME_CALLBACKS_DELAY = milliseconds_to_nanoseconds(4);
TaskQueue::TaskQueue() : mHead(0), mTail(0) {} TaskQueue::TaskQueue() : mHead(0), mTail(0) {}
@ -209,16 +209,16 @@ static nsecs_t latestVsyncEvent(DisplayEventReceiver* receiver) {
return latest; return latest;
} }
void RenderThread::drainDisplayEventQueue(bool skipCallbacks) { void RenderThread::drainDisplayEventQueue() {
ATRACE_CALL(); ATRACE_CALL();
nsecs_t vsyncEvent = latestVsyncEvent(mDisplayEventReceiver); nsecs_t vsyncEvent = latestVsyncEvent(mDisplayEventReceiver);
if (vsyncEvent > 0) { if (vsyncEvent > 0) {
mVsyncRequested = false; mVsyncRequested = false;
mTimeLord.vsyncReceived(vsyncEvent); if (mTimeLord.vsyncReceived(vsyncEvent) && !mFrameCallbackTaskPending) {
if (!skipCallbacks && !mFrameCallbackTaskPending) {
ATRACE_NAME("queue mFrameCallbackTask"); ATRACE_NAME("queue mFrameCallbackTask");
mFrameCallbackTaskPending = true; mFrameCallbackTaskPending = true;
queueDelayed(mFrameCallbackTask, DISPATCH_FRAME_CALLBACKS_DELAY); nsecs_t runAt = (vsyncEvent + DISPATCH_FRAME_CALLBACKS_DELAY);
queueAt(mFrameCallbackTask, runAt);
} }
} }
} }
@ -230,9 +230,14 @@ void RenderThread::dispatchFrameCallbacks() {
std::set<IFrameCallback*> callbacks; std::set<IFrameCallback*> callbacks;
mFrameCallbacks.swap(callbacks); mFrameCallbacks.swap(callbacks);
if (callbacks.size()) {
// Assume one of them will probably animate again so preemptively
// request the next vsync in case it occurs mid-frame
requestVsync();
for (std::set<IFrameCallback*>::iterator it = callbacks.begin(); it != callbacks.end(); it++) { for (std::set<IFrameCallback*>::iterator it = callbacks.begin(); it != callbacks.end(); it++) {
(*it)->doFrame(); (*it)->doFrame();
} }
}
} }
void RenderThread::requestVsync() { void RenderThread::requestVsync() {
@ -273,7 +278,7 @@ bool RenderThread::threadLoop() {
} }
if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) { if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) {
drainDisplayEventQueue(true); drainDisplayEventQueue();
mFrameCallbacks.insert( mFrameCallbacks.insert(
mPendingRegistrationFrameCallbacks.begin(), mPendingRegistrationFrameCallbacks.end()); mPendingRegistrationFrameCallbacks.begin(), mPendingRegistrationFrameCallbacks.end());
mPendingRegistrationFrameCallbacks.clear(); mPendingRegistrationFrameCallbacks.clear();
@ -299,9 +304,8 @@ void RenderThread::queueAtFront(RenderTask* task) {
mLooper->wake(); mLooper->wake();
} }
void RenderThread::queueDelayed(RenderTask* task, int delayMs) { void RenderThread::queueAt(RenderTask* task, nsecs_t runAtNs) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); task->mRunAt = runAtNs;
task->mRunAt = now + milliseconds_to_nanoseconds(delayMs);
queue(task); queue(task);
} }

View File

@ -75,7 +75,7 @@ public:
// and will delete them after they are run // and will delete them after they are run
ANDROID_API void queue(RenderTask* task); ANDROID_API void queue(RenderTask* task);
ANDROID_API void queueAtFront(RenderTask* task); ANDROID_API void queueAtFront(RenderTask* task);
void queueDelayed(RenderTask* task, int delayMs); void queueAt(RenderTask* task, nsecs_t runAtNs);
void remove(RenderTask* task); void remove(RenderTask* task);
// Mimics android.view.Choreographer // Mimics android.view.Choreographer
@ -103,7 +103,7 @@ private:
void initThreadLocals(); void initThreadLocals();
void initializeDisplayEventReceiver(); void initializeDisplayEventReceiver();
static int displayEventReceiverCallback(int fd, int events, void* data); static int displayEventReceiverCallback(int fd, int events, void* data);
void drainDisplayEventQueue(bool skipCallbacks = false); void drainDisplayEventQueue();
void dispatchFrameCallbacks(); void dispatchFrameCallbacks();
void requestVsync(); void requestVsync();

View File

@ -24,10 +24,12 @@ TimeLord::TimeLord()
, mFrameTimeNanos(0) { , mFrameTimeNanos(0) {
} }
void TimeLord::vsyncReceived(nsecs_t vsync) { bool TimeLord::vsyncReceived(nsecs_t vsync) {
if (vsync > mFrameTimeNanos) { if (vsync > mFrameTimeNanos) {
mFrameTimeNanos = vsync; mFrameTimeNanos = vsync;
return true;
} }
return false;
} }
nsecs_t TimeLord::computeFrameTimeMs() { nsecs_t TimeLord::computeFrameTimeMs() {

View File

@ -29,7 +29,8 @@ class RenderThread;
class TimeLord { class TimeLord {
public: public:
void setFrameInterval(nsecs_t intervalNanos) { mFrameIntervalNanos = intervalNanos; } void setFrameInterval(nsecs_t intervalNanos) { mFrameIntervalNanos = intervalNanos; }
void vsyncReceived(nsecs_t vsync); // returns true if the vsync is newer, false if it was rejected for staleness
bool vsyncReceived(nsecs_t vsync);
nsecs_t computeFrameTimeMs(); nsecs_t computeFrameTimeMs();
private: private: