diff options
Diffstat (limited to 'libs/gui/BufferQueueProducer.cpp')
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 122 |
1 files changed, 114 insertions, 8 deletions
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index fb69fda32d..69345a971e 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -423,6 +423,11 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou sp<IConsumerListener> listener; bool callOnFrameDequeued = false; uint64_t bufferId = 0; // Only used if callOnFrameDequeued == true +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + std::vector<gui::AdditionalOptions> allocOptions; + uint32_t allocOptionsGenId = 0; +#endif + { // Autolock scope std::unique_lock<std::mutex> lock(mCore->mMutex); @@ -486,11 +491,17 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou } const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); - if (mCore->mSharedBufferSlot == found && - buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage)) { - BQ_LOGE("dequeueBuffer: cannot re-allocate a shared" - "buffer"); + bool needsReallocation = buffer == nullptr || + buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage); + +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + needsReallocation |= mSlots[found].mAdditionalOptionsGenerationId != + mCore->mAdditionalOptionsGenerationId; +#endif + + if (mCore->mSharedBufferSlot == found && needsReallocation) { + BQ_LOGE("dequeueBuffer: cannot re-allocate a shared buffer"); return BAD_VALUE; } @@ -505,9 +516,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou mSlots[found].mBufferState.dequeue(); - if ((buffer == nullptr) || - buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage)) - { + if (needsReallocation) { if (CC_UNLIKELY(ATRACE_ENABLED())) { if (buffer == nullptr) { ATRACE_FORMAT_INSTANT("%s buffer reallocation: null", mConsumerName.c_str()); @@ -530,6 +539,10 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou mSlots[found].mFence = Fence::NO_FENCE; mCore->mBufferAge = 0; mCore->mIsAllocating = true; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + allocOptions = mCore->mAdditionalOptions; + allocOptionsGenId = mCore->mAdditionalOptionsGenerationId; +#endif returnFlags |= BUFFER_NEEDS_REALLOCATION; } else { @@ -575,9 +588,29 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou if (returnFlags & BUFFER_NEEDS_REALLOCATION) { BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); + +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + std::vector<GraphicBufferAllocator::AdditionalOptions> tempOptions; + tempOptions.reserve(allocOptions.size()); + for (const auto& it : allocOptions) { + tempOptions.emplace_back(it.name.c_str(), it.value); + } + const GraphicBufferAllocator::AllocationRequest allocRequest = { + .importBuffer = true, + .width = width, + .height = height, + .format = format, + .layerCount = BQ_LAYER_COUNT, + .usage = usage, + .requestorName = {mConsumerName.c_str(), mConsumerName.size()}, + .extras = std::move(tempOptions), + }; + sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(allocRequest); +#else sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(width, height, format, BQ_LAYER_COUNT, usage, {mConsumerName.c_str(), mConsumerName.size()}); +#endif status_t error = graphicBuffer->initCheck(); @@ -587,6 +620,9 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou if (error == NO_ERROR && !mCore->mIsAbandoned) { graphicBuffer->setGenerationNumber(mCore->mGenerationNumber); mSlots[*outSlot].mGraphicBuffer = graphicBuffer; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + mSlots[*outSlot].mAdditionalOptionsGenerationId = allocOptionsGenId; +#endif callOnFrameDequeued = true; bufferId = mSlots[*outSlot].mGraphicBuffer->getId(); } @@ -1342,6 +1378,9 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, } mCore->mAllowAllocation = true; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + mCore->mAdditionalOptions.clear(); +#endif VALIDATE_CONSISTENCY(); return status; } @@ -1410,6 +1449,9 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { mCore->mSidebandStream.clear(); mCore->mDequeueCondition.notify_all(); mCore->mAutoPrerotation = false; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + mCore->mAdditionalOptions.clear(); +#endif listener = mCore->mConsumerListener; } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("disconnect: not connected (req=%d)", api); @@ -1462,6 +1504,10 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; uint64_t allocUsage = 0; std::string allocName; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + std::vector<gui::AdditionalOptions> allocOptions; + uint32_t allocOptionsGenId = 0; +#endif { // Autolock scope std::unique_lock<std::mutex> lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(lock); @@ -1490,14 +1536,42 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, allocUsage = usage | mCore->mConsumerUsageBits; allocName.assign(mCore->mConsumerName.c_str(), mCore->mConsumerName.size()); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + allocOptions = mCore->mAdditionalOptions; + allocOptionsGenId = mCore->mAdditionalOptionsGenerationId; +#endif + mCore->mIsAllocating = true; + } // Autolock scope +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + std::vector<GraphicBufferAllocator::AdditionalOptions> tempOptions; + tempOptions.reserve(allocOptions.size()); + for (const auto& it : allocOptions) { + tempOptions.emplace_back(it.name.c_str(), it.value); + } + const GraphicBufferAllocator::AllocationRequest allocRequest = { + .importBuffer = true, + .width = allocWidth, + .height = allocHeight, + .format = allocFormat, + .layerCount = BQ_LAYER_COUNT, + .usage = allocUsage, + .requestorName = allocName, + .extras = std::move(tempOptions), + }; +#endif + Vector<sp<GraphicBuffer>> buffers; for (size_t i = 0; i < newBufferCount; ++i) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(allocRequest); +#else sp<GraphicBuffer> graphicBuffer = new GraphicBuffer( allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT, allocUsage, allocName); +#endif status_t result = graphicBuffer->initCheck(); @@ -1524,8 +1598,12 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, PixelFormat checkFormat = format != 0 ? format : mCore->mDefaultBufferFormat; uint64_t checkUsage = usage | mCore->mConsumerUsageBits; + bool allocOptionsChanged = false; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + allocOptionsChanged = allocOptionsGenId != mCore->mAdditionalOptionsGenerationId; +#endif if (checkWidth != allocWidth || checkHeight != allocHeight || - checkFormat != allocFormat || checkUsage != allocUsage) { + checkFormat != allocFormat || checkUsage != allocUsage || allocOptionsChanged) { // Something changed while we released the lock. Retry. BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); mCore->mIsAllocating = false; @@ -1543,6 +1621,9 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, mCore->clearBufferSlotLocked(*slot); // Clean up the slot first mSlots[*slot].mGraphicBuffer = buffers[i]; mSlots[*slot].mFence = Fence::NO_FENCE; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) + mSlots[*slot].mAdditionalOptionsGenerationId = allocOptionsGenId; +#endif // freeBufferLocked puts this slot on the free slots list. Since // we then attached a buffer, move the slot to free buffer list. @@ -1778,4 +1859,29 @@ status_t BufferQueueProducer::setFrameRate(float frameRate, int8_t compatibility } #endif +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) +status_t BufferQueueProducer::setAdditionalOptions( + const std::vector<gui::AdditionalOptions>& options) { + ATRACE_CALL(); + BQ_LOGV("setAdditionalOptions, size = %zu", options.size()); + + if (!GraphicBufferAllocator::get().supportsAdditionalOptions()) { + return INVALID_OPERATION; + } + + std::lock_guard<std::mutex> lock(mCore->mMutex); + + if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { + BQ_LOGE("setAdditionalOptions: BufferQueue not connected, cannot set additional options"); + return NO_INIT; + } + + if (mCore->mAdditionalOptions != options) { + mCore->mAdditionalOptions = options; + mCore->mAdditionalOptionsGenerationId++; + } + return NO_ERROR; +} +#endif + } // namespace android |