| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 1 | #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 Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 6 | #include <private/dvr/buffer_hub_queue_client.h> | 
| Corey Tabaka | 3f82d31 | 2017-04-20 14:42:08 -0700 | [diff] [blame] | 7 | #include <private/dvr/display_protocol.h> | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 8 | #include <private/dvr/ring_buffer.h> | 
|  | 9 |  | 
|  | 10 | #include <functional> | 
|  | 11 | #include <iterator> | 
|  | 12 | #include <memory> | 
|  | 13 | #include <string> | 
|  | 14 | #include <vector> | 
|  | 15 |  | 
|  | 16 | #include "acquired_buffer.h" | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 17 |  | 
|  | 18 | namespace android { | 
|  | 19 | namespace dvr { | 
|  | 20 |  | 
|  | 21 | class DisplayService; | 
|  | 22 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 23 | enum class SurfaceType { | 
|  | 24 | Direct, | 
|  | 25 | Application, | 
|  | 26 | }; | 
|  | 27 |  | 
|  | 28 | class DisplaySurface : public pdx::Channel { | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 29 | public: | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 30 | static pdx::Status<std::shared_ptr<DisplaySurface>> Create( | 
|  | 31 | DisplayService* service, int surface_id, int process_id, int user_id, | 
|  | 32 | const display::SurfaceAttributes& attributes); | 
|  | 33 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 34 | ~DisplaySurface() override; | 
|  | 35 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 36 | DisplayService* service() const { return service_; } | 
|  | 37 | SurfaceType surface_type() const { return surface_type_; } | 
|  | 38 | int surface_id() const { return surface_id_; } | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 39 | int process_id() const { return process_id_; } | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 40 | int user_id() const { return user_id_; } | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 41 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 42 | bool visible() const { return visible_; } | 
|  | 43 | int z_order() const { return z_order_; } | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 44 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 45 | const display::SurfaceAttributes& attributes() const { return attributes_; } | 
|  | 46 | display::SurfaceUpdateFlags update_flags() const { return update_flags_; } | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 47 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 48 | virtual std::vector<int32_t> GetQueueIds() const { return {}; } | 
|  | 49 |  | 
|  | 50 | bool IsUpdatePending() const { | 
|  | 51 | return update_flags_.value() != display::SurfaceUpdateFlags::None; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 52 | } | 
|  | 53 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 54 | protected: | 
|  | 55 | DisplaySurface(DisplayService* service, SurfaceType surface_type, | 
|  | 56 | int surface_id, int process_id, int user_id, | 
|  | 57 | const display::SurfaceAttributes& attributes); | 
|  | 58 |  | 
|  | 59 | // Utility to retrieve a shared pointer to this channel as the desired derived | 
|  | 60 | // type. | 
|  | 61 | template < | 
|  | 62 | typename T = DisplaySurface, | 
|  | 63 | typename = std::enable_if_t<std::is_base_of<DisplaySurface, T>::value>> | 
|  | 64 | std::shared_ptr<T> Self() { | 
|  | 65 | return std::static_pointer_cast<T>(shared_from_this()); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 66 | } | 
|  | 67 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 68 | virtual pdx::Status<pdx::LocalChannelHandle> OnCreateQueue( | 
|  | 69 | pdx::Message& message, size_t meta_size_bytes) = 0; | 
|  | 70 |  | 
|  | 71 | // Registers a consumer queue with the event dispatcher in DisplayService. The | 
|  | 72 | // OnQueueEvent callback below is called to handle queue events. | 
|  | 73 | pdx::Status<void> RegisterQueue( | 
|  | 74 | const std::shared_ptr<ConsumerQueue>& consumer_queue); | 
|  | 75 | pdx::Status<void> UnregisterQueue( | 
|  | 76 | const std::shared_ptr<ConsumerQueue>& consumer_queue); | 
|  | 77 |  | 
|  | 78 | // Called by the event dispatcher in DisplayService when a registered queue | 
|  | 79 | // event triggers. Executes on the event dispatcher thread. | 
|  | 80 | virtual void OnQueueEvent( | 
|  | 81 | const std::shared_ptr<ConsumerQueue>& consumer_queue, int events); | 
|  | 82 |  | 
|  | 83 | void SurfaceUpdated(display::SurfaceUpdateFlags update_flags); | 
|  | 84 | void ClearUpdate(); | 
|  | 85 |  | 
|  | 86 | // Synchronizes access to mutable state below between message dispatch thread | 
|  | 87 | // and frame post thread. | 
|  | 88 | mutable std::mutex lock_; | 
|  | 89 |  | 
|  | 90 | private: | 
|  | 91 | friend class DisplayService; | 
|  | 92 | friend class DisplayManagerService; | 
|  | 93 |  | 
|  | 94 | // Dispatches display surface messages to the appropriate handlers. This | 
|  | 95 | // handler runs on the VrFlinger message dispatch thread. | 
|  | 96 | pdx::Status<void> HandleMessage(pdx::Message& message); | 
|  | 97 |  | 
|  | 98 | pdx::Status<void> OnSetAttributes( | 
|  | 99 | pdx::Message& message, const display::SurfaceAttributes& attributes); | 
|  | 100 | pdx::Status<display::SurfaceInfo> OnGetSurfaceInfo(pdx::Message& message); | 
|  | 101 |  | 
|  | 102 | DisplayService* service_; | 
|  | 103 | SurfaceType surface_type_; | 
|  | 104 | int surface_id_; | 
|  | 105 | int process_id_; | 
|  | 106 | int user_id_; | 
|  | 107 |  | 
|  | 108 | display::SurfaceAttributes attributes_; | 
|  | 109 | display::SurfaceUpdateFlags update_flags_ = display::SurfaceUpdateFlags::None; | 
|  | 110 |  | 
|  | 111 | // Subset of attributes that may be interpreted by the display service. | 
|  | 112 | bool visible_ = false; | 
|  | 113 | int z_order_ = 0; | 
|  | 114 |  | 
|  | 115 | DisplaySurface(const DisplaySurface&) = delete; | 
|  | 116 | void operator=(const DisplaySurface&) = delete; | 
|  | 117 | }; | 
|  | 118 |  | 
|  | 119 | class ApplicationDisplaySurface : public DisplaySurface { | 
|  | 120 | public: | 
|  | 121 | ApplicationDisplaySurface(DisplayService* service, int surface_id, | 
|  | 122 | int process_id, int user_id, | 
|  | 123 | const display::SurfaceAttributes& attributes) | 
|  | 124 | : DisplaySurface(service, SurfaceType::Application, surface_id, | 
|  | 125 | process_id, user_id, attributes) {} | 
|  | 126 |  | 
|  | 127 | std::shared_ptr<ConsumerQueue> GetQueue(int32_t queue_id); | 
|  | 128 | std::vector<int32_t> GetQueueIds() const override; | 
|  | 129 |  | 
|  | 130 | private: | 
|  | 131 | pdx::Status<pdx::LocalChannelHandle> OnCreateQueue( | 
|  | 132 | pdx::Message& message, size_t meta_size_bytes) override; | 
|  | 133 | void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue, | 
|  | 134 | int events) override; | 
|  | 135 |  | 
|  | 136 | std::unordered_map<int32_t, std::shared_ptr<ConsumerQueue>> consumer_queues_; | 
|  | 137 | }; | 
|  | 138 |  | 
|  | 139 | class DirectDisplaySurface : public DisplaySurface { | 
|  | 140 | public: | 
|  | 141 | DirectDisplaySurface(DisplayService* service, int surface_id, int process_id, | 
|  | 142 | int user_id, | 
|  | 143 | const display::SurfaceAttributes& attributes) | 
|  | 144 | : DisplaySurface(service, SurfaceType::Direct, surface_id, process_id, | 
|  | 145 | user_id, attributes), | 
|  | 146 | acquired_buffers_(kMaxPostedBuffers) {} | 
| Jiwen 'Steve' Cai | a361361 | 2017-03-08 17:41:48 -0800 | [diff] [blame] | 147 | bool IsBufferAvailable(); | 
|  | 148 | bool IsBufferPosted(); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 149 | AcquiredBuffer AcquireCurrentBuffer(); | 
|  | 150 |  | 
|  | 151 | // Get the newest buffer. Up to one buffer will be skipped. If a buffer is | 
|  | 152 | // skipped, it will be stored in skipped_buffer if non null. | 
|  | 153 | AcquiredBuffer AcquireNewestAvailableBuffer(AcquiredBuffer* skipped_buffer); | 
|  | 154 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 155 | private: | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 156 | pdx::Status<pdx::LocalChannelHandle> OnCreateQueue( | 
|  | 157 | pdx::Message& message, size_t meta_size_bytes) override; | 
|  | 158 | void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue, | 
|  | 159 | int events) override; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 160 |  | 
|  | 161 | // The capacity of the pending buffer queue. Should be enough to hold all the | 
|  | 162 | // buffers of this DisplaySurface, although in practice only 1 or 2 frames | 
|  | 163 | // will be pending at a time. | 
| Hendrik Wagenaar | fac4074 | 2017-05-09 08:59:51 -0700 | [diff] [blame] | 164 | static constexpr int kSurfaceBufferMaxCount = 4; | 
|  | 165 | static constexpr int kSurfaceViewMaxCount = 4; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 166 | static constexpr int kMaxPostedBuffers = | 
|  | 167 | kSurfaceBufferMaxCount * kSurfaceViewMaxCount; | 
|  | 168 |  | 
|  | 169 | // Returns whether a frame is available without locking the mutex. | 
|  | 170 | bool IsFrameAvailableNoLock() const; | 
|  | 171 |  | 
| Jiwen 'Steve' Cai | a361361 | 2017-03-08 17:41:48 -0800 | [diff] [blame] | 172 | // Dequeue all available buffers from the consumer queue. | 
|  | 173 | void DequeueBuffersLocked(); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 174 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 175 | // In a triple-buffered surface, up to kMaxPostedBuffers buffers may be | 
|  | 176 | // posted and pending. | 
| Jiwen 'Steve' Cai | a361361 | 2017-03-08 17:41:48 -0800 | [diff] [blame] | 177 | RingBuffer<AcquiredBuffer> acquired_buffers_; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 178 |  | 
| Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 179 | std::shared_ptr<ConsumerQueue> direct_queue_; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 180 | }; | 
|  | 181 |  | 
|  | 182 | }  // namespace dvr | 
|  | 183 | }  // namespace android | 
|  | 184 |  | 
|  | 185 | #endif  // ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_ |