private final long syncTimer(long startMS) {
   if (mInSeekingAction || mInSyncAction) {
     return 0;
   }
   mInSyncAction = true;
   long d = 0;
   long time = startMS - mTimeBase;
   if (!mDanmakusVisible || mRenderingState.nothingRendered || mInWaitingState) {
     timer.update(time);
     mRemainingTime = 0;
   } else {
     long gapTime = time - timer.currMillisecond;
     long averageTime = Math.max(mFrameUpdateRate, getAverageRenderingTime());
     if (gapTime > 2000
         || mRenderingState.consumingTime > mCordonTime
         || averageTime > mCordonTime) {
       d = gapTime;
       gapTime = 0;
     } else {
       d = averageTime + gapTime / mFrameUpdateRate;
       d = Math.max(mFrameUpdateRate, d);
       d = Math.min(mCordonTime, d);
       long a = d - mLastDeltaTime;
       if (a > 3 && a < 8 && mLastDeltaTime >= mFrameUpdateRate && mLastDeltaTime <= mCordonTime) {
         d = mLastDeltaTime;
       }
       gapTime -= d;
       mLastDeltaTime = d;
     }
     mRemainingTime = gapTime;
     timer.add(d);
     //            Log.e("DrawHandler", time+"|d:" + d  + "RemaingTime:" + mRemainingTime +
     // ",gapTime:" + gapTime + ",rtim:" + mRenderingState.consumingTime + ",average:" +
     // averageTime);
   }
   if (mCallback != null) {
     mCallback.updateTimer(timer);
   }
   mInSyncAction = false;
   return d;
 }
  private void updateInCurrentThread() {
    if (quitFlag) {
      return;
    }
    long startMS = SystemClock.uptimeMillis();
    long d = syncTimer(startMS);
    if (d < 0) {
      removeMessages(UPDATE);
      sendEmptyMessageDelayed(UPDATE, 60 - d);
      return;
    }
    d = mDanmakuView.drawDanmakus();
    removeMessages(UPDATE);
    if (d
        > mCordonTime2) { // this situation may be cuased by ui-thread waiting of DanmakuView, so we
                          // sync-timer at once
      timer.add(d);
      mDrawTimes.clear();
    }
    if (!mDanmakusVisible) {
      waitRendering(INDEFINITE_TIME);
      return;
    } else if (mRenderingState.nothingRendered && mIdleSleep) {
      long dTime = mRenderingState.endTime - timer.currMillisecond;
      if (dTime > 500) {
        waitRendering(dTime - 10);
        return;
      }
    }

    if (d < mFrameUpdateRate) {
      sendEmptyMessageDelayed(UPDATE, mFrameUpdateRate - d);
      return;
    }
    sendEmptyMessage(UPDATE);
  }