| #include <private/dvr/clock_ns.h> | |
| #include <private/dvr/shared_buffer_helpers.h> | |
| 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<IonBuffer> 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<int>(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 |