| 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 | 
|  | 66 | // occurs. |compositor_time_ns| is the number of ns before the next vsync when | 
|  | 67 | // the compositor will preempt the GPU to do EDS and lens warp. | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 68 | void VSyncEvent(int display, int64_t timestamp_ns, int64_t compositor_time_ns, | 
|  | 69 | uint32_t vsync_count); | 
|  | 70 |  | 
|  | 71 | private: | 
|  | 72 | friend BASE; | 
|  | 73 |  | 
|  | 74 | VSyncService(); | 
|  | 75 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 76 | pdx::Status<int64_t> OnGetLastTimestamp(pdx::Message& message); | 
|  | 77 | pdx::Status<display::VSyncSchedInfo> OnGetSchedInfo(pdx::Message& message); | 
|  | 78 | pdx::Status<void> OnAcknowledge(pdx::Message& message); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 79 |  | 
|  | 80 | void NotifierThreadFunction(); | 
|  | 81 |  | 
|  | 82 | void AddWaiter(pdx::Message& message); | 
|  | 83 | void NotifyWaiters(); | 
|  | 84 | void UpdateClients(); | 
|  | 85 |  | 
|  | 86 | void AddClient(const std::shared_ptr<VSyncChannel>& client); | 
|  | 87 | void RemoveClient(const std::shared_ptr<VSyncChannel>& client); | 
|  | 88 |  | 
|  | 89 | int64_t last_vsync_; | 
|  | 90 | int64_t current_vsync_; | 
|  | 91 | int64_t compositor_time_ns_; | 
|  | 92 | uint32_t current_vsync_count_; | 
|  | 93 |  | 
|  | 94 | std::mutex mutex_; | 
|  | 95 |  | 
|  | 96 | std::list<std::unique_ptr<VSyncWaiter>> waiters_; | 
|  | 97 | std::list<std::shared_ptr<VSyncChannel>> clients_; | 
|  | 98 |  | 
|  | 99 | VSyncService(const VSyncService&) = delete; | 
|  | 100 | void operator=(VSyncService&) = delete; | 
|  | 101 | }; | 
|  | 102 |  | 
|  | 103 | }  // namespace dvr | 
|  | 104 | }  // namespace android | 
|  | 105 |  | 
|  | 106 | #endif  // ANDROID_DVR_SERVICES_DISPLAYD_VSYNC_SERVICE_H_ |