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 
CPUMappedBuffer(DvrGlobalBufferKey key,CPUUsageMode mode)12 CPUMappedBuffer::CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode)
13     : buffer_key_(key), usage_mode_(mode) {
14   TryMapping();
15 }
16 
CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer,CPUUsageMode mode)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 
CPUMappedBuffer(IonBuffer * buffer,CPUUsageMode mode)25 CPUMappedBuffer::CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode)
26     : buffer_(buffer), usage_mode_(mode) {
27   TryMapping();
28 }
29 
~CPUMappedBuffer()30 CPUMappedBuffer::~CPUMappedBuffer() {
31   if (IsMapped()) {
32     buffer_->Unlock();
33   }
34 }
35 
TryMapping()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