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