1822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#ifndef ANDROID_DVR_SHARED_BUFFER_HELPERS_H_ 2822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#define ANDROID_DVR_SHARED_BUFFER_HELPERS_H_ 3822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 4822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#include <assert.h> 5822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#include <tuple> 6822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 7822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#include <libbroadcastring/broadcast_ring.h> 8822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#include <private/dvr/display_client.h> 9822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 10822b710a714c342dda0087f594c8ababa6630f44Okan Arikannamespace android { 11822b710a714c342dda0087f594c8ababa6630f44Okan Arikannamespace dvr { 12822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 13822b710a714c342dda0087f594c8ababa6630f44Okan Arikan// The buffer usage type for mapped shared buffers. 14822b710a714c342dda0087f594c8ababa6630f44Okan Arikanenum class CPUUsageMode { READ_OFTEN, READ_RARELY, WRITE_OFTEN, WRITE_RARELY }; 15822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 16822b710a714c342dda0087f594c8ababa6630f44Okan Arikan// Holds the memory for the mapped shared buffer. Unlocks and releases the 17822b710a714c342dda0087f594c8ababa6630f44Okan Arikan// underlying IonBuffer in destructor. 18822b710a714c342dda0087f594c8ababa6630f44Okan Arikanclass CPUMappedBuffer { 19822b710a714c342dda0087f594c8ababa6630f44Okan Arikan public: 20822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // This constructor will create a display client and get the buffer from it. 21822b710a714c342dda0087f594c8ababa6630f44Okan Arikan CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode); 22822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 23822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // If you already have the IonBuffer, use this. It will take ownership. 24822b710a714c342dda0087f594c8ababa6630f44Okan Arikan CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer, CPUUsageMode mode); 25822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 26822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // Use this if you do not want to take ownership. 27822b710a714c342dda0087f594c8ababa6630f44Okan Arikan CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode); 28822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 29822b710a714c342dda0087f594c8ababa6630f44Okan Arikan ~CPUMappedBuffer(); 30822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 31822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // Getters. 32822b710a714c342dda0087f594c8ababa6630f44Okan Arikan size_t Size() const { return size_; } 33822b710a714c342dda0087f594c8ababa6630f44Okan Arikan void* Address() const { return address_; } 34822b710a714c342dda0087f594c8ababa6630f44Okan Arikan bool IsMapped() const { return Address() != nullptr; } 35822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 36822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // Attempt mapping this buffer to the CPU addressable space. 37822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // This will create a display client and see if the buffer exists. 38822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // If the buffer has not been setup yet, you will need to try again later. 39822b710a714c342dda0087f594c8ababa6630f44Okan Arikan void TryMapping(); 40822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 41822b710a714c342dda0087f594c8ababa6630f44Okan Arikan protected: 42822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // The memory area if we managed to map it. 43822b710a714c342dda0087f594c8ababa6630f44Okan Arikan size_t size_ = 0; 44822b710a714c342dda0087f594c8ababa6630f44Okan Arikan void* address_ = nullptr; 45822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 46822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // If we are polling the display client, the buffer key here. 47822b710a714c342dda0087f594c8ababa6630f44Okan Arikan DvrGlobalBufferKey buffer_key_; 48822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 49822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // If we just own the IonBuffer outright, it's here. 50822b710a714c342dda0087f594c8ababa6630f44Okan Arikan std::unique_ptr<IonBuffer> owned_buffer_ = nullptr; 51822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 524a3863d067003a4428582a8484040cad09f6a29dOkan Arikan // The last time we connected to the display service. 534a3863d067003a4428582a8484040cad09f6a29dOkan Arikan int64_t last_display_service_connection_ns_ = 0; 544a3863d067003a4428582a8484040cad09f6a29dOkan Arikan 55822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // If we do not own the IonBuffer, it's here 56822b710a714c342dda0087f594c8ababa6630f44Okan Arikan IonBuffer* buffer_ = nullptr; 57822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 58822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // The usage mode. 59822b710a714c342dda0087f594c8ababa6630f44Okan Arikan CPUUsageMode usage_mode_ = CPUUsageMode::READ_OFTEN; 60822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}; 61822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 62822b710a714c342dda0087f594c8ababa6630f44Okan Arikan// Represents a broadcast ring inside a mapped shared memory buffer. 63822b710a714c342dda0087f594c8ababa6630f44Okan Arikan// If has the same set of constructors as CPUMappedBuffer. 64822b710a714c342dda0087f594c8ababa6630f44Okan Arikan// The template argument is the concrete BroadcastRing class that this buffer 65822b710a714c342dda0087f594c8ababa6630f44Okan Arikan// holds. 66822b710a714c342dda0087f594c8ababa6630f44Okan Arikantemplate <class RingType> 67822b710a714c342dda0087f594c8ababa6630f44Okan Arikanclass CPUMappedBroadcastRing : public CPUMappedBuffer { 68822b710a714c342dda0087f594c8ababa6630f44Okan Arikan public: 69822b710a714c342dda0087f594c8ababa6630f44Okan Arikan CPUMappedBroadcastRing(DvrGlobalBufferKey key, CPUUsageMode mode) 70822b710a714c342dda0087f594c8ababa6630f44Okan Arikan : CPUMappedBuffer(key, mode) {} 71822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 72822b710a714c342dda0087f594c8ababa6630f44Okan Arikan CPUMappedBroadcastRing(std::unique_ptr<IonBuffer> buffer, CPUUsageMode mode) 73822b710a714c342dda0087f594c8ababa6630f44Okan Arikan : CPUMappedBuffer(std::move(buffer), mode) {} 74822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 75822b710a714c342dda0087f594c8ababa6630f44Okan Arikan CPUMappedBroadcastRing(IonBuffer* buffer, CPUUsageMode mode) 76822b710a714c342dda0087f594c8ababa6630f44Okan Arikan : CPUMappedBuffer(buffer, mode) {} 77822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 78822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // Helper function for publishing records in the ring. 79822b710a714c342dda0087f594c8ababa6630f44Okan Arikan void Publish(const typename RingType::Record& record) { 80822b710a714c342dda0087f594c8ababa6630f44Okan Arikan assert((usage_mode_ == CPUUsageMode::WRITE_OFTEN) || 81822b710a714c342dda0087f594c8ababa6630f44Okan Arikan (usage_mode_ == CPUUsageMode::WRITE_RARELY)); 82822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 83822b710a714c342dda0087f594c8ababa6630f44Okan Arikan auto ring = Ring(); 84822b710a714c342dda0087f594c8ababa6630f44Okan Arikan if (ring) { 85822b710a714c342dda0087f594c8ababa6630f44Okan Arikan ring->Put(record); 86822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 87822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 88822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 89822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // Helper function for getting records from the ring. 90822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // Returns true if we were able to retrieve the latest. 91822b710a714c342dda0087f594c8ababa6630f44Okan Arikan bool GetNewest(typename RingType::Record* record) { 92822b710a714c342dda0087f594c8ababa6630f44Okan Arikan assert((usage_mode_ == CPUUsageMode::READ_OFTEN) || 93822b710a714c342dda0087f594c8ababa6630f44Okan Arikan (usage_mode_ == CPUUsageMode::READ_RARELY)); 94822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 95822b710a714c342dda0087f594c8ababa6630f44Okan Arikan auto ring = Ring(); 96822b710a714c342dda0087f594c8ababa6630f44Okan Arikan if (ring) { 97822b710a714c342dda0087f594c8ababa6630f44Okan Arikan return ring->GetNewest(&sequence_, record); 98822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 99822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 100822b710a714c342dda0087f594c8ababa6630f44Okan Arikan return false; 101822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 102822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 103822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // Try obtaining the ring. If the named buffer has not been created yet, it 104822b710a714c342dda0087f594c8ababa6630f44Okan Arikan // will return nullptr. 105822b710a714c342dda0087f594c8ababa6630f44Okan Arikan RingType* Ring() { 1062a4d63ce1737705fff6def88e68b2e537db9074cOkan Arikan // No ring created yet? 1072a4d63ce1737705fff6def88e68b2e537db9074cOkan Arikan if (ring_ == nullptr) { 1082a4d63ce1737705fff6def88e68b2e537db9074cOkan Arikan // Not mapped the memory yet? 1092a4d63ce1737705fff6def88e68b2e537db9074cOkan Arikan if (IsMapped() == false) { 1102a4d63ce1737705fff6def88e68b2e537db9074cOkan Arikan TryMapping(); 1112a4d63ce1737705fff6def88e68b2e537db9074cOkan Arikan } 112822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 1132a4d63ce1737705fff6def88e68b2e537db9074cOkan Arikan // If have the memory mapped, allocate the ring. 114822b710a714c342dda0087f594c8ababa6630f44Okan Arikan if (IsMapped()) { 115822b710a714c342dda0087f594c8ababa6630f44Okan Arikan switch (usage_mode_) { 116822b710a714c342dda0087f594c8ababa6630f44Okan Arikan case CPUUsageMode::READ_OFTEN: 117822b710a714c342dda0087f594c8ababa6630f44Okan Arikan case CPUUsageMode::READ_RARELY: { 118822b710a714c342dda0087f594c8ababa6630f44Okan Arikan RingType ring; 119822b710a714c342dda0087f594c8ababa6630f44Okan Arikan bool import_ok; 120822b710a714c342dda0087f594c8ababa6630f44Okan Arikan std::tie(ring, import_ok) = RingType::Import(address_, size_); 121822b710a714c342dda0087f594c8ababa6630f44Okan Arikan if (import_ok) { 122822b710a714c342dda0087f594c8ababa6630f44Okan Arikan ring_ = std::make_unique<RingType>(ring); 123822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 124822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } break; 125822b710a714c342dda0087f594c8ababa6630f44Okan Arikan case CPUUsageMode::WRITE_OFTEN: 126822b710a714c342dda0087f594c8ababa6630f44Okan Arikan case CPUUsageMode::WRITE_RARELY: 127822b710a714c342dda0087f594c8ababa6630f44Okan Arikan ring_ = 128822b710a714c342dda0087f594c8ababa6630f44Okan Arikan std::make_unique<RingType>(RingType::Create(address_, size_)); 129822b710a714c342dda0087f594c8ababa6630f44Okan Arikan break; 130822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 131822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 132822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 133822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 134822b710a714c342dda0087f594c8ababa6630f44Okan Arikan return ring_.get(); 135822b710a714c342dda0087f594c8ababa6630f44Okan Arikan } 136822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 137822b710a714c342dda0087f594c8ababa6630f44Okan Arikan protected: 138822b710a714c342dda0087f594c8ababa6630f44Okan Arikan std::unique_ptr<RingType> ring_ = nullptr; 139822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 140822b710a714c342dda0087f594c8ababa6630f44Okan Arikan uint32_t sequence_ = 0; 141822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}; 142822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 143822b710a714c342dda0087f594c8ababa6630f44Okan Arikan} // namespace dvr 144822b710a714c342dda0087f594c8ababa6630f44Okan Arikan} // namespace android 145822b710a714c342dda0087f594c8ababa6630f44Okan Arikan 146822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#endif // ANDROID_DVR_SHARED_BUFFER_HELPERS_H_ 147