File: vsync_service.h

package info (click to toggle)
android-platform-frameworks-native 1%3A8.1.0%2Br23-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 20,612 kB
  • sloc: cpp: 199,842; xml: 48,803; ansic: 23,250; java: 5,012; python: 1,624; sh: 225; asm: 105; perl: 74; makefile: 22
file content (106 lines) | stat: -rw-r--r-- 2,967 bytes parent folder | download
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_