1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "include/private/dvr/buffer_hub_queue_producer.h"
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai#include <dvr/dvr_api.h>
44fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <inttypes.h>
54fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h>
64fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr {
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
10e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai/* static */
11e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Caisp<BufferHubQueueProducer> BufferHubQueueProducer::Create() {
12e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  sp<BufferHubQueueProducer> producer = new BufferHubQueueProducer;
13e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  producer->queue_ = ProducerQueue::Create<DvrNativeBufferMetadata>();
14e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  return producer;
15e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai}
16e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
17e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai/* static */
18e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Caisp<BufferHubQueueProducer> BufferHubQueueProducer::Create(
19e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    const std::shared_ptr<ProducerQueue>& queue) {
20e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (queue->metadata_size() != sizeof(DvrNativeBufferMetadata)) {
21e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    ALOGE(
22e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai        "BufferHubQueueProducer::Create producer's metadata size is different "
23e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai        "than the size of DvrNativeBufferMetadata");
24e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    return nullptr;
25e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  }
26e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
27e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  sp<BufferHubQueueProducer> producer = new BufferHubQueueProducer;
28e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  producer->queue_ = queue;
29e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  return producer;
30e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai}
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::requestBuffer(int slot,
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                               sp<GraphicBuffer>* buf) {
3425fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, "requestBuffer: slot=%d", slot);
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
36e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
38e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (connected_api_ == kNoConnectedApi) {
391601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE("requestBuffer: BufferHubQueueProducer has no connected producer");
401601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return NO_INIT;
411601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
421601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
431601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (slot < 0 || slot >= max_buffer_count_) {
444fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot,
451601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai          max_buffer_count_);
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
47e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  } else if (!buffers_[slot].mBufferState.isDequeued()) {
484fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)",
49e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai          slot, buffers_[slot].mBufferState.string());
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
51e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  } else if (buffers_[slot].mGraphicBuffer != nullptr) {
521601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE("requestBuffer: slot %d is not empty.", slot);
531601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
54e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  } else if (buffers_[slot].mBufferProducer == nullptr) {
551601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE("requestBuffer: slot %d is not dequeued.", slot);
561601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
59e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  const auto& buffer_producer = buffers_[slot].mBufferProducer;
60cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka  sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
611601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
62e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mGraphicBuffer = graphic_buffer;
63e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mRequestBufferCalled = true;
641601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
651601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  *buf = graphic_buffer;
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::setMaxDequeuedBufferCount(
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    int max_dequeued_buffers) {
7125fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, "setMaxDequeuedBufferCount: max_dequeued_buffers=%d",
7225fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai           max_dequeued_buffers);
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
74e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (max_dequeued_buffers <= 0 ||
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      max_dequeued_buffers >
78cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai          static_cast<int>(BufferHubQueue::kMaxQueueCapacity -
79e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai                           kDefaultUndequeuedBuffers)) {
804fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]",
814fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko          max_dequeued_buffers, BufferHubQueue::kMaxQueueCapacity);
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
851601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // The new dequeued_buffers count should not be violated by the number
861601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // of currently dequeued buffers.
871601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  int dequeued_count = 0;
88e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  for (const auto& buf : buffers_) {
891601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    if (buf.mBufferState.isDequeued()) {
901601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      dequeued_count++;
911601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    }
921601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
931601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (dequeued_count > max_dequeued_buffers) {
941601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE(
951601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai        "setMaxDequeuedBufferCount: the requested dequeued_buffers"
961601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai        "count (%d) exceeds the current dequeued buffer count (%d)",
971601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai        max_dequeued_buffers, dequeued_count);
981601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
991601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
1001601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
1011601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  max_dequeued_buffer_count_ = max_dequeued_buffers;
102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1051601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Caistatus_t BufferHubQueueProducer::setAsyncMode(bool async) {
1061601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (async) {
1071601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer
1081601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // automatically and behaves differently from IGraphicBufferConsumer. Thus,
1091601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // android::BufferQueue's async mode (a.k.a. allocating an additional buffer
1101601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // to prevent dequeueBuffer from being blocking) technically does not apply
1111601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // here.
1121601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    //
1131601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // In Daydream, non-blocking producer side dequeue is guaranteed by careful
1141601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // buffer consumer implementations. In another word, BufferHubQueue based
1151601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // dequeueBuffer should never block whether setAsyncMode(true) is set or
1161601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // not.
1171601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    //
1181601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // See: IGraphicBufferProducer::setAsyncMode and
1191601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // BufferQueueProducer::setAsyncMode for more about original implementation.
1201601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGW(
1211601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai        "BufferHubQueueProducer::setAsyncMode: BufferHubQueue should always be "
1221601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai        "asynchronous. This call makes no effact.");
1231601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return NO_ERROR;
1241601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
1251601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  return NO_ERROR;
126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1281601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Caistatus_t BufferHubQueueProducer::dequeueBuffer(
1291601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    int* out_slot, sp<Fence>* out_fence, uint32_t width, uint32_t height,
1301601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    PixelFormat format, uint32_t usage,
1311601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    FrameEventHistoryDelta* /* out_timestamps */) {
13225fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, "dequeueBuffer: w=%u, h=%u, format=%d, usage=%u", width,
13325fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai           height, format, usage);
134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  status_t ret;
136e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
138e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (connected_api_ == kNoConnectedApi) {
1391601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE("dequeueBuffer: BufferQueue has no connected producer");
1401601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return NO_INIT;
1411601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
1421601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
143108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar  const uint32_t kLayerCount = 1;
144e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (static_cast<int32_t>(queue_->capacity()) <
145e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) {
146e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    // Lazy allocation. When the capacity of |queue_| has not reached
1471601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    // |max_dequeued_buffer_count_|, allocate new buffer.
148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // TODO(jwcai) To save memory, the really reasonable thing to do is to go
149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // over existing slots and find first existing one to dequeue.
150e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    ret = AllocateBuffer(width, height, kLayerCount, format, usage);
151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (ret < 0)
152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return ret;
153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  size_t slot;
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::shared_ptr<BufferProducer> buffer_producer;
157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
159ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai    LocalHandle fence;
160e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1629d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka    buffer_producer = buffer_status.take();
163b85082115a3c7b900ff7f0200f2fd6fa49f8d191Jiwen 'Steve' Cai    if (!buffer_producer)
164b85082115a3c7b900ff7f0200f2fd6fa49f8d191Jiwen 'Steve' Cai      return NO_MEMORY;
1659d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka
166cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka    if (width == buffer_producer->width() &&
167cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka        height == buffer_producer->height() &&
168cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka        static_cast<uint32_t>(format) == buffer_producer->format()) {
169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      // The producer queue returns a buffer producer matches the request.
170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      break;
171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Needs reallocation.
174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
1754fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGI(
176cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka        "dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
177cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka        "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
1784fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko        "re-allocattion.",
1794fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko        width, height, format, slot, buffer_producer->width(),
1804fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko        buffer_producer->height(), buffer_producer->format());
181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Mark the slot as reallocating, so that later we can set
182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
183e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    buffers_[slot].mIsReallocating = true;
184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
185e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    // Remove the old buffer once the allocation before allocating its
186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // replacement.
187e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    RemoveBuffer(slot);
188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Allocate a new producer buffer with new buffer configs. Note that if
190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // there are already multiple buffers in the queue, the next one returned
191e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    // from |queue_->Dequeue| may not be the new buffer we just reallocated.
192e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    // Retry up to BufferHubQueue::kMaxQueueCapacity times.
193e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    ret = AllocateBuffer(width, height, kLayerCount, format, usage);
194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (ret < 0)
195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return ret;
196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // With the BufferHub backed solution. Buffer slot returned from
199e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  // |queue_->Dequeue| is guaranteed to avaiable for producer's use.
200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // It's either in free state (if the buffer has never been used before) or
201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // in queued state (if the buffer has been dequeued and queued back to
202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // BufferHubQueue).
203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // TODO(jwcai) Clean this up, make mBufferState compatible with BufferHub's
204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // model.
205e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() &&
206e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai                       !buffers_[slot].mBufferState.isQueued()),
2074fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko                      "dequeueBuffer: slot %zu is not free or queued.", slot);
208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
209e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mBufferState.freeQueued();
210e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mBufferState.dequeue();
21125fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, "dequeueBuffer: slot=%zu", slot);
212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we
214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // just need to exopose that through |BufferHubQueue| once we need fence.
215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  *out_fence = Fence::NO_FENCE;
216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  *out_slot = slot;
217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ret = NO_ERROR;
218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
219e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (buffers_[slot].mIsReallocating) {
220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ret |= BUFFER_NEEDS_REALLOCATION;
221e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    buffers_[slot].mIsReallocating = false;
222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ret;
225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::detachBuffer(int /* slot */) {
2284fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  ALOGE("BufferHubQueueProducer::detachBuffer not implemented.");
229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return INVALID_OPERATION;
230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::detachNextBuffer(
233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    sp<GraphicBuffer>* /* out_buffer */, sp<Fence>* /* out_fence */) {
2344fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  ALOGE("BufferHubQueueProducer::detachNextBuffer not implemented.");
235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return INVALID_OPERATION;
236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::attachBuffer(
239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    int* /* out_slot */, const sp<GraphicBuffer>& /* buffer */) {
240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // With this BufferHub backed implementation, we assume (for now) all buffers
241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // are allocated and owned by the BufferHub. Thus the attempt of transfering
242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // ownership of a buffer to the buffer queue is intentionally unsupported.
2434fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  LOG_ALWAYS_FATAL("BufferHubQueueProducer::attachBuffer not supported.");
244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return INVALID_OPERATION;
245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::queueBuffer(int slot,
248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                             const QueueBufferInput& input,
2491601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai                                             QueueBufferOutput* output) {
25025fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, "queueBuffer: slot %d", slot);
251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
2521601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (output == nullptr) {
2531601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
2541601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
2551601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int64_t timestamp;
257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  bool is_auto_timestamp;
258cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  android_dataspace dataspace;
259cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  Rect crop(Rect::EMPTY_RECT);
260cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  int scaling_mode;
261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  uint32_t transform;
262cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  sp<Fence> fence;
263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
264cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  input.deflate(&timestamp, &is_auto_timestamp, &dataspace, &crop,
265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                &scaling_mode, &transform, &fence);
266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
2671601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // Check input scaling mode is valid.
2681601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  switch (scaling_mode) {
2691601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_SCALING_MODE_FREEZE:
2701601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
2711601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
2721601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
2731601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      break;
2741601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    default:
2751601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode);
2761601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      return BAD_VALUE;
2771601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
2781601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
2791601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // Check input fence is valid.
280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (fence == nullptr) {
2814fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("queueBuffer: fence is NULL");
282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  status_t ret;
286e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
288e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (connected_api_ == kNoConnectedApi) {
2891601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE("queueBuffer: BufferQueue has no connected producer");
2901601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return NO_INIT;
2911601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
2921601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
2931601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (slot < 0 || slot >= max_buffer_count_) {
2944fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot,
2951601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai          max_buffer_count_);
296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
297e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  } else if (!buffers_[slot].mBufferState.isDequeued()) {
2984fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)",
299e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai          slot, buffers_[slot].mBufferState.string());
300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
301e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  } else if ((!buffers_[slot].mRequestBufferCalled ||
302e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai              buffers_[slot].mGraphicBuffer == nullptr)) {
3031601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE(
3041601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai        "queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, "
3051601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai        "mGraphicBuffer=%p)",
306e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai        slot, buffers_[slot].mRequestBufferCalled,
307e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai        buffers_[slot].mGraphicBuffer.get());
3081601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Post the buffer producer with timestamp in the metadata.
312e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  const auto& buffer_producer = buffers_[slot].mBufferProducer;
3131601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
3141601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // Check input crop is not out of boundary of current buffer.
3151601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  Rect buffer_rect(buffer_producer->width(), buffer_producer->height());
3161601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  Rect cropped_rect(Rect::EMPTY_RECT);
3171601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  crop.intersect(buffer_rect, &cropped_rect);
3181601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (cropped_rect != crop) {
3191601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot);
3201601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
3211601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
3221601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1);
324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
325e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  DvrNativeBufferMetadata meta_data = {};
326cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.timestamp = timestamp;
327cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.is_auto_timestamp = static_cast<int32_t>(is_auto_timestamp);
328cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.dataspace = static_cast<int32_t>(dataspace);
329cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.crop_left = crop.left;
330cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.crop_top = crop.top;
331cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.crop_right = crop.right;
332cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.crop_bottom = crop.bottom;
333cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.scaling_mode = static_cast<int32_t>(scaling_mode);
334cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  meta_data.transform = static_cast<int32_t>(transform);
335cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai
336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  buffer_producer->Post(fence_fd, &meta_data, sizeof(meta_data));
337e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mBufferState.queue();
338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3391601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  output->width = buffer_producer->width();
3401601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  output->height = buffer_producer->height();
341cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka  output->transformHint = 0;  // default value, we don't use it yet.
3421601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
3431601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // |numPendingBuffers| counts of the number of buffers that has been enqueued
3441601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // by the producer but not yet acquired by the consumer. Due to the nature
3451601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // of BufferHubQueue design, this is hard to trace from the producer's client
3461601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // side, but it's safe to assume it's zero.
3471601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  output->numPendingBuffers = 0;
3481601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
3491601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // Note that we are not setting nextFrameNumber here as it seems to be only
3501601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // used by surface flinger. See more at b/22802885, ag/791760.
3511601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  output->nextFrameNumber = 0;
3521601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::cancelBuffer(int slot,
357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                              const sp<Fence>& fence) {
35825fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, __FUNCTION__);
359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
360e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
362e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (connected_api_ == kNoConnectedApi) {
3631601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    ALOGE("cancelBuffer: BufferQueue has no connected producer");
3641601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return NO_INIT;
3651601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
3661601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
3671601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (slot < 0 || slot >= max_buffer_count_) {
3684fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot,
3691601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai          max_buffer_count_);
370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
371e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  } else if (!buffers_[slot].mBufferState.isDequeued()) {
3724fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)",
373e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai          slot, buffers_[slot].mBufferState.string());
374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
3751601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  } else if (fence == nullptr) {
3764fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("cancelBuffer: fence is NULL");
377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
380e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  auto buffer_producer = buffers_[slot].mBufferProducer;
381e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  queue_->Enqueue(buffer_producer, slot);
382e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mBufferState.cancel();
383e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mFence = fence;
38425fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, "cancelBuffer: slot %d", slot);
385e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
386e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::query(int what, int* out_value) {
39025fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, __FUNCTION__);
391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
392e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3941601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (out_value == nullptr) {
3954fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("query: out_value was NULL");
396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return BAD_VALUE;
397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int value = 0;
400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  switch (what) {
401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
402cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // TODO(b/36187402) This should be the maximum number of buffers that this
403cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // producer queue's consumer can acquire. Set to be at least one. Need to
404cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // find a way to set from the consumer side.
405e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      value = kDefaultUndequeuedBuffers;
406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      break;
407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_BUFFER_AGE:
408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      value = 0;
409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      break;
410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_WIDTH:
411e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      value = queue_->default_width();
4121601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      break;
413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_HEIGHT:
414e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      value = queue_->default_height();
4151601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      break;
416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_FORMAT:
417e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      value = queue_->default_format();
4181601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      break;
419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
4201601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      // BufferHubQueue is always operating in async mode, thus semantically
4211601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      // consumer can never be running behind. See BufferQueueCore.cpp core
4221601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      // for more information about the original meaning of this flag.
4231601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      value = 0;
4241601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      break;
425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
4261601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      // TODO(jwcai) This is currently not implement as we don't need
4271601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      // IGraphicBufferConsumer parity.
4281601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      value = 0;
4291601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      break;
430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case NATIVE_WINDOW_DEFAULT_DATASPACE:
431cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // TODO(jwcai) Return the default value android::BufferQueue is using as
432cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // there is no way dvr::ConsumerQueue can set it.
433cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      value = 0;  // HAL_DATASPACE_UNKNOWN
434cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      break;
435cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai    case NATIVE_WINDOW_STICKY_TRANSFORM:
436cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // TODO(jwcai) Return the default value android::BufferQueue is using as
437cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // there is no way dvr::ConsumerQueue can set it.
438cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      value = 0;
439cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      break;
440e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
441e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      // In Daydream's implementation, the consumer end (i.e. VR Compostior)
442e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      // knows how to handle protected buffers.
443e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      value = 1;
444e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      break;
445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    default:
446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return BAD_VALUE;
447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
44925fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, "query: key=%d, v=%d", what, value);
450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  *out_value = value;
451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::connect(
4551601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    const sp<IProducerListener>& /* listener */, int api,
4561601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    bool /* producer_controlled_by_app */, QueueBufferOutput* output) {
457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Consumer interaction are actually handled by buffer hub, and we need
4581601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // to maintain consumer operations here. We only need to perform basic input
4591601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // parameter checks here.
46025fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, __FUNCTION__);
4611601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
4621601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (output == nullptr) {
4631601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
4641601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
4651601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
466e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
4671601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
468e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (connected_api_ != kNoConnectedApi) {
4691601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
4701601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
4711601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
4721601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  switch (api) {
4731601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_API_EGL:
4741601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_API_CPU:
4751601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_API_MEDIA:
4761601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    case NATIVE_WINDOW_API_CAMERA:
477e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      connected_api_ = api;
478cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai
479e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      output->width = queue_->default_width();
480e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      output->height = queue_->default_height();
481cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai
482cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      // default values, we don't use them yet.
483cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      output->transformHint = 0;
484cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      output->numPendingBuffers = 0;
485cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      output->nextFrameNumber = 0;
486cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai      output->bufferReplaced = false;
487cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai
4881601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      break;
4891601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    default:
4901601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      ALOGE("BufferHubQueueProducer::connect: unknow API %d", api);
4911601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai      return BAD_VALUE;
4921601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
4931601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
496e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
497cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabakastatus_t BufferHubQueueProducer::disconnect(int api, DisconnectMode /*mode*/) {
498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Consumer interaction are actually handled by buffer hub, and we need
4991601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // to maintain consumer operations here.  We only need to perform basic input
5001601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // parameter checks here.
50125fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, __FUNCTION__);
5021601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
503e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
5041601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
505e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (kNoConnectedApi == connected_api_) {
5063e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    return NO_INIT;
507e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  } else if (api != connected_api_) {
5081601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return BAD_VALUE;
5091601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  }
5101601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai
511e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  connected_api_ = kNoConnectedApi;
512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
515e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::setSidebandStream(
516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const sp<NativeHandle>& stream) {
5171601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  if (stream != nullptr) {
518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's
519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // metadata.
5204fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko    ALOGE("SidebandStream is not currently supported.");
521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return INVALID_OPERATION;
522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid BufferHubQueueProducer::allocateBuffers(uint32_t /* width */,
527e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                             uint32_t /* height */,
528e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                             PixelFormat /* format */,
529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                             uint32_t /* usage */) {
530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number
531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // of buffers permitted by the current BufferQueue configuration (aka
5321601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai  // |max_buffer_count_|).
5334fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  ALOGE("BufferHubQueueProducer::allocateBuffers not implemented.");
534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::allowAllocation(bool /* allow */) {
5374fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  ALOGE("BufferHubQueueProducer::allowAllocation not implemented.");
538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return INVALID_OPERATION;
539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
540e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::setGenerationNumber(
542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    uint32_t generation_number) {
54325fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, __FUNCTION__);
544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
545e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
546e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  generation_number_ = generation_number;
547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoString8 BufferHubQueueProducer::getConsumerName() const {
551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // BufferHub based implementation could have one to many producer/consumer
552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // relationship, thus |getConsumerName| from the producer side does not
553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // make any sense.
5544fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  ALOGE("BufferHubQueueProducer::getConsumerName not supported.");
555e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return String8("BufferHubQueue::DummyConsumer");
556e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
558cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Caistatus_t BufferHubQueueProducer::setSharedBufferMode(bool shared_buffer_mode) {
559cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  if (shared_buffer_mode) {
5604d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar    ALOGE(
5614d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar        "BufferHubQueueProducer::setSharedBufferMode(true) is not supported.");
562cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai    // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow.
563cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai    return INVALID_OPERATION;
564cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  }
565cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  // Setting to default should just work as a no-op.
566cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  return NO_ERROR;
567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
569cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Caistatus_t BufferHubQueueProducer::setAutoRefresh(bool auto_refresh) {
570cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  if (auto_refresh) {
571cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai    ALOGE("BufferHubQueueProducer::setAutoRefresh(true) is not supported.");
572cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai    return INVALID_OPERATION;
573cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  }
574cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  // Setting to default should just work as a no-op.
575cb4751c52a5625a22b6a11b4de537ff026d9bfe3Jiwen 'Steve' Cai  return NO_ERROR;
576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::setDequeueTimeout(nsecs_t timeout) {
57925fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, __FUNCTION__);
580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
581e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  std::unique_lock<std::mutex> lock(mutex_);
582e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000));
583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::getLastQueuedBuffer(
587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    sp<GraphicBuffer>* /* out_buffer */, sp<Fence>* /* out_fence */,
588e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    float /*out_transform_matrix*/[16]) {
5894fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  ALOGE("BufferHubQueueProducer::getLastQueuedBuffer not implemented.");
590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return INVALID_OPERATION;
591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid BufferHubQueueProducer::getFrameTimestamps(
594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    FrameEventHistoryDelta* /*outDelta*/) {
5954fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko  ALOGE("BufferHubQueueProducer::getFrameTimestamps not implemented.");
596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatus_t BufferHubQueueProducer::getUniqueId(uint64_t* out_id) const {
59925fd3faa260ad1c92ac57d71af46eb4d73ff277cJiwen 'Steve' Cai  ALOGD_IF(TRACE, __FUNCTION__);
600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
601e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  *out_id = unique_id_;
602e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  return NO_ERROR;
603e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai}
604e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
605e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Caistatus_t BufferHubQueueProducer::AllocateBuffer(uint32_t width, uint32_t height,
606e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai                                                uint32_t layer_count,
607e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai                                                PixelFormat format,
608e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai                                                uint64_t usage) {
609e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  size_t slot;
610e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
611e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (queue_->AllocateBuffer(width, height, layer_count, format, usage, &slot) <
612e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai      0) {
613e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    ALOGE("Failed to allocate new buffer in BufferHub.");
614e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    return NO_MEMORY;
615e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  }
616e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
617e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  auto buffer_producer = queue_->GetBuffer(slot);
618e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
619e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr,
620e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai                      "Failed to get buffer producer at slot: %zu", slot);
621e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
622e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mBufferProducer = buffer_producer;
623e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return NO_ERROR;
625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
627e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Caistatus_t BufferHubQueueProducer::RemoveBuffer(size_t slot) {
628e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  int ret = queue_->DetachBuffer(slot);
629e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  if (ret < 0) {
630e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    ALOGE("BufferHubQueueProducer::RemoveBuffer failed through RPC, ret=%s",
631e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai          strerror(-ret));
632e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai    return ret;
633e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  }
634e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai
635e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  // Reset in memory objects related the the buffer.
636e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mBufferProducer = nullptr;
637e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mGraphicBuffer = nullptr;
638e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  buffers_[slot].mBufferState.detachProducer();
639e08ab3f70982e055d8374db7ece59f90cfe3db3cJiwen 'Steve' Cai  return NO_ERROR;
640e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
642e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace dvr
643e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
644