Add DaydreamVR native libraries and services
Upstreaming the main VR system components from master-dreamos-dev
into goog/master.
Bug: None
Test: `m -j32` succeeds. Sailfish boots and basic_vr sample app works
Change-Id: I853015872afc443aecee10411ef2d6b79184d051
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/buffer_hub.h
new file mode 100644
index 0000000..28cb468
--- /dev/null
+++ b/services/vr/bufferhubd/buffer_hub.h
@@ -0,0 +1,182 @@
+#ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
+#define ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include <hardware/gralloc.h>
+#include <pdx/service.h>
+
+namespace android {
+namespace dvr {
+
+class BufferHubService;
+class ConsumerChannel;
+class ProducerChannel;
+class ConsumerQueueChannel;
+class ProducerQueueChannel;
+
+class BufferHubChannel : public pdx::Channel {
+ public:
+ enum ChannelType {
+ kProducerType,
+ kConsumerType,
+ kProducerQueueType,
+ kConsumerQueueType,
+ };
+
+ enum : int { kDetachedId = -1 };
+
+ BufferHubChannel(BufferHubService* service, int buffer_id, int channel_id,
+ ChannelType channel_type)
+ : service_(service),
+ buffer_id_(buffer_id),
+ channel_id_(channel_id),
+ channel_type_(channel_type) {}
+ virtual ~BufferHubChannel() {}
+
+ virtual bool HandleMessage(pdx::Message& message) = 0;
+ virtual void HandleImpulse(pdx::Message& message) = 0;
+
+ // Captures buffer info for use by BufferHubService::DumpState().
+ struct BufferInfo {
+ // Common data field shared by BufferProducer and ProducerQueue.
+ int id = -1;
+ int type = -1;
+ size_t consumer_count = 0;
+
+ // Data field for buffer producer.
+ int width = 0;
+ int height = 0;
+ int format = 0;
+ int usage = 0;
+ size_t slice_count = 0;
+ std::string name;
+
+ // Data filed for producer queue.
+ size_t capacity = 0;
+ int usage_set_mask = 0;
+ int usage_clear_mask = 0;
+ int usage_deny_set_mask = 0;
+ int usage_deny_clear_mask = 0;
+
+ BufferInfo(int id, size_t consumer_count, int width, int height, int format,
+ int usage, size_t slice_count, const std::string& name)
+ : id(id),
+ type(kProducerType),
+ consumer_count(consumer_count),
+ width(width),
+ height(height),
+ format(format),
+ usage(usage),
+ slice_count(slice_count),
+ name(name) {}
+
+ BufferInfo(int id, size_t consumer_count, size_t capacity, int usage_set_mask,
+ int usage_clear_mask, int usage_deny_set_mask,
+ int usage_deny_clear_mask)
+ : id(id),
+ type(kProducerQueueType),
+ consumer_count(consumer_count),
+ capacity(capacity),
+ usage_set_mask(usage_set_mask),
+ usage_clear_mask(usage_clear_mask),
+ usage_deny_set_mask(usage_deny_set_mask),
+ usage_deny_clear_mask(usage_deny_clear_mask) {}
+
+ BufferInfo() {}
+ };
+
+ // Returns the buffer info for this buffer.
+ virtual BufferInfo GetBufferInfo() const = 0;
+
+ // Signal the client fd that an ownership change occurred using POLLIN.
+ void SignalAvailable();
+
+ // Clear the ownership change event.
+ void ClearAvailable();
+
+ // Signal hangup event.
+ void Hangup();
+
+ BufferHubService* service() const { return service_; }
+ ChannelType channel_type() const { return channel_type_; }
+ int buffer_id() const { return buffer_id_; }
+
+ int channel_id() const { return channel_id_; }
+ bool IsDetached() const { return channel_id_ == kDetachedId; }
+
+ void Detach() {
+ if (channel_type_ == kProducerType)
+ channel_id_ = kDetachedId;
+ }
+ void Attach(int channel_id) {
+ if (channel_type_ == kProducerType && channel_id_ == kDetachedId)
+ channel_id_ = channel_id;
+ }
+
+ private:
+ BufferHubService* service_;
+
+ // Static id of the buffer for logging and informational purposes. This id
+ // does not change for the life of the buffer.
+ // TODO(eieio): Consider using an id allocator instead of the originating
+ // channel id; channel ids wrap after 2^31 ids, but this is not a problem in
+ // general because channel ids are not used for any lookup in this service.
+ int buffer_id_;
+
+ // The channel id of the buffer. This may change for a persistent producer
+ // buffer if it is detached and re-attached to another channel.
+ int channel_id_;
+
+ ChannelType channel_type_;
+
+ BufferHubChannel(const BufferHubChannel&) = delete;
+ void operator=(const BufferHubChannel&) = delete;
+};
+
+class BufferHubService : public pdx::ServiceBase<BufferHubService> {
+ public:
+ BufferHubService();
+ ~BufferHubService() override;
+
+ int HandleMessage(pdx::Message& message) override;
+ void HandleImpulse(pdx::Message& message) override;
+
+ void OnChannelClose(pdx::Message& message,
+ const std::shared_ptr<pdx::Channel>& channel) override;
+
+ bool IsInitialized() const override;
+ std::string DumpState(size_t max_length) override;
+
+ bool AddNamedBuffer(const std::string& name,
+ const std::shared_ptr<ProducerChannel>& buffer);
+ std::shared_ptr<ProducerChannel> GetNamedBuffer(const std::string& name);
+ bool RemoveNamedBuffer(const ProducerChannel& buffer);
+
+ private:
+ friend BASE;
+
+ std::unordered_map<std::string, std::shared_ptr<ProducerChannel>>
+ named_buffers_;
+
+ int OnCreateBuffer(pdx::Message& message, int width, int height, int format,
+ int usage, size_t meta_size_bytes, size_t slice_count);
+ int OnCreatePersistentBuffer(pdx::Message& message, const std::string& name,
+ int user_id, int group_id, int width, int height,
+ int format, int usage, size_t meta_size_bytes,
+ size_t slice_count);
+ int OnGetPersistentBuffer(pdx::Message& message, const std::string& name);
+ int OnCreateProducerQueue(pdx::Message& message, size_t meta_size_bytes,
+ int usage_set_mask, int usage_clear_mask,
+ int usage_deny_set_mask, int usage_deny_clear_mask);
+
+ BufferHubService(const BufferHubService&) = delete;
+ void operator=(const BufferHubService&) = delete;
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_