14a3863d067003a4428582a8484040cad09f6a29dOkan Arikan#include <private/dvr/clock_ns.h>
2822b710a714c342dda0087f594c8ababa6630f44Okan Arikan#include <private/dvr/shared_buffer_helpers.h>
3822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
4822b710a714c342dda0087f594c8ababa6630f44Okan Arikannamespace android {
5822b710a714c342dda0087f594c8ababa6630f44Okan Arikannamespace dvr {
64a3863d067003a4428582a8484040cad09f6a29dOkan Arikannamespace {
74a3863d067003a4428582a8484040cad09f6a29dOkan Arikan
84a3863d067003a4428582a8484040cad09f6a29dOkan Arikan// We will not poll the display service for buffers more frequently than this.
94a3863d067003a4428582a8484040cad09f6a29dOkan Arikanconstexpr size_t kDisplayServiceTriesPerSecond = 2;
104a3863d067003a4428582a8484040cad09f6a29dOkan Arikan}  // namespace
11822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
12822b710a714c342dda0087f594c8ababa6630f44Okan ArikanCPUMappedBuffer::CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode)
13822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    : buffer_key_(key), usage_mode_(mode) {
14822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  TryMapping();
15822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}
16822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
17822b710a714c342dda0087f594c8ababa6630f44Okan ArikanCPUMappedBuffer::CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer,
18822b710a714c342dda0087f594c8ababa6630f44Okan Arikan                                 CPUUsageMode mode)
19822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    : owned_buffer_(std::move(buffer)),
20822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      buffer_(owned_buffer_.get()),
21822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      usage_mode_(mode) {
22822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  TryMapping();
23822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}
24822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
25822b710a714c342dda0087f594c8ababa6630f44Okan ArikanCPUMappedBuffer::CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode)
26822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    : buffer_(buffer), usage_mode_(mode) {
27822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  TryMapping();
28822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}
29822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
30822b710a714c342dda0087f594c8ababa6630f44Okan ArikanCPUMappedBuffer::~CPUMappedBuffer() {
31822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  if (IsMapped()) {
32822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    buffer_->Unlock();
33822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  }
34822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}
35822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
36822b710a714c342dda0087f594c8ababa6630f44Okan Arikanvoid CPUMappedBuffer::TryMapping() {
37822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  // Do we have an IonBuffer for this shared memory object?
38822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  if (buffer_ == nullptr) {
394a3863d067003a4428582a8484040cad09f6a29dOkan Arikan    // Has it been too long since we last connected to the display service?
404a3863d067003a4428582a8484040cad09f6a29dOkan Arikan    const auto current_time_ns = GetSystemClockNs();
414a3863d067003a4428582a8484040cad09f6a29dOkan Arikan    if ((current_time_ns - last_display_service_connection_ns_) <
424a3863d067003a4428582a8484040cad09f6a29dOkan Arikan        (1e9 / kDisplayServiceTriesPerSecond)) {
434a3863d067003a4428582a8484040cad09f6a29dOkan Arikan      // Early exit.
444a3863d067003a4428582a8484040cad09f6a29dOkan Arikan      return;
454a3863d067003a4428582a8484040cad09f6a29dOkan Arikan    }
464a3863d067003a4428582a8484040cad09f6a29dOkan Arikan    last_display_service_connection_ns_ = current_time_ns;
474a3863d067003a4428582a8484040cad09f6a29dOkan Arikan
48822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    // Create a display client and get the buffer.
49822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    auto display_client = display::DisplayClient::Create();
50822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    if (display_client) {
51822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      auto get_result = display_client->GetGlobalBuffer(buffer_key_);
52822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      if (get_result.ok()) {
53822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        owned_buffer_ = get_result.take();
54822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        buffer_ = owned_buffer_.get();
55822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      } else {
564a3863d067003a4428582a8484040cad09f6a29dOkan Arikan        // The buffer has not been created yet. This is OK, we will keep
574a3863d067003a4428582a8484040cad09f6a29dOkan Arikan        // retrying.
58822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      }
59822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    } else {
60822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      ALOGE("Unable to create display client for shared buffer access");
61822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    }
62822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  }
63822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
64822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  if (buffer_) {
65822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    auto usage = buffer_->usage() & ~GRALLOC_USAGE_SW_READ_MASK &
66822b710a714c342dda0087f594c8ababa6630f44Okan Arikan                 ~GRALLOC_USAGE_SW_WRITE_MASK;
67822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
68822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    // Figure out the usage bits.
69822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    switch (usage_mode_) {
70822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      case CPUUsageMode::READ_OFTEN:
71822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        usage |= GRALLOC_USAGE_SW_READ_OFTEN;
72822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        break;
73822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      case CPUUsageMode::READ_RARELY:
74822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        usage |= GRALLOC_USAGE_SW_READ_RARELY;
75822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        break;
76822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      case CPUUsageMode::WRITE_OFTEN:
77822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
78822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        break;
79822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      case CPUUsageMode::WRITE_RARELY:
80822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        usage |= GRALLOC_USAGE_SW_WRITE_RARELY;
81822b710a714c342dda0087f594c8ababa6630f44Okan Arikan        break;
82822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    }
83822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
84822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    int width = static_cast<int>(buffer_->width());
85822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    int height = 1;
86822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    const auto ret = buffer_->Lock(usage, 0, 0, width, height, &address_);
87822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
88822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    if (ret < 0 || !address_) {
89822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, address_);
90822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      buffer_->Unlock();
91822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    } else {
92822b710a714c342dda0087f594c8ababa6630f44Okan Arikan      size_ = width;
93822b710a714c342dda0087f594c8ababa6630f44Okan Arikan    }
94822b710a714c342dda0087f594c8ababa6630f44Okan Arikan  }
95822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}
96822b710a714c342dda0087f594c8ababa6630f44Okan Arikan
97822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}  // namespace dvr
98822b710a714c342dda0087f594c8ababa6630f44Okan Arikan}  // namespace android
99