diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 144 | ||||
| -rw-r--r-- | libs/gui/Surface.cpp | 6 | ||||
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 5 | ||||
| -rw-r--r-- | libs/gui/include/gui/BLASTBufferQueue.h | 8 | ||||
| -rw-r--r-- | libs/gui/include/gui/Surface.h | 2 | ||||
| -rw-r--r-- | libs/gui/include/gui/TraceUtils.h | 16 | ||||
| -rw-r--r-- | libs/nativewindow/include/system/window.h | 5 | ||||
| -rw-r--r-- | libs/sensor/ISensorServer.cpp | 12 | ||||
| -rw-r--r-- | libs/sensor/Sensor.cpp | 6 | ||||
| -rw-r--r-- | libs/sensor/SensorManager.cpp | 15 | ||||
| -rw-r--r-- | libs/sensor/include/sensor/SensorManager.h | 1 |
11 files changed, 142 insertions, 78 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 97c467053e..000f458fd1 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -485,20 +485,26 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId, mSyncedFrameNumbers.erase(callbackId.framenumber); } -void BLASTBufferQueue::acquireNextBufferLocked( +status_t BLASTBufferQueue::acquireNextBufferLocked( const std::optional<SurfaceComposerClient::Transaction*> transaction) { - // If the next transaction is set, we want to guarantee the our acquire will not fail, so don't - // include the extra buffer when checking if we can acquire the next buffer. - const bool includeExtraAcquire = !transaction; - const bool maxAcquired = maxBuffersAcquired(includeExtraAcquire); - if (mNumFrameAvailable == 0 || maxAcquired) { - BQA_LOGV("Can't process next buffer maxBuffersAcquired=%s", boolToString(maxAcquired)); - return; + // Check if we have frames available and we have not acquired the maximum number of buffers. + // Even with this check, the consumer can fail to acquire an additional buffer if the consumer + // has already acquired (mMaxAcquiredBuffers + 1) and the new buffer is not droppable. In this + // case mBufferItemConsumer->acquireBuffer will return with NO_BUFFER_AVAILABLE. + if (mNumFrameAvailable == 0) { + BQA_LOGV("Can't acquire next buffer. No available frames"); + return BufferQueue::NO_BUFFER_AVAILABLE; + } + + if (mNumAcquired >= (mMaxAcquiredBuffers + 2)) { + BQA_LOGV("Can't acquire next buffer. Already acquired max frames %d max:%d + 2", + mNumAcquired, mMaxAcquiredBuffers); + return BufferQueue::NO_BUFFER_AVAILABLE; } if (mSurfaceControl == nullptr) { BQA_LOGE("ERROR : surface control is null"); - return; + return NAME_NOT_FOUND; } SurfaceComposerClient::Transaction localTransaction; @@ -515,10 +521,10 @@ void BLASTBufferQueue::acquireNextBufferLocked( mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false); if (status == BufferQueue::NO_BUFFER_AVAILABLE) { BQA_LOGV("Failed to acquire a buffer, err=NO_BUFFER_AVAILABLE"); - return; + return status; } else if (status != OK) { BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str()); - return; + return status; } auto buffer = bufferItem.mGraphicBuffer; @@ -528,7 +534,7 @@ void BLASTBufferQueue::acquireNextBufferLocked( if (buffer == nullptr) { mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE); BQA_LOGE("Buffer was empty"); - return; + return BAD_VALUE; } if (rejectBuffer(bufferItem)) { @@ -537,8 +543,7 @@ void BLASTBufferQueue::acquireNextBufferLocked( mSize.width, mSize.height, mRequestedSize.width, mRequestedSize.height, buffer->getWidth(), buffer->getHeight(), bufferItem.mTransform); mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE); - acquireNextBufferLocked(transaction); - return; + return acquireNextBufferLocked(transaction); } mNumAcquired++; @@ -592,9 +597,23 @@ void BLASTBufferQueue::acquireNextBufferLocked( t->setDesiredPresentTime(bufferItem.mTimestamp); } - if (!mNextFrameTimelineInfoQueue.empty()) { - t->setFrameTimelineInfo(mNextFrameTimelineInfoQueue.front()); - mNextFrameTimelineInfoQueue.pop(); + // Drop stale frame timeline infos + while (!mPendingFrameTimelines.empty() && + mPendingFrameTimelines.front().first < bufferItem.mFrameNumber) { + ATRACE_FORMAT_INSTANT("dropping stale frameNumber: %" PRIu64 " vsyncId: %" PRId64, + mPendingFrameTimelines.front().first, + mPendingFrameTimelines.front().second.vsyncId); + mPendingFrameTimelines.pop(); + } + + if (!mPendingFrameTimelines.empty() && + mPendingFrameTimelines.front().first == bufferItem.mFrameNumber) { + ATRACE_FORMAT_INSTANT("Transaction::setFrameTimelineInfo frameNumber: %" PRIu64 + " vsyncId: %" PRId64, + bufferItem.mFrameNumber, + mPendingFrameTimelines.front().second.vsyncId); + t->setFrameTimelineInfo(mPendingFrameTimelines.front().second); + mPendingFrameTimelines.pop(); } { @@ -626,6 +645,7 @@ void BLASTBufferQueue::acquireNextBufferLocked( bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp ? "(auto)" : "", static_cast<uint32_t>(mPendingTransactions.size()), bufferItem.mGraphicBuffer->getId(), bufferItem.mAutoRefresh ? " mAutoRefresh" : "", bufferItem.mTransform); + return OK; } Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { @@ -648,44 +668,19 @@ void BLASTBufferQueue::acquireAndReleaseBuffer() { mBufferItemConsumer->releaseBuffer(bufferItem, bufferItem.mFence); } -void BLASTBufferQueue::flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& lock) { - if (!mSyncedFrameNumbers.empty() && mNumFrameAvailable > 0) { - // We are waiting on a previous sync's transaction callback so allow another sync - // transaction to proceed. - // - // We need to first flush out the transactions that were in between the two syncs. - // We do this by merging them into mSyncTransaction so any buffer merging will get - // a release callback invoked. The release callback will be async so we need to wait - // on max acquired to make sure we have the capacity to acquire another buffer. - if (maxBuffersAcquired(false /* includeExtraAcquire */)) { - BQA_LOGD("waiting to flush shadow queue..."); - mCallbackCV.wait(lock); - } - while (mNumFrameAvailable > 0) { - // flush out the shadow queue - acquireAndReleaseBuffer(); - } - } - - while (maxBuffersAcquired(false /* includeExtraAcquire */)) { - BQA_LOGD("waiting for free buffer."); - mCallbackCV.wait(lock); - } -} - void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr; SurfaceComposerClient::Transaction* prevTransaction = nullptr; - bool waitForTransactionCallback = !mSyncedFrameNumbers.empty(); { - BBQ_TRACE(); std::unique_lock _lock{mMutex}; + BBQ_TRACE(); + + bool waitForTransactionCallback = !mSyncedFrameNumbers.empty(); const bool syncTransactionSet = mTransactionReadyCallback != nullptr; BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet)); if (syncTransactionSet) { - bool mayNeedToWaitForBuffer = true; // If we are going to re-use the same mSyncTransaction, release the buffer that may // already be set in the Transaction. This is to allow us a free slot early to continue // processing a new buffer. @@ -696,14 +691,29 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { bufferData->frameNumber); releaseBuffer(bufferData->generateReleaseCallbackId(), bufferData->acquireFence); - // Because we just released a buffer, we know there's no need to wait for a free - // buffer. - mayNeedToWaitForBuffer = false; } } - if (mayNeedToWaitForBuffer) { - flushAndWaitForFreeBuffer(_lock); + if (waitForTransactionCallback) { + // We are waiting on a previous sync's transaction callback so allow another sync + // transaction to proceed. + // + // We need to first flush out the transactions that were in between the two syncs. + // We do this by merging them into mSyncTransaction so any buffer merging will get + // a release callback invoked. + while (mNumFrameAvailable > 0) { + // flush out the shadow queue + acquireAndReleaseBuffer(); + } + } else { + // Make sure the frame available count is 0 before proceeding with a sync to ensure + // the correct frame is used for the sync. The only way mNumFrameAvailable would be + // greater than 0 is if we already ran out of buffers previously. This means we + // need to flush the buffers before proceeding with the sync. + while (mNumFrameAvailable > 0) { + BQA_LOGD("waiting until no queued buffers"); + mCallbackCV.wait(_lock); + } } } @@ -719,14 +729,23 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { item.mFrameNumber, boolToString(syncTransactionSet)); if (syncTransactionSet) { - acquireNextBufferLocked(mSyncTransaction); + // Add to mSyncedFrameNumbers before waiting in case any buffers are released + // while waiting for a free buffer. The release and commit callback will try to + // acquire buffers if there are any available, but we don't want it to acquire + // in the case where a sync transaction wants the buffer. + mSyncedFrameNumbers.emplace(item.mFrameNumber); + // If there's no available buffer and we're in a sync transaction, we need to wait + // instead of returning since we guarantee a buffer will be acquired for the sync. + while (acquireNextBufferLocked(mSyncTransaction) == BufferQueue::NO_BUFFER_AVAILABLE) { + BQA_LOGD("waiting for available buffer"); + mCallbackCV.wait(_lock); + } // Only need a commit callback when syncing to ensure the buffer that's synced has been // sent to SF incStrong((void*)transactionCommittedCallbackThunk); mSyncTransaction->addTransactionCommittedCallback(transactionCommittedCallbackThunk, static_cast<void*>(this)); - mSyncedFrameNumbers.emplace(item.mFrameNumber); if (mAcquireSingleBuffer) { prevCallback = mTransactionReadyCallback; prevTransaction = mSyncTransaction; @@ -829,15 +848,6 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { return mSize != bufferSize; } -// Check if we have acquired the maximum number of buffers. -// Consumer can acquire an additional buffer if that buffer is not droppable. Set -// includeExtraAcquire is true to include this buffer to the count. Since this depends on the state -// of the buffer, the next acquire may return with NO_BUFFER_AVAILABLE. -bool BLASTBufferQueue::maxBuffersAcquired(bool includeExtraAcquire) const { - int maxAcquiredBuffers = mMaxAcquiredBuffers + (includeExtraAcquire ? 2 : 1); - return mNumAcquired >= maxAcquiredBuffers; -} - class BBQSurface : public Surface { private: std::mutex mMutex; @@ -874,12 +884,13 @@ public: return mBbq->setFrameRate(frameRate, compatibility, changeFrameRateStrategy); } - status_t setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) override { + status_t setFrameTimelineInfo(uint64_t frameNumber, + const FrameTimelineInfo& frameTimelineInfo) override { std::unique_lock _lock{mMutex}; if (mDestroyed) { return DEAD_OBJECT; } - return mBbq->setFrameTimelineInfo(frameTimelineInfo); + return mBbq->setFrameTimelineInfo(frameNumber, frameTimelineInfo); } void destroy() override { @@ -901,9 +912,12 @@ status_t BLASTBufferQueue::setFrameRate(float frameRate, int8_t compatibility, return t.setFrameRate(mSurfaceControl, frameRate, compatibility, shouldBeSeamless).apply(); } -status_t BLASTBufferQueue::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) { +status_t BLASTBufferQueue::setFrameTimelineInfo(uint64_t frameNumber, + const FrameTimelineInfo& frameTimelineInfo) { + ATRACE_FORMAT("%s(%s) frameNumber: %" PRIu64 " vsyncId: %" PRId64, __func__, mName.c_str(), + frameNumber, frameTimelineInfo.vsyncId); std::unique_lock _lock{mMutex}; - mNextFrameTimelineInfoQueue.push(frameTimelineInfo); + mPendingFrameTimelines.push({frameNumber, frameTimelineInfo}); return OK; } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 100e36e7b3..16edfd4267 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1869,12 +1869,13 @@ int Surface::dispatchGetLastQueuedBuffer2(va_list args) { int Surface::dispatchSetFrameTimelineInfo(va_list args) { ATRACE_CALL(); + auto frameNumber = static_cast<uint64_t>(va_arg(args, uint64_t)); auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t)); auto inputEventId = static_cast<int32_t>(va_arg(args, int32_t)); auto startTimeNanos = static_cast<int64_t>(va_arg(args, int64_t)); ALOGV("Surface::%s", __func__); - return setFrameTimelineInfo({frameTimelineVsyncId, inputEventId, startTimeNanos}); + return setFrameTimelineInfo(frameNumber, {frameTimelineVsyncId, inputEventId, startTimeNanos}); } bool Surface::transformToDisplayInverse() const { @@ -2648,7 +2649,8 @@ status_t Surface::setFrameRate(float frameRate, int8_t compatibility, changeFrameRateStrategy); } -status_t Surface::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) { +status_t Surface::setFrameTimelineInfo(uint64_t /*frameNumber*/, + const FrameTimelineInfo& frameTimelineInfo) { return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo); } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 0f5192d41c..05beb07891 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1274,8 +1274,11 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha mStatus = BAD_INDEX; return *this; } + if (alpha < 0.0f || alpha > 1.0f) { + ALOGE("SurfaceComposerClient::Transaction::setAlpha: invalid alpha %f, clamping", alpha); + } s->what |= layer_state_t::eAlphaChanged; - s->alpha = alpha; + s->alpha = std::clamp(alpha, 0.f, 1.f); registerSurfaceControlForCallback(sc); return *this; diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index 1278931202..40ffea6809 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -111,7 +111,7 @@ public: void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format); status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); - status_t setFrameTimelineInfo(const FrameTimelineInfo& info); + status_t setFrameTimelineInfo(uint64_t frameNumber, const FrameTimelineInfo& info); void setSidebandStream(const sp<NativeHandle>& stream); @@ -141,12 +141,11 @@ private: void resizeFrameEventHistory(size_t newSize); - void acquireNextBufferLocked( + status_t acquireNextBufferLocked( const std::optional<SurfaceComposerClient::Transaction*> transaction) REQUIRES(mMutex); Rect computeCrop(const BufferItem& item) REQUIRES(mMutex); // Return true if we need to reject the buffer based on the scaling mode and the buffer size. bool rejectBuffer(const BufferItem& item) REQUIRES(mMutex); - bool maxBuffersAcquired(bool includeExtraAcquire) const REQUIRES(mMutex); static PixelFormat convertBufferFormat(PixelFormat& format); void mergePendingTransactions(SurfaceComposerClient::Transaction* t, uint64_t frameNumber) REQUIRES(mMutex); @@ -155,7 +154,6 @@ private: void acquireAndReleaseBuffer() REQUIRES(mMutex); void releaseBuffer(const ReleaseCallbackId& callbackId, const sp<Fence>& releaseFence) REQUIRES(mMutex); - void flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& lock); std::string mName; // Represents the queued buffer count from buffer queue, @@ -244,7 +242,7 @@ private: std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>> mPendingTransactions GUARDED_BY(mMutex); - std::queue<FrameTimelineInfo> mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); + std::queue<std::pair<uint64_t, FrameTimelineInfo>> mPendingFrameTimelines GUARDED_BY(mMutex); // Tracks the last acquired frame number uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0; diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 77615fe4c1..4a552b6643 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -211,7 +211,7 @@ public: virtual status_t setFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy); - virtual status_t setFrameTimelineInfo(const FrameTimelineInfo& info); + virtual status_t setFrameTimelineInfo(uint64_t frameNumber, const FrameTimelineInfo& info); protected: virtual ~Surface(); diff --git a/libs/gui/include/gui/TraceUtils.h b/libs/gui/include/gui/TraceUtils.h index e5d268445c..00096158e7 100644 --- a/libs/gui/include/gui/TraceUtils.h +++ b/libs/gui/include/gui/TraceUtils.h @@ -27,6 +27,8 @@ #define ATRACE_FORMAT_BEGIN(fmt, ...) TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__) +#define ATRACE_FORMAT_INSTANT(fmt, ...) TraceUtils::intantFormat(fmt, ##__VA_ARGS__) + namespace android { class TraceUtils { @@ -50,6 +52,20 @@ public: ATRACE_BEGIN(buf); } + static void intantFormat(const char* fmt, ...) { + if (CC_LIKELY(!ATRACE_ENABLED())) return; + + const int BUFFER_SIZE = 256; + va_list ap; + char buf[BUFFER_SIZE]; + + va_start(ap, fmt); + vsnprintf(buf, BUFFER_SIZE, fmt, ap); + va_end(ap); + + ATRACE_INSTANT(buf); + } + }; // class TraceUtils } /* namespace android */ diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index a54af1fa62..86e76c4f2c 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -1043,11 +1043,12 @@ static inline int native_window_set_frame_rate(struct ANativeWindow* window, flo } static inline int native_window_set_frame_timeline_info(struct ANativeWindow* window, + uint64_t frameNumber, int64_t frameTimelineVsyncId, int32_t inputEventId, int64_t startTimeNanos) { - return window->perform(window, NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO, frameTimelineVsyncId, - inputEventId, startTimeNanos); + return window->perform(window, NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO, frameNumber, + frameTimelineVsyncId, inputEventId, startTimeNanos); } // ------------------------------------------------------------------------------------------------ diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp index a6cacad374..93c95b98c5 100644 --- a/libs/sensor/ISensorServer.cpp +++ b/libs/sensor/ISensorServer.cpp @@ -66,7 +66,11 @@ public: v.setCapacity(n); while (n) { n--; - reply.read(s); + if(reply.read(s) != OK) { + ALOGE("Failed to read reply from getSensorList"); + v.clear(); + break; + } v.add(s); } return v; @@ -84,7 +88,11 @@ public: v.setCapacity(n); while (n) { n--; - reply.read(s); + if(reply.read(s) != OK) { + ALOGE("Failed to read reply from getDynamicSensorList"); + v.clear(); + break; + } v.add(s); } return v; diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp index ec0ced8663..b865c4d5d6 100644 --- a/libs/sensor/Sensor.cpp +++ b/libs/sensor/Sensor.cpp @@ -632,7 +632,13 @@ bool Sensor::unflattenString8(void const*& buffer, size_t& size, String8& output return false; } outputString8.setTo(static_cast<char const*>(buffer), len); + + if (size < FlattenableUtils::align<4>(len)) { + ALOGE("Malformed Sensor String8 field. Should be in a 4-byte aligned buffer but is not."); + return false; + } FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); + return true; } diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp index 0ba9704263..40061cde61 100644 --- a/libs/sensor/SensorManager.cpp +++ b/libs/sensor/SensorManager.cpp @@ -92,6 +92,16 @@ SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) return *sensorManager; } +void SensorManager::removeInstanceForPackage(const String16& packageName) { + Mutex::Autolock _l(sLock); + auto iterator = sPackageInstances.find(packageName); + if (iterator != sPackageInstances.end()) { + SensorManager* sensorManager = iterator->second; + delete sensorManager; + sPackageInstances.erase(iterator); + } +} + SensorManager::SensorManager(const String16& opPackageName) : mSensorList(nullptr), mOpPackageName(opPackageName), mDirectConnectionHandle(1) { Mutex::Autolock _l(mLock); @@ -166,6 +176,11 @@ status_t SensorManager::assertStateLocked() { mSensors = mSensorServer->getSensorList(mOpPackageName); size_t count = mSensors.size(); + if (count == 0) { + ALOGE("Failed to get Sensor list"); + mSensorServer.clear(); + return UNKNOWN_ERROR; + } mSensorList = static_cast<Sensor const**>(malloc(count * sizeof(Sensor*))); LOG_ALWAYS_FATAL_IF(mSensorList == nullptr, "mSensorList NULL"); diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h index 8d0a8a45d9..7c9d604ff7 100644 --- a/libs/sensor/include/sensor/SensorManager.h +++ b/libs/sensor/include/sensor/SensorManager.h @@ -54,6 +54,7 @@ class SensorManager : public ASensorManager { public: static SensorManager& getInstanceForPackage(const String16& packageName); + static void removeInstanceForPackage(const String16& packageName); ~SensorManager(); ssize_t getSensorList(Sensor const* const** list); |