blob: a8077b9fe1d2bf5009656a3cc5cdb5076a006e53 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "include/private/dvr/buffer_hub_queue_client.h"
2
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -08003//#define LOG_NDEBUG 0
4
Alex Vakulenko4fe60582017-02-02 11:35:59 -08005#include <inttypes.h>
6#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08007#include <sys/epoll.h>
8
9#include <array>
10
11#include <pdx/default_transport/client_channel.h>
12#include <pdx/default_transport/client_channel_factory.h>
13#include <pdx/file_handle.h>
14#include <private/dvr/bufferhub_rpc.h>
15
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080016namespace android {
17namespace dvr {
18
19BufferHubQueue::BufferHubQueue(LocalChannelHandle channel_handle,
20 size_t meta_size)
21 : Client{pdx::default_transport::ClientChannel::Create(
22 std::move(channel_handle))},
23 meta_size_(meta_size),
24 meta_buffer_tmp_(meta_size ? new uint8_t[meta_size] : nullptr),
25 buffers_(BufferHubQueue::kMaxQueueCapacity),
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -080026 epollhup_pending_(BufferHubQueue::kMaxQueueCapacity, false),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080027 available_buffers_(BufferHubQueue::kMaxQueueCapacity),
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -070028 fences_(BufferHubQueue::kMaxQueueCapacity),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080029 capacity_(0) {
30 Initialize();
31}
32
33BufferHubQueue::BufferHubQueue(const std::string& endpoint_path,
34 size_t meta_size)
35 : Client{pdx::default_transport::ClientChannelFactory::Create(
36 endpoint_path)},
37 meta_size_(meta_size),
38 meta_buffer_tmp_(meta_size ? new uint8_t[meta_size] : nullptr),
39 buffers_(BufferHubQueue::kMaxQueueCapacity),
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -080040 epollhup_pending_(BufferHubQueue::kMaxQueueCapacity, false),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080041 available_buffers_(BufferHubQueue::kMaxQueueCapacity),
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -070042 fences_(BufferHubQueue::kMaxQueueCapacity),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080043 capacity_(0) {
44 Initialize();
45}
46
47void BufferHubQueue::Initialize() {
48 int ret = epoll_fd_.Create();
49 if (ret < 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080050 ALOGE("BufferHubQueue::BufferHubQueue: Failed to create epoll fd: %s",
51 strerror(-ret));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080052 return;
53 }
54
55 epoll_event event = {.events = EPOLLIN | EPOLLET,
56 .data = {.u64 = static_cast<uint64_t>(
57 BufferHubQueue::kEpollQueueEventIndex)}};
58 ret = epoll_fd_.Control(EPOLL_CTL_ADD, event_fd(), &event);
59 if (ret < 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080060 ALOGE("Failed to register ConsumerQueue into epoll event: %s",
61 strerror(-ret));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062 }
63}
64
65std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() {
66 Status<std::pair<LocalChannelHandle, size_t>> status =
67 InvokeRemoteMethod<BufferHubRPC::CreateConsumerQueue>();
68
69 if (!status) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080070 ALOGE("Cannot create ConsumerQueue: %s", status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080071 return nullptr;
72 }
73
74 auto return_value = status.take();
75
Alex Vakulenko4fe60582017-02-02 11:35:59 -080076 ALOGD("CreateConsumerQueue: meta_size_bytes=%zu", return_value.second);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080077 return ConsumerQueue::Create(std::move(return_value.first),
78 return_value.second);
79}
80
81bool BufferHubQueue::WaitForBuffers(int timeout) {
82 std::array<epoll_event, kMaxEvents> events;
83
84 while (count() == 0) {
85 int ret = epoll_fd_.Wait(events.data(), events.size(), timeout);
86
87 if (ret == 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080088 ALOGD("Wait on epoll returns nothing before timeout.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080089 return false;
90 }
91
92 if (ret < 0 && ret != -EINTR) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080093 ALOGE("Failed to wait for buffers: %s", strerror(-ret));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080094 return false;
95 }
96
97 const int num_events = ret;
98
99 // A BufferQueue's epoll fd tracks N+1 events, where there are N events,
100 // one for each buffer, in the queue and one extra event for the queue
101 // client itself.
102 for (int i = 0; i < num_events; i++) {
103 int64_t index = static_cast<int64_t>(events[i].data.u64);
104
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800105 ALOGD("New BufferHubQueue event %d: index=%" PRId64, i, index);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800106
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -0800107 if (is_buffer_event_index(index)) {
108 HandleBufferEvent(static_cast<size_t>(index), events[i]);
109 } else if (is_queue_event_index(index)) {
110 HandleQueueEvent(events[i]);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800111 } else {
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -0800112 ALOGW("Unknown event index: %" PRId64, index);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800113 }
114 }
115 }
116
117 return true;
118}
119
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -0800120void BufferHubQueue::HandleBufferEvent(size_t slot, const epoll_event& event) {
121 auto buffer = buffers_[slot];
122 if (!buffer) {
123 ALOGW("BufferHubQueue::HandleBufferEvent: Invalid buffer slot: %zu", slot);
124 return;
125 }
126
127 auto status = buffer->GetEventMask(event.events);
128 if (!status) {
129 ALOGW("BufferHubQueue::HandleBufferEvent: Failed to get event mask: %s",
130 status.GetErrorMessage().c_str());
131 return;
132 }
133
134 int events = status.get();
135 if (events & EPOLLIN) {
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700136 int ret = OnBufferReady(buffer, &fences_[slot]);
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -0800137 if (ret < 0) {
138 ALOGE("Failed to set buffer ready: %s", strerror(-ret));
139 return;
140 }
141 Enqueue(buffer, slot);
142 } else if (events & EPOLLHUP) {
143 // This might be caused by producer replacing an existing buffer slot, or
144 // when BufferHubQueue is shutting down. For the first case, currently the
145 // epoll FD is cleaned up when the replacement consumer client is imported,
146 // we shouldn't detach again if |epollhub_pending_[slot]| is set.
147 ALOGW(
148 "Receives EPOLLHUP at slot: %zu, buffer event fd: %d, EPOLLHUP "
149 "pending: %d",
150 slot, buffer->event_fd(), epollhup_pending_[slot]);
151 if (epollhup_pending_[slot]) {
152 epollhup_pending_[slot] = false;
153 } else {
154 DetachBuffer(slot);
155 }
156 } else {
157 ALOGW("Unknown event, slot=%zu, epoll events=%d", slot, events);
158 }
159}
160
161void BufferHubQueue::HandleQueueEvent(const epoll_event& event) {
162 auto status = GetEventMask(event.events);
163 if (!status) {
164 ALOGW("BufferHubQueue::HandleQueueEvent: Failed to get event mask: %s",
165 status.GetErrorMessage().c_str());
166 return;
167 }
168
169 int events = status.get();
170 if (events & EPOLLIN) {
171 // Note that after buffer imports, if |count()| still returns 0, epoll
172 // wait will be tried again to acquire the newly imported buffer.
173 int ret = OnBufferAllocated();
174 if (ret < 0) {
175 ALOGE("Failed to import buffer: %s", strerror(-ret));
176 }
177 } else {
178 ALOGW("Unknown epoll events=%d", events);
179 }
180}
181
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800182int BufferHubQueue::AddBuffer(const std::shared_ptr<BufferHubBuffer>& buf,
183 size_t slot) {
184 if (is_full()) {
185 // TODO(jwcai) Move the check into Producer's AllocateBuffer and consumer's
186 // import buffer.
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800187 ALOGE("BufferHubQueue::AddBuffer queue is at maximum capacity: %zu",
188 capacity_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800189 return -E2BIG;
190 }
191
192 if (buffers_[slot] != nullptr) {
193 // Replace the buffer if the slot is preoccupied. This could happen when the
194 // producer side replaced the slot with a newly allocated buffer. Detach the
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -0800195 // buffer before setting up with the new one.
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800196 DetachBuffer(slot);
Jiwen 'Steve' Caidc14e5b2017-01-24 17:05:12 -0800197 epollhup_pending_[slot] = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800198 }
199
200 epoll_event event = {.events = EPOLLIN | EPOLLET, .data = {.u64 = slot}};
201 const int ret = epoll_fd_.Control(EPOLL_CTL_ADD, buf->event_fd(), &event);
202 if (ret < 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800203 ALOGE("BufferHubQueue::AddBuffer: Failed to add buffer to epoll set: %s",
204 strerror(-ret));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800205 return ret;
206 }
207
208 buffers_[slot] = buf;
209 capacity_++;
210 return 0;
211}
212
213int BufferHubQueue::DetachBuffer(size_t slot) {
214 auto& buf = buffers_[slot];
215 if (buf == nullptr) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800216 ALOGE("BufferHubQueue::DetachBuffer: Invalid slot: %zu", slot);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800217 return -EINVAL;
218 }
219
220 const int ret = epoll_fd_.Control(EPOLL_CTL_DEL, buf->event_fd(), nullptr);
221 if (ret < 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800222 ALOGE(
223 "BufferHubQueue::DetachBuffer: Failed to detach buffer from epoll set: "
224 "%s",
225 strerror(-ret));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800226 return ret;
227 }
228
229 buffers_[slot] = nullptr;
230 capacity_--;
231 return 0;
232}
233
234void BufferHubQueue::Enqueue(std::shared_ptr<BufferHubBuffer> buf,
235 size_t slot) {
236 if (count() == capacity_) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800237 ALOGE("Buffer queue is full!");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800238 return;
239 }
240
241 // Set slot buffer back to vector.
242 // TODO(jwcai) Here have to dynamically allocate BufferInfo::metadata due to
243 // the limitation of the RingBuffer we are using. Would be better to refactor
244 // that.
245 BufferInfo buffer_info(slot, meta_size_);
246 // Swap buffer into vector.
247 std::swap(buffer_info.buffer, buf);
248 // Swap metadata loaded during onBufferReady into vector.
249 std::swap(buffer_info.metadata, meta_buffer_tmp_);
250
251 available_buffers_.Append(std::move(buffer_info));
252}
253
254std::shared_ptr<BufferHubBuffer> BufferHubQueue::Dequeue(int timeout,
255 size_t* slot,
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700256 void* meta,
257 LocalHandle* fence) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800258 ALOGD("Dequeue: count=%zu, timeout=%d", count(), timeout);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800259
260 if (count() == 0 && !WaitForBuffers(timeout))
261 return nullptr;
262
263 std::shared_ptr<BufferHubBuffer> buf;
264 BufferInfo& buffer_info = available_buffers_.Front();
265
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700266 *fence = std::move(fences_[buffer_info.slot]);
267
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800268 // Report current pos as the output slot.
269 std::swap(buffer_info.slot, *slot);
270 // Swap buffer from vector to be returned later.
271 std::swap(buffer_info.buffer, buf);
272 // Swap metadata from vector into tmp so that we can write out to |meta|.
273 std::swap(buffer_info.metadata, meta_buffer_tmp_);
274
275 available_buffers_.PopFront();
276
277 if (!buf) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800278 ALOGE("Dequeue: Buffer to be dequeued is nullptr");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800279 return nullptr;
280 }
281
282 if (meta) {
283 std::copy(meta_buffer_tmp_.get(), meta_buffer_tmp_.get() + meta_size_,
284 reinterpret_cast<uint8_t*>(meta));
285 }
286
287 return buf;
288}
289
290ProducerQueue::ProducerQueue(size_t meta_size)
291 : ProducerQueue(meta_size, 0, 0, 0, 0) {}
292
293ProducerQueue::ProducerQueue(LocalChannelHandle handle, size_t meta_size)
294 : BASE(std::move(handle), meta_size) {}
295
296ProducerQueue::ProducerQueue(size_t meta_size, int usage_set_mask,
297 int usage_clear_mask, int usage_deny_set_mask,
298 int usage_deny_clear_mask)
299 : BASE(BufferHubRPC::kClientPath, meta_size) {
300 auto status = InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(
301 meta_size_, usage_set_mask, usage_clear_mask, usage_deny_set_mask,
302 usage_deny_clear_mask);
303 if (!status) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800304 ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s",
305 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800306 Close(-status.error());
307 return;
308 }
309}
310
311int ProducerQueue::AllocateBuffer(int width, int height, int format, int usage,
312 size_t slice_count, size_t* out_slot) {
313 if (out_slot == nullptr) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800314 ALOGE("Parameter out_slot cannot be null.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800315 return -EINVAL;
316 }
317
318 if (is_full()) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800319 ALOGE("ProducerQueue::AllocateBuffer queue is at maximum capacity: %zu",
320 capacity());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800321 return -E2BIG;
322 }
323
324 const size_t kBufferCount = 1U;
325
326 Status<std::vector<std::pair<LocalChannelHandle, size_t>>> status =
327 InvokeRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>(
328 width, height, format, usage, slice_count, kBufferCount);
329 if (!status) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800330 ALOGE(
331 "ProducerQueue::AllocateBuffer failed to create producer buffer "
332 "through BufferHub.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800333 return -status.error();
334 }
335
336 auto buffer_handle_slots = status.take();
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800337 LOG_ALWAYS_FATAL_IF(buffer_handle_slots.size() != kBufferCount,
338 "BufferHubRPC::ProducerQueueAllocateBuffers should "
339 "return one and only one buffer handle.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800340
341 // We only allocate one buffer at a time.
342 auto& buffer_handle = buffer_handle_slots[0].first;
343 size_t buffer_slot = buffer_handle_slots[0].second;
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800344 ALOGD("ProducerQueue::AllocateBuffer, new buffer, channel_handle: %d",
345 buffer_handle.value());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800346
347 *out_slot = buffer_slot;
348 return AddBuffer(BufferProducer::Import(std::move(buffer_handle)),
349 buffer_slot);
350}
351
352int ProducerQueue::AddBuffer(const std::shared_ptr<BufferProducer>& buf,
353 size_t slot) {
354 // For producer buffer, we need to enqueue the newly added buffer
355 // immediately. Producer queue starts with all buffers in available state.
356 const int ret = BufferHubQueue::AddBuffer(buf, slot);
357 if (ret < 0)
358 return ret;
359
360 Enqueue(buf, slot);
361 return 0;
362}
363
364int ProducerQueue::DetachBuffer(size_t slot) {
365 Status<int> status =
366 InvokeRemoteMethod<BufferHubRPC::ProducerQueueDetachBuffer>(slot);
367 if (!status) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800368 ALOGE(
369 "ProducerQueue::DetachBuffer failed to detach producer buffer through "
370 "BufferHub, error: %s",
371 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800372 return -status.error();
373 }
374
375 return BufferHubQueue::DetachBuffer(slot);
376}
377
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700378std::shared_ptr<BufferProducer> ProducerQueue::Dequeue(
379 int timeout, size_t* slot, LocalHandle* release_fence) {
380 if (slot == nullptr || release_fence == nullptr) {
381 ALOGE("invalid parameter, slot=%p, release_fence=%p", slot, release_fence);
382 return nullptr;
383 }
384
385 auto buf = BufferHubQueue::Dequeue(timeout, slot, nullptr, release_fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800386 return std::static_pointer_cast<BufferProducer>(buf);
387}
388
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700389int ProducerQueue::OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
390 LocalHandle* release_fence) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800391 auto buffer = std::static_pointer_cast<BufferProducer>(buf);
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700392 return buffer->Gain(release_fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800393}
394
395ConsumerQueue::ConsumerQueue(LocalChannelHandle handle, size_t meta_size)
396 : BASE(std::move(handle), meta_size) {
397 // TODO(b/34387835) Import consumer queue in case the ProducerQueue we are
398 // based on was not empty.
399}
400
401int ConsumerQueue::ImportBuffers() {
402 Status<std::vector<std::pair<LocalChannelHandle, size_t>>> status =
403 InvokeRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>();
404 if (!status) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800405 ALOGE(
406 "ConsumerQueue::ImportBuffers failed to import consumer buffer through "
407 "BufferBub, error: %s",
408 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800409 return -status.error();
410 }
411
412 int last_error = 0;
413 int imported_buffers = 0;
414
415 auto buffer_handle_slots = status.take();
416 for (auto& buffer_handle_slot : buffer_handle_slots) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800417 ALOGD("ConsumerQueue::ImportBuffers, new buffer, buffer_handle: %d",
418 buffer_handle_slot.first.value());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800419
420 std::unique_ptr<BufferConsumer> buffer_consumer =
421 BufferConsumer::Import(std::move(buffer_handle_slot.first));
422 int ret = AddBuffer(std::move(buffer_consumer), buffer_handle_slot.second);
423 if (ret < 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800424 ALOGE("ConsumerQueue::ImportBuffers failed to add buffer, ret: %s",
425 strerror(-ret));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800426 last_error = ret;
427 continue;
428 } else {
429 imported_buffers++;
430 }
431 }
432
433 return imported_buffers > 0 ? imported_buffers : last_error;
434}
435
436int ConsumerQueue::AddBuffer(const std::shared_ptr<BufferConsumer>& buf,
437 size_t slot) {
438 // Consumer queue starts with all buffers in unavailable state.
439 return BufferHubQueue::AddBuffer(buf, slot);
440}
441
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700442std::shared_ptr<BufferConsumer> ConsumerQueue::Dequeue(
443 int timeout, size_t* slot, void* meta, size_t meta_size,
444 LocalHandle* acquire_fence) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800445 if (meta_size != meta_size_) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800446 ALOGE(
447 "metadata size (%zu) for the dequeuing buffer does not match metadata "
448 "size (%zu) for the queue.",
449 meta_size, meta_size_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800450 return nullptr;
451 }
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700452
453 if (slot == nullptr || meta == nullptr || acquire_fence == nullptr) {
454 ALOGE("invalid parameter, slot=%p, meta=%p, acquire_fence=%p", slot, meta,
455 acquire_fence);
456 return nullptr;
457 }
458
459 auto buf = BufferHubQueue::Dequeue(timeout, slot, meta, acquire_fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800460 return std::static_pointer_cast<BufferConsumer>(buf);
461}
462
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700463int ConsumerQueue::OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
464 LocalHandle* acquire_fence) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800465 auto buffer = std::static_pointer_cast<BufferConsumer>(buf);
Jiwen 'Steve' Caied654322017-03-13 17:04:43 -0700466 return buffer->Acquire(acquire_fence, meta_buffer_tmp_.get(), meta_size_);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800467}
468
469int ConsumerQueue::OnBufferAllocated() {
470 const int ret = ImportBuffers();
471 if (ret == 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800472 ALOGW("No new buffer can be imported on buffer allocated event.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800473 } else if (ret < 0) {
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800474 ALOGE("Failed to import buffers on buffer allocated event.");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800475 }
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800476 ALOGD("Imported %d consumer buffers.", ret);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800477 return ret;
478}
479
480} // namespace dvr
481} // namespace android