Loading libs/gui/BufferQueueProducer.cpp +114 −8 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading @@ -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()); Loading @@ -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 { Loading Loading @@ -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(); Loading @@ -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(); } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading @@ -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. Loading Loading @@ -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 libs/gui/IGraphicBufferProducer.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ enum { QUERY_MULTIPLE, GET_LAST_QUEUED_BUFFER2, SET_FRAME_RATE, SET_ADDITIONAL_OPTIONS, }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> Loading Loading @@ -778,6 +779,25 @@ public: return result; } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) virtual status_t setAdditionalOptions(const std::vector<gui::AdditionalOptions>& options) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); if (options.size() > 100) { return BAD_VALUE; } data.writeInt32(options.size()); for (const auto& it : options) { data.writeCString(it.name.c_str()); data.writeInt64(it.value); } status_t result = remote()->transact(SET_ADDITIONAL_OPTIONS, data, &reply); if (result == NO_ERROR) { result = reply.readInt32(); } return result; } #endif }; // Out-of-line virtual method definition to trigger vtable emission in this Loading Loading @@ -981,6 +1001,13 @@ status_t IGraphicBufferProducer::setFrameRate(float /*frameRate*/, int8_t /*comp } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) status_t IGraphicBufferProducer::setAdditionalOptions(const std::vector<gui::AdditionalOptions>&) { // No-op for IGBP other than BufferQueue. return INVALID_OPERATION; } #endif status_t IGraphicBufferProducer::exportToParcel(Parcel* parcel) { status_t res = OK; res = parcel->writeUint32(USE_BUFFER_QUEUE); Loading Loading @@ -1532,6 +1559,28 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); return NO_ERROR; } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) case SET_ADDITIONAL_OPTIONS: { CHECK_INTERFACE(IGraphicBuffer, data, reply); int optionCount = data.readInt32(); if (optionCount < 0 || optionCount > 100) { return BAD_VALUE; } std::vector<gui::AdditionalOptions> opts; opts.reserve(optionCount); for (int i = 0; i < optionCount; i++) { const char* name = data.readCString(); int64_t value = 0; if (name == nullptr || data.readInt64(&value) != NO_ERROR) { return BAD_VALUE; } opts.emplace_back(name, value); } status_t result = setAdditionalOptions(opts); reply->writeInt32(result); return NO_ERROR; } #endif } return BBinder::onTransact(code, data, reply, flags); Loading libs/gui/LayerStatePermissions.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -23,31 +23,31 @@ #include <gui/LayerState.h> namespace android { std::unordered_map<std::string, int> LayerStatePermissions::mPermissionMap = { std::vector<std::pair<String16, int>> LayerStatePermissions::mPermissionMap = { // If caller has ACCESS_SURFACE_FLINGER, they automatically get ROTATE_SURFACE_FLINGER // permission, as well {"android.permission.ACCESS_SURFACE_FLINGER", {String16("android.permission.ACCESS_SURFACE_FLINGER"), layer_state_t::Permission::ACCESS_SURFACE_FLINGER | layer_state_t::Permission::ROTATE_SURFACE_FLINGER}, {"android.permission.ROTATE_SURFACE_FLINGER", {String16("android.permission.ROTATE_SURFACE_FLINGER"), layer_state_t::Permission::ROTATE_SURFACE_FLINGER}, {"android.permission.INTERNAL_SYSTEM_WINDOW", {String16("android.permission.INTERNAL_SYSTEM_WINDOW"), layer_state_t::Permission::INTERNAL_SYSTEM_WINDOW}, }; static bool callingThreadHasPermission(const std::string& permission __attribute__((unused)), static bool callingThreadHasPermission(const String16& permission __attribute__((unused)), int pid __attribute__((unused)), int uid __attribute__((unused))) { #ifndef __ANDROID_VNDK__ return uid == AID_GRAPHICS || uid == AID_SYSTEM || PermissionCache::checkPermission(String16(permission.c_str()), pid, uid); PermissionCache::checkPermission(permission, pid, uid); #endif // __ANDROID_VNDK__ return false; } uint32_t LayerStatePermissions::getTransactionPermissions(int pid, int uid) { uint32_t permissions = 0; for (auto [permissionName, permissionVal] : mPermissionMap) { for (const auto& [permissionName, permissionVal] : mPermissionMap) { if (callingThreadHasPermission(permissionName, pid, uid)) { permissions |= permissionVal; } Loading libs/gui/Surface.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -1475,6 +1475,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO: res = dispatchSetFrameTimelineInfo(args); break; case NATIVE_WINDOW_SET_BUFFERS_ADDITIONAL_OPTIONS: res = dispatchSetAdditionalOptions(args); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -1833,6 +1836,24 @@ int Surface::dispatchSetFrameTimelineInfo(va_list args) { return setFrameTimelineInfo(nativeWindowFtlInfo.frameNumber, ftlInfo); } int Surface::dispatchSetAdditionalOptions(va_list args) { ATRACE_CALL(); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) const AHardwareBufferLongOptions* opts = va_arg(args, const AHardwareBufferLongOptions*); const size_t optsSize = va_arg(args, size_t); std::vector<gui::AdditionalOptions> convertedOpts; convertedOpts.reserve(optsSize); for (size_t i = 0; i < optsSize; i++) { convertedOpts.emplace_back(opts[i].name, opts[i].value); } return setAdditionalOptions(convertedOpts); #else (void)args; return INVALID_OPERATION; #endif } bool Surface::transformToDisplayInverse() const { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; Loading Loading @@ -2619,6 +2640,17 @@ status_t Surface::setFrameTimelineInfo(uint64_t /*frameNumber*/, return BAD_VALUE; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) status_t Surface::setAdditionalOptions(const std::vector<gui::AdditionalOptions>& options) { if (!GraphicBufferAllocator::get().supportsAdditionalOptions()) { return INVALID_OPERATION; } Mutex::Autolock lock(mMutex); return mGraphicBufferProducer->setAdditionalOptions(options); } #endif sp<IBinder> Surface::getSurfaceControlHandle() const { Mutex::Autolock lock(mMutex); return mSurfaceControlHandle; Loading libs/gui/SurfaceComposerClient.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -706,6 +706,7 @@ void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId) { SurfaceComposerClient::Transaction::Transaction() { mId = generateId(); mTransactionCompletedListener = TransactionCompletedListener::getInstance(); } SurfaceComposerClient::Transaction::Transaction(const Transaction& other) Loading @@ -723,6 +724,7 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mComposerStates = other.mComposerStates; mInputWindowCommands = other.mInputWindowCommands; mListenerCallbacks = other.mListenerCallbacks; mTransactionCompletedListener = TransactionCompletedListener::getInstance(); } void SurfaceComposerClient::Transaction::sanitize(int pid, int uid) { Loading Loading @@ -1000,8 +1002,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr // register all surface controls for all callbackIds for this listener that is merging for (const auto& surfaceControl : currentProcessCallbackInfo.surfaceControls) { TransactionCompletedListener::getInstance() ->addSurfaceControlToCallbacks(currentProcessCallbackInfo, surfaceControl); mTransactionCompletedListener->addSurfaceControlToCallbacks(currentProcessCallbackInfo, surfaceControl); } } Loading Loading @@ -1354,7 +1356,7 @@ void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()]; callbackInfo.surfaceControls.insert(sc); TransactionCompletedListener::getInstance()->addSurfaceControlToCallbacks(callbackInfo, sc); mTransactionCompletedListener->addSurfaceControlToCallbacks(callbackInfo, sc); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( Loading Loading @@ -1672,7 +1674,7 @@ std::shared_ptr<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffe std::shared_ptr<BufferData> bufferData = std::move(s->bufferData); TransactionCompletedListener::getInstance()->removeReleaseBufferCallback( mTransactionCompletedListener->removeReleaseBufferCallback( bufferData->generateReleaseCallbackId()); s->what &= ~layer_state_t::eBufferChanged; s->bufferData = nullptr; Loading Loading @@ -1715,8 +1717,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe bufferData->acquireFence = *fence; bufferData->flags |= BufferData::BufferDataChange::fenceChanged; } bufferData->releaseBufferEndpoint = IInterface::asBinder(TransactionCompletedListener::getIInstance()); bufferData->releaseBufferEndpoint = IInterface::asBinder(mTransactionCompletedListener); setReleaseBufferCallback(bufferData.get(), callback); } Loading Loading @@ -1774,9 +1775,10 @@ void SurfaceComposerClient::Transaction::setReleaseBufferCallback(BufferData* bu return; } bufferData->releaseBufferListener = TransactionCompletedListener::getIInstance(); auto listener = TransactionCompletedListener::getInstance(); listener->setReleaseBufferCallback(bufferData->generateReleaseCallbackId(), callback); bufferData->releaseBufferListener = static_cast<sp<ITransactionCompletedListener>>(mTransactionCompletedListener); mTransactionCompletedListener->setReleaseBufferCallback(bufferData->generateReleaseCallbackId(), callback); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDataspace( Loading Loading @@ -1932,18 +1934,15 @@ SurfaceComposerClient::Transaction::setFrameRateSelectionPriority(const sp<Surfa SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addTransactionCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext, CallbackId::Type callbackType) { auto listener = TransactionCompletedListener::getInstance(); auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); const auto& surfaceControls = mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls; const auto& surfaceControls = mListenerCallbacks[mTransactionCompletedListener].surfaceControls; CallbackId callbackId = listener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType); mTransactionCompletedListener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType); mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace( callbackId); mListenerCallbacks[mTransactionCompletedListener].callbackIds.emplace(callbackId); return *this; } Loading Loading @@ -2333,8 +2332,9 @@ SurfaceComposerClient::Transaction::setTrustedPresentationCallback( const sp<SurfaceControl>& sc, TrustedPresentationCallback cb, const TrustedPresentationThresholds& thresholds, void* context, sp<SurfaceComposerClient::PresentationCallbackRAII>& outCallbackRef) { auto listener = TransactionCompletedListener::getInstance(); outCallbackRef = listener->addTrustedPresentationCallback(cb, sc->getLayerId(), context); outCallbackRef = mTransactionCompletedListener->addTrustedPresentationCallback(cb, sc->getLayerId(), context); layer_state_t* s = getLayerState(sc); if (!s) { Loading @@ -2351,8 +2351,7 @@ SurfaceComposerClient::Transaction::setTrustedPresentationCallback( SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::clearTrustedPresentationCallback(const sp<SurfaceControl>& sc) { auto listener = TransactionCompletedListener::getInstance(); listener->clearTrustedPresentationCallback(sc->getLayerId()); mTransactionCompletedListener->clearTrustedPresentationCallback(sc->getLayerId()); layer_state_t* s = getLayerState(sc); if (!s) { Loading Loading
libs/gui/BufferQueueProducer.cpp +114 −8 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading @@ -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()); Loading @@ -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 { Loading Loading @@ -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(); Loading @@ -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(); } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading @@ -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. Loading Loading @@ -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
libs/gui/IGraphicBufferProducer.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ enum { QUERY_MULTIPLE, GET_LAST_QUEUED_BUFFER2, SET_FRAME_RATE, SET_ADDITIONAL_OPTIONS, }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> Loading Loading @@ -778,6 +779,25 @@ public: return result; } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) virtual status_t setAdditionalOptions(const std::vector<gui::AdditionalOptions>& options) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); if (options.size() > 100) { return BAD_VALUE; } data.writeInt32(options.size()); for (const auto& it : options) { data.writeCString(it.name.c_str()); data.writeInt64(it.value); } status_t result = remote()->transact(SET_ADDITIONAL_OPTIONS, data, &reply); if (result == NO_ERROR) { result = reply.readInt32(); } return result; } #endif }; // Out-of-line virtual method definition to trigger vtable emission in this Loading Loading @@ -981,6 +1001,13 @@ status_t IGraphicBufferProducer::setFrameRate(float /*frameRate*/, int8_t /*comp } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) status_t IGraphicBufferProducer::setAdditionalOptions(const std::vector<gui::AdditionalOptions>&) { // No-op for IGBP other than BufferQueue. return INVALID_OPERATION; } #endif status_t IGraphicBufferProducer::exportToParcel(Parcel* parcel) { status_t res = OK; res = parcel->writeUint32(USE_BUFFER_QUEUE); Loading Loading @@ -1532,6 +1559,28 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); return NO_ERROR; } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) case SET_ADDITIONAL_OPTIONS: { CHECK_INTERFACE(IGraphicBuffer, data, reply); int optionCount = data.readInt32(); if (optionCount < 0 || optionCount > 100) { return BAD_VALUE; } std::vector<gui::AdditionalOptions> opts; opts.reserve(optionCount); for (int i = 0; i < optionCount; i++) { const char* name = data.readCString(); int64_t value = 0; if (name == nullptr || data.readInt64(&value) != NO_ERROR) { return BAD_VALUE; } opts.emplace_back(name, value); } status_t result = setAdditionalOptions(opts); reply->writeInt32(result); return NO_ERROR; } #endif } return BBinder::onTransact(code, data, reply, flags); Loading
libs/gui/LayerStatePermissions.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -23,31 +23,31 @@ #include <gui/LayerState.h> namespace android { std::unordered_map<std::string, int> LayerStatePermissions::mPermissionMap = { std::vector<std::pair<String16, int>> LayerStatePermissions::mPermissionMap = { // If caller has ACCESS_SURFACE_FLINGER, they automatically get ROTATE_SURFACE_FLINGER // permission, as well {"android.permission.ACCESS_SURFACE_FLINGER", {String16("android.permission.ACCESS_SURFACE_FLINGER"), layer_state_t::Permission::ACCESS_SURFACE_FLINGER | layer_state_t::Permission::ROTATE_SURFACE_FLINGER}, {"android.permission.ROTATE_SURFACE_FLINGER", {String16("android.permission.ROTATE_SURFACE_FLINGER"), layer_state_t::Permission::ROTATE_SURFACE_FLINGER}, {"android.permission.INTERNAL_SYSTEM_WINDOW", {String16("android.permission.INTERNAL_SYSTEM_WINDOW"), layer_state_t::Permission::INTERNAL_SYSTEM_WINDOW}, }; static bool callingThreadHasPermission(const std::string& permission __attribute__((unused)), static bool callingThreadHasPermission(const String16& permission __attribute__((unused)), int pid __attribute__((unused)), int uid __attribute__((unused))) { #ifndef __ANDROID_VNDK__ return uid == AID_GRAPHICS || uid == AID_SYSTEM || PermissionCache::checkPermission(String16(permission.c_str()), pid, uid); PermissionCache::checkPermission(permission, pid, uid); #endif // __ANDROID_VNDK__ return false; } uint32_t LayerStatePermissions::getTransactionPermissions(int pid, int uid) { uint32_t permissions = 0; for (auto [permissionName, permissionVal] : mPermissionMap) { for (const auto& [permissionName, permissionVal] : mPermissionMap) { if (callingThreadHasPermission(permissionName, pid, uid)) { permissions |= permissionVal; } Loading
libs/gui/Surface.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -1475,6 +1475,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO: res = dispatchSetFrameTimelineInfo(args); break; case NATIVE_WINDOW_SET_BUFFERS_ADDITIONAL_OPTIONS: res = dispatchSetAdditionalOptions(args); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -1833,6 +1836,24 @@ int Surface::dispatchSetFrameTimelineInfo(va_list args) { return setFrameTimelineInfo(nativeWindowFtlInfo.frameNumber, ftlInfo); } int Surface::dispatchSetAdditionalOptions(va_list args) { ATRACE_CALL(); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) const AHardwareBufferLongOptions* opts = va_arg(args, const AHardwareBufferLongOptions*); const size_t optsSize = va_arg(args, size_t); std::vector<gui::AdditionalOptions> convertedOpts; convertedOpts.reserve(optsSize); for (size_t i = 0; i < optsSize; i++) { convertedOpts.emplace_back(opts[i].name, opts[i].value); } return setAdditionalOptions(convertedOpts); #else (void)args; return INVALID_OPERATION; #endif } bool Surface::transformToDisplayInverse() const { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; Loading Loading @@ -2619,6 +2640,17 @@ status_t Surface::setFrameTimelineInfo(uint64_t /*frameNumber*/, return BAD_VALUE; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) status_t Surface::setAdditionalOptions(const std::vector<gui::AdditionalOptions>& options) { if (!GraphicBufferAllocator::get().supportsAdditionalOptions()) { return INVALID_OPERATION; } Mutex::Autolock lock(mMutex); return mGraphicBufferProducer->setAdditionalOptions(options); } #endif sp<IBinder> Surface::getSurfaceControlHandle() const { Mutex::Autolock lock(mMutex); return mSurfaceControlHandle; Loading
libs/gui/SurfaceComposerClient.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -706,6 +706,7 @@ void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId) { SurfaceComposerClient::Transaction::Transaction() { mId = generateId(); mTransactionCompletedListener = TransactionCompletedListener::getInstance(); } SurfaceComposerClient::Transaction::Transaction(const Transaction& other) Loading @@ -723,6 +724,7 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mComposerStates = other.mComposerStates; mInputWindowCommands = other.mInputWindowCommands; mListenerCallbacks = other.mListenerCallbacks; mTransactionCompletedListener = TransactionCompletedListener::getInstance(); } void SurfaceComposerClient::Transaction::sanitize(int pid, int uid) { Loading Loading @@ -1000,8 +1002,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr // register all surface controls for all callbackIds for this listener that is merging for (const auto& surfaceControl : currentProcessCallbackInfo.surfaceControls) { TransactionCompletedListener::getInstance() ->addSurfaceControlToCallbacks(currentProcessCallbackInfo, surfaceControl); mTransactionCompletedListener->addSurfaceControlToCallbacks(currentProcessCallbackInfo, surfaceControl); } } Loading Loading @@ -1354,7 +1356,7 @@ void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()]; callbackInfo.surfaceControls.insert(sc); TransactionCompletedListener::getInstance()->addSurfaceControlToCallbacks(callbackInfo, sc); mTransactionCompletedListener->addSurfaceControlToCallbacks(callbackInfo, sc); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( Loading Loading @@ -1672,7 +1674,7 @@ std::shared_ptr<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffe std::shared_ptr<BufferData> bufferData = std::move(s->bufferData); TransactionCompletedListener::getInstance()->removeReleaseBufferCallback( mTransactionCompletedListener->removeReleaseBufferCallback( bufferData->generateReleaseCallbackId()); s->what &= ~layer_state_t::eBufferChanged; s->bufferData = nullptr; Loading Loading @@ -1715,8 +1717,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe bufferData->acquireFence = *fence; bufferData->flags |= BufferData::BufferDataChange::fenceChanged; } bufferData->releaseBufferEndpoint = IInterface::asBinder(TransactionCompletedListener::getIInstance()); bufferData->releaseBufferEndpoint = IInterface::asBinder(mTransactionCompletedListener); setReleaseBufferCallback(bufferData.get(), callback); } Loading Loading @@ -1774,9 +1775,10 @@ void SurfaceComposerClient::Transaction::setReleaseBufferCallback(BufferData* bu return; } bufferData->releaseBufferListener = TransactionCompletedListener::getIInstance(); auto listener = TransactionCompletedListener::getInstance(); listener->setReleaseBufferCallback(bufferData->generateReleaseCallbackId(), callback); bufferData->releaseBufferListener = static_cast<sp<ITransactionCompletedListener>>(mTransactionCompletedListener); mTransactionCompletedListener->setReleaseBufferCallback(bufferData->generateReleaseCallbackId(), callback); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDataspace( Loading Loading @@ -1932,18 +1934,15 @@ SurfaceComposerClient::Transaction::setFrameRateSelectionPriority(const sp<Surfa SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addTransactionCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext, CallbackId::Type callbackType) { auto listener = TransactionCompletedListener::getInstance(); auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); const auto& surfaceControls = mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls; const auto& surfaceControls = mListenerCallbacks[mTransactionCompletedListener].surfaceControls; CallbackId callbackId = listener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType); mTransactionCompletedListener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType); mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace( callbackId); mListenerCallbacks[mTransactionCompletedListener].callbackIds.emplace(callbackId); return *this; } Loading Loading @@ -2333,8 +2332,9 @@ SurfaceComposerClient::Transaction::setTrustedPresentationCallback( const sp<SurfaceControl>& sc, TrustedPresentationCallback cb, const TrustedPresentationThresholds& thresholds, void* context, sp<SurfaceComposerClient::PresentationCallbackRAII>& outCallbackRef) { auto listener = TransactionCompletedListener::getInstance(); outCallbackRef = listener->addTrustedPresentationCallback(cb, sc->getLayerId(), context); outCallbackRef = mTransactionCompletedListener->addTrustedPresentationCallback(cb, sc->getLayerId(), context); layer_state_t* s = getLayerState(sc); if (!s) { Loading @@ -2351,8 +2351,7 @@ SurfaceComposerClient::Transaction::setTrustedPresentationCallback( SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::clearTrustedPresentationCallback(const sp<SurfaceControl>& sc) { auto listener = TransactionCompletedListener::getInstance(); listener->clearTrustedPresentationCallback(sc->getLayerId()); mTransactionCompletedListener->clearTrustedPresentationCallback(sc->getLayerId()); layer_state_t* s = getLayerState(sc); if (!s) { Loading