| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 1 | #ifndef ANDROID_DVR_SERVICES_DISPLAYD_VSYNC_SERVICE_H_ | 
 | 2 | #define ANDROID_DVR_SERVICES_DISPLAYD_VSYNC_SERVICE_H_ | 
 | 3 |  | 
 | 4 | #include <pdx/service.h> | 
 | 5 |  | 
 | 6 | #include <list> | 
 | 7 | #include <memory> | 
 | 8 | #include <mutex> | 
 | 9 | #include <thread> | 
 | 10 |  | 
 | 11 | #include "display_service.h" | 
 | 12 |  | 
 | 13 | namespace android { | 
 | 14 | namespace dvr { | 
 | 15 |  | 
 | 16 | // VSyncWaiter encapsulates a client blocked waiting for the next vsync. | 
 | 17 | // It is used to enqueue the Message to reply to when the next vsync event | 
 | 18 | // occurs. | 
 | 19 | class VSyncWaiter { | 
 | 20 |  public: | 
 | 21 |   explicit VSyncWaiter(pdx::Message& message) : message_(std::move(message)) {} | 
 | 22 |  | 
 | 23 |   void Notify(int64_t timestamp); | 
 | 24 |  | 
 | 25 |  private: | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 26 |   pdx::Status<int64_t> OnWait(pdx::Message& message); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 27 |  | 
 | 28 |   pdx::Message message_; | 
 | 29 |   int64_t timestamp_ = 0; | 
 | 30 |  | 
 | 31 |   VSyncWaiter(const VSyncWaiter&) = delete; | 
 | 32 |   void operator=(const VSyncWaiter&) = delete; | 
 | 33 | }; | 
 | 34 |  | 
 | 35 | // VSyncChannel manages the service-side per-client context for each client | 
 | 36 | // using the service. | 
 | 37 | class VSyncChannel : public pdx::Channel { | 
 | 38 |  public: | 
 | 39 |   VSyncChannel(pdx::Service& service, int pid, int cid) | 
 | 40 |       : service_(service), pid_(pid), cid_(cid) {} | 
 | 41 |  | 
 | 42 |   void Ack(); | 
 | 43 |   void Signal(); | 
 | 44 |  | 
 | 45 |  private: | 
 | 46 |   pdx::Service& service_; | 
 | 47 |   pid_t pid_; | 
 | 48 |   int cid_; | 
 | 49 |  | 
 | 50 |   VSyncChannel(const VSyncChannel&) = delete; | 
 | 51 |   void operator=(const VSyncChannel&) = delete; | 
 | 52 | }; | 
 | 53 |  | 
 | 54 | // VSyncService implements the displayd vsync service over ServiceFS. | 
 | 55 | class VSyncService : public pdx::ServiceBase<VSyncService> { | 
 | 56 |  public: | 
 | 57 |   ~VSyncService() override; | 
 | 58 |  | 
| Alex Vakulenko | f0a7bd0 | 2017-03-31 18:06:19 -0700 | [diff] [blame] | 59 |   pdx::Status<void> HandleMessage(pdx::Message& message) override; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 60 |  | 
 | 61 |   std::shared_ptr<pdx::Channel> OnChannelOpen(pdx::Message& message) override; | 
 | 62 |   void OnChannelClose(pdx::Message& message, | 
 | 63 |                       const std::shared_ptr<pdx::Channel>& channel) override; | 
 | 64 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 65 |   // Called by the hardware composer HAL, or similar, whenever a vsync event | 
| Steven Thomas | 6e8f706 | 2017-11-22 14:15:29 -0800 | [diff] [blame] | 66 |   // occurs on the primary display. |compositor_time_ns| is the number of ns | 
 | 67 |   // before the next vsync when the compositor will preempt the GPU to do EDS | 
 | 68 |   // and lens warp. | 
 | 69 |   void VSyncEvent(int64_t timestamp_ns, int64_t compositor_time_ns, | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 70 |                   uint32_t vsync_count); | 
 | 71 |  | 
 | 72 |  private: | 
 | 73 |   friend BASE; | 
 | 74 |  | 
 | 75 |   VSyncService(); | 
 | 76 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 77 |   pdx::Status<int64_t> OnGetLastTimestamp(pdx::Message& message); | 
 | 78 |   pdx::Status<display::VSyncSchedInfo> OnGetSchedInfo(pdx::Message& message); | 
 | 79 |   pdx::Status<void> OnAcknowledge(pdx::Message& message); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 80 |  | 
 | 81 |   void NotifierThreadFunction(); | 
 | 82 |  | 
 | 83 |   void AddWaiter(pdx::Message& message); | 
 | 84 |   void NotifyWaiters(); | 
 | 85 |   void UpdateClients(); | 
 | 86 |  | 
 | 87 |   void AddClient(const std::shared_ptr<VSyncChannel>& client); | 
 | 88 |   void RemoveClient(const std::shared_ptr<VSyncChannel>& client); | 
 | 89 |  | 
 | 90 |   int64_t last_vsync_; | 
 | 91 |   int64_t current_vsync_; | 
 | 92 |   int64_t compositor_time_ns_; | 
 | 93 |   uint32_t current_vsync_count_; | 
 | 94 |  | 
 | 95 |   std::mutex mutex_; | 
 | 96 |  | 
 | 97 |   std::list<std::unique_ptr<VSyncWaiter>> waiters_; | 
 | 98 |   std::list<std::shared_ptr<VSyncChannel>> clients_; | 
 | 99 |  | 
 | 100 |   VSyncService(const VSyncService&) = delete; | 
 | 101 |   void operator=(VSyncService&) = delete; | 
 | 102 | }; | 
 | 103 |  | 
 | 104 | }  // namespace dvr | 
 | 105 | }  // namespace android | 
 | 106 |  | 
 | 107 | #endif  // ANDROID_DVR_SERVICES_DISPLAYD_VSYNC_SERVICE_H_ |