Home | History | Annotate | Download | only in libdisplay
      1 #include <private/dvr/clock_ns.h>
      2 #include <private/dvr/shared_buffer_helpers.h>
      3 
      4 namespace android {
      5 namespace dvr {
      6 namespace {
      7 
      8 // We will not poll the display service for buffers more frequently than this.
      9 constexpr size_t kDisplayServiceTriesPerSecond = 2;
     10 }  // namespace
     11 
     12 CPUMappedBuffer::CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode)
     13     : buffer_key_(key), usage_mode_(mode) {
     14   TryMapping();
     15 }
     16 
     17 CPUMappedBuffer::CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer,
     18                                  CPUUsageMode mode)
     19     : owned_buffer_(std::move(buffer)),
     20       buffer_(owned_buffer_.get()),
     21       usage_mode_(mode) {
     22   TryMapping();
     23 }
     24 
     25 CPUMappedBuffer::CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode)
     26     : buffer_(buffer), usage_mode_(mode) {
     27   TryMapping();
     28 }
     29 
     30 CPUMappedBuffer::~CPUMappedBuffer() {
     31   if (IsMapped()) {
     32     buffer_->Unlock();
     33   }
     34 }
     35 
     36 void CPUMappedBuffer::TryMapping() {
     37   // Do we have an IonBuffer for this shared memory object?
     38   if (buffer_ == nullptr) {
     39     // Has it been too long since we last connected to the display service?
     40     const auto current_time_ns = GetSystemClockNs();
     41     if ((current_time_ns - last_display_service_connection_ns_) <
     42         (1e9 / kDisplayServiceTriesPerSecond)) {
     43       // Early exit.
     44       return;
     45     }
     46     last_display_service_connection_ns_ = current_time_ns;
     47 
     48     // Create a display client and get the buffer.
     49     auto display_client = display::DisplayClient::Create();
     50     if (display_client) {
     51       auto get_result = display_client->GetGlobalBuffer(buffer_key_);
     52       if (get_result.ok()) {
     53         owned_buffer_ = get_result.take();
     54         buffer_ = owned_buffer_.get();
     55       } else {
     56         // The buffer has not been created yet. This is OK, we will keep
     57         // retrying.
     58       }
     59     } else {
     60       ALOGE("Unable to create display client for shared buffer access");
     61     }
     62   }
     63 
     64   if (buffer_) {
     65     auto usage = buffer_->usage() & ~GRALLOC_USAGE_SW_READ_MASK &
     66                  ~GRALLOC_USAGE_SW_WRITE_MASK;
     67 
     68     // Figure out the usage bits.
     69     switch (usage_mode_) {
     70       case CPUUsageMode::READ_OFTEN:
     71         usage |= GRALLOC_USAGE_SW_READ_OFTEN;
     72         break;
     73       case CPUUsageMode::READ_RARELY:
     74         usage |= GRALLOC_USAGE_SW_READ_RARELY;
     75         break;
     76       case CPUUsageMode::WRITE_OFTEN:
     77         usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
     78         break;
     79       case CPUUsageMode::WRITE_RARELY:
     80         usage |= GRALLOC_USAGE_SW_WRITE_RARELY;
     81         break;
     82     }
     83 
     84     int width = static_cast<int>(buffer_->width());
     85     int height = 1;
     86     const auto ret = buffer_->Lock(usage, 0, 0, width, height, &address_);
     87 
     88     if (ret < 0 || !address_) {
     89       ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, address_);
     90       buffer_->Unlock();
     91     } else {
     92       size_ = width;
     93     }
     94   }
     95 }
     96 
     97 }  // namespace dvr
     98 }  // namespace android
     99