diff options
author | Jorim Jaggi <jjaggi@google.com> | 2018-07-17 13:48:33 +0200 |
---|---|---|
committer | Jorim Jaggi <jjaggi@google.com> | 2018-07-17 16:57:06 +0200 |
commit | 0a3e7847012108f047a6582ebfb88026d640277f (patch) | |
tree | 38f6fc2edc609a577b6b9a33740aa0a00cc5a75f | |
parent | 9885bd4b3faf93a5651f069e52cbb346418e6ca5 (diff) | |
download | native-0a3e7847012108f047a6582ebfb88026d640277f.tar.gz |
Do not block on allocating buffers
There is really no point in doing that because this can be done
in an async way such that the first and subsequent dequeueBuffer
still don't block because at that point allocation is very likely
done.
Furthermore, avoid calling setAsyncMode initially, as it will also
block RT on buffer allocation. However, the default is false in
any case, so we really don't need to call it.
Also, only allocate one buffer at a time and don't block in
dequeueBuffer on allocating buffers. It will likely have one buffer
available already, and there is no point in waiting for other
buffers to be allocated.
Test: Press home with memory contention, observe less delay.
Test: General smoke testing for increased jank
Bug: 111517695
Change-Id: I9deb435013b2503178d2fe032151c1aaedd667af
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 7 | ||||
-rw-r--r-- | libs/gui/IGraphicBufferProducer.cpp | 2 | ||||
-rw-r--r-- | libs/gui/Surface.cpp | 6 |
3 files changed, 10 insertions, 5 deletions
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index c8021e4d54..c96a2dd6a3 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -381,7 +381,6 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou { // Autolock scope Mutex::Autolock lock(mCore->mMutex); - mCore->waitWhileAllocatingLocked(); if (format == 0) { format = mCore->mDefaultBufferFormat; @@ -1345,7 +1344,9 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, return; } - newBufferCount = mCore->mFreeSlots.size(); + // Only allocate one buffer at a time to reduce risks of overlapping an allocation from + // both allocateBuffers and dequeueBuffer. + newBufferCount = mCore->mFreeSlots.empty() ? 0 : 1; if (newBufferCount == 0) { return; } @@ -1360,7 +1361,7 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, } // Autolock scope Vector<sp<GraphicBuffer>> buffers; - for (size_t i = 0; i < newBufferCount; ++i) { + for (size_t i = 0; i < newBufferCount; ++i) { sp<GraphicBuffer> graphicBuffer = new GraphicBuffer( allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT, allocUsage, allocName); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 0749fde1ad..0b3796056d 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -355,7 +355,7 @@ public: data.writeUint32(height); data.writeInt32(static_cast<int32_t>(format)); data.writeUint64(usage); - status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply); + status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply, TF_ONE_WAY); if (result != NO_ERROR) { ALOGE("allocateBuffers failed to transact: %d", result); } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 339bd0fa4e..2de14c8846 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -464,8 +464,12 @@ int Surface::setSwapInterval(int interval) { if (interval > maxSwapInterval) interval = maxSwapInterval; + const bool wasSwapIntervalZero = mSwapIntervalZero; mSwapIntervalZero = (interval == 0); - mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero); + + if (mSwapIntervalZero != wasSwapIntervalZero) { + mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero); + } return NO_ERROR; } |