|  | #ifndef ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_ | 
|  | #define ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_ | 
|  |  | 
|  | #include <pdx/file_handle.h> | 
|  | #include <pdx/service.h> | 
|  | #include <private/dvr/buffer_hub_queue_client.h> | 
|  | #include <private/dvr/display_protocol.h> | 
|  | #include <private/dvr/ring_buffer.h> | 
|  |  | 
|  | #include <functional> | 
|  | #include <iterator> | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "acquired_buffer.h" | 
|  |  | 
|  | namespace android { | 
|  | namespace dvr { | 
|  |  | 
|  | class DisplayService; | 
|  |  | 
|  | enum class SurfaceType { | 
|  | Direct, | 
|  | Application, | 
|  | }; | 
|  |  | 
|  | class DisplaySurface : public pdx::Channel { | 
|  | public: | 
|  | static pdx::Status<std::shared_ptr<DisplaySurface>> Create( | 
|  | DisplayService* service, int surface_id, int process_id, int user_id, | 
|  | const display::SurfaceAttributes& attributes); | 
|  |  | 
|  | ~DisplaySurface() override; | 
|  |  | 
|  | DisplayService* service() const { return service_; } | 
|  | SurfaceType surface_type() const { return surface_type_; } | 
|  | int surface_id() const { return surface_id_; } | 
|  | int process_id() const { return process_id_; } | 
|  | int user_id() const { return user_id_; } | 
|  |  | 
|  | bool visible() const { return visible_; } | 
|  | int z_order() const { return z_order_; } | 
|  |  | 
|  | const display::SurfaceAttributes& attributes() const { return attributes_; } | 
|  | display::SurfaceUpdateFlags update_flags() const { return update_flags_; } | 
|  |  | 
|  | virtual std::vector<int32_t> GetQueueIds() const { return {}; } | 
|  |  | 
|  | bool IsUpdatePending() const { | 
|  | return update_flags_.value() != display::SurfaceUpdateFlags::None; | 
|  | } | 
|  |  | 
|  | protected: | 
|  | DisplaySurface(DisplayService* service, SurfaceType surface_type, | 
|  | int surface_id, int process_id, int user_id); | 
|  |  | 
|  | // Utility to retrieve a shared pointer to this channel as the desired derived | 
|  | // type. | 
|  | template < | 
|  | typename T = DisplaySurface, | 
|  | typename = std::enable_if_t<std::is_base_of<DisplaySurface, T>::value>> | 
|  | std::shared_ptr<T> Self() { | 
|  | return std::static_pointer_cast<T>(shared_from_this()); | 
|  | } | 
|  |  | 
|  | virtual pdx::Status<pdx::LocalChannelHandle> OnCreateQueue( | 
|  | pdx::Message& message, const ProducerQueueConfig& config) = 0; | 
|  |  | 
|  | // Registers a consumer queue with the event dispatcher in DisplayService. The | 
|  | // OnQueueEvent callback below is called to handle queue events. | 
|  | pdx::Status<void> RegisterQueue( | 
|  | const std::shared_ptr<ConsumerQueue>& consumer_queue); | 
|  | pdx::Status<void> UnregisterQueue( | 
|  | const std::shared_ptr<ConsumerQueue>& consumer_queue); | 
|  |  | 
|  | // Called by the event dispatcher in DisplayService when a registered queue | 
|  | // event triggers. Executes on the event dispatcher thread. | 
|  | virtual void OnQueueEvent( | 
|  | const std::shared_ptr<ConsumerQueue>& consumer_queue, int events); | 
|  |  | 
|  | void SurfaceUpdated(display::SurfaceUpdateFlags update_flags); | 
|  | void ClearUpdate(); | 
|  |  | 
|  | // Synchronizes access to mutable state below between message dispatch thread | 
|  | // and frame post thread. | 
|  | mutable std::mutex lock_; | 
|  |  | 
|  | private: | 
|  | friend class DisplayService; | 
|  | friend class DisplayManagerService; | 
|  |  | 
|  | // Dispatches display surface messages to the appropriate handlers. This | 
|  | // handler runs on the VrFlinger message dispatch thread. | 
|  | pdx::Status<void> HandleMessage(pdx::Message& message); | 
|  |  | 
|  | pdx::Status<void> OnSetAttributes( | 
|  | pdx::Message& message, const display::SurfaceAttributes& attributes); | 
|  | pdx::Status<display::SurfaceInfo> OnGetSurfaceInfo(pdx::Message& message); | 
|  |  | 
|  | DisplayService* service_; | 
|  | SurfaceType surface_type_; | 
|  | int surface_id_; | 
|  | int process_id_; | 
|  | int user_id_; | 
|  |  | 
|  | display::SurfaceAttributes attributes_; | 
|  | display::SurfaceUpdateFlags update_flags_ = display::SurfaceUpdateFlags::None; | 
|  |  | 
|  | // Subset of attributes that may be interpreted by the display service. | 
|  | bool visible_ = false; | 
|  | int z_order_ = 0; | 
|  |  | 
|  | DisplaySurface(const DisplaySurface&) = delete; | 
|  | void operator=(const DisplaySurface&) = delete; | 
|  | }; | 
|  |  | 
|  | class ApplicationDisplaySurface : public DisplaySurface { | 
|  | public: | 
|  | ApplicationDisplaySurface(DisplayService* service, int surface_id, | 
|  | int process_id, int user_id) | 
|  | : DisplaySurface(service, SurfaceType::Application, surface_id, | 
|  | process_id, user_id) {} | 
|  |  | 
|  | std::shared_ptr<ConsumerQueue> GetQueue(int32_t queue_id); | 
|  | std::vector<int32_t> GetQueueIds() const override; | 
|  |  | 
|  | private: | 
|  | pdx::Status<pdx::LocalChannelHandle> OnCreateQueue( | 
|  | pdx::Message& message, const ProducerQueueConfig& config) override; | 
|  | void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue, | 
|  | int events) override; | 
|  |  | 
|  | // Accessed by both message dispatch thread and epoll event thread. | 
|  | std::unordered_map<int32_t, std::shared_ptr<ConsumerQueue>> consumer_queues_; | 
|  | }; | 
|  |  | 
|  | class DirectDisplaySurface : public DisplaySurface { | 
|  | public: | 
|  | DirectDisplaySurface(DisplayService* service, int surface_id, int process_id, | 
|  | int user_id) | 
|  | : DisplaySurface(service, SurfaceType::Direct, surface_id, process_id, | 
|  | user_id), | 
|  | acquired_buffers_(kMaxPostedBuffers), | 
|  | metadata_(nullptr) {} | 
|  | std::vector<int32_t> GetQueueIds() const override; | 
|  | bool IsBufferAvailable(); | 
|  | bool IsBufferPosted(); | 
|  | AcquiredBuffer AcquireCurrentBuffer(); | 
|  |  | 
|  | // Get the newest buffer. Up to one buffer will be skipped. If a buffer is | 
|  | // skipped, it will be stored in skipped_buffer if non null. | 
|  | AcquiredBuffer AcquireNewestAvailableBuffer(AcquiredBuffer* skipped_buffer); | 
|  |  | 
|  | private: | 
|  | pdx::Status<pdx::LocalChannelHandle> OnCreateQueue( | 
|  | pdx::Message& message, const ProducerQueueConfig& config) override; | 
|  | void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue, | 
|  | int events) override; | 
|  |  | 
|  | // The capacity of the pending buffer queue. Should be enough to hold all the | 
|  | // buffers of this DisplaySurface, although in practice only 1 or 2 frames | 
|  | // will be pending at a time. | 
|  | static constexpr int kSurfaceBufferMaxCount = 4; | 
|  | static constexpr int kSurfaceViewMaxCount = 4; | 
|  | static constexpr int kMaxPostedBuffers = | 
|  | kSurfaceBufferMaxCount * kSurfaceViewMaxCount; | 
|  |  | 
|  | // Returns whether a frame is available without locking the mutex. | 
|  | bool IsFrameAvailableNoLock() const; | 
|  |  | 
|  | // Dequeue all available buffers from the consumer queue. | 
|  | void DequeueBuffersLocked(); | 
|  |  | 
|  | // In a triple-buffered surface, up to kMaxPostedBuffers buffers may be | 
|  | // posted and pending. | 
|  | RingBuffer<AcquiredBuffer> acquired_buffers_; | 
|  |  | 
|  | std::shared_ptr<ConsumerQueue> direct_queue_; | 
|  |  | 
|  | // Stores metadata when it dequeue buffers from consumer queue. | 
|  | std::unique_ptr<uint8_t[]> metadata_; | 
|  | }; | 
|  |  | 
|  | }  // namespace dvr | 
|  | }  // namespace android | 
|  |  | 
|  | #endif  // ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_ |