#ifndef ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_ #define ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_ #include #include #include #include #include #include #include #include #include #include #include "acquired_buffer.h" namespace android { namespace dvr { class DisplayService; enum class SurfaceType { Direct, Application, }; class DisplaySurface : public pdx::Channel { public: static pdx::Status> 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 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::value>> std::shared_ptr Self() { return std::static_pointer_cast(shared_from_this()); } virtual pdx::Status 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 RegisterQueue( const std::shared_ptr& consumer_queue); pdx::Status UnregisterQueue( const std::shared_ptr& 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& 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 HandleMessage(pdx::Message& message); pdx::Status OnSetAttributes( pdx::Message& message, const display::SurfaceAttributes& attributes); pdx::Status 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 GetQueue(int32_t queue_id); std::vector GetQueueIds() const override; private: pdx::Status OnCreateQueue( pdx::Message& message, const ProducerQueueConfig& config) override; void OnQueueEvent(const std::shared_ptr& consumer_queue, int events) override; // Accessed by both message dispatch thread and epoll event thread. std::unordered_map> 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 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 OnCreateQueue( pdx::Message& message, const ProducerQueueConfig& config) override; void OnQueueEvent(const std::shared_ptr& 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 acquired_buffers_; std::shared_ptr direct_queue_; // Stores metadata when it dequeue buffers from consumer queue. std::unique_ptr metadata_; }; } // namespace dvr } // namespace android #endif // ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SURFACE_H_