99 lines
2.8 KiB
C++
99 lines
2.8 KiB
C++
#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
|