19a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai/* 29a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * Copyright 2018 The Android Open Source Project 39a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * 49a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * Licensed under the Apache License, Version 2.0 (the "License"); 59a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * you may not use this file except in compliance with the License. 69a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * You may obtain a copy of the License at 79a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * 89a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * http://www.apache.org/licenses/LICENSE-2.0 99a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * 109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * Unless required by applicable law or agreed to in writing, software 119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * distributed under the License is distributed on an "AS IS" BASIS, 129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * See the License for the specific language governing permissions and 149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * limitations under the License. 159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai */ 169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 17d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai#include <dvr/dvr_api.h> 180f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai#include <gui/BufferHubProducer.h> 194fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <inttypes.h> 204fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h> 216a3c05bcfab588fd99dd8d619a53d15374e99507Mathias Agopian#include <system/window.h> 224fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 25c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caiusing namespace dvr; 26c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai 27d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai/* static */ 28c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caisp<BufferHubProducer> BufferHubProducer::Create(const std::shared_ptr<ProducerQueue>& queue) { 299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai sp<BufferHubProducer> producer = new BufferHubProducer; 309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai producer->queue_ = queue; 319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return producer; 32d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai} 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 345afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai/* static */ 35c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caisp<BufferHubProducer> BufferHubProducer::Create(ProducerQueueParcelable parcelable) { 369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!parcelable.IsValid()) { 379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::Create: Invalid producer parcelable."); 389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return nullptr; 399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai sp<BufferHubProducer> producer = new BufferHubProducer; 42c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle()); 439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return producer; 445afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai} 455afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai 460f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV("requestBuffer: slot=%d", slot); 489a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (connected_api_ == kNoConnectedApi) { 529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("requestBuffer: BufferHubProducer has no connected producer"); 539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_INIT; 549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (slot < 0 || slot >= max_buffer_count_) { 579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); 589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if (!buffers_[slot].mBufferState.isDequeued()) { 609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", slot, 619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.string()); 629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if (buffers_[slot].mGraphicBuffer != nullptr) { 649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("requestBuffer: slot %d is not empty.", slot); 659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if (buffers_[slot].mBufferProducer == nullptr) { 679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("requestBuffer: slot %d is not dequeued.", slot); 689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai const auto& buffer_producer = buffers_[slot].mBufferProducer; 729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer(); 739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mGraphicBuffer = graphic_buffer; 759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mRequestBufferCalled = true; 769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *buf = graphic_buffer; 789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::setMaxDequeuedBufferCount(int max_dequeued_buffers) { 829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers); 839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (max_dequeued_buffers <= 0 || 879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai max_dequeued_buffers > 88c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai int(BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) { 899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers, 90c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai BufferHubQueue::kMaxQueueCapacity); 919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // The new dequeued_buffers count should not be violated by the number 959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // of currently dequeued buffers. 969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai int dequeued_count = 0; 979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai for (const auto& buf : buffers_) { 989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (buf.mBufferState.isDequeued()) { 999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai dequeued_count++; 1009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (dequeued_count > max_dequeued_buffers) { 1039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("setMaxDequeuedBufferCount: the requested dequeued_buffers" 1049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "count (%d) exceeds the current dequeued buffer count (%d)", 1059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai max_dequeued_buffers, dequeued_count); 1069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 1079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai max_dequeued_buffer_count_ = max_dequeued_buffers; 1109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1130f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setAsyncMode(bool async) { 1149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (async) { 1159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer 1169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // automatically and behaves differently from IGraphicBufferConsumer. Thus, 1179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // android::BufferQueue's async mode (a.k.a. allocating an additional buffer 1189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // to prevent dequeueBuffer from being blocking) technically does not apply 1199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // here. 1209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // 1219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // In Daydream, non-blocking producer side dequeue is guaranteed by careful 1229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // buffer consumer implementations. In another word, BufferHubQueue based 1239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // dequeueBuffer should never block whether setAsyncMode(true) is set or 1249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // not. 1259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // 1269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // See: IGraphicBufferProducer::setAsyncMode and 1279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // BufferQueueProducer::setAsyncMode for more about original implementation. 1289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGW("BufferHubProducer::setAsyncMode: BufferHubQueue should always be " 1299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "asynchronous. This call makes no effact."); 1309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 1319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1321601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai return NO_ERROR; 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width, 1369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai uint32_t height, PixelFormat format, uint64_t usage, 1379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai uint64_t* /*outBufferAge*/, 1389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai FrameEventHistoryDelta* /* out_timestamps */) { 139e7cf62ab152d273849b7d80fe4dd709d00e5f9daJiwen 'Steve' Cai ALOGV("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage); 1409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai status_t ret; 1429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 1439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (connected_api_ == kNoConnectedApi) { 1459a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("dequeueBuffer: BufferQueue has no connected producer"); 1469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_INIT; 1479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1489a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai const uint32_t kLayerCount = 1; 1509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) { 1519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Lazy allocation. When the capacity of |queue_| has not reached 1529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // |max_dequeued_buffer_count_|, allocate new buffer. 1539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) To save memory, the really reasonable thing to do is to go 1549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // over existing slots and find first existing one to dequeue. 1559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ret = AllocateBuffer(width, height, kLayerCount, format, usage); 1569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (ret < 0) return ret; 1579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai size_t slot = 0; 160c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai std::shared_ptr<BufferProducer> buffer_producer; 1619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 162c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) { 1639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai LocalHandle fence; 1649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence); 1659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!buffer_status) return NO_MEMORY; 1669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffer_producer = buffer_status.take(); 1689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!buffer_producer) return NO_MEMORY; 1699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (width == buffer_producer->width() && height == buffer_producer->height() && 1719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai uint32_t(format) == buffer_producer->format()) { 1729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // The producer queue returns a buffer producer matches the request. 1739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 1749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Needs reallocation. 1779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) Consider use VLOG instead if we find this log is not useful. 1789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different " 1799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need " 1809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "re-allocattion.", 1819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai width, height, format, slot, buffer_producer->width(), buffer_producer->height(), 1829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffer_producer->format()); 1839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Mark the slot as reallocating, so that later we can set 1849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued. 1859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mIsReallocating = true; 1869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Remove the old buffer once the allocation before allocating its 1889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // replacement. 1899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai RemoveBuffer(slot); 1909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Allocate a new producer buffer with new buffer configs. Note that if 1929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // there are already multiple buffers in the queue, the next one returned 1939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // from |queue_->Dequeue| may not be the new buffer we just reallocated. 1949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Retry up to BufferHubQueue::kMaxQueueCapacity times. 1959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ret = AllocateBuffer(width, height, kLayerCount, format, usage); 1969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (ret < 0) return ret; 1979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 1989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 1999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // With the BufferHub backed solution. Buffer slot returned from 2009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // |queue_->Dequeue| is guaranteed to avaiable for producer's use. 2019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // It's either in free state (if the buffer has never been used before) or 2029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // in queued state (if the buffer has been dequeued and queued back to 2039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // BufferHubQueue). 2049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() && 2059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai !buffers_[slot].mBufferState.isQueued()), 2069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot, 2079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.string()); 2089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.freeQueued(); 2109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.dequeue(); 211e7cf62ab152d273849b7d80fe4dd709d00e5f9daJiwen 'Steve' Cai ALOGV("dequeueBuffer: slot=%zu", slot); 2129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we 2149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // just need to exopose that through |BufferHubQueue| once we need fence. 2159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *out_fence = Fence::NO_FENCE; 2169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *out_slot = int(slot); 2179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ret = NO_ERROR; 2189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (buffers_[slot].mIsReallocating) { 2209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ret |= BUFFER_NEEDS_REALLOCATION; 2219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mIsReallocating = false; 2229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 2239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return ret; 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 2270f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::detachBuffer(int /* slot */) { 2289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::detachBuffer not implemented."); 2299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 2329a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* /* out_buffer */, 2339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai sp<Fence>* /* out_fence */) { 2349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::detachNextBuffer not implemented."); 2359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 2389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::attachBuffer(int* /* out_slot */, 2399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai const sp<GraphicBuffer>& /* buffer */) { 2409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // With this BufferHub backed implementation, we assume (for now) all buffers 2419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // are allocated and owned by the BufferHub. Thus the attempt of transfering 2429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // ownership of a buffer to the buffer queue is intentionally unsupported. 2439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai LOG_ALWAYS_FATAL("BufferHubProducer::attachBuffer not supported."); 2449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 2470f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input, 2480f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai QueueBufferOutput* output) { 2499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV("queueBuffer: slot %d", slot); 2509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (output == nullptr) { 2529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 2539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 2549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai int64_t timestamp; 2569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai bool is_auto_timestamp; 2579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai android_dataspace dataspace; 2589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai Rect crop(Rect::EMPTY_RECT); 2599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai int scaling_mode; 2609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai uint32_t transform; 2619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai sp<Fence> fence; 2629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai input.deflate(×tamp, &is_auto_timestamp, &dataspace, &crop, &scaling_mode, &transform, 2649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai &fence); 2659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Check input scaling mode is valid. 2679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai switch (scaling_mode) { 2689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_SCALING_MODE_FREEZE: 2699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 2709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 2719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 2729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 2739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai default: 2749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode); 2759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 2769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 2779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Check input fence is valid. 2799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (fence == nullptr) { 2809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("queueBuffer: fence is NULL"); 2819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 2829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 2839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 2859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (connected_api_ == kNoConnectedApi) { 2879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("queueBuffer: BufferQueue has no connected producer"); 2889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_INIT; 2899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 2909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 2919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (slot < 0 || slot >= max_buffer_count_) { 2929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); 2939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 2949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if (!buffers_[slot].mBufferState.isDequeued()) { 2959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", slot, 2969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.string()); 2979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 2989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if ((!buffers_[slot].mRequestBufferCalled || buffers_[slot].mGraphicBuffer == nullptr)) { 2999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, " 3009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "mGraphicBuffer=%p)", 3019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai slot, buffers_[slot].mRequestBufferCalled, buffers_[slot].mGraphicBuffer.get()); 3029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 3039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 3049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Post the buffer producer with timestamp in the metadata. 3069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai const auto& buffer_producer = buffers_[slot].mBufferProducer; 3079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Check input crop is not out of boundary of current buffer. 3099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai Rect buffer_rect(buffer_producer->width(), buffer_producer->height()); 3109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai Rect cropped_rect(Rect::EMPTY_RECT); 3119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai crop.intersect(buffer_rect, &cropped_rect); 3129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (cropped_rect != crop) { 3139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot); 3149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 3159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 3169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1); 3189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai DvrNativeBufferMetadata meta_data; 3209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.timestamp = timestamp; 3219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.is_auto_timestamp = int32_t(is_auto_timestamp); 3229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.dataspace = int32_t(dataspace); 3239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.crop_left = crop.left; 3249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.crop_top = crop.top; 3259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.crop_right = crop.right; 3269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.crop_bottom = crop.bottom; 3279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.scaling_mode = int32_t(scaling_mode); 3289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai meta_data.transform = int32_t(transform); 3299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffer_producer->PostAsync(&meta_data, fence_fd); 3319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.queue(); 3329a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->width = buffer_producer->width(); 3349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->height = buffer_producer->height(); 3359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->transformHint = 0; // default value, we don't use it yet. 3369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // |numPendingBuffers| counts of the number of buffers that has been enqueued 3389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // by the producer but not yet acquired by the consumer. Due to the nature 3399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // of BufferHubQueue design, this is hard to trace from the producer's client 3409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // side, but it's safe to assume it's zero. 3419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->numPendingBuffers = 0; 3429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Note that we are not setting nextFrameNumber here as it seems to be only 3449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // used by surface flinger. See more at b/22802885, ag/791760. 3459a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->nextFrameNumber = 0; 3469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3500f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 3519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 3529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 3549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (connected_api_ == kNoConnectedApi) { 3569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("cancelBuffer: BufferQueue has no connected producer"); 3579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_INIT; 3589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 3599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (slot < 0 || slot >= max_buffer_count_) { 3619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); 3629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 3639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if (!buffers_[slot].mBufferState.isDequeued()) { 3649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", slot, 3659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.string()); 3669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 3679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if (fence == nullptr) { 3689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("cancelBuffer: fence is NULL"); 3699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 3709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 3719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai auto buffer_producer = buffers_[slot].mBufferProducer; 3739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai queue_->Enqueue(buffer_producer, size_t(slot), 0ULL); 3749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.cancel(); 3759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mFence = fence; 3769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV("cancelBuffer: slot %d", slot); 3779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3810f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::query(int what, int* out_value) { 3829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 3839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 3859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (out_value == nullptr) { 3879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("query: out_value was NULL"); 3889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 3899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 3909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 3919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai int value = 0; 3929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai switch (what) { 3939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 3949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(b/36187402) This should be the maximum number of buffers that this 3959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // producer queue's consumer can acquire. Set to be at least one. Need to 3969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // find a way to set from the consumer side. 3979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = kDefaultUndequeuedBuffers; 3989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 3999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_BUFFER_AGE: 4009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = 0; 4019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_WIDTH: 4039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = int32_t(queue_->default_width()); 4049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_HEIGHT: 4069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = int32_t(queue_->default_height()); 4079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_FORMAT: 4099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = int32_t(queue_->default_format()); 4109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 4129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // BufferHubQueue is always operating in async mode, thus semantically 4139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // consumer can never be running behind. See BufferQueueCore.cpp core 4149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // for more information about the original meaning of this flag. 4159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = 0; 4169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 4189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) This is currently not implement as we don't need 4199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // IGraphicBufferConsumer parity. 4209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = 0; 4219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_DEFAULT_DATASPACE: 4239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) Return the default value android::BufferQueue is using as 4249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // there is no way dvr::ConsumerQueue can set it. 4259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = 0; // HAL_DATASPACE_UNKNOWN 4269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_STICKY_TRANSFORM: 4289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) Return the default value android::BufferQueue is using as 4299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // there is no way dvr::ConsumerQueue can set it. 4309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = 0; 4319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4329a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_CONSUMER_IS_PROTECTED: 4339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // In Daydream's implementation, the consumer end (i.e. VR Compostior) 4349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // knows how to handle protected buffers. 4359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai value = 1; 4369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai default: 4389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 4399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 4409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV("query: key=%d, v=%d", what, value); 4429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *out_value = value; 4439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */, int api, 4470f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai bool /* producer_controlled_by_app */, 4480f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai QueueBufferOutput* output) { 4499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Consumer interaction are actually handled by buffer hub, and we need 4509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // to maintain consumer operations here. We only need to perform basic input 4519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // parameter checks here. 4529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 4539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (output == nullptr) { 4559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 4569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 4579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 4599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (connected_api_ != kNoConnectedApi) { 4619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 4629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 4639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!queue_->is_connected()) { 4659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::connect: This BufferHubProducer is not " 4669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "connected to bufferhud. Has it been taken out as a parcelable?"); 4679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 4689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 4699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai switch (api) { 4719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_API_EGL: 4729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_API_CPU: 4739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_API_MEDIA: 4749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai case NATIVE_WINDOW_API_CAMERA: 4759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai connected_api_ = api; 4769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->width = queue_->default_width(); 4789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->height = queue_->default_height(); 4799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // default values, we don't use them yet. 4819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->transformHint = 0; 4829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->numPendingBuffers = 0; 4839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->nextFrameNumber = 0; 4849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai output->bufferReplaced = false; 4859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai break; 4879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai default: 4889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::connect: unknow API %d", api); 4899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 4909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 4919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 4929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4950f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) { 4969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Consumer interaction are actually handled by buffer hub, and we need 4979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // to maintain consumer operations here. We only need to perform basic input 4989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // parameter checks here. 4999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 5009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 5019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 5029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 5039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (kNoConnectedApi == connected_api_) { 5049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_INIT; 5059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } else if (api != connected_api_) { 5069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 5079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 5089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 5099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai FreeAllBuffers(); 5109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai connected_api_ = kNoConnectedApi; 5119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5140f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) { 5159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (stream != nullptr) { 5169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's 5179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // metadata. 5189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("SidebandStream is not currently supported."); 5199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 5209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 5219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caivoid BufferHubProducer::allocateBuffers(uint32_t /* width */, uint32_t /* height */, 5259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai PixelFormat /* format */, uint64_t /* usage */) { 5269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number 5279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // of buffers permitted by the current BufferQueue configuration (aka 5289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // |max_buffer_count_|). 5299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::allocateBuffers not implemented."); 530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5320f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::allowAllocation(bool /* allow */) { 5339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::allowAllocation not implemented."); 5349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5370f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) { 5389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 5419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai generation_number_ = generation_number; 5429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5450f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' CaiString8 BufferHubProducer::getConsumerName() const { 5469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // BufferHub based implementation could have one to many producer/consumer 5479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // relationship, thus |getConsumerName| from the producer side does not 5489a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // make any sense. 5499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::getConsumerName not supported."); 5509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return String8("BufferHubQueue::DummyConsumer"); 551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5530f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) { 5549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (shared_buffer_mode) { 5559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported."); 5569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow. 5579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 5589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 5599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Setting to default should just work as a no-op. 5609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5630f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setAutoRefresh(bool auto_refresh) { 5649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (auto_refresh) { 5659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported."); 5669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 5679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 5689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Setting to default should just work as a no-op. 5699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5720f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) { 5739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai std::unique_lock<std::mutex> lock(mutex_); 576c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000)); 5779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::getLastQueuedBuffer(sp<GraphicBuffer>* /* out_buffer */, 5819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai sp<Fence>* /* out_fence */, 5829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai float /*out_transform_matrix*/[16]) { 5839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented."); 5849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caivoid BufferHubProducer::getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) { 5889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::getFrameTimestamps not implemented."); 589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5910f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::getUniqueId(uint64_t* out_id) const { 5929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *out_id = unique_id_; 5959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 596d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai} 597d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai 5980f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const { 5999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGV(__FUNCTION__); 600e2786ea5aec3a12d948feb85ffbb535fc89c0fe6Chia-I Wu 6019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS 6029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *out_usage = 0; 6039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 604e2786ea5aec3a12d948feb85ffbb535fc89c0fe6Chia-I Wu} 605e2786ea5aec3a12d948feb85ffbb535fc89c0fe6Chia-I Wu 606c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caistatus_t BufferHubProducer::TakeAsParcelable(ProducerQueueParcelable* out_parcelable) { 6079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!out_parcelable || out_parcelable->IsValid()) return BAD_VALUE; 6089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 6099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (connected_api_ != kNoConnectedApi) { 6109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::TakeAsParcelable: BufferHubProducer has " 6119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "connected client. Must disconnect first."); 6129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 6139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 6149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 6159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!queue_->is_connected()) { 6169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::TakeAsParcelable: This BufferHubProducer " 6179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "is not connected to bufferhud. Has it been taken out as a " 6189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "parcelable?"); 6199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 6209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 6219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 6229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai auto status = queue_->TakeAsParcelable(); 6239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!status) { 6249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::TakeAsParcelable: Failed to take out " 6259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "ProducuerQueueParcelable from the producer queue, error: %s.", 6269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai status.GetErrorMessage().c_str()); 6279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return BAD_VALUE; 6289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 6299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 6309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *out_parcelable = status.take(); 6319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 6325afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai} 6335afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai 6349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count, 6350f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai PixelFormat format, uint64_t usage) { 6369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai auto status = queue_->AllocateBuffer(width, height, layer_count, uint32_t(format), usage); 6379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!status) { 6389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s", 6399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai status.GetErrorMessage().c_str()); 6409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_MEMORY; 6419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 642d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai 6439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai size_t slot = status.get(); 6449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai auto buffer_producer = queue_->GetBuffer(slot); 645d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai 6469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr, "Failed to get buffer producer at slot: %zu", 6479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai slot); 648d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai 6499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferProducer = buffer_producer; 650d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai 6519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 653e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 6540f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::RemoveBuffer(size_t slot) { 6559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai auto status = queue_->RemoveBuffer(slot); 6569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!status) { 6579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer: %s", 6589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai status.GetErrorMessage().c_str()); 6599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return INVALID_OPERATION; 6609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 661d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai 6629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Reset in memory objects related the the buffer. 6639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferProducer = nullptr; 6649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mGraphicBuffer = nullptr; 6659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.detachProducer(); 6669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 668e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 6690f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::FreeAllBuffers() { 670c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) { 6719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai // Reset in memory objects related the the buffer. 6729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mGraphicBuffer = nullptr; 6739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferState.reset(); 6749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mRequestBufferCalled = false; 6759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mBufferProducer = nullptr; 6769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai buffers_[slot].mFence = Fence::NO_FENCE; 6779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 6789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 6799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai auto status = queue_->FreeAllBuffers(); 6809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (!status) { 6819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai ALOGE("BufferHubProducer::FreeAllBuffers: Failed to free all buffers on " 6829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai "the queue: %s", 6839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai status.GetErrorMessage().c_str()); 6849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 6859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 6869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai if (queue_->capacity() != 0 || queue_->count() != 0) { 6879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai LOG_ALWAYS_FATAL("BufferHubProducer::FreeAllBuffers: Not all buffers are freed."); 6889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai } 6899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai 6909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai return NO_ERROR; 691005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai} 692005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 693c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caistatus_t BufferHubProducer::exportToParcel(Parcel* parcel) { 694c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai status_t res = TakeAsParcelable(&pending_producer_parcelable_); 695c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai if (res != NO_ERROR) return res; 696c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai 697c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai if (!pending_producer_parcelable_.IsValid()) { 698c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai ALOGE("BufferHubProducer::exportToParcel: Invalid parcelable object."); 699c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai return BAD_VALUE; 700c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai } 701c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai 702c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai res = parcel->writeUint32(USE_BUFFER_HUB); 703c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai if (res != NO_ERROR) { 704c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai ALOGE("BufferHubProducer::exportToParcel: Cannot write magic, res=%d.", res); 705c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai return res; 706c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai } 707c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai 708c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai return pending_producer_parcelable_.writeToParcel(parcel); 709c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai} 710c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai 711c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' CaiIBinder* BufferHubProducer::onAsBinder() { 712c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai ALOGE("BufferHubProducer::onAsBinder: BufferHubProducer should never be used as an Binder " 713c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai "object."); 714c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai return nullptr; 715c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai} 716c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai 7179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai} // namespace android 718