DispSync.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef ANDROID_DISPSYNC_H
  17. #define ANDROID_DISPSYNC_H
  18. #include <stddef.h>
  19. #include <utils/Mutex.h>
  20. #include <utils/Timers.h>
  21. #include <utils/RefBase.h>
  22. namespace android {
  23. // Ignore present (retire) fences if the device doesn't have support for the
  24. // sync framework.
  25. #if defined(RUNNING_WITHOUT_SYNC_FRAMEWORK)
  26. static const bool kIgnorePresentFences = true;
  27. #else
  28. static const bool kIgnorePresentFences = false;
  29. #endif
  30. class String8;
  31. class Fence;
  32. class DispSyncThread;
  33. // DispSync maintains a model of the periodic hardware-based vsync events of a
  34. // display and uses that model to execute period callbacks at specific phase
  35. // offsets from the hardware vsync events. The model is constructed by
  36. // feeding consecutive hardware event timestamps to the DispSync object via
  37. // the addResyncSample method.
  38. //
  39. // The model is validated using timestamps from Fence objects that are passed
  40. // to the DispSync object via the addPresentFence method. These fence
  41. // timestamps should correspond to a hardware vsync event, but they need not
  42. // be consecutive hardware vsync times. If this method determines that the
  43. // current model accurately represents the hardware event times it will return
  44. // false to indicate that a resynchronization (via addResyncSample) is not
  45. // needed.
  46. class DispSync {
  47. public:
  48. class Callback: public virtual RefBase {
  49. public:
  50. virtual ~Callback() {};
  51. virtual void onDispSyncEvent(nsecs_t when) = 0;
  52. };
  53. DispSync();
  54. ~DispSync();
  55. // reset clears the resync samples and error value.
  56. void reset();
  57. // addPresentFence adds a fence for use in validating the current vsync
  58. // event model. The fence need not be signaled at the time
  59. // addPresentFence is called. When the fence does signal, its timestamp
  60. // should correspond to a hardware vsync event. Unlike the
  61. // addResyncSample method, the timestamps of consecutive fences need not
  62. // correspond to consecutive hardware vsync events.
  63. //
  64. // This method should be called with the retire fence from each HWComposer
  65. // set call that affects the display.
  66. bool addPresentFence(const sp<Fence>& fence);
  67. // The beginResync, addResyncSample, and endResync methods are used to re-
  68. // synchronize the DispSync's model to the hardware vsync events. The re-
  69. // synchronization process involves first calling beginResync, then
  70. // calling addResyncSample with a sequence of consecutive hardware vsync
  71. // event timestamps, and finally calling endResync when addResyncSample
  72. // indicates that no more samples are needed by returning false.
  73. //
  74. // This resynchronization process should be performed whenever the display
  75. // is turned on (i.e. once immediately after it's turned on) and whenever
  76. // addPresentFence returns true indicating that the model has drifted away
  77. // from the hardware vsync events.
  78. void beginResync();
  79. bool addResyncSample(nsecs_t timestamp);
  80. void endResync();
  81. // The setPeriod method sets the vsync event model's period to a specific
  82. // value. This should be used to prime the model when a display is first
  83. // turned on. It should NOT be used after that.
  84. void setPeriod(nsecs_t period);
  85. // The getPeriod method returns the current vsync period.
  86. nsecs_t getPeriod();
  87. // setRefreshSkipCount specifies an additional number of refresh
  88. // cycles to skip. For example, on a 60Hz display, a skip count of 1
  89. // will result in events happening at 30Hz. Default is zero. The idea
  90. // is to sacrifice smoothness for battery life.
  91. void setRefreshSkipCount(int count);
  92. // addEventListener registers a callback to be called repeatedly at the
  93. // given phase offset from the hardware vsync events. The callback is
  94. // called from a separate thread and it should return reasonably quickly
  95. // (i.e. within a few hundred microseconds).
  96. status_t addEventListener(nsecs_t phase, const sp<Callback>& callback);
  97. // removeEventListener removes an already-registered event callback. Once
  98. // this method returns that callback will no longer be called by the
  99. // DispSync object.
  100. status_t removeEventListener(const sp<Callback>& callback);
  101. // computeNextRefresh computes when the next refresh is expected to begin.
  102. // The periodOffset value can be used to move forward or backward; an
  103. // offset of zero is the next refresh, -1 is the previous refresh, 1 is
  104. // the refresh after next. etc.
  105. nsecs_t computeNextRefresh(int periodOffset) const;
  106. // dump appends human-readable debug info to the result string.
  107. void dump(String8& result) const;
  108. private:
  109. void updateModelLocked();
  110. void updateErrorLocked();
  111. void resetErrorLocked();
  112. enum { MAX_RESYNC_SAMPLES = 32 };
  113. enum { MIN_RESYNC_SAMPLES_FOR_UPDATE = 3 };
  114. enum { NUM_PRESENT_SAMPLES = 8 };
  115. enum { MAX_RESYNC_SAMPLES_WITHOUT_PRESENT = 4 };
  116. // mPeriod is the computed period of the modeled vsync events in
  117. // nanoseconds.
  118. nsecs_t mPeriod;
  119. // mPhase is the phase offset of the modeled vsync events. It is the
  120. // number of nanoseconds from time 0 to the first vsync event.
  121. nsecs_t mPhase;
  122. // mReferenceTime is the reference time of the modeled vsync events.
  123. // It is the nanosecond timestamp of the first vsync event after a resync.
  124. nsecs_t mReferenceTime;
  125. // mError is the computed model error. It is based on the difference
  126. // between the estimated vsync event times and those observed in the
  127. // mPresentTimes array.
  128. nsecs_t mError;
  129. // Whether we have updated the vsync event model since the last resync.
  130. bool mModelUpdated;
  131. // These member variables are the state used during the resynchronization
  132. // process to store information about the hardware vsync event times used
  133. // to compute the model.
  134. nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES];
  135. size_t mFirstResyncSample;
  136. size_t mNumResyncSamples;
  137. int mNumResyncSamplesSincePresent;
  138. // These member variables store information about the present fences used
  139. // to validate the currently computed model.
  140. sp<Fence> mPresentFences[NUM_PRESENT_SAMPLES];
  141. nsecs_t mPresentTimes[NUM_PRESENT_SAMPLES];
  142. size_t mPresentSampleOffset;
  143. int mRefreshSkipCount;
  144. // mThread is the thread from which all the callbacks are called.
  145. sp<DispSyncThread> mThread;
  146. // mMutex is used to protect access to all member variables.
  147. mutable Mutex mMutex;
  148. };
  149. }
  150. #endif // ANDROID_DISPSYNC_H