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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
#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_
|