From 9f034475d961892e4c10e6ff7ecee96e464be00c Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Wed, 28 Mar 2018 15:29:00 -0700 Subject: Add proper namespace to GraphicTypes. Renamed GraphicsTypes.h to GraphicTypes.h and added proper namespace to avoid naming conflict. BUG: 77156734 Test: Build and flash Change-Id: Ibd9f454b5b72d5f8c6d94a3869a60a1bf821f106 --- libs/gui/Surface.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 2e1c24b755..6a1aebd6d6 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -44,6 +44,8 @@ namespace android { +using ui::ColorMode; + Surface::Surface(const sp& bufferProducer, bool controlledByApp) : mGraphicBufferProducer(bufferProducer), mCrop(Rect::EMPTY_RECT), -- cgit v1.2.3-59-g8ed1b From 48a619f8332e06ea1cd96d82719cdf5e05c69630 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Tue, 5 Jun 2018 16:34:59 -0700 Subject: Replace NULL/0 with nullptr Fixes -Wzero-as-null-pointer-constant warning. clang-tidy -checks=modernize-use-nullptr -p compile_commands.json -fix ... Test: m Bug: 68236239 Change-Id: I3a8e982ba40f9b029bafef78437b146a878f56a9 --- libs/gui/BufferItem.cpp | 16 ++++++------ libs/gui/BufferItemConsumer.cpp | 2 +- libs/gui/BufferQueue.cpp | 32 +++++++++++------------ libs/gui/BufferQueueConsumer.cpp | 24 ++++++++--------- libs/gui/BufferQueueProducer.cpp | 52 ++++++++++++++++++------------------- libs/gui/ConsumerBase.cpp | 12 ++++----- libs/gui/DisplayEventReceiver.cpp | 12 ++++----- libs/gui/GLConsumer.cpp | 24 ++++++++--------- libs/gui/IGraphicBufferProducer.cpp | 18 ++++++------- libs/gui/StreamSplitter.cpp | 6 ++--- libs/gui/Surface.cpp | 36 ++++++++++++------------- libs/gui/SurfaceComposerClient.cpp | 18 ++++++------- libs/gui/SurfaceControl.cpp | 10 +++---- libs/gui/SyncFeatures.cpp | 2 +- 14 files changed, 132 insertions(+), 132 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp index f50379b3ed..5beba02e63 100644 --- a/libs/gui/BufferItem.cpp +++ b/libs/gui/BufferItem.cpp @@ -39,8 +39,8 @@ static inline constexpr T to64(const uint32_t lo, const uint32_t hi) { } BufferItem::BufferItem() : - mGraphicBuffer(NULL), - mFence(NULL), + mGraphicBuffer(nullptr), + mFence(nullptr), mCrop(Rect::INVALID_RECT), mTransform(0), mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), @@ -91,11 +91,11 @@ size_t BufferItem::getPodSize() const { size_t BufferItem::getFlattenedSize() const { size_t size = sizeof(uint32_t); // Flags - if (mGraphicBuffer != 0) { + if (mGraphicBuffer != nullptr) { size += mGraphicBuffer->getFlattenedSize(); size = FlattenableUtils::align<4>(size); } - if (mFence != 0) { + if (mFence != nullptr) { size += mFence->getFlattenedSize(); size = FlattenableUtils::align<4>(size); } @@ -107,10 +107,10 @@ size_t BufferItem::getFlattenedSize() const { size_t BufferItem::getFdCount() const { size_t count = 0; - if (mGraphicBuffer != 0) { + if (mGraphicBuffer != nullptr) { count += mGraphicBuffer->getFdCount(); } - if (mFence != 0) { + if (mFence != nullptr) { count += mFence->getFdCount(); } return count; @@ -137,13 +137,13 @@ status_t BufferItem::flatten( FlattenableUtils::advance(buffer, size, sizeof(uint32_t)); flags = 0; - if (mGraphicBuffer != 0) { + if (mGraphicBuffer != nullptr) { status_t err = mGraphicBuffer->flatten(buffer, size, fds, count); if (err) return err; size -= FlattenableUtils::align<4>(buffer); flags |= 1; } - if (mFence != 0) { + if (mFence != nullptr) { status_t err = mFence->flatten(buffer, size, fds, count); if (err) return err; size -= FlattenableUtils::align<4>(buffer); diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp index 89bc0c4c2d..f50bc203e8 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -107,7 +107,7 @@ status_t BufferItemConsumer::releaseBuffer(const BufferItem &item, void BufferItemConsumer::freeBufferLocked(int slotIndex) { sp listener = mBufferFreedListener.promote(); - if (listener != NULL && mSlots[slotIndex].mGraphicBuffer != NULL) { + if (listener != nullptr && mSlots[slotIndex].mGraphicBuffer != nullptr) { // Fire callback if we have a listener registered and the buffer being freed is valid. BI_LOGV("actually calling onBufferFreed"); listener->onBufferFreed(mSlots[slotIndex].mGraphicBuffer); diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index a8da1347cb..5fb3f0b80f 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -38,7 +38,7 @@ BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} void BufferQueue::ProxyConsumerListener::onDisconnect() { sp listener(mConsumerListener.promote()); - if (listener != NULL) { + if (listener != nullptr) { listener->onDisconnect(); } } @@ -46,7 +46,7 @@ void BufferQueue::ProxyConsumerListener::onDisconnect() { void BufferQueue::ProxyConsumerListener::onFrameAvailable( const BufferItem& item) { sp listener(mConsumerListener.promote()); - if (listener != NULL) { + if (listener != nullptr) { listener->onFrameAvailable(item); } } @@ -54,21 +54,21 @@ void BufferQueue::ProxyConsumerListener::onFrameAvailable( void BufferQueue::ProxyConsumerListener::onFrameReplaced( const BufferItem& item) { sp listener(mConsumerListener.promote()); - if (listener != NULL) { + if (listener != nullptr) { listener->onFrameReplaced(item); } } void BufferQueue::ProxyConsumerListener::onBuffersReleased() { sp listener(mConsumerListener.promote()); - if (listener != NULL) { + if (listener != nullptr) { listener->onBuffersReleased(); } } void BufferQueue::ProxyConsumerListener::onSidebandStreamChanged() { sp listener(mConsumerListener.promote()); - if (listener != NULL) { + if (listener != nullptr) { listener->onSidebandStreamChanged(); } } @@ -85,21 +85,21 @@ void BufferQueue::ProxyConsumerListener::addAndGetFrameTimestamps( void BufferQueue::createBufferQueue(sp* outProducer, sp* outConsumer, bool consumerIsSurfaceFlinger) { - LOG_ALWAYS_FATAL_IF(outProducer == NULL, + LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BufferQueue: outProducer must not be NULL"); - LOG_ALWAYS_FATAL_IF(outConsumer == NULL, + LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BufferQueue: outConsumer must not be NULL"); sp core(new BufferQueueCore()); - LOG_ALWAYS_FATAL_IF(core == NULL, + LOG_ALWAYS_FATAL_IF(core == nullptr, "BufferQueue: failed to create BufferQueueCore"); sp producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger)); - LOG_ALWAYS_FATAL_IF(producer == NULL, + LOG_ALWAYS_FATAL_IF(producer == nullptr, "BufferQueue: failed to create BufferQueueProducer"); sp consumer(new BufferQueueConsumer(core)); - LOG_ALWAYS_FATAL_IF(consumer == NULL, + LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BufferQueue: failed to create BufferQueueConsumer"); *outProducer = producer; @@ -109,8 +109,8 @@ void BufferQueue::createBufferQueue(sp* outProducer, #ifndef NO_BUFFERHUB void BufferQueue::createBufferHubQueue(sp* outProducer, sp* outConsumer) { - LOG_ALWAYS_FATAL_IF(outProducer == NULL, "BufferQueue: outProducer must not be NULL"); - LOG_ALWAYS_FATAL_IF(outConsumer == NULL, "BufferQueue: outConsumer must not be NULL"); + LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BufferQueue: outProducer must not be NULL"); + LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BufferQueue: outConsumer must not be NULL"); sp producer; sp consumer; @@ -118,16 +118,16 @@ void BufferQueue::createBufferHubQueue(sp* outProducer, dvr::ProducerQueueConfigBuilder configBuilder; std::shared_ptr producerQueue = dvr::ProducerQueue::Create(configBuilder.Build(), dvr::UsagePolicy{}); - LOG_ALWAYS_FATAL_IF(producerQueue == NULL, "BufferQueue: failed to create ProducerQueue."); + LOG_ALWAYS_FATAL_IF(producerQueue == nullptr, "BufferQueue: failed to create ProducerQueue."); std::shared_ptr consumerQueue = producerQueue->CreateConsumerQueue(); - LOG_ALWAYS_FATAL_IF(consumerQueue == NULL, "BufferQueue: failed to create ConsumerQueue."); + LOG_ALWAYS_FATAL_IF(consumerQueue == nullptr, "BufferQueue: failed to create ConsumerQueue."); producer = BufferHubProducer::Create(producerQueue); consumer = BufferHubConsumer::Create(consumerQueue); - LOG_ALWAYS_FATAL_IF(producer == NULL, "BufferQueue: failed to create BufferQueueProducer"); - LOG_ALWAYS_FATAL_IF(consumer == NULL, "BufferQueue: failed to create BufferQueueConsumer"); + LOG_ALWAYS_FATAL_IF(producer == nullptr, "BufferQueue: failed to create BufferQueueProducer"); + LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BufferQueue: failed to create BufferQueueConsumer"); *outProducer = producer; *outConsumer = consumer; diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index d70e1422b0..3837c3e11a 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -255,7 +255,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer // on the consumer side if (outBuffer->mAcquireCalled) { - outBuffer->mGraphicBuffer = NULL; + outBuffer->mGraphicBuffer = nullptr; } mCore->mQueue.erase(front); @@ -272,7 +272,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, VALIDATE_CONSISTENCY(); } - if (listener != NULL) { + if (listener != nullptr) { for (int i = 0; i < numDroppedBuffers; ++i) { listener->onBufferReleased(); } @@ -321,10 +321,10 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, const sp& buffer) { ATRACE_CALL(); - if (outSlot == NULL) { + if (outSlot == nullptr) { BQ_LOGE("attachBuffer: outSlot must not be NULL"); return BAD_VALUE; - } else if (buffer == NULL) { + } else if (buffer == nullptr) { BQ_LOGE("attachBuffer: cannot attach NULL buffer"); return BAD_VALUE; } @@ -413,7 +413,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, ATRACE_BUFFER_INDEX(slot); if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || - releaseFence == NULL) { + releaseFence == nullptr) { BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, releaseFence.get()); return BAD_VALUE; @@ -465,7 +465,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, } // Autolock scope // Call back without lock held - if (listener != NULL) { + if (listener != nullptr) { listener->onBufferReleased(); } @@ -476,7 +476,7 @@ status_t BufferQueueConsumer::connect( const sp& consumerListener, bool controlledByApp) { ATRACE_CALL(); - if (consumerListener == NULL) { + if (consumerListener == nullptr) { BQ_LOGE("connect: consumerListener may not be NULL"); return BAD_VALUE; } @@ -504,13 +504,13 @@ status_t BufferQueueConsumer::disconnect() { Mutex::Autolock lock(mCore->mMutex); - if (mCore->mConsumerListener == NULL) { + if (mCore->mConsumerListener == nullptr) { BQ_LOGE("disconnect: no consumer is connected"); return BAD_VALUE; } mCore->mIsAbandoned = true; - mCore->mConsumerListener = NULL; + mCore->mConsumerListener = nullptr; mCore->mQueue.clear(); mCore->freeAllBuffersLocked(); mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; @@ -521,7 +521,7 @@ status_t BufferQueueConsumer::disconnect() { status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { ATRACE_CALL(); - if (outSlotMask == NULL) { + if (outSlotMask == nullptr) { BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL"); return BAD_VALUE; } @@ -673,7 +673,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( } } // Call back without lock held - if (listener != NULL) { + if (listener != nullptr) { listener->onBuffersReleased(); } @@ -772,7 +772,7 @@ status_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResul if (uid != shellUid) { #endif android_errorWriteWithInfoLog(0x534e4554, "27046057", - static_cast(uid), NULL, 0); + static_cast(uid), nullptr, 0); return PERMISSION_DENIED; } diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index c8021e4d54..ce3a90a483 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -166,7 +166,7 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( } // Autolock scope // Call back without lock held - if (listener != NULL) { + if (listener != nullptr) { listener->onBuffersReleased(); } @@ -221,7 +221,7 @@ status_t BufferQueueProducer::setAsyncMode(bool async) { } // Autolock scope // Call back without lock held - if (listener != NULL) { + if (listener != nullptr) { listener->onBuffersReleased(); } return NO_ERROR; @@ -450,11 +450,11 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp* ou mSlots[found].mBufferState.dequeue(); - if ((buffer == NULL) || + if ((buffer == nullptr) || buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage)) { mSlots[found].mAcquireCalled = false; - mSlots[found].mGraphicBuffer = NULL; + mSlots[found].mGraphicBuffer = nullptr; mSlots[found].mRequestBufferCalled = false; mSlots[found].mEglDisplay = EGL_NO_DISPLAY; mSlots[found].mEglFence = EGL_NO_SYNC_KHR; @@ -472,7 +472,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp* ou BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64, mCore->mBufferAge); - if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { + if (CC_UNLIKELY(mSlots[found].mFence == nullptr)) { BQ_LOGE("dequeueBuffer: about to return a NULL fence - " "slot=%d w=%d h=%d format=%u", found, buffer->width, buffer->height, buffer->format); @@ -613,7 +613,7 @@ status_t BufferQueueProducer::detachBuffer(int slot) { listener = mCore->mConsumerListener; } - if (listener != NULL) { + if (listener != nullptr) { listener->onBuffersReleased(); } @@ -624,10 +624,10 @@ status_t BufferQueueProducer::detachNextBuffer(sp* outBuffer, sp* outFence) { ATRACE_CALL(); - if (outBuffer == NULL) { + if (outBuffer == nullptr) { BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); return BAD_VALUE; - } else if (outFence == NULL) { + } else if (outFence == nullptr) { BQ_LOGE("detachNextBuffer: outFence must not be NULL"); return BAD_VALUE; } @@ -671,7 +671,7 @@ status_t BufferQueueProducer::detachNextBuffer(sp* outBuffer, listener = mCore->mConsumerListener; } - if (listener != NULL) { + if (listener != nullptr) { listener->onBuffersReleased(); } @@ -682,10 +682,10 @@ status_t BufferQueueProducer::attachBuffer(int* outSlot, const sp& buffer) { ATRACE_CALL(); - if (outSlot == NULL) { + if (outSlot == nullptr) { BQ_LOGE("attachBuffer: outSlot must not be NULL"); return BAD_VALUE; - } else if (buffer == NULL) { + } else if (buffer == nullptr) { BQ_LOGE("attachBuffer: cannot attach NULL buffer"); return BAD_VALUE; } @@ -767,7 +767,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, const Region& surfaceDamage = input.getSurfaceDamage(); const HdrMetadata& hdrMetadata = input.getHdrMetadata(); - if (acquireFence == NULL) { + if (acquireFence == nullptr) { BQ_LOGE("queueBuffer: fence is NULL"); return BAD_VALUE; } @@ -973,9 +973,9 @@ status_t BufferQueueProducer::queueBuffer(int slot, mCallbackCondition.wait(mCallbackMutex); } - if (frameAvailableListener != NULL) { + if (frameAvailableListener != nullptr) { frameAvailableListener->onFrameAvailable(item); - } else if (frameReplacedListener != NULL) { + } else if (frameReplacedListener != nullptr) { frameReplacedListener->onFrameReplaced(item); } @@ -1040,7 +1040,7 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp& fence) { BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " "(state = %s)", slot, mSlots[slot].mBufferState.string()); return BAD_VALUE; - } else if (fence == NULL) { + } else if (fence == nullptr) { BQ_LOGE("cancelBuffer: fence is NULL"); return BAD_VALUE; } @@ -1070,7 +1070,7 @@ int BufferQueueProducer::query(int what, int *outValue) { ATRACE_CALL(); Mutex::Autolock lock(mCore->mMutex); - if (outValue == NULL) { + if (outValue == nullptr) { BQ_LOGE("query: outValue was NULL"); return BAD_VALUE; } @@ -1146,12 +1146,12 @@ status_t BufferQueueProducer::connect(const sp& listener, return NO_INIT; } - if (mCore->mConsumerListener == NULL) { + if (mCore->mConsumerListener == nullptr) { BQ_LOGE("connect: BufferQueue has no consumer"); return NO_INIT; } - if (output == NULL) { + if (output == nullptr) { BQ_LOGE("connect: output was NULL"); return BAD_VALUE; } @@ -1189,10 +1189,10 @@ status_t BufferQueueProducer::connect(const sp& listener, output->nextFrameNumber = mCore->mFrameCounter + 1; output->bufferReplaced = false; - if (listener != NULL) { + if (listener != nullptr) { // Set up a death notification so that we can disconnect // automatically if the remote producer dies - if (IInterface::asBinder(listener)->remoteBinder() != NULL) { + if (IInterface::asBinder(listener)->remoteBinder() != nullptr) { status = IInterface::asBinder(listener)->linkToDeath( static_cast(this)); if (status != NO_ERROR) { @@ -1269,7 +1269,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { mCore->freeAllBuffersLocked(); // Remove our death notification callback if we have one - if (mCore->mLinkedToDeath != NULL) { + if (mCore->mLinkedToDeath != nullptr) { sp token = IInterface::asBinder(mCore->mLinkedToDeath); // This can fail if we're here because of the death @@ -1279,8 +1279,8 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { } mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; - mCore->mLinkedToDeath = NULL; - mCore->mConnectedProducerListener = NULL; + mCore->mLinkedToDeath = nullptr; + mCore->mConnectedProducerListener = nullptr; mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; mCore->mConnectedPid = -1; mCore->mSidebandStream.clear(); @@ -1303,7 +1303,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { } // Autolock scope // Call back without lock held - if (listener != NULL) { + if (listener != nullptr) { listener->onBuffersReleased(); listener->onDisconnect(); } @@ -1319,7 +1319,7 @@ status_t BufferQueueProducer::setSidebandStream(const sp& stream) listener = mCore->mConsumerListener; } // Autolock scope - if (listener != NULL) { + if (listener != nullptr) { listener->onSidebandStreamChanged(); } return NO_ERROR; @@ -1535,7 +1535,7 @@ void BufferQueueProducer::addAndGetFrameTimestamps( Mutex::Autolock lock(mCore->mMutex); listener = mCore->mConsumerListener; } - if (listener != NULL) { + if (listener != nullptr) { listener->addAndGetFrameTimestamps(newTimestamps, outDelta); } } diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index f9e292e199..abd9921fa9 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -96,7 +96,7 @@ void ConsumerBase::onLastStrongRef(const void* id __attribute__((unused))) { void ConsumerBase::freeBufferLocked(int slotIndex) { CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); - mSlots[slotIndex].mGraphicBuffer = 0; + mSlots[slotIndex].mGraphicBuffer = nullptr; mSlots[slotIndex].mFence = Fence::NO_FENCE; mSlots[slotIndex].mFrameNumber = 0; } @@ -110,7 +110,7 @@ void ConsumerBase::onFrameAvailable(const BufferItem& item) { listener = mFrameAvailableListener.promote(); } - if (listener != NULL) { + if (listener != nullptr) { CB_LOGV("actually calling onFrameAvailable"); listener->onFrameAvailable(item); } @@ -125,7 +125,7 @@ void ConsumerBase::onFrameReplaced(const BufferItem &item) { listener = mFrameAvailableListener.promote(); } - if (listener != NULL) { + if (listener != nullptr) { CB_LOGV("actually calling onFrameReplaced"); listener->onFrameReplaced(item); } @@ -352,8 +352,8 @@ status_t ConsumerBase::acquireBufferLocked(BufferItem *item, return err; } - if (item->mGraphicBuffer != NULL) { - if (mSlots[item->mSlot].mGraphicBuffer != NULL) { + if (item->mGraphicBuffer != nullptr) { + if (mSlots[item->mSlot].mGraphicBuffer != nullptr) { freeBufferLocked(item->mSlot); } mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer; @@ -468,7 +468,7 @@ bool ConsumerBase::stillTracking(int slot, if (slot < 0 || slot >= BufferQueue::NUM_BUFFER_SLOTS) { return false; } - return (mSlots[slot].mGraphicBuffer != NULL && + return (mSlots[slot].mGraphicBuffer != nullptr && mSlots[slot].mGraphicBuffer->handle == graphicBuffer->handle); } diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp index 1757ec1cd3..f5cf1c4d5a 100644 --- a/libs/gui/DisplayEventReceiver.cpp +++ b/libs/gui/DisplayEventReceiver.cpp @@ -34,9 +34,9 @@ namespace android { DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) { sp sf(ComposerService::getComposerService()); - if (sf != NULL) { + if (sf != nullptr) { mEventConnection = sf->createDisplayEventConnection(vsyncSource); - if (mEventConnection != NULL) { + if (mEventConnection != nullptr) { mDataChannel = std::make_unique(); mEventConnection->stealReceiveChannel(mDataChannel.get()); } @@ -47,13 +47,13 @@ DisplayEventReceiver::~DisplayEventReceiver() { } status_t DisplayEventReceiver::initCheck() const { - if (mDataChannel != NULL) + if (mDataChannel != nullptr) return NO_ERROR; return NO_INIT; } int DisplayEventReceiver::getFd() const { - if (mDataChannel == NULL) + if (mDataChannel == nullptr) return NO_INIT; return mDataChannel->getFd(); @@ -63,7 +63,7 @@ status_t DisplayEventReceiver::setVsyncRate(uint32_t count) { if (int32_t(count) < 0) return BAD_VALUE; - if (mEventConnection != NULL) { + if (mEventConnection != nullptr) { mEventConnection->setVsyncRate(count); return NO_ERROR; } @@ -71,7 +71,7 @@ status_t DisplayEventReceiver::setVsyncRate(uint32_t count) { } status_t DisplayEventReceiver::requestNextVsync() { - if (mEventConnection != NULL) { + if (mEventConnection != nullptr) { mEventConnection->requestNextVsync(); return NO_ERROR; } diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 885efec9b9..8efbef5404 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -291,7 +291,7 @@ status_t GLConsumer::releaseTexImage() { return err; } - if (mReleasedTexImage == NULL) { + if (mReleasedTexImage == nullptr) { mReleasedTexImage = new EglImage(getDebugTexImageBuffer()); } @@ -321,7 +321,7 @@ status_t GLConsumer::releaseTexImage() { sp GLConsumer::getDebugTexImageBuffer() { Mutex::Autolock _l(sStaticInitLock); - if (CC_UNLIKELY(sReleasedTexImageBuffer == NULL)) { + if (CC_UNLIKELY(sReleasedTexImageBuffer == nullptr)) { // The first time, create the debug texture in case the application // continues to use it. sp buffer = new GraphicBuffer( @@ -357,7 +357,7 @@ status_t GLConsumer::acquireBufferLocked(BufferItem *item, // If item->mGraphicBuffer is not null, this buffer has not been acquired // before, so any prior EglImage created is using a stale buffer. This // replaces any old EglImage with a new one (using the new buffer). - if (item->mGraphicBuffer != NULL) { + if (item->mGraphicBuffer != nullptr) { int slot = item->mSlot; mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer); } @@ -431,7 +431,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, mCurrentTextureImage != NULL ? - mCurrentTextureImage->graphicBufferHandle() : 0, + mCurrentTextureImage->graphicBufferHandle() : nullptr, slot, mSlots[slot].mGraphicBuffer->handle); // Hang onto the pointer so that it isn't freed in the call to @@ -491,7 +491,7 @@ status_t GLConsumer::bindTextureImageLocked() { glBindTexture(mTexTarget, mTexName); if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && - mCurrentTextureImage == NULL) { + mCurrentTextureImage == nullptr) { GLC_LOGE("bindTextureImage: no currently-bound texture"); return NO_INIT; } @@ -655,7 +655,7 @@ status_t GLConsumer::attachToContext(uint32_t tex) { mTexName = tex; mAttached = true; - if (mCurrentTextureImage != NULL) { + if (mCurrentTextureImage != nullptr) { // This may wait for a buffer a second time. This is likely required if // this is a different context, since otherwise the wait could be skipped // by bouncing through another context. For the same context the extra @@ -676,7 +676,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (SyncFeatures::getInstance().useNativeFenceSync()) { EGLSyncKHR sync = eglCreateSyncKHR(dpy, - EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); + EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); if (sync == EGL_NO_SYNC_KHR) { GLC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", eglGetError()); @@ -720,7 +720,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { // Create a fence for the outstanding accesses in the current // OpenGL ES context. - fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); + fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr); if (fence == EGL_NO_SYNC_KHR) { GLC_LOGE("syncForReleaseLocked: error creating fence: %#x", eglGetError()); @@ -752,11 +752,11 @@ void GLConsumer::setFilteringEnabled(bool enabled) { bool needsRecompute = mFilteringEnabled != enabled; mFilteringEnabled = enabled; - if (needsRecompute && mCurrentTextureImage==NULL) { + if (needsRecompute && mCurrentTextureImage==nullptr) { GLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL"); } - if (needsRecompute && mCurrentTextureImage != NULL) { + if (needsRecompute && mCurrentTextureImage != nullptr) { computeCurrentTransformMatrixLocked(); } } @@ -938,7 +938,7 @@ sp GLConsumer::getCurrentBuffer(int* outSlot) const { } return (mCurrentTextureImage == nullptr) ? - NULL : mCurrentTextureImage->graphicBuffer(); + nullptr : mCurrentTextureImage->graphicBuffer(); } Rect GLConsumer::getCurrentCrop() const { @@ -1150,7 +1150,7 @@ EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy, attrs[3] = attrs[11]; attrs[4] = EGL_NONE; } - eglInitialize(dpy, 0, 0); + eglInitialize(dpy, nullptr, nullptr); EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); if (image == EGL_NO_IMAGE_KHR) { diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 0749fde1ad..3693d2cb21 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -190,10 +190,10 @@ public: virtual status_t detachNextBuffer(sp* outBuffer, sp* outFence) { - if (outBuffer == NULL) { + if (outBuffer == nullptr) { ALOGE("detachNextBuffer: outBuffer must not be NULL"); return BAD_VALUE; - } else if (outFence == NULL) { + } else if (outFence == nullptr) { ALOGE("detachNextBuffer: outFence must not be NULL"); return BAD_VALUE; } @@ -301,7 +301,7 @@ public: int api, bool producerControlledByApp, QueueBufferOutput* output) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); - if (listener != NULL) { + if (listener != nullptr) { data.writeInt32(1); data.writeStrongBinder(IInterface::asBinder(listener)); } else { @@ -738,8 +738,8 @@ status_t BnGraphicBufferProducer::onTransact( int bufferIdx = data.readInt32(); sp buffer; int result = requestBuffer(bufferIdx, &buffer); - reply->writeInt32(buffer != 0); - if (buffer != 0) { + reply->writeInt32(buffer != nullptr); + if (buffer != nullptr) { reply->write(*buffer); } reply->writeInt32(result); @@ -797,12 +797,12 @@ status_t BnGraphicBufferProducer::onTransact( int32_t result = detachNextBuffer(&buffer, &fence); reply->writeInt32(result); if (result == NO_ERROR) { - reply->writeInt32(buffer != NULL); - if (buffer != NULL) { + reply->writeInt32(buffer != nullptr); + if (buffer != nullptr) { reply->write(*buffer); } - reply->writeInt32(fence != NULL); - if (fence != NULL) { + reply->writeInt32(fence != nullptr); + if (fence != nullptr) { reply->write(*fence); } } diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp index 52c906775e..2f8e104ea0 100644 --- a/libs/gui/StreamSplitter.cpp +++ b/libs/gui/StreamSplitter.cpp @@ -38,11 +38,11 @@ namespace android { status_t StreamSplitter::createSplitter( const sp& inputQueue, sp* outSplitter) { - if (inputQueue == NULL) { + if (inputQueue == nullptr) { ALOGE("createSplitter: inputQueue must not be NULL"); return BAD_VALUE; } - if (outSplitter == NULL) { + if (outSplitter == nullptr) { ALOGE("createSplitter: outSplitter must not be NULL"); return BAD_VALUE; } @@ -74,7 +74,7 @@ StreamSplitter::~StreamSplitter() { status_t StreamSplitter::addOutput( const sp& outputQueue) { - if (outputQueue == NULL) { + if (outputQueue == nullptr) { ALOGE("addOutput: outputQueue must not be NULL"); return BAD_VALUE; } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 339bd0fa4e..7bddaaf3b6 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -156,7 +156,7 @@ status_t Surface::getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration) { ATRACE_CALL(); DisplayStatInfo stats; - status_t result = composerService()->getDisplayStats(NULL, &stats); + status_t result = composerService()->getDisplayStats(nullptr, &stats); if (result != NO_ERROR) { return result; } @@ -497,7 +497,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot != BufferItem::INVALID_BUFFER_SLOT) { sp& gbuf(mSlots[mSharedBufferSlot].buffer); - if (gbuf != NULL) { + if (gbuf != nullptr) { *buffer = gbuf.get(); *fenceFd = -1; return OK; @@ -537,7 +537,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { sp& gbuf(mSlots[buf].buffer); // this should never happen - ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); + ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { freeAllBuffers(); @@ -615,7 +615,7 @@ int Surface::cancelBuffer(android_native_buffer_t* buffer, int Surface::getSlotFromBufferLocked( android_native_buffer_t* buffer) const { for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { - if (mSlots[i].buffer != NULL && + if (mSlots[i].buffer != nullptr && mSlots[i].buffer->handle == buffer->handle) { return i; } @@ -1264,7 +1264,7 @@ int Surface::detachNextBuffer(sp* outBuffer, ATRACE_CALL(); ALOGV("Surface::detachNextBuffer"); - if (outBuffer == NULL || outFence == NULL) { + if (outBuffer == nullptr || outFence == nullptr) { return BAD_VALUE; } @@ -1273,8 +1273,8 @@ int Surface::detachNextBuffer(sp* outBuffer, mRemovedBuffers.clear(); } - sp buffer(NULL); - sp fence(NULL); + sp buffer(nullptr); + sp fence(nullptr); status_t result = mGraphicBufferProducer->detachNextBuffer( &buffer, &fence); if (result != NO_ERROR) { @@ -1282,19 +1282,19 @@ int Surface::detachNextBuffer(sp* outBuffer, } *outBuffer = buffer; - if (fence != NULL && fence->isValid()) { + if (fence != nullptr && fence->isValid()) { *outFence = fence; } else { *outFence = Fence::NO_FENCE; } for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { - if (mSlots[i].buffer != NULL && + if (mSlots[i].buffer != nullptr && mSlots[i].buffer->getId() == buffer->getId()) { if (mReportRemovedBuffers) { mRemovedBuffers.push_back(mSlots[i].buffer); } - mSlots[i].buffer = NULL; + mSlots[i].buffer = nullptr; } } @@ -1345,7 +1345,7 @@ int Surface::setCrop(Rect const* rect) ATRACE_CALL(); Rect realRect(Rect::EMPTY_RECT); - if (rect == NULL || rect->isEmpty()) { + if (rect == nullptr || rect->isEmpty()) { realRect.clear(); } else { realRect = *rect; @@ -1572,7 +1572,7 @@ Dataspace Surface::getBuffersDataSpace() { void Surface::freeAllBuffers() { for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { - mSlots[i].buffer = 0; + mSlots[i].buffer = nullptr; } } @@ -1612,12 +1612,12 @@ static status_t copyBlt( // src and dst with, height and format must be identical. no verification // is done here. status_t err; - uint8_t* src_bits = NULL; + uint8_t* src_bits = nullptr; err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), reinterpret_cast(&src_bits)); ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); - uint8_t* dst_bits = NULL; + uint8_t* dst_bits = nullptr; err = dst->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), reinterpret_cast(&dst_bits), *dstFenceFd); ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); @@ -1665,7 +1665,7 @@ static status_t copyBlt( status_t Surface::lock( ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) { - if (mLockedBuffer != 0) { + if (mLockedBuffer != nullptr) { ALOGE("Surface::lock failed, already locked"); return INVALID_OPERATION; } @@ -1697,7 +1697,7 @@ status_t Surface::lock( // figure out if we can copy the frontbuffer back const sp& frontBuffer(mPostedBuffer); - const bool canCopyBack = (frontBuffer != 0 && + const bool canCopyBack = (frontBuffer != nullptr && backBuffer->width == frontBuffer->width && backBuffer->height == frontBuffer->height && backBuffer->format == frontBuffer->format); @@ -1759,7 +1759,7 @@ status_t Surface::lock( status_t Surface::unlockAndPost() { - if (mLockedBuffer == 0) { + if (mLockedBuffer == nullptr) { ALOGE("Surface::unlockAndPost failed, no locked buffer"); return INVALID_OPERATION; } @@ -1773,7 +1773,7 @@ status_t Surface::unlockAndPost() mLockedBuffer->handle, strerror(-err)); mPostedBuffer = mLockedBuffer; - mLockedBuffer = 0; + mLockedBuffer = nullptr; return err; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 63560c4b89..d2b472b52f 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -81,7 +81,7 @@ void ComposerService::connectLocked() { /*static*/ sp ComposerService::getComposerService() { ComposerService& instance = ComposerService::getInstance(); Mutex::Autolock _l(instance.mLock); - if (instance.mComposerService == NULL) { + if (instance.mComposerService == nullptr) { ComposerService::getInstance().connectLocked(); assert(instance.mComposerService != NULL); ALOGD("ComposerService reconnected"); @@ -92,8 +92,8 @@ void ComposerService::connectLocked() { void ComposerService::composerServiceDied() { Mutex::Autolock _l(mLock); - mComposerService = NULL; - mDeathObserver = NULL; + mComposerService = nullptr; + mDeathObserver = nullptr; } // --------------------------------------------------------------------------- @@ -571,12 +571,12 @@ SurfaceComposerClient::SurfaceComposerClient(const sp& c void SurfaceComposerClient::onFirstRef() { sp sf(ComposerService::getComposerService()); - if (sf != 0 && mStatus == NO_INIT) { + if (sf != nullptr && mStatus == NO_INIT) { auto rootProducer = mParent.promote(); sp conn; conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) : sf->createConnection(); - if (conn != 0) { + if (conn != nullptr) { mClient = conn; mStatus = NO_ERROR; } @@ -606,7 +606,7 @@ void SurfaceComposerClient::dispose() { // this can be called more than once. sp client; Mutex::Autolock _lm(mLock); - if (mClient != 0) { + if (mClient != nullptr) { client = mClient; // hold ref while lock is held mClient.clear(); } @@ -766,7 +766,7 @@ status_t ScreenshotClient::capture(const sp& display, Rect sourceCrop, bool useIdentityTransform, uint32_t rotation, sp* outBuffer) { sp s(ComposerService::getComposerService()); - if (s == NULL) return NO_INIT; + if (s == nullptr) return NO_INIT; status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, static_cast(rotation)); @@ -779,7 +779,7 @@ status_t ScreenshotClient::capture(const sp& display, Rect sourceCrop, status_t ScreenshotClient::captureLayers(const sp& layerHandle, Rect sourceCrop, float frameScale, sp* outBuffer) { sp s(ComposerService::getComposerService()); - if (s == NULL) return NO_INIT; + if (s == nullptr) return NO_INIT; status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale, false /* childrenOnly */); return ret; @@ -788,7 +788,7 @@ status_t ScreenshotClient::captureLayers(const sp& layerHandle, Rect so status_t ScreenshotClient::captureChildLayers(const sp& layerHandle, Rect sourceCrop, float frameScale, sp* outBuffer) { sp s(ComposerService::getComposerService()); - if (s == NULL) return NO_INIT; + if (s == nullptr) return NO_INIT; status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale, true /* childrenOnly */); return ret; diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 5eafbb3555..19ad31b8c7 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -86,7 +86,7 @@ void SurfaceControl::clear() } void SurfaceControl::disconnect() { - if (mGraphicBufferProducer != NULL) { + if (mGraphicBufferProducer != nullptr) { mGraphicBufferProducer->disconnect( BufferQueueCore::CURRENTLY_CONNECTED_API); } @@ -95,7 +95,7 @@ void SurfaceControl::disconnect() { bool SurfaceControl::isSameSurface( const sp& lhs, const sp& rhs) { - if (lhs == 0 || rhs == 0) + if (lhs == nullptr || rhs == nullptr) return false; return lhs->mHandle == rhs->mHandle; } @@ -116,7 +116,7 @@ status_t SurfaceControl::getLayerFrameStats(FrameStats* outStats) const { status_t SurfaceControl::validate() const { - if (mHandle==0 || mClient==0) { + if (mHandle==nullptr || mClient==nullptr) { ALOGE("invalid handle (%p) or client (%p)", mHandle.get(), mClient.get()); return NO_INIT; @@ -128,7 +128,7 @@ status_t SurfaceControl::writeSurfaceToParcel( const sp& control, Parcel* parcel) { sp bp; - if (control != NULL) { + if (control != nullptr) { bp = control->mGraphicBufferProducer; } return parcel->writeStrongBinder(IInterface::asBinder(bp)); @@ -146,7 +146,7 @@ sp SurfaceControl::generateSurfaceLocked() const sp SurfaceControl::getSurface() const { Mutex::Autolock _l(mLock); - if (mSurfaceData == 0) { + if (mSurfaceData == nullptr) { return generateSurfaceLocked(); } return mSurfaceData; diff --git a/libs/gui/SyncFeatures.cpp b/libs/gui/SyncFeatures.cpp index afa15c5cda..fcae05c8ad 100644 --- a/libs/gui/SyncFeatures.cpp +++ b/libs/gui/SyncFeatures.cpp @@ -41,7 +41,7 @@ SyncFeatures::SyncFeatures() : Singleton(), // This can only be called after EGL has been initialized; otherwise the // check below will abort. const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS); - LOG_ALWAYS_FATAL_IF(exts == NULL, "eglQueryStringImplementationANDROID failed"); + LOG_ALWAYS_FATAL_IF(exts == nullptr, "eglQueryStringImplementationANDROID failed"); if (strstr(exts, "EGL_ANDROID_native_fence_sync")) { // This makes GLConsumer use the EGL_ANDROID_native_fence_sync // extension to create Android native fences to signal when all -- cgit v1.2.3-59-g8ed1b From a82679d85492b4bcab53484d684e444fa2311769 Mon Sep 17 00:00:00 2001 From: Valerie Hau Date: Wed, 21 Nov 2018 09:31:43 -0800 Subject: Adding HDR10+ metadata support for media API Bug: 118343714 Test: build, boot, run libgui_test Change-Id: Ifa5ccb31083d920f1162ea892de0be047f5b88a1 --- libs/gui/HdrMetadata.cpp | 31 +++++++++++++++++++++++++++++++ libs/gui/Surface.cpp | 22 ++++++++++++++++++++++ libs/gui/include/gui/HdrMetadata.h | 6 +++++- libs/gui/include/gui/Surface.h | 2 ++ libs/gui/tests/Surface_test.cpp | 7 +++++++ libs/nativewindow/include/system/window.h | 26 ++++++++++++++++++++++++-- 6 files changed, 91 insertions(+), 3 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/HdrMetadata.cpp b/libs/gui/HdrMetadata.cpp index b715e431d5..add3ef0458 100644 --- a/libs/gui/HdrMetadata.cpp +++ b/libs/gui/HdrMetadata.cpp @@ -15,6 +15,7 @@ */ #include +#include namespace android { @@ -26,6 +27,10 @@ size_t HdrMetadata::getFlattenedSize() const { if (validTypes & CTA861_3) { size += sizeof(cta8613); } + if (validTypes & HDR10PLUS) { + size += sizeof(size_t); + size += hdr10plus.size(); + } return size; } @@ -41,6 +46,12 @@ status_t HdrMetadata::flatten(void* buffer, size_t size) const { if (validTypes & CTA861_3) { FlattenableUtils::write(buffer, size, cta8613); } + if (validTypes & HDR10PLUS) { + size_t metadataSize = hdr10plus.size(); + FlattenableUtils::write(buffer, size, metadataSize); + memcpy(buffer, hdr10plus.data(), metadataSize); + FlattenableUtils::advance(buffer, size, metadataSize); + } return NO_ERROR; } @@ -62,6 +73,22 @@ status_t HdrMetadata::unflatten(void const* buffer, size_t size) { } FlattenableUtils::read(buffer, size, cta8613); } + if (validTypes & HDR10PLUS) { + if (size < sizeof(size_t)) { + return NO_MEMORY; + } + + size_t metadataSize; + FlattenableUtils::read(buffer, size, metadataSize); + + if (size < metadataSize) { + return NO_MEMORY; + } + + hdr10plus.resize(metadataSize); + memcpy(hdr10plus.data(), buffer, metadataSize); + FlattenableUtils::advance(buffer, size, metadataSize); + } return NO_ERROR; } @@ -91,6 +118,10 @@ bool HdrMetadata::operator==(const HdrMetadata& rhs) const { } } + if ((validTypes & HDR10PLUS) == HDR10PLUS) { + if (hdr10plus != rhs.hdr10plus) return false; + } + return true; } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index b505c6fa23..00e23f0df1 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -965,6 +965,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA: res = dispatchSetBuffersCta8613Metadata(args); break; + case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA: + res = dispatchSetBuffersHdr10PlusMetadata(args); + break; case NATIVE_WINDOW_SET_SURFACE_DAMAGE: res = dispatchSetSurfaceDamage(args); break; @@ -1120,6 +1123,12 @@ int Surface::dispatchSetBuffersCta8613Metadata(va_list args) { return setBuffersCta8613Metadata(metadata); } +int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) { + const size_t size = va_arg(args, size_t); + const uint8_t* metadata = va_arg(args, const uint8_t*); + return setBuffersHdr10PlusMetadata(size, metadata); +} + int Surface::dispatchSetSurfaceDamage(va_list args) { android_native_rect_t* rects = va_arg(args, android_native_rect_t*); size_t numRects = va_arg(args, size_t); @@ -1568,6 +1577,19 @@ int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata return NO_ERROR; } +int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) { + ALOGV("Surface::setBuffersBlobMetadata"); + Mutex::Autolock lock(mMutex); + if (size > 0) { + mHdrMetadata.hdr10plus.assign(metadata, metadata + size); + mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS; + } else { + mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS; + mHdrMetadata.hdr10plus.clear(); + } + return NO_ERROR; +} + Dataspace Surface::getBuffersDataSpace() { ALOGV("Surface::getBuffersDataSpace"); Mutex::Autolock lock(mMutex); diff --git a/libs/gui/include/gui/HdrMetadata.h b/libs/gui/include/gui/HdrMetadata.h index 9800602d6c..1e9c3e7102 100644 --- a/libs/gui/include/gui/HdrMetadata.h +++ b/libs/gui/include/gui/HdrMetadata.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include @@ -26,12 +27,15 @@ namespace android { struct HdrMetadata : public LightFlattenable { enum Type : uint32_t { SMPTE2086 = 1 << 0, - CTA861_3 = 1 << 1, + CTA861_3 = 1 << 1, + HDR10PLUS = 1 << 2, }; + uint32_t validTypes{0}; android_smpte2086_metadata smpte2086{}; android_cta861_3_metadata cta8613{}; + std::vector hdr10plus{}; // LightFlattenable bool isFixedSize() const { return false; } diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 32ee595d45..248e105d04 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -218,6 +218,7 @@ private: int dispatchSetBuffersDataSpace(va_list args); int dispatchSetBuffersSmpte2086Metadata(va_list args); int dispatchSetBuffersCta8613Metadata(va_list args); + int dispatchSetBuffersHdr10PlusMetadata(va_list args); int dispatchSetSurfaceDamage(va_list args); int dispatchSetSharedBufferMode(va_list args); int dispatchSetAutoRefresh(va_list args); @@ -249,6 +250,7 @@ protected: virtual int setBuffersDataSpace(ui::Dataspace dataSpace); virtual int setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata); virtual int setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata); + virtual int setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata); virtual int setCrop(Rect const* rect); virtual int setUsage(uint64_t reqUsage); virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index d0600daa0d..4ba7da3560 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -366,10 +366,17 @@ TEST_F(SurfaceTest, SetHdrMetadata) { 78.0, 62.0, }; + + std::vector hdr10plus; + hdr10plus.push_back(0xff); + int error = native_window_set_buffers_smpte2086_metadata(window.get(), &smpte2086); ASSERT_EQ(error, NO_ERROR); error = native_window_set_buffers_cta861_3_metadata(window.get(), &cta861_3); ASSERT_EQ(error, NO_ERROR); + error = native_window_set_buffers_hdr10_plus_metadata(window.get(), hdr10plus.size(), + hdr10plus.data()); + ASSERT_EQ(error, NO_ERROR); } TEST_F(SurfaceTest, DynamicSetBufferCount) { diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 197f73f3b1..61590e0196 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -202,7 +202,7 @@ enum { * ANativeWindow. */ enum { -// clang-format off + // clang-format off NATIVE_WINDOW_SET_USAGE = 0, /* deprecated */ NATIVE_WINDOW_CONNECT = 1, /* deprecated */ NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */ @@ -237,7 +237,8 @@ enum { NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31, NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32, NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33, -// clang-format on + NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34, + // clang-format on }; /* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */ @@ -747,6 +748,27 @@ static inline int native_window_set_buffers_cta861_3_metadata( metadata); } +/* + * native_window_set_buffers_hdr10_plus_metadata(..., metadata) + * All buffers queued after this call will be associated with the + * HDR10+ dynamic metadata specified. + * + * metadata specifies additional dynamic information about the + * contents of the buffer that may affect how it is displayed. When + * it is nullptr, it means no such information is available. No + * HDR10+ dynamic emtadata is associated with the buffers by default. + * + * Parameter "size" refers to the length of the metadata blob pointed to + * by parameter "data". The metadata blob will adhere to the HDR10+ SEI + * message standard. + */ +static inline int native_window_set_buffers_hdr10_plus_metadata(struct ANativeWindow* window, + const size_t size, + const uint8_t* metadata) { + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA, size, + metadata); +} + /* * native_window_set_buffers_transform(..., int transform) * All buffers queued after this call will be displayed transformed according -- cgit v1.2.3-59-g8ed1b From 4f3fddf272851052db5e08db3a828d911e3e4605 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Thu, 24 Jan 2019 17:21:24 -0800 Subject: Eliminate the usage of ConfigStore in native/libs/gui. Ideally modules above SurfaceFlinger should query ConfigStore through ISurfaceComposer APIs. Previously Surface::getWideColorSupport directly evaluate wide color support for built-in display, we don't want that, we should align it with SurfaceFlinger. This patch essentially creates an API to allow other modules to query whether a given display is a wide color display. As a result, we must enforce that wide color display board config together with the wide color modes returned from hardware composer. BUG: 123312783 Test: Build, flash and boot. Verify in logcat. Test: SurfaceFlinger_test --gtest_filter=CredentialsTest.IsWideColorDisplay\* Change-Id: I0a5e3cc404e5365343adb0c9efaee8c13cc49cfe --- libs/gui/Android.bp | 2 -- libs/gui/ISurfaceComposer.cpp | 35 ++++++++++++++++++++++ libs/gui/Surface.cpp | 34 ++------------------- libs/gui/SurfaceComposerClient.cpp | 6 ++++ libs/gui/include/gui/ISurfaceComposer.h | 9 ++++++ libs/gui/include/gui/SurfaceComposerClient.h | 3 ++ libs/gui/tests/Surface_test.cpp | 1 + services/surfaceflinger/SurfaceFlinger.cpp | 17 ++++++++++- services/surfaceflinger/SurfaceFlinger.h | 2 ++ services/surfaceflinger/tests/Credentials_test.cpp | 33 ++++++++++++++++++++ 10 files changed, 107 insertions(+), 35 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 3521e89ae6..ff88a50cd7 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -141,8 +141,6 @@ cc_library_shared { "libhidltransport", "android.hidl.token@1.0-utils", "android.hardware.graphics.bufferqueue@1.0", - "android.hardware.configstore@1.0", - "android.hardware.configstore-utils", ], // bufferhub is not used when building libgui for vendors diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index ad2dc14858..a7e51e09a6 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -731,6 +731,26 @@ public: return remote()->transact(BnSurfaceComposer::UNCACHE_BUFFER, data, &reply); } + + virtual status_t isWideColorDisplay(const sp& token, + bool* outIsWideColorDisplay) const { + Parcel data, reply; + status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (error != NO_ERROR) { + return error; + } + error = data.writeStrongBinder(token); + if (error != NO_ERROR) { + return error; + } + + error = remote()->transact(BnSurfaceComposer::IS_WIDE_COLOR_DISPLAY, data, &reply); + if (error != NO_ERROR) { + return error; + } + error = reply.readBool(outIsWideColorDisplay); + return error; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -1167,6 +1187,7 @@ status_t BnSurfaceComposer::onTransact( CHECK_INTERFACE(ISurfaceComposer, data, reply); bool result; status_t error = getProtectedContentSupport(&result); + reply->writeInt32(error); if (error == NO_ERROR) { reply->writeBool(result); } @@ -1214,6 +1235,20 @@ status_t BnSurfaceComposer::onTransact( return uncacheBuffer(token, bufferId); } + case IS_WIDE_COLOR_DISPLAY: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp display = nullptr; + status_t error = data.readStrongBinder(&display); + if (error != NO_ERROR) { + return error; + } + bool result; + error = isWideColorDisplay(display, &result); + if (error == NO_ERROR) { + reply->writeBool(result); + } + return error; + } default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 00e23f0df1..1f726b2ba4 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -39,9 +39,6 @@ #include #include -#include -#include - namespace android { using ui::ColorMode; @@ -321,41 +318,14 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, return NO_ERROR; } -using namespace android::hardware::configstore; -using namespace android::hardware::configstore::V1_0; - status_t Surface::getWideColorSupport(bool* supported) { ATRACE_CALL(); sp display( composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); - Vector colorModes; - status_t err = - composerService()->getDisplayColorModes(display, &colorModes); - - if (err) - return err; - - bool wideColorBoardConfig = - getBool(false); - *supported = false; - for (ColorMode colorMode : colorModes) { - switch (colorMode) { - case ColorMode::DISPLAY_P3: - case ColorMode::ADOBE_RGB: - case ColorMode::DCI_P3: - if (wideColorBoardConfig) { - *supported = true; - } - break; - default: - break; - } - } - - return NO_ERROR; + status_t error = composerService()->isWideColorDisplay(display, supported); + return error; } status_t Surface::getHdrSupport(bool* supported) { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 6c1c52e1bd..e9632536a0 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1361,6 +1361,12 @@ status_t SurfaceComposerClient::getDisplayedContentSample(const sp& dis timestamp, outStats); } +status_t SurfaceComposerClient::isWideColorDisplay(const sp& display, + bool* outIsWideColorDisplay) { + return ComposerService::getComposerService()->isWideColorDisplay(display, + outIsWideColorDisplay); +} + // ---------------------------------------------------------------------------- status_t ScreenshotClient::capture(const sp& display, const ui::Dataspace reqDataSpace, diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 418d5fbf35..bbfc8c45fc 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -321,6 +321,13 @@ public: int32_t* outBufferId) = 0; virtual status_t uncacheBuffer(const sp& token, int32_t bufferId) = 0; + + /* + * Queries whether the given display is a wide color display. + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t isWideColorDisplay(const sp& token, + bool* outIsWideColorDisplay) const = 0; }; // ---------------------------------------------------------------------------- @@ -365,6 +372,8 @@ public: GET_PROTECTED_CONTENT_SUPPORT, CACHE_BUFFER, UNCACHE_BUFFER, + IS_WIDE_COLOR_DISPLAY, + // Always append new enum to the end. }; virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 24b656b543..4ba6fc960a 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -153,6 +153,9 @@ public: // Uncaches a buffer set by cacheBuffer static status_t uncacheBuffer(int32_t bufferId); + // Queries whether a given display is wide color display. + static status_t isWideColorDisplay(const sp& display, bool* outIsWideColorDisplay); + // ------------------------------------------------------------------------ // surface creation / destruction diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 259ef9f212..d525a338db 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -665,6 +665,7 @@ public: return NO_ERROR; } status_t uncacheBuffer(const sp& /*token*/, int32_t /*bufferId*/) { return NO_ERROR; } + status_t isWideColorDisplay(const sp&, bool*) const override { return NO_ERROR; } protected: IBinder* onAsBinder() override { return nullptr; } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 299499da12..61bf9090b4 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1158,6 +1158,20 @@ status_t SurfaceFlinger::uncacheBuffer(const sp& token, int32_t bufferI return NO_ERROR; } +status_t SurfaceFlinger::isWideColorDisplay(const sp& displayToken, + bool* outIsWideColorDisplay) const { + if (!displayToken || !outIsWideColorDisplay) { + return BAD_VALUE; + } + Mutex::Autolock _l(mStateLock); + const auto display = getDisplayDeviceLocked(displayToken); + if (!display) { + return BAD_VALUE; + } + *outIsWideColorDisplay = display->hasWideColorGamut(); + return NO_ERROR; +} + status_t SurfaceFlinger::enableVSyncInjections(bool enable) { postMessageSync(new LambdaMessage([&] { Mutex::Autolock _l(mStateLock); @@ -4997,7 +5011,8 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case GET_COMPOSITION_PREFERENCE: case GET_PROTECTED_CONTENT_SUPPORT: case CACHE_BUFFER: - case UNCACHE_BUFFER: { + case UNCACHE_BUFFER: + case IS_WIDE_COLOR_DISPLAY: { return OK; } case CAPTURE_LAYERS: diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 68a602cf61..9cded31691 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -472,6 +472,8 @@ private: status_t cacheBuffer(const sp& token, const sp& buffer, int32_t* outBufferId) override; status_t uncacheBuffer(const sp& token, int32_t bufferId) override; + status_t isWideColorDisplay(const sp& displayToken, + bool* outIsWideColorDisplay) const override; /* ------------------------------------------------------------------------ * DeathRecipient interface diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp index 8560f5ed3e..48b2b807b1 100644 --- a/services/surfaceflinger/tests/Credentials_test.cpp +++ b/services/surfaceflinger/tests/Credentials_test.cpp @@ -19,6 +19,7 @@ namespace android { using Transaction = SurfaceComposerClient::Transaction; +using ui::ColorMode; namespace { const String8 DISPLAY_NAME("Credentials Display Test"); @@ -312,4 +313,36 @@ TEST_F(CredentialsTest, GetLayerDebugInfo) { seteuid(AID_BIN); ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers)); } + +TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) { + sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + bool result = false; + status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result); + ASSERT_EQ(NO_ERROR, error); + bool hasWideColorMode = false; + Vector colorModes; + SurfaceComposerClient::getDisplayColorModes(display, &colorModes); + for (ColorMode colorMode : colorModes) { + switch (colorMode) { + case ColorMode::DISPLAY_P3: + case ColorMode::ADOBE_RGB: + case ColorMode::DCI_P3: + hasWideColorMode = true; + break; + default: + break; + } + } + ASSERT_EQ(hasWideColorMode, result); +} + +TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) { + sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + std::function condition = [=]() { + bool result = false; + return SurfaceComposerClient::isWideColorDisplay(display, &result); + }; + ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, NO_ERROR, NO_ERROR)); +} + } // namespace android -- cgit v1.2.3-59-g8ed1b From dcb38bbd32eb96ec46d69658390353a853b3af6d Mon Sep 17 00:00:00 2001 From: Dominik Laskowski Date: Fri, 25 Jan 2019 02:35:50 -0800 Subject: SF: Plumb physical display IDs to libgui This CL replaces ISurfaceComposer::{eDisplayIdMain,eDisplayIdHdmi} with the stable 64-bit display IDs generated by SF. Note that the 64-bit IDs fall back to the old values if the HWC API for display identification is not supported. Bug: 74619554 Test: LocalDisplayAdapter and Choreographer receive 64-bit IDs Test: 64-bit IDs fall back to 0 and 1 on HWC 2.2 and below Change-Id: I3c08eff6eb8bb179ecce596ab2820a2aa44c8649 --- cmds/flatland/GLHelper.cpp | 4 +- libs/gui/ISurfaceComposer.cpp | 35 ++++-- libs/gui/Surface.cpp | 14 ++- libs/gui/SurfaceComposerClient.cpp | 16 ++- libs/gui/include/gui/DisplayEventReceiver.h | 2 +- libs/gui/include/gui/ISurfaceComposer.h | 33 ++++-- libs/gui/include/gui/SurfaceComposerClient.h | 10 +- libs/gui/tests/DisplayedContentSampling_test.cpp | 2 +- libs/gui/tests/EndToEndNativeInputTest.cpp | 6 +- libs/gui/tests/Surface_test.cpp | 9 +- libs/ui/include/ui/GraphicTypes.h | 10 +- opengl/tests/lib/WindowSurface.cpp | 8 +- .../DisplayHardware/DisplayIdentification.h | 4 +- services/surfaceflinger/Scheduler/EventThread.cpp | 26 +++-- services/surfaceflinger/Scheduler/EventThread.h | 13 +-- services/surfaceflinger/Scheduler/Scheduler.cpp | 5 +- services/surfaceflinger/Scheduler/Scheduler.h | 4 +- services/surfaceflinger/SurfaceFlinger.cpp | 128 +++++++++++---------- services/surfaceflinger/SurfaceFlinger.h | 31 +++-- services/surfaceflinger/tests/Credentials_test.cpp | 30 ++--- .../tests/SurfaceInterceptor_test.cpp | 8 +- services/surfaceflinger/tests/Transaction_test.cpp | 24 ++-- .../tests/fakehwc/SFFakeHwc_test.cpp | 52 +++++---- .../tests/unittests/DisplayTransactionTest.cpp | 29 +++-- .../tests/unittests/EventThreadTest.cpp | 42 +++---- .../tests/unittests/SchedulerTest.cpp | 16 +-- .../tests/unittests/mock/MockEventThread.h | 2 +- 27 files changed, 323 insertions(+), 240 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp index 62d2fa1548..d398559ee8 100644 --- a/cmds/flatland/GLHelper.cpp +++ b/cmds/flatland/GLHelper.cpp @@ -222,9 +222,9 @@ bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h, } bool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) { - sp dpy = mSurfaceComposerClient->getBuiltInDisplay(0); + const sp dpy = mSurfaceComposerClient->getInternalDisplayToken(); if (dpy == nullptr) { - fprintf(stderr, "SurfaceComposer::getBuiltInDisplay failed.\n"); + fprintf(stderr, "SurfaceComposer::getInternalDisplayToken failed.\n"); return false; } diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index bef68ef22f..4357f798df 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -275,12 +275,25 @@ public: remote()->transact(BnSurfaceComposer::DESTROY_DISPLAY, data, &reply); } - virtual sp getBuiltInDisplay(int32_t id) - { + virtual std::vector getPhysicalDisplayIds() const { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) == + NO_ERROR) { + std::vector displayIds; + if (reply.readUint64Vector(&displayIds) == NO_ERROR) { + return displayIds; + } + } + + return {}; + } + + virtual sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - data.writeInt32(id); - remote()->transact(BnSurfaceComposer::GET_BUILT_IN_DISPLAY, data, &reply); + data.writeUint64(displayId); + remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN, data, &reply); return reply.readStrongBinder(); } @@ -932,10 +945,10 @@ status_t BnSurfaceComposer::onTransact( destroyDisplay(display); return NO_ERROR; } - case GET_BUILT_IN_DISPLAY: { + case GET_PHYSICAL_DISPLAY_TOKEN: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - int32_t id = data.readInt32(); - sp display(getBuiltInDisplay(id)); + PhysicalDisplayId displayId = data.readUint64(); + sp display = getPhysicalDisplayToken(displayId); reply->writeStrongBinder(display); return NO_ERROR; } @@ -1294,12 +1307,14 @@ status_t BnSurfaceComposer::onTransact( } return error; } + case GET_PHYSICAL_DISPLAY_IDS: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + return reply->writeUint64Vector(getPhysicalDisplayIds()); + } default: { return BBinder::onTransact(code, data, reply, flags); } } } -// ---------------------------------------------------------------------------- - -}; +} // namespace android diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 1f726b2ba4..3affa23482 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -321,8 +321,11 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, status_t Surface::getWideColorSupport(bool* supported) { ATRACE_CALL(); - sp display( - composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const sp display = composerService()->getInternalDisplayToken(); + if (display == nullptr) { + return NAME_NOT_FOUND; + } + *supported = false; status_t error = composerService()->isWideColorDisplay(display, supported); return error; @@ -331,8 +334,11 @@ status_t Surface::getWideColorSupport(bool* supported) { status_t Surface::getHdrSupport(bool* supported) { ATRACE_CALL(); - sp display( - composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const sp display = composerService()->getInternalDisplayToken(); + if (display == nullptr) { + return NAME_NOT_FOUND; + } + HdrCapabilities hdrCapabilities; status_t err = composerService()->getHdrCapabilities(display, &hdrCapabilities); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c712bde97d..90656d60c7 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -374,8 +374,20 @@ void SurfaceComposerClient::destroyDisplay(const sp& display) { return ComposerService::getComposerService()->destroyDisplay(display); } -sp SurfaceComposerClient::getBuiltInDisplay(int32_t id) { - return ComposerService::getComposerService()->getBuiltInDisplay(id); +std::vector SurfaceComposerClient::getPhysicalDisplayIds() { + return ComposerService::getComposerService()->getPhysicalDisplayIds(); +} + +std::optional SurfaceComposerClient::getInternalDisplayId() { + return ComposerService::getComposerService()->getInternalDisplayId(); +} + +sp SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId displayId) { + return ComposerService::getComposerService()->getPhysicalDisplayToken(displayId); +} + +sp SurfaceComposerClient::getInternalDisplayToken() { + return ComposerService::getComposerService()->getInternalDisplayToken(); } void SurfaceComposerClient::Transaction::setAnimationTransaction() { diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h index a4102dfe03..8c3f46305c 100644 --- a/libs/gui/include/gui/DisplayEventReceiver.h +++ b/libs/gui/include/gui/DisplayEventReceiver.h @@ -58,7 +58,7 @@ public: struct Header { uint32_t type; - uint32_t id; + PhysicalDisplayId displayId; nsecs_t timestamp __attribute__((aligned(8))); }; diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 3899f6a3d0..9d6b8729d0 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -34,6 +34,7 @@ #include #include +#include #include namespace android { @@ -71,11 +72,6 @@ public: eEarlyWakeup = 0x04 }; - enum { - eDisplayIdMain = 0, - eDisplayIdHdmi = 1 - }; - enum Rotation { eRotateNone = 0, eRotate90 = 1, @@ -88,7 +84,7 @@ public: eVsyncSourceSurfaceFlinger = 1 }; - /* + /* * Create a connection with SurfaceFlinger. */ virtual sp createConnection() = 0; @@ -108,10 +104,26 @@ public: */ virtual void destroyDisplay(const sp& display) = 0; - /* get the token for the existing default displays. possible values - * for id are eDisplayIdMain and eDisplayIdHdmi. + /* get stable IDs for connected physical displays. + */ + virtual std::vector getPhysicalDisplayIds() const = 0; + + // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic. + std::optional getInternalDisplayId() const { + const auto displayIds = getPhysicalDisplayIds(); + return displayIds.empty() ? std::nullopt : std::make_optional(displayIds.front()); + } + + /* get token for a physical display given its stable ID obtained via getPhysicalDisplayIds or a + * DisplayEventReceiver hotplug event. */ - virtual sp getBuiltInDisplay(int32_t id) = 0; + virtual sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const = 0; + + // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic. + sp getInternalDisplayToken() const { + const auto displayId = getInternalDisplayId(); + return displayId ? getPhysicalDisplayToken(*displayId) : nullptr; + } /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ virtual void setTransactionState(const Vector& state, @@ -346,7 +358,7 @@ public: CREATE_DISPLAY_EVENT_CONNECTION, CREATE_DISPLAY, DESTROY_DISPLAY, - GET_BUILT_IN_DISPLAY, + GET_PHYSICAL_DISPLAY_TOKEN, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, GET_SUPPORTED_FRAME_TIMESTAMPS, @@ -377,6 +389,7 @@ public: UNCACHE_BUFFER, IS_WIDE_COLOR_DISPLAY, GET_DISPLAY_NATIVE_PRIMARIES, + GET_PHYSICAL_DISPLAY_IDS, // Always append new enum to the end. }; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 8e2bb2b6e6..f92c0fe547 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -202,9 +202,13 @@ public: //! Destroy a virtual display static void destroyDisplay(const sp& display); - //! Get the token for the existing default displays. - //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi. - static sp getBuiltInDisplay(int32_t id); + //! Get stable IDs for connected physical displays + static std::vector getPhysicalDisplayIds(); + static std::optional getInternalDisplayId(); + + //! Get token for a physical display given its stable ID + static sp getPhysicalDisplayToken(PhysicalDisplayId displayId); + static sp getInternalDisplayToken(); static status_t enableVSyncInjections(bool enable); diff --git a/libs/gui/tests/DisplayedContentSampling_test.cpp b/libs/gui/tests/DisplayedContentSampling_test.cpp index 5443812bff..b647aaba8f 100644 --- a/libs/gui/tests/DisplayedContentSampling_test.cpp +++ b/libs/gui/tests/DisplayedContentSampling_test.cpp @@ -32,7 +32,7 @@ protected: void SetUp() { mComposerClient = new SurfaceComposerClient; ASSERT_EQ(OK, mComposerClient->initCheck()); - mDisplayToken = mComposerClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + mDisplayToken = mComposerClient->getInternalDisplayToken(); ASSERT_TRUE(mDisplayToken); } diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index ac97733508..4a7848020f 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -233,9 +233,11 @@ public: mComposerClient = new SurfaceComposerClient; ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); + const auto display = mComposerClient->getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - auto display = mComposerClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, mComposerClient->getDisplayInfo(display, &info)); // After a new buffer is queued, SurfaceFlinger is notified and will // latch the new buffer on next vsync. Let's heuristically wait for 3 diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 1705fd7383..ca58574e95 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -131,8 +131,10 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) { // Verify the screenshot works with no protected buffers. sp sf(ComposerService::getComposerService()); - sp display(sf->getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain)); + + const sp display = sf->getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + sp outBuffer; ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB, @@ -552,7 +554,8 @@ public: sp createDisplay(const String8& /*displayName*/, bool /*secure*/) override { return nullptr; } void destroyDisplay(const sp& /*display */) override {} - sp getBuiltInDisplay(int32_t /*id*/) override { return nullptr; } + std::vector getPhysicalDisplayIds() const override { return {}; } + sp getPhysicalDisplayToken(PhysicalDisplayId) const override { return nullptr; } void setTransactionState(const Vector& /*state*/, const Vector& /*displays*/, uint32_t /*flags*/, const sp& /*applyToken*/, diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h index 4b03e44978..5dc56c8181 100644 --- a/libs/ui/include/ui/GraphicTypes.h +++ b/libs/ui/include/ui/GraphicTypes.h @@ -16,13 +16,21 @@ #pragma once +#include +#include + #include #include #include +#define ANDROID_PHYSICAL_DISPLAY_ID_FORMAT PRIu64 + +namespace android { + +using PhysicalDisplayId = uint64_t; + // android::ui::* in this header file will alias different types as // the HIDL interface is updated. -namespace android { namespace ui { using android::hardware::graphics::common::V1_1::RenderIntent; diff --git a/opengl/tests/lib/WindowSurface.cpp b/opengl/tests/lib/WindowSurface.cpp index b06422a98c..a0bd4e2409 100644 --- a/opengl/tests/lib/WindowSurface.cpp +++ b/opengl/tests/lib/WindowSurface.cpp @@ -34,8 +34,12 @@ WindowSurface::WindowSurface() { } // Get main display parameters. - sp mainDpy = SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain); + const auto mainDpy = SurfaceComposerClient::getInternalDisplayToken(); + if (mainDpy == nullptr) { + fprintf(stderr, "ERROR: no display\n"); + return; + } + DisplayInfo mainDpyInfo; err = SurfaceComposerClient::getDisplayInfo(mainDpy, &mainDpyInfo); if (err != NO_ERROR) { diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h index 1599995297..d63cd79b03 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h +++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h @@ -23,10 +23,12 @@ #include #include +#include + namespace android { struct DisplayId { - using Type = uint64_t; + using Type = PhysicalDisplayId; Type value; uint16_t manufacturerId() const; diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 52abe9ca38..91ae087adb 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -69,24 +69,28 @@ std::string toString(const EventThreadConnection& connection) { std::string toString(const DisplayEventReceiver::Event& event) { switch (event.header.type) { case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: - return StringPrintf("Hotplug{displayId=%u, %s}", event.header.id, + return StringPrintf("Hotplug{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", %s}", + event.header.displayId, event.hotplug.connected ? "connected" : "disconnected"); case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: - return StringPrintf("VSync{displayId=%u, count=%u}", event.header.id, - event.vsync.count); + return StringPrintf("VSync{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT + ", count=%u}", + event.header.displayId, event.vsync.count); default: return "Event{}"; } } -DisplayEventReceiver::Event makeHotplug(uint32_t displayId, nsecs_t timestamp, bool connected) { +DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t timestamp, + bool connected) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, displayId, timestamp}; event.hotplug.connected = connected; return event; } -DisplayEventReceiver::Event makeVSync(uint32_t displayId, nsecs_t timestamp, uint32_t count) { +DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp, + uint32_t count) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp}; event.vsync.count = count; @@ -290,10 +294,9 @@ void EventThread::onVSyncEvent(nsecs_t timestamp) { mCondition.notify_all(); } -void EventThread::onHotplugReceived(DisplayType displayType, bool connected) { +void EventThread::onHotplugReceived(PhysicalDisplayId displayId, bool connected) { std::lock_guard lock(mMutex); - const uint32_t displayId = displayType == DisplayType::Primary ? 0 : 1; mPendingEvents.push_back(makeHotplug(displayId, systemTime(), connected)); mCondition.notify_all(); } @@ -312,9 +315,9 @@ void EventThread::threadMain(std::unique_lock& lock) { switch (event->header.type) { case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: if (event->hotplug.connected && !mVSyncState) { - mVSyncState.emplace(event->header.id); + mVSyncState.emplace(event->header.displayId); } else if (!event->hotplug.connected && mVSyncState && - mVSyncState->displayId == event->header.id) { + mVSyncState->displayId == event->header.displayId) { mVSyncState.reset(); } break; @@ -440,8 +443,9 @@ void EventThread::dump(std::string& result) const { StringAppendF(&result, "%s: state=%s VSyncState=", mThreadName, toCString(mState)); if (mVSyncState) { - StringAppendF(&result, "{displayId=%u, count=%u%s}\n", mVSyncState->displayId, - mVSyncState->count, mVSyncState->synthetic ? ", synthetic" : ""); + StringAppendF(&result, "{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%u%s}\n", + mVSyncState->displayId, mVSyncState->count, + mVSyncState->synthetic ? ", synthetic" : ""); } else { StringAppendF(&result, "none\n"); } diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 89b799e59f..62b6a8b65f 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -94,9 +94,6 @@ private: class EventThread { public: - // TODO: Remove once stable display IDs are plumbed through SF/WM interface. - enum class DisplayType { Primary, External }; - virtual ~EventThread(); virtual sp createEventConnection( @@ -108,8 +105,7 @@ public: // called after the screen is turned on from main thread virtual void onScreenAcquired() = 0; - // called when receiving a hotplug event - virtual void onHotplugReceived(DisplayType displayType, bool connected) = 0; + virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0; virtual void dump(std::string& result) const = 0; @@ -151,8 +147,7 @@ public: // called after the screen is turned on from main thread void onScreenAcquired() override; - // called when receiving a hotplug event - void onHotplugReceived(DisplayType displayType, bool connected) override; + void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override; void dump(std::string& result) const override; @@ -199,9 +194,9 @@ private: // VSYNC state of connected display. struct VSyncState { - explicit VSyncState(uint32_t displayId) : displayId(displayId) {} + explicit VSyncState(PhysicalDisplayId displayId) : displayId(displayId) {} - const uint32_t displayId; + const PhysicalDisplayId displayId; // Number of VSYNC events since display was connected. uint32_t count = 0; diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 00820f15fd..a29877e884 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -128,9 +127,9 @@ sp Scheduler::getEventConnection(const sp& handle, - EventThread::DisplayType displayType, bool connected) { + PhysicalDisplayId displayId, bool connected) { RETURN_IF_INVALID(); - mConnections[handle->id]->thread->onHotplugReceived(displayType, connected); + mConnections[handle->id]->thread->onHotplugReceived(displayId, connected); } void Scheduler::onScreenAcquired(const sp& handle) { diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index b7176050a7..e77dc06c34 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include "DispSync.h" #include "EventControlThread.h" @@ -85,7 +85,7 @@ public: sp getEventConnection(const sp& handle); // Should be called when receiving a hotplug event. - void hotplugReceived(const sp& handle, EventThread::DisplayType displayType, + void hotplugReceived(const sp& handle, PhysicalDisplayId displayId, bool connected); // Should be called after the screen is turned on. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 2cf2cd8a5d..4c1b267397 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -496,21 +496,30 @@ void SurfaceFlinger::destroyDisplay(const sp& displayToken) { setTransactionFlags(eDisplayTransactionNeeded); } -sp SurfaceFlinger::getBuiltInDisplay(int32_t id) { - std::optional displayId; +std::vector SurfaceFlinger::getPhysicalDisplayIds() const { + Mutex::Autolock lock(mStateLock); - if (id == HWC_DISPLAY_PRIMARY) { - displayId = getInternalDisplayId(); - } else if (id == HWC_DISPLAY_EXTERNAL) { - displayId = getExternalDisplayId(); + const auto internalDisplayId = getInternalDisplayIdLocked(); + if (!internalDisplayId) { + return {}; } - if (!displayId) { - ALOGE("%s: Invalid display %d", __FUNCTION__, id); - return nullptr; + std::vector displayIds; + displayIds.reserve(mPhysicalDisplayTokens.size()); + displayIds.push_back(internalDisplayId->value); + + for (const auto& [id, token] : mPhysicalDisplayTokens) { + if (id != *internalDisplayId) { + displayIds.push_back(id.value); + } } - return getPhysicalDisplayToken(*displayId); + return displayIds; +} + +sp SurfaceFlinger::getPhysicalDisplayToken(PhysicalDisplayId displayId) const { + Mutex::Autolock lock(mStateLock); + return getPhysicalDisplayTokenLocked(DisplayId{displayId}); } status_t SurfaceFlinger::getColorManagement(bool* outGetColorManagement) const { @@ -614,9 +623,9 @@ void SurfaceFlinger::init() { // start the EventThread if (mUseScheduler) { - mScheduler = getFactory().createScheduler([this](bool enabled) { - setVsyncEnabled(EventThread::DisplayType::Primary, enabled); - }); + mScheduler = getFactory().createScheduler( + [this](bool enabled) { setPrimaryVsyncEnabled(enabled); }); + // TODO(b/113612090): Currently we assume that if scheduler is turned on, then the refresh // rate is 90. Once b/122905403 is completed, this should be updated accordingly. mPhaseOffsets->setRefreshRateType( @@ -705,7 +714,7 @@ void SurfaceFlinger::init() { } mEventControlThread = getFactory().createEventControlThread( - [this](bool enabled) { setVsyncEnabled(EventThread::DisplayType::Primary, enabled); }); + [this](bool enabled) { setPrimaryVsyncEnabled(enabled); }); // initialize our drawing state mDrawingState = mCurrentState; @@ -820,7 +829,9 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp& displayToken, return BAD_VALUE; } - const auto displayId = getPhysicalDisplayId(displayToken); + ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); + + const auto displayId = getPhysicalDisplayIdLocked(displayToken); if (!displayId) { return NAME_NOT_FOUND; } @@ -844,8 +855,6 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp& displayToken, configs->clear(); - ConditionalLock _l(mStateLock, - std::this_thread::get_id() != mMainThreadId); for (const auto& hwConfig : getHwComposer().getConfigs(*displayId)) { DisplayInfo info = DisplayInfo(); @@ -858,7 +867,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp& displayToken, info.viewportW = info.w; info.viewportH = info.h; - if (displayId == getInternalDisplayId()) { + if (displayId == getInternalDisplayIdLocked()) { // The density of the device is provided by a build property float density = Density::getBuildDensity() / 160.0f; if (density == 0) { @@ -914,7 +923,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp& displayToken, // All non-virtual displays are currently considered secure. info.secure = true; - if (displayId == getInternalDisplayId() && + if (displayId == getInternalDisplayIdLocked() && primaryDisplayOrientation & DisplayState::eOrientationSwapMask) { std::swap(info.w, info.h); } @@ -1012,15 +1021,15 @@ status_t SurfaceFlinger::getDisplayColorModes(const sp& displayToken, return BAD_VALUE; } - const auto displayId = getPhysicalDisplayId(displayToken); - if (!displayId) { - return NAME_NOT_FOUND; - } - std::vector modes; { - ConditionalLock _l(mStateLock, - std::this_thread::get_id() != mMainThreadId); + ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); + + const auto displayId = getPhysicalDisplayIdLocked(displayToken); + if (!displayId) { + return NAME_NOT_FOUND; + } + modes = getHwComposer().getColorModes(*displayId); } outColorModes->clear(); @@ -1330,7 +1339,7 @@ void SurfaceFlinger::run() { } nsecs_t SurfaceFlinger::getVsyncPeriod() const { - const auto displayId = getInternalDisplayId(); + const auto displayId = getInternalDisplayIdLocked(); if (!displayId || !getHwComposer().isConnected(*displayId)) { return 0; } @@ -1447,9 +1456,10 @@ void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { *compositorTiming = getBE().mCompositorTiming; } -void SurfaceFlinger::setRefreshRateTo(float newFps) { - const auto displayId = getInternalDisplayId(); - if (!displayId || mBootStage != BootStage::FINISHED) { +// TODO(b/123715322): Fix thread safety. +void SurfaceFlinger::setRefreshRateTo(float newFps) NO_THREAD_SAFETY_ANALYSIS { + const auto display = getDefaultDisplayDeviceLocked(); + if (!display || mBootStage != BootStage::FINISHED) { return; } // TODO(b/113612090): There should be a message queue flush here. Because this esentially @@ -1458,8 +1468,7 @@ void SurfaceFlinger::setRefreshRateTo(float newFps) { // refresh cycle. // Don't do any updating if the current fps is the same as the new one. - const auto activeConfig = getHwComposer().getActiveConfig(*displayId); - const nsecs_t currentVsyncPeriod = activeConfig->getVsyncPeriod(); + const nsecs_t currentVsyncPeriod = getVsyncPeriod(); if (currentVsyncPeriod == 0) { return; } @@ -1470,7 +1479,7 @@ void SurfaceFlinger::setRefreshRateTo(float newFps) { return; } - auto configs = getHwComposer().getConfigs(*displayId); + auto configs = getHwComposer().getConfigs(*display->getId()); for (int i = 0; i < configs.size(); i++) { const nsecs_t vsyncPeriod = configs.at(i)->getVsyncPeriod(); if (vsyncPeriod == 0) { @@ -1480,11 +1489,12 @@ void SurfaceFlinger::setRefreshRateTo(float newFps) { // TODO(b/113612090): There should be a better way at determining which config // has the right refresh rate. if (std::abs(fps - newFps) <= 1) { - const auto display = getBuiltInDisplay(HWC_DISPLAY_PRIMARY); - if (!display) return; + const sp token = display->getDisplayToken().promote(); + LOG_ALWAYS_FATAL_IF(token == nullptr); + // This is posted in async function to avoid deadlock when getDisplayDevice // requires mStateLock. - setActiveConfigAsync(display, i); + setActiveConfigAsync(token, i); ATRACE_INT("FPS", newFps); } } @@ -1524,10 +1534,10 @@ void SurfaceFlinger::onRefreshReceived(int sequenceId, hwc2_display_t /*hwcDispl repaintEverythingForHWC(); } -void SurfaceFlinger::setVsyncEnabled(EventThread::DisplayType /*displayType*/, bool enabled) { +void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) { ATRACE_CALL(); Mutex::Autolock lock(mStateLock); - if (const auto displayId = getInternalDisplayId()) { + if (const auto displayId = getInternalDisplayIdLocked()) { getHwComposer().setVsyncEnabled(*displayId, enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable); } @@ -2593,14 +2603,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { mPendingHotplugEvents.clear(); } -void SurfaceFlinger::dispatchDisplayHotplugEvent(EventThread::DisplayType displayType, - bool connected) { +void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) { if (mUseScheduler) { - mScheduler->hotplugReceived(mAppConnectionHandle, displayType, connected); - mScheduler->hotplugReceived(mSfConnectionHandle, displayType, connected); + mScheduler->hotplugReceived(mAppConnectionHandle, displayId, connected); + mScheduler->hotplugReceived(mSfConnectionHandle, displayId, connected); } else { - mEventThread->onHotplugReceived(displayType, connected); - mSFEventThread->onHotplugReceived(displayType, connected); + mEventThread->onHotplugReceived(displayId, connected); + mSFEventThread->onHotplugReceived(displayId, connected); } } @@ -2616,7 +2625,7 @@ sp SurfaceFlinger::setupNewDisplayDeviceInternal( creationArgs.hasWideColorGamut = false; creationArgs.supportedPerFrameMetadata = 0; - const bool isInternalDisplay = displayId && displayId == getInternalDisplayId(); + const bool isInternalDisplay = displayId && displayId == getInternalDisplayIdLocked(); creationArgs.isPrimary = isInternalDisplay; if (useColorManagement && displayId) { @@ -2699,19 +2708,18 @@ void SurfaceFlinger::processDisplayChangesLocked() { for (size_t i = 0; i < dc;) { const ssize_t j = curr.indexOfKey(draw.keyAt(i)); if (j < 0) { - // Save display IDs before disconnecting. - const auto internalDisplayId = getInternalDisplayId(); - const auto externalDisplayId = getExternalDisplayId(); - // in drawing state but not in current state if (const auto display = getDisplayDeviceLocked(draw.keyAt(i))) { + // Save display ID before disconnecting. + const auto displayId = display->getId(); display->disconnect(); + + if (!display->isVirtual()) { + LOG_ALWAYS_FATAL_IF(!displayId); + dispatchDisplayHotplugEvent(displayId->value, false); + } } - if (internalDisplayId && internalDisplayId == draw[i].displayId) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::Primary, false); - } else if (externalDisplayId && externalDisplayId == draw[i].displayId) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::External, false); - } + mDisplays.erase(draw.keyAt(i)); } else { // this display is in both lists. see if something changed. @@ -2814,12 +2822,7 @@ void SurfaceFlinger::processDisplayChangesLocked() { dispSurface, producer)); if (!state.isVirtual()) { LOG_ALWAYS_FATAL_IF(!displayId); - - if (displayId == getInternalDisplayId()) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::Primary, true); - } else if (displayId == getExternalDisplayId()) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::External, true); - } + dispatchDisplayHotplugEvent(displayId->value, true); } } } @@ -4829,7 +4832,7 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co " gpu_to_cpu_unsupported : %d\n", mTransactionFlags.load(), !mGpuToCpuSupported); - if (const auto displayId = getInternalDisplayId(); + if (const auto displayId = getInternalDisplayIdLocked(); displayId && getHwComposer().isConnected(*displayId)) { const auto activeConfig = getHwComposer().getActiveConfig(*displayId); StringAppendF(&result, @@ -4999,7 +5002,8 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { // information, so it is OK to pass them. case AUTHENTICATE_SURFACE: case GET_ACTIVE_CONFIG: - case GET_BUILT_IN_DISPLAY: + case GET_PHYSICAL_DISPLAY_IDS: + case GET_PHYSICAL_DISPLAY_TOKEN: case GET_DISPLAY_COLOR_MODES: case GET_DISPLAY_NATIVE_PRIMARIES: case GET_DISPLAY_CONFIGS: diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a48e8113d3..73b0cde413 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -313,7 +313,7 @@ public: compositionengine::CompositionEngine& getCompositionEngine() const; // returns the default Display - sp getDefaultDisplayDevice() const { + sp getDefaultDisplayDevice() { Mutex::Autolock _l(mStateLock); return getDefaultDisplayDeviceLocked(); } @@ -327,7 +327,7 @@ public: // enable/disable h/w composer event // TODO: this should be made accessible only to EventThread - void setVsyncEnabled(EventThread::DisplayType displayType, bool enabled); + void setPrimaryVsyncEnabled(bool enabled); // called on the main thread by MessageQueue when an internal message // is received @@ -414,7 +414,8 @@ private: sp createConnection() override; sp createDisplay(const String8& displayName, bool secure) override; void destroyDisplay(const sp& displayToken) override; - sp getBuiltInDisplay(int32_t id) override; + std::vector getPhysicalDisplayIds() const override; + sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const override; void setTransactionState(const Vector& state, const Vector& displays, uint32_t flags, const sp& applyToken, @@ -657,7 +658,7 @@ private: } sp getDefaultDisplayDeviceLocked() { - if (const auto token = getInternalDisplayToken()) { + if (const auto token = getInternalDisplayTokenLocked()) { return getDisplayDeviceLocked(token); } return nullptr; @@ -761,7 +762,7 @@ private: void processDisplayChangesLocked(); void processDisplayHotplugEventsLocked(); - void dispatchDisplayHotplugEvent(EventThread::DisplayType displayType, bool connected); + void dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected); /* ------------------------------------------------------------------------ * VSync @@ -801,12 +802,12 @@ private: /* * Display identification */ - sp getPhysicalDisplayToken(DisplayId displayId) const { + sp getPhysicalDisplayTokenLocked(DisplayId displayId) const { const auto it = mPhysicalDisplayTokens.find(displayId); return it != mPhysicalDisplayTokens.end() ? it->second : nullptr; } - std::optional getPhysicalDisplayId(const sp& displayToken) const { + std::optional getPhysicalDisplayIdLocked(const sp& displayToken) const { for (const auto& [id, token] : mPhysicalDisplayTokens) { if (token == displayToken) { return id; @@ -816,22 +817,16 @@ private: } // TODO(b/74619554): Remove special cases for primary display. - sp getInternalDisplayToken() const { - const auto displayId = getInternalDisplayId(); - return displayId ? getPhysicalDisplayToken(*displayId) : nullptr; + sp getInternalDisplayTokenLocked() const { + const auto displayId = getInternalDisplayIdLocked(); + return displayId ? getPhysicalDisplayTokenLocked(*displayId) : nullptr; } - std::optional getInternalDisplayId() const { + std::optional getInternalDisplayIdLocked() const { const auto hwcDisplayId = getHwComposer().getInternalHwcDisplayId(); return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt; } - // TODO(b/74619554): Remove special cases for external display. - std::optional getExternalDisplayId() const { - const auto hwcDisplayId = getHwComposer().getExternalHwcDisplayId(); - return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt; - } - /* * Debugging & dumpsys */ @@ -951,7 +946,6 @@ private: std::unique_ptr mSfEventThreadSource; std::unique_ptr mVSyncInjector; std::unique_ptr mEventControlThread; - std::unordered_map> mPhysicalDisplayTokens; // Calculates correct offsets. VSyncModulator mVsyncModulator; @@ -985,6 +979,7 @@ private: // this may only be written from the main thread with mStateLock held // it may be read from other threads with mStateLock held std::map, sp> mDisplays; + std::unordered_map> mPhysicalDisplayTokens; // don't use a lock for these, we don't care int mDebugRegion; diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp index f021d3dfa7..61d09daed2 100644 --- a/services/surfaceflinger/tests/Credentials_test.cpp +++ b/services/surfaceflinger/tests/Credentials_test.cpp @@ -62,9 +62,11 @@ protected: } void setupBackgroundSurface() { - mDisplay = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + mDisplay = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(mDisplay == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(mDisplay, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mDisplay, &info)); const ssize_t displayWidth = info.w; const ssize_t displayHeight = info.h; @@ -170,10 +172,8 @@ TEST_F(CredentialsTest, ClientInitTest) { } TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) { - std::function condition = [=]() { - sp display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); - return (display != nullptr); + std::function condition = [] { + return SurfaceComposerClient::getInternalDisplayToken() != nullptr; }; // Anyone can access display information. ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true)); @@ -183,7 +183,7 @@ TEST_F(CredentialsTest, AllowedGetterMethodsTest) { // The following methods are tested with a UID that is not root, graphics, // or system, to show that anyone can access them. setBinUID(); - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); ASSERT_TRUE(display != nullptr); DisplayInfo info; @@ -199,7 +199,7 @@ TEST_F(CredentialsTest, AllowedGetterMethodsTest) { } TEST_F(CredentialsTest, GetDisplayColorModesTest) { - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function condition = [=]() { Vector outColorModes; return SurfaceComposerClient::getDisplayColorModes(display, &outColorModes); @@ -208,7 +208,7 @@ TEST_F(CredentialsTest, GetDisplayColorModesTest) { } TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) { - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function condition = [=]() { ui::DisplayPrimaries primaries; return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries); @@ -217,7 +217,7 @@ TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) { } TEST_F(CredentialsTest, SetActiveConfigTest) { - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function condition = [=]() { return SurfaceComposerClient::setActiveConfig(display, 0); }; @@ -225,7 +225,7 @@ TEST_F(CredentialsTest, SetActiveConfigTest) { } TEST_F(CredentialsTest, SetActiveColorModeTest) { - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function condition = [=]() { return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE); }; @@ -258,7 +258,7 @@ TEST_F(CredentialsTest, DISABLED_DestroyDisplayTest) { } TEST_F(CredentialsTest, CaptureTest) { - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function condition = [=]() { sp outBuffer; return ScreenshotClient::capture(display, ui::Dataspace::V0_SRGB, @@ -324,7 +324,8 @@ TEST_F(CredentialsTest, GetLayerDebugInfo) { } TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) { - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); bool result = false; status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result); ASSERT_EQ(NO_ERROR, error); @@ -346,7 +347,8 @@ TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) { } TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) { - sp display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); std::function condition = [=]() { bool result = false; return SurfaceComposerClient::isWideColorDisplay(display, &result); diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index 8ec3e154e3..5cc946aa79 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -240,10 +240,12 @@ void SurfaceInterceptorTest::capture(TestAction action, Trace* outTrace) { } void SurfaceInterceptorTest::setupBackgroundSurface() { - sp display(SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); + ssize_t displayWidth = info.w; ssize_t displayHeight = info.h; diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 56d3bd49a8..05a73dcd94 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -195,13 +195,12 @@ static void fillSurfaceRGBA8(const sp& sc, uint8_t r, uint8_t g, class ScreenCapture : public RefBase { public: static void captureScreen(std::unique_ptr* sc) { - sp sf(ComposerService::getComposerService()); - sp display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto sf = ComposerService::getComposerService(); + const auto token = sf->getInternalDisplayToken(); SurfaceComposerClient::Transaction().apply(true); sp outBuffer; - ASSERT_EQ(NO_ERROR, - sf->captureScreen(display, &outBuffer, Rect(), 0, 0, false)); + ASSERT_EQ(NO_ERROR, sf->captureScreen(token, &outBuffer, Rect(), 0, 0, false)); *sc = std::make_unique(outBuffer); } @@ -324,7 +323,6 @@ protected: ASSERT_NO_FATAL_FAILURE(SetUpDisplay()); sp sf(ComposerService::getComposerService()); - sp binder = sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); ASSERT_NO_FATAL_FAILURE(sf->getColorManagement(&mColorManagementUsed)); } @@ -502,12 +500,12 @@ protected: private: void SetUpDisplay() { - mDisplay = mClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); - ASSERT_NE(nullptr, mDisplay.get()) << "failed to get built-in display"; + mDisplay = mClient->getInternalDisplayToken(); + ASSERT_FALSE(mDisplay == nullptr) << "failed to get display"; // get display width/height DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(mDisplay, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mDisplay, &info)); mDisplayWidth = info.w; mDisplayHeight = info.h; mDisplayRect = @@ -558,8 +556,7 @@ public: return mDelegate->screenshot(); case RenderPath::VIRTUAL_DISPLAY: - sp mainDisplay = - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + const auto mainDisplay = SurfaceComposerClient::getInternalDisplayToken(); DisplayInfo mainDisplayInfo; SurfaceComposerClient::getDisplayInfo(mainDisplay, &mainDisplayInfo); @@ -3930,10 +3927,11 @@ protected: LayerTransactionTest::SetUp(); ASSERT_EQ(NO_ERROR, mClient->initCheck()); - sp display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); ssize_t displayWidth = info.w; ssize_t displayHeight = info.h; diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index 16e08918a0..f9e0b6413b 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -145,7 +145,7 @@ protected: void TearDown() override; void waitForDisplayTransaction(); - bool waitForHotplugEvent(uint32_t id, bool connected); + bool waitForHotplugEvent(PhysicalDisplayId displayId, bool connected); sp mFakeService; sp mComposerClient; @@ -242,7 +242,7 @@ void DisplayTest::waitForDisplayTransaction() { mMockComposer->runVSyncAndWait(); } -bool DisplayTest::waitForHotplugEvent(uint32_t id, bool connected) { +bool DisplayTest::waitForHotplugEvent(PhysicalDisplayId displayId, bool connected) { int waitCount = 20; while (waitCount--) { while (!mReceivedDisplayEvents.empty()) { @@ -250,11 +250,12 @@ bool DisplayTest::waitForHotplugEvent(uint32_t id, bool connected) { mReceivedDisplayEvents.pop_front(); ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, - "event hotplug: id %d, connected %d\t", event.header.id, - event.hotplug.connected); + "event hotplug: displayId %" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT + ", connected %d\t", + event.header.displayId, event.hotplug.connected); if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG && - event.header.id == id && event.hotplug.connected == connected) { + event.header.displayId == displayId && event.hotplug.connected == connected) { return true; } } @@ -294,13 +295,14 @@ TEST_F(DisplayTest, Hotplug) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, true)); + EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); { - sp display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdHdmi)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(EXTERNAL_DISPLAY); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); ASSERT_EQ(400u, info.w); ASSERT_EQ(200u, info.h); @@ -328,14 +330,15 @@ TEST_F(DisplayTest, Hotplug) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, false)); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, true)); + EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false)); + EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); { - sp display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdHdmi)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(EXTERNAL_DISPLAY); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); ASSERT_EQ(400u, info.w); ASSERT_EQ(200u, info.h); @@ -364,11 +367,12 @@ TEST_F(DisplayTest, HotplugPrimaryDisplay) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdMain, false)); + EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, false)); { - sp display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY); + EXPECT_FALSE(display == nullptr); + DisplayInfo info; auto result = SurfaceComposerClient::getDisplayInfo(display, &info); EXPECT_NE(NO_ERROR, result); @@ -402,11 +406,12 @@ TEST_F(DisplayTest, HotplugPrimaryDisplay) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdMain, true)); + EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, true)); { - sp display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY); + EXPECT_FALSE(display == nullptr); + DisplayInfo info; auto result = SurfaceComposerClient::getDisplayInfo(display, &info); EXPECT_EQ(NO_ERROR, result); @@ -473,10 +478,11 @@ void TransactionTest::SetUp() { ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); ALOGI("TransactionTest::SetUp - display"); - sp display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); mDisplayWidth = info.w; mDisplayHeight = info.h; diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp index 4cb79ab495..da3472e3fa 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp @@ -45,9 +45,9 @@ namespace android { namespace { using testing::_; -using testing::ByMove; using testing::DoAll; using testing::Mock; +using testing::ResultOf; using testing::Return; using testing::SetArgPointee; @@ -321,11 +321,6 @@ struct DisplayVariant { // Whether the display is primary static constexpr Primary PRIMARY = primary; - static constexpr auto displayType() { - return static_cast(PRIMARY) ? EventThread::DisplayType::Primary - : EventThread::DisplayType::External; - } - static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) { auto injector = FakeDisplayDeviceInjector(test->mFlinger, DISPLAY_ID::get(), @@ -1470,6 +1465,9 @@ public: template void setupCommonPreconditions(); + template + static void expectHotplugReceived(mock::EventThread*); + template void setupCommonCallExpectationsForConnectProcessing(); @@ -1507,6 +1505,17 @@ void HandleTransactionLockedTest::setupCommonPreconditions() { injectFakeNativeWindowSurfaceFactory(); } +template +void HandleTransactionLockedTest::expectHotplugReceived(mock::EventThread* eventThread) { + const auto convert = [](auto physicalDisplayId) { + return std::make_optional(DisplayId{physicalDisplayId}); + }; + + EXPECT_CALL(*eventThread, + onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected)) + .Times(1); +} + template void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() { Case::Display::setupHwcHotplugCallExpectations(this); @@ -1522,16 +1531,16 @@ void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessin EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1); - EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::displayType(), true)).Times(1); - EXPECT_CALL(*mSFEventThread, onHotplugReceived(Case::Display::displayType(), true)).Times(1); + expectHotplugReceived(mEventThread); + expectHotplugReceived(mSFEventThread); } template void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() { EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1); - EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::displayType(), false)).Times(1); - EXPECT_CALL(*mSFEventThread, onHotplugReceived(Case::Display::displayType(), false)).Times(1); + expectHotplugReceived(mEventThread); + expectHotplugReceived(mSFEventThread); } template diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp index dd90063d93..ad7dcb4217 100644 --- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp +++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp @@ -36,6 +36,9 @@ using testing::Invoke; namespace android { namespace { +constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = 111; +constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID = 222; + class MockVSyncSource : public VSyncSource { public: MOCK_METHOD1(setVSyncEnabled, void(bool)); @@ -72,7 +75,7 @@ protected: ConnectionEventRecorder& connectionEventRecorder, nsecs_t expectedTimestamp, unsigned expectedCount); void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount); - void expectHotplugEventReceivedByConnection(EventThread::DisplayType expectedDisplayType, + void expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId, bool expectedConnected); AsyncCallRecorder mVSyncSetEnabledCallRecorder; @@ -106,8 +109,8 @@ EventThreadTest::EventThreadTest() { mConnection = createConnection(mConnectionEventCallRecorder); // A display must be connected for VSYNC events to be delivered. - mThread->onHotplugReceived(EventThread::DisplayType::Primary, true); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, true); + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true); } EventThreadTest::~EventThreadTest() { @@ -183,16 +186,13 @@ void EventThreadTest::expectVsyncEventReceivedByConnection(nsecs_t expectedTimes expectedCount); } -void EventThreadTest::expectHotplugEventReceivedByConnection( - EventThread::DisplayType expectedDisplayType, bool expectedConnected) { - const uint32_t expectedDisplayId = - expectedDisplayType == EventThread::DisplayType::Primary ? 0 : 1; - +void EventThreadTest::expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId, + bool expectedConnected) { auto args = mConnectionEventCallRecorder.waitForCall(); ASSERT_TRUE(args.has_value()); const auto& event = std::get<0>(args.value()); EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type); - EXPECT_EQ(expectedDisplayId, event.header.id); + EXPECT_EQ(expectedDisplayId, event.header.displayId); EXPECT_EQ(expectedConnected, event.hotplug.connected); } @@ -212,8 +212,8 @@ TEST_F(EventThreadTest, canCreateAndDestroyThreadWithNoEventsSent) { } TEST_F(EventThreadTest, vsyncRequestIsIgnoredIfDisplayIsDisconnected) { - mThread->onHotplugReceived(EventThread::DisplayType::Primary, false); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, false); + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false); // Signal that we want the next vsync event to be posted to the connection. mThread->requestNextVsync(mConnection, false); @@ -400,24 +400,24 @@ TEST_F(EventThreadTest, setPhaseOffsetForwardsToVSyncSource) { expectVSyncSetPhaseOffsetCallReceived(321); } -TEST_F(EventThreadTest, postHotplugPrimaryDisconnect) { - mThread->onHotplugReceived(EventThread::DisplayType::Primary, false); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, false); +TEST_F(EventThreadTest, postHotplugInternalDisconnect) { + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false); } -TEST_F(EventThreadTest, postHotplugPrimaryConnect) { - mThread->onHotplugReceived(EventThread::DisplayType::Primary, true); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, true); +TEST_F(EventThreadTest, postHotplugInternalConnect) { + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true); } TEST_F(EventThreadTest, postHotplugExternalDisconnect) { - mThread->onHotplugReceived(EventThread::DisplayType::External, false); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::External, false); + mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, false); + expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, false); } TEST_F(EventThreadTest, postHotplugExternalConnect) { - mThread->onHotplugReceived(EventThread::DisplayType::External, true); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::External, true); + mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, true); + expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, true); } } // namespace diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp index 4d9aec6b66..0db96d95ce 100644 --- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp +++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp @@ -18,6 +18,8 @@ using testing::Return; namespace android { +constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID = 999; + class SchedulerTest : public testing::Test { protected: class MockEventThreadConnection : public android::EventThreadConnection { @@ -104,8 +106,7 @@ TEST_F(SchedulerTest, testNullPtr) { EXPECT_TRUE(returnedValue == nullptr); EXPECT_TRUE(mScheduler->getEventThread(nullptr) == nullptr); EXPECT_TRUE(mScheduler->getEventConnection(nullptr) == nullptr); - ASSERT_NO_FATAL_FAILURE( - mScheduler->hotplugReceived(nullptr, EventThread::DisplayType::Primary, false)); + ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(nullptr, PHYSICAL_DISPLAY_ID, false)); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(nullptr)); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(nullptr)); std::string testString; @@ -129,8 +130,8 @@ TEST_F(SchedulerTest, invalidConnectionHandle) { // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads. EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0); - ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(connectionHandle, - EventThread::DisplayType::Primary, false)); + ASSERT_NO_FATAL_FAILURE( + mScheduler->hotplugReceived(connectionHandle, PHYSICAL_DISPLAY_ID, false)); EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(0); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(connectionHandle)); @@ -158,10 +159,9 @@ TEST_F(SchedulerTest, validConnectionHandle) { EXPECT_TRUE(mScheduler->getEventThread(mConnectionHandle) != nullptr); EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle) != nullptr); - EXPECT_CALL(*mEventThread, onHotplugReceived(EventThread::DisplayType::Primary, false)) - .Times(1); - ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(mConnectionHandle, - EventThread::DisplayType::Primary, false)); + EXPECT_CALL(*mEventThread, onHotplugReceived(PHYSICAL_DISPLAY_ID, false)).Times(1); + ASSERT_NO_FATAL_FAILURE( + mScheduler->hotplugReceived(mConnectionHandle, PHYSICAL_DISPLAY_ID, false)); EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(1); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(mConnectionHandle)); diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h index 3242ef12a4..aaf67e9559 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h +++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h @@ -31,7 +31,7 @@ public: MOCK_CONST_METHOD1(createEventConnection, sp(ResyncCallback)); MOCK_METHOD0(onScreenReleased, void()); MOCK_METHOD0(onScreenAcquired, void()); - MOCK_METHOD2(onHotplugReceived, void(DisplayType, bool)); + MOCK_METHOD2(onHotplugReceived, void(PhysicalDisplayId, bool)); MOCK_CONST_METHOD1(dump, void(std::string&)); MOCK_METHOD1(setPhaseOffset, void(nsecs_t phaseOffset)); MOCK_METHOD1(registerDisplayEventConnection, -- cgit v1.2.3-59-g8ed1b From 9e919eb8c26c96e3276474dd52adbc24067c1d29 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Thu, 7 Mar 2019 23:21:40 -0800 Subject: systrace: monitor GPU completion fence and HWC release fence Bug: 127781085 Test: build, flash, boot and take systrace with gfx category Change-Id: I7a1e28a7498bcdfd1b4286fffbe6d58bddddf049 --- libs/gui/Surface.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 3affa23482..af6373df57 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -20,6 +20,11 @@ #include +#include +#include +#include +#include + #include #include @@ -450,6 +455,74 @@ int Surface::setSwapInterval(int interval) { return NO_ERROR; } +class FenceMonitor { +public: + explicit FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) { + std::thread thread(&FenceMonitor::loop, this); + pthread_setname_np(thread.native_handle(), mName); + thread.detach(); + } + + void queueFence(const sp& fence) { + char message[64]; + + std::lock_guard lock(mMutex); + snprintf(message, sizeof(message), "Trace fence %u", mFencesQueued); + ATRACE_NAME(message); + + mQueue.push_back(fence); + mCondition.notify_one(); + mFencesQueued++; + ATRACE_INT(mName, int32_t(mQueue.size())); + } + +private: +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-noreturn" + void loop() { + while (true) { + threadLoop(); + } + } +#pragma clang diagnostic pop + + void threadLoop() { + sp fence; + uint32_t fenceNum; + { + std::unique_lock lock(mMutex); + while (mQueue.empty()) { + mCondition.wait(lock); + } + fence = mQueue[0]; + fenceNum = mFencesSignaled; + } + { + char message[64]; + snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum); + ATRACE_NAME(message); + + status_t result = fence->waitForever(message); + if (result != OK) { + ALOGE("Error waiting for fence: %d", result); + } + } + { + std::lock_guard lock(mMutex); + mQueue.pop_front(); + mFencesSignaled++; + ATRACE_INT(mName, int32_t(mQueue.size())); + } + } + + const char* mName; + uint32_t mFencesQueued; + uint32_t mFencesSignaled; + std::deque> mQueue; + std::condition_variable mCondition; + std::mutex mMutex; +}; + int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { ATRACE_CALL(); ALOGV("Surface::dequeueBuffer"); @@ -519,6 +592,11 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { // this should never happen ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); + if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { + static FenceMonitor hwcReleaseThread("HWC release"); + hwcReleaseThread.queueFence(fence); + } + if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { freeAllBuffers(); } @@ -761,6 +839,11 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mQueueBufferCondition.broadcast(); + if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { + static FenceMonitor gpuCompletionThread("GPU completion"); + gpuCompletionThread.queueFence(fence); + } + return err; } -- cgit v1.2.3-59-g8ed1b From 28178135a31b8fd395398b45709b1d414903ab81 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Fri, 8 Mar 2019 17:14:53 -0800 Subject: systrace: avoid queuing signaled fence in FenceMonitor If the HWC release fence dequeued has already signaled, the existing mechanism will still queue it and show it later if there's release fence waiting, which is not accurate. This change will avoid queuing signaled fences into FenceMonitor to make the trace more reasonable. Bug: 127781085 Test: build, flash, boot and take systrace with gfx category Change-Id: Ie607f690bba8ccdfab4d02793abcf21e18c3eb63 --- libs/gui/Surface.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index af6373df57..6460325582 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -467,7 +467,15 @@ public: char message[64]; std::lock_guard lock(mMutex); - snprintf(message, sizeof(message), "Trace fence %u", mFencesQueued); + if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) { + snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued); + ATRACE_NAME(message); + // Need an increment on both to make the trace number correct. + mFencesQueued++; + mFencesSignaled++; + return; + } + snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued); ATRACE_NAME(message); mQueue.push_back(fence); -- cgit v1.2.3-59-g8ed1b From f0c12503208923c6b699853d54f9fa3fe1349728 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 13 Mar 2019 16:09:05 -0700 Subject: systrace: forbid FrameEventHistory from stealing the fence Previously if EGL_TIMESTAMPS_ANDROID is used, FrameEventHistory will steal the ownership of the acquire fence after queueBuffer. The FenceMonitor for tracing the GPU completion fence will crash in that case. Bug: 127781085 Test: install bouncyball.apk and do systrace without crashing Change-Id: I6679324eb2a3b9366c957db4e9a14da5a87e98e8 --- libs/gui/Surface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 6460325582..93b41914bf 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -816,7 +816,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { // The consumer doesn't send it back to prevent us from having two // file descriptors of the same fence. mFrameEventHistory->updateAcquireFence(mNextFrameNumber, - std::make_shared(std::move(fence))); + std::make_shared(fence)); // Cache timestamps of signaled fences so we can close their file // descriptors. -- cgit v1.2.3-59-g8ed1b From 5eb3f064a6a0d73d1e7acff3a3b20d6ce9ef0aa3 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Mon, 8 Apr 2019 08:21:03 -0700 Subject: Make NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY transforms sticky When a client sets the NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY flag, the buffer producer may override the flag if it sets a buffer transform. The second issue is that SurfaceFlinger may apply a transform hint based on display orientation which may be applied by the buffer producer. The flag NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY indicates the client wants to submit buffers in the same orientation regardless of display orientation. So if the flag is set, make it sticky until the surface is disconnected. Secondly, ignore the transform hint if the flag is set. Test: Launch test app and test seamless rotation in portrait mode and landscape mode Test: go/wm-smoke Test: atest libsurfaceflinger_unittest libgui_test SurfaceFlinger_test Bug: 127953232 Change-Id: Ic153faae0f3cdc9d385cdfe8162d3caabac60901 --- libs/gui/Surface.cpp | 23 +++++++++++++++++++---- libs/gui/include/gui/Surface.h | 1 + services/surfaceflinger/Layer.cpp | 6 ++---- 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 93b41914bf..e6eb327c6f 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -829,8 +829,9 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mDefaultHeight = output.height; mNextFrameNumber = output.nextFrameNumber; - // Disable transform hint if sticky transform is set. - if (mStickyTransform == 0) { + // Ignore transform hint if sticky transform is set or transform to display inverse flag is + // set. + if (mStickyTransform == 0 && !transformToDisplayInverse()) { mTransformHint = output.transformHint; } @@ -1271,6 +1272,11 @@ int Surface::dispatchGetConsumerUsage64(va_list args) { return getConsumerUsage(usage); } +bool Surface::transformToDisplayInverse() { + return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == + NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; +} + int Surface::connect(int api) { static sp listener = new DummyProducerListener(); return connect(api, listener); @@ -1293,8 +1299,10 @@ int Surface::connect( mDefaultHeight = output.height; mNextFrameNumber = output.nextFrameNumber; - // Disable transform hint if sticky transform is set. - if (mStickyTransform == 0) { + // Ignore transform hint if sticky transform is set or transform to display inverse flag is + // set. Transform hint should be ignored if the client is expected to always submit buffers + // in the same orientation. + if (mStickyTransform == 0 && !transformToDisplayInverse()) { mTransformHint = output.transformHint; } @@ -1591,6 +1599,13 @@ int Surface::setBuffersTransform(uint32_t transform) ATRACE_CALL(); ALOGV("Surface::setBuffersTransform"); Mutex::Autolock lock(mMutex); + // Ensure NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY is sticky. If the client sets the flag, do not + // override it until the surface is disconnected. This is a temporary workaround for camera + // until they switch to using Buffer State Layers. Currently if client sets the buffer transform + // it may be overriden by the buffer producer when the producer sets the buffer transform. + if (transformToDisplayInverse()) { + transform |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; + } mTransform = transform; return NO_ERROR; } diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 248e105d04..0c471bb701 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -230,6 +230,7 @@ private: int dispatchGetWideColorSupport(va_list args); int dispatchGetHdrSupport(va_list args); int dispatchGetConsumerUsage64(va_list args); + bool transformToDisplayInverse(); protected: virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 7965245823..aa7ff81dd6 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1225,10 +1225,8 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const { void Layer::updateTransformHint(const sp& display) const { uint32_t orientation = 0; - // Disable setting transform hint if the debug flag is set or if the - // getTransformToDisplayInverse flag is set and the client wants to submit buffers - // in one orientation. - if (!mFlinger->mDebugDisableTransformHint && !getTransformToDisplayInverse()) { + // Disable setting transform hint if the debug flag is set. + if (!mFlinger->mDebugDisableTransformHint) { // The transform hint is used to improve performance, but we can // only have a single transform hint, it cannot // apply to all displays. -- cgit v1.2.3-59-g8ed1b