#include #include namespace android { namespace dvr { namespace { // We will not poll the display service for buffers more frequently than this. constexpr size_t kDisplayServiceTriesPerSecond = 2; } // namespace CPUMappedBuffer::CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode) : buffer_key_(key), usage_mode_(mode) { TryMapping(); } CPUMappedBuffer::CPUMappedBuffer(std::unique_ptr buffer, CPUUsageMode mode) : owned_buffer_(std::move(buffer)), buffer_(owned_buffer_.get()), usage_mode_(mode) { TryMapping(); } CPUMappedBuffer::CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode) : buffer_(buffer), usage_mode_(mode) { TryMapping(); } CPUMappedBuffer::~CPUMappedBuffer() { if (IsMapped()) { buffer_->Unlock(); } } void CPUMappedBuffer::TryMapping() { // Do we have an IonBuffer for this shared memory object? if (buffer_ == nullptr) { // Has it been too long since we last connected to the display service? const auto current_time_ns = GetSystemClockNs(); if ((current_time_ns - last_display_service_connection_ns_) < (1e9 / kDisplayServiceTriesPerSecond)) { // Early exit. return; } last_display_service_connection_ns_ = current_time_ns; // Create a display client and get the buffer. auto display_client = display::DisplayClient::Create(); if (display_client) { auto get_result = display_client->GetGlobalBuffer(buffer_key_); if (get_result.ok()) { owned_buffer_ = get_result.take(); buffer_ = owned_buffer_.get(); } else { // The buffer has not been created yet. This is OK, we will keep // retrying. } } else { ALOGE("Unable to create display client for shared buffer access"); } } if (buffer_) { auto usage = buffer_->usage() & ~GRALLOC_USAGE_SW_READ_MASK & ~GRALLOC_USAGE_SW_WRITE_MASK; // Figure out the usage bits. switch (usage_mode_) { case CPUUsageMode::READ_OFTEN: usage |= GRALLOC_USAGE_SW_READ_OFTEN; break; case CPUUsageMode::READ_RARELY: usage |= GRALLOC_USAGE_SW_READ_RARELY; break; case CPUUsageMode::WRITE_OFTEN: usage |= GRALLOC_USAGE_SW_WRITE_OFTEN; break; case CPUUsageMode::WRITE_RARELY: usage |= GRALLOC_USAGE_SW_WRITE_RARELY; break; } int width = static_cast(buffer_->width()); int height = 1; const auto ret = buffer_->Lock(usage, 0, 0, width, height, &address_); if (ret < 0 || !address_) { ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, address_); buffer_->Unlock(); } else { size_ = width; } } } } // namespace dvr } // namespace android