blob: 47a07f0471688240ca08e123619d0d1410abcab5 [file] [log] [blame]
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001#ifndef ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_
2#define ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_
3
4#include <pdx/file_handle.h>
5#include <pdx/service.h>
Corey Tabaka2251d822017-04-20 16:04:07 -07006#include <private/dvr/buffer_hub_queue_client.h>
Corey Tabaka3f82d312017-04-20 14:42:08 -07007#include <private/dvr/display_protocol.h>
Corey Tabaka2251d822017-04-20 16:04:07 -07008#include <private/dvr/graphics_private.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08009#include <private/dvr/ring_buffer.h>
10
11#include <functional>
12#include <iterator>
13#include <memory>
14#include <string>
15#include <vector>
16
17#include "acquired_buffer.h"
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080018
19namespace android {
20namespace dvr {
21
22class DisplayService;
23
Corey Tabaka2251d822017-04-20 16:04:07 -070024enum class SurfaceType {
25 Direct,
26 Application,
27};
28
29class DisplaySurface : public pdx::Channel {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080030 public:
Corey Tabaka2251d822017-04-20 16:04:07 -070031 static pdx::Status<std::shared_ptr<DisplaySurface>> Create(
32 DisplayService* service, int surface_id, int process_id, int user_id,
33 const display::SurfaceAttributes& attributes);
34
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080035 ~DisplaySurface() override;
36
Corey Tabaka2251d822017-04-20 16:04:07 -070037 DisplayService* service() const { return service_; }
38 SurfaceType surface_type() const { return surface_type_; }
39 int surface_id() const { return surface_id_; }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080040 int process_id() const { return process_id_; }
Corey Tabaka2251d822017-04-20 16:04:07 -070041 int user_id() const { return user_id_; }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080042
Corey Tabaka2251d822017-04-20 16:04:07 -070043 bool visible() const { return visible_; }
44 int z_order() const { return z_order_; }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080045
Corey Tabaka2251d822017-04-20 16:04:07 -070046 const display::SurfaceAttributes& attributes() const { return attributes_; }
47 display::SurfaceUpdateFlags update_flags() const { return update_flags_; }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080048
Corey Tabaka2251d822017-04-20 16:04:07 -070049 virtual std::vector<int32_t> GetQueueIds() const { return {}; }
50
51 bool IsUpdatePending() const {
52 return update_flags_.value() != display::SurfaceUpdateFlags::None;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080053 }
54
Corey Tabaka2251d822017-04-20 16:04:07 -070055 protected:
56 DisplaySurface(DisplayService* service, SurfaceType surface_type,
57 int surface_id, int process_id, int user_id,
58 const display::SurfaceAttributes& attributes);
59
60 // Utility to retrieve a shared pointer to this channel as the desired derived
61 // type.
62 template <
63 typename T = DisplaySurface,
64 typename = std::enable_if_t<std::is_base_of<DisplaySurface, T>::value>>
65 std::shared_ptr<T> Self() {
66 return std::static_pointer_cast<T>(shared_from_this());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080067 }
68
Corey Tabaka2251d822017-04-20 16:04:07 -070069 virtual pdx::Status<pdx::LocalChannelHandle> OnCreateQueue(
70 pdx::Message& message, size_t meta_size_bytes) = 0;
71
72 // Registers a consumer queue with the event dispatcher in DisplayService. The
73 // OnQueueEvent callback below is called to handle queue events.
74 pdx::Status<void> RegisterQueue(
75 const std::shared_ptr<ConsumerQueue>& consumer_queue);
76 pdx::Status<void> UnregisterQueue(
77 const std::shared_ptr<ConsumerQueue>& consumer_queue);
78
79 // Called by the event dispatcher in DisplayService when a registered queue
80 // event triggers. Executes on the event dispatcher thread.
81 virtual void OnQueueEvent(
82 const std::shared_ptr<ConsumerQueue>& consumer_queue, int events);
83
84 void SurfaceUpdated(display::SurfaceUpdateFlags update_flags);
85 void ClearUpdate();
86
87 // Synchronizes access to mutable state below between message dispatch thread
88 // and frame post thread.
89 mutable std::mutex lock_;
90
91 private:
92 friend class DisplayService;
93 friend class DisplayManagerService;
94
95 // Dispatches display surface messages to the appropriate handlers. This
96 // handler runs on the VrFlinger message dispatch thread.
97 pdx::Status<void> HandleMessage(pdx::Message& message);
98
99 pdx::Status<void> OnSetAttributes(
100 pdx::Message& message, const display::SurfaceAttributes& attributes);
101 pdx::Status<display::SurfaceInfo> OnGetSurfaceInfo(pdx::Message& message);
102
103 DisplayService* service_;
104 SurfaceType surface_type_;
105 int surface_id_;
106 int process_id_;
107 int user_id_;
108
109 display::SurfaceAttributes attributes_;
110 display::SurfaceUpdateFlags update_flags_ = display::SurfaceUpdateFlags::None;
111
112 // Subset of attributes that may be interpreted by the display service.
113 bool visible_ = false;
114 int z_order_ = 0;
115
116 DisplaySurface(const DisplaySurface&) = delete;
117 void operator=(const DisplaySurface&) = delete;
118};
119
120class ApplicationDisplaySurface : public DisplaySurface {
121 public:
122 ApplicationDisplaySurface(DisplayService* service, int surface_id,
123 int process_id, int user_id,
124 const display::SurfaceAttributes& attributes)
125 : DisplaySurface(service, SurfaceType::Application, surface_id,
126 process_id, user_id, attributes) {}
127
128 std::shared_ptr<ConsumerQueue> GetQueue(int32_t queue_id);
129 std::vector<int32_t> GetQueueIds() const override;
130
131 private:
132 pdx::Status<pdx::LocalChannelHandle> OnCreateQueue(
133 pdx::Message& message, size_t meta_size_bytes) override;
134 void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue,
135 int events) override;
136
137 std::unordered_map<int32_t, std::shared_ptr<ConsumerQueue>> consumer_queues_;
138};
139
140class DirectDisplaySurface : public DisplaySurface {
141 public:
142 DirectDisplaySurface(DisplayService* service, int surface_id, int process_id,
143 int user_id,
144 const display::SurfaceAttributes& attributes)
145 : DisplaySurface(service, SurfaceType::Direct, surface_id, process_id,
146 user_id, attributes),
147 acquired_buffers_(kMaxPostedBuffers) {}
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -0800148 bool IsBufferAvailable();
149 bool IsBufferPosted();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800150 AcquiredBuffer AcquireCurrentBuffer();
151
152 // Get the newest buffer. Up to one buffer will be skipped. If a buffer is
153 // skipped, it will be stored in skipped_buffer if non null.
154 AcquiredBuffer AcquireNewestAvailableBuffer(AcquiredBuffer* skipped_buffer);
155
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800156 private:
Corey Tabaka2251d822017-04-20 16:04:07 -0700157 pdx::Status<pdx::LocalChannelHandle> OnCreateQueue(
158 pdx::Message& message, size_t meta_size_bytes) override;
159 void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue,
160 int events) override;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800161
162 // The capacity of the pending buffer queue. Should be enough to hold all the
163 // buffers of this DisplaySurface, although in practice only 1 or 2 frames
164 // will be pending at a time.
165 static constexpr int kMaxPostedBuffers =
166 kSurfaceBufferMaxCount * kSurfaceViewMaxCount;
167
168 // Returns whether a frame is available without locking the mutex.
169 bool IsFrameAvailableNoLock() const;
170
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -0800171 // Dequeue all available buffers from the consumer queue.
172 void DequeueBuffersLocked();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800173
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800174 // In a triple-buffered surface, up to kMaxPostedBuffers buffers may be
175 // posted and pending.
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -0800176 RingBuffer<AcquiredBuffer> acquired_buffers_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800177
Corey Tabaka2251d822017-04-20 16:04:07 -0700178 std::shared_ptr<ConsumerQueue> direct_queue_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800179};
180
181} // namespace dvr
182} // namespace android
183
184#endif // ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_