Merge "Enable compiling dex files in isolation on low ram devices." into sc-dev
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index b9a293f..52d3fa3 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -29,9 +29,10 @@
#include <gui/IProducerListener.h>
#include <gui/Surface.h>
#include <utils/Singleton.h>
-
#include <utils/Trace.h>
+#include <private/gui/ComposerService.h>
+
#include <chrono>
using namespace std::chrono_literals;
@@ -158,6 +159,9 @@
mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
mBufferItemConsumer->setBlastBufferQueue(this);
+ ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
+ mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
+
mTransformHint = mSurfaceControl->getTransformHint();
mBufferItemConsumer->setTransformHint(mTransformHint);
SurfaceComposerClient::Transaction()
@@ -302,18 +306,20 @@
// So we pass in a weak pointer to the BBQ and if it still alive, then we release the buffer.
// Otherwise, this is a no-op.
static void releaseBufferCallbackThunk(wp<BLASTBufferQueue> context, uint64_t graphicBufferId,
- const sp<Fence>& releaseFence, uint32_t transformHint) {
+ const sp<Fence>& releaseFence, uint32_t transformHint,
+ uint32_t currentMaxAcquiredBufferCount) {
sp<BLASTBufferQueue> blastBufferQueue = context.promote();
ALOGV("releaseBufferCallbackThunk graphicBufferId=%" PRIu64 " blastBufferQueue=%s",
graphicBufferId, blastBufferQueue ? "alive" : "dead");
if (blastBufferQueue) {
- blastBufferQueue->releaseBufferCallback(graphicBufferId, releaseFence, transformHint);
+ blastBufferQueue->releaseBufferCallback(graphicBufferId, releaseFence, transformHint,
+ currentMaxAcquiredBufferCount);
}
}
void BLASTBufferQueue::releaseBufferCallback(uint64_t graphicBufferId,
- const sp<Fence>& releaseFence,
- uint32_t transformHint) {
+ const sp<Fence>& releaseFence, uint32_t transformHint,
+ uint32_t currentMaxAcquiredBufferCount) {
ATRACE_CALL();
std::unique_lock _lock{mMutex};
BQA_LOGV("releaseBufferCallback graphicBufferId=%" PRIu64, graphicBufferId);
@@ -324,15 +330,36 @@
mBufferItemConsumer->setTransformHint(mTransformHint);
}
- auto it = mSubmitted.find(graphicBufferId);
- if (it == mSubmitted.end()) {
- BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %" PRIu64,
- graphicBufferId);
- return;
+ // Calculate how many buffers we need to hold before we release them back
+ // to the buffer queue. This will prevent higher latency when we are running
+ // on a lower refresh rate than the max supported. We only do that for EGL
+ // clients as others don't care about latency
+ const bool isEGL = [&] {
+ const auto it = mSubmitted.find(graphicBufferId);
+ return it != mSubmitted.end() && it->second.mApi == NATIVE_WINDOW_API_EGL;
+ }();
+
+ const auto numPendingBuffersToHold =
+ isEGL ? std::max(0u, mMaxAcquiredBuffers - currentMaxAcquiredBufferCount) : 0;
+ mPendingRelease.emplace_back(ReleasedBuffer{graphicBufferId, releaseFence});
+
+ // Release all buffers that are beyond the ones that we need to hold
+ while (mPendingRelease.size() > numPendingBuffersToHold) {
+ const auto releaseBuffer = mPendingRelease.front();
+ mPendingRelease.pop_front();
+ auto it = mSubmitted.find(releaseBuffer.bufferId);
+ if (it == mSubmitted.end()) {
+ BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %" PRIu64,
+ graphicBufferId);
+ return;
+ }
+
+ mBufferItemConsumer->releaseBuffer(it->second, releaseBuffer.releaseFence);
+ mSubmitted.erase(it);
}
- mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
- mSubmitted.erase(it);
+ ATRACE_INT("PendingRelease", mPendingRelease.size());
+
mNumAcquired--;
processNextBufferLocked(false /* useNextTransaction */);
mCallbackCV.notify_all();
@@ -414,7 +441,8 @@
auto releaseBufferCallback =
std::bind(releaseBufferCallbackThunk, wp<BLASTBufferQueue>(this) /* callbackContext */,
- std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+ std::placeholders::_4);
t->setBuffer(mSurfaceControl, buffer, releaseBufferCallback);
t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace));
t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata);
@@ -567,7 +595,7 @@
// 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 = MAX_ACQUIRED_BUFFERS + (includeExtraAcquire ? 2 : 1);
+ int maxAcquiredBuffers = mMaxAcquiredBuffers + (includeExtraAcquire ? 2 : 1);
return mNumAcquired == maxAcquiredBuffers;
}
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 71e18a9..0d7795e 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -1215,16 +1215,17 @@
return reply.readInt32();
}
- status_t getExtraBufferCount(int* extraBuffers) const override {
+ status_t getMaxAcquiredBufferCount(int* buffers) const override {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- status_t err = remote()->transact(BnSurfaceComposer::GET_EXTRA_BUFFER_COUNT, data, &reply);
+ status_t err =
+ remote()->transact(BnSurfaceComposer::GET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
if (err != NO_ERROR) {
- ALOGE("getExtraBufferCount failed to read data: %s (%d)", strerror(-err), err);
+ ALOGE("getMaxAcquiredBufferCount failed to read data: %s (%d)", strerror(-err), err);
return err;
}
- return reply.readInt32(extraBuffers);
+ return reply.readInt32(buffers);
}
};
@@ -2069,14 +2070,14 @@
SAFE_PARCEL(reply->writeInt32, priority);
return NO_ERROR;
}
- case GET_EXTRA_BUFFER_COUNT: {
+ case GET_MAX_ACQUIRED_BUFFER_COUNT: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int extraBuffers = 0;
- int err = getExtraBufferCount(&extraBuffers);
+ int buffers = 0;
+ int err = getMaxAcquiredBufferCount(&buffers);
if (err != NO_ERROR) {
return err;
}
- SAFE_PARCEL(reply->writeInt32, extraBuffers);
+ SAFE_PARCEL(reply->writeInt32, buffers);
return NO_ERROR;
}
case OVERRIDE_HDR_TYPES: {
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index 63d07ba..17499ec 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -119,6 +119,7 @@
SAFE_PARCEL(output->writeBool, false);
}
SAFE_PARCEL(output->writeUint32, transformHint);
+ SAFE_PARCEL(output->writeUint32, currentMaxAcquiredBufferCount);
SAFE_PARCEL(output->writeParcelable, eventStats);
SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(jankData.size()));
for (const auto& data : jankData) {
@@ -138,6 +139,7 @@
SAFE_PARCEL(input->read, *previousReleaseFence);
}
SAFE_PARCEL(input->readUint32, &transformHint);
+ SAFE_PARCEL(input->readUint32, ¤tMaxAcquiredBufferCount);
SAFE_PARCEL(input->readParcelable, &eventStats);
int32_t jankData_size = 0;
@@ -251,11 +253,13 @@
stats);
}
- void onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence,
- uint32_t transformHint) override {
+ void onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint,
+ uint32_t currentMaxAcquiredBufferCount) override {
callRemoteAsync<decltype(
&ITransactionCompletedListener::onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER,
- graphicBufferId, releaseFence, transformHint);
+ graphicBufferId, releaseFence,
+ transformHint,
+ currentMaxAcquiredBufferCount);
}
};
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index e117d11..821ec16 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1501,9 +1501,6 @@
case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO:
res = dispatchSetFrameTimelineInfo(args);
break;
- case NATIVE_WINDOW_GET_EXTRA_BUFFER_COUNT:
- res = dispatchGetExtraBufferCount(args);
- break;
default:
res = NAME_NOT_FOUND;
break;
@@ -1853,14 +1850,6 @@
return setFrameTimelineInfo({frameTimelineVsyncId, inputEventId});
}
-int Surface::dispatchGetExtraBufferCount(va_list args) {
- ATRACE_CALL();
- auto extraBuffers = static_cast<int*>(va_arg(args, int*));
-
- ALOGV("Surface::dispatchGetExtraBufferCount");
- return getExtraBufferCount(extraBuffers);
-}
-
bool Surface::transformToDisplayInverse() const {
return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) ==
NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
@@ -2632,8 +2621,4 @@
return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo);
}
-status_t Surface::getExtraBufferCount(int* extraBuffers) const {
- return composerService()->getExtraBufferCount(extraBuffers);
-}
-
}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 660c5bd..c69435d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -328,7 +328,8 @@
surfaceStats.previousReleaseFence
? surfaceStats.previousReleaseFence
: Fence::NO_FENCE,
- surfaceStats.transformHint);
+ surfaceStats.transformHint,
+ surfaceStats.currentMaxAcquiredBufferCount);
}
}
}
@@ -364,9 +365,9 @@
}
}
-void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId,
- sp<Fence> releaseFence,
- uint32_t transformHint) {
+void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence,
+ uint32_t transformHint,
+ uint32_t currentMaxAcquiredBufferCount) {
ReleaseBufferCallback callback;
{
std::scoped_lock<std::mutex> lock(mMutex);
@@ -376,7 +377,7 @@
ALOGE("Could not call release buffer callback, buffer not found %" PRIu64, graphicBufferId);
return;
}
- callback(graphicBufferId, releaseFence, transformHint);
+ callback(graphicBufferId, releaseFence, transformHint, currentMaxAcquiredBufferCount);
}
ReleaseBufferCallback TransactionCompletedListener::popReleaseBufferCallbackLocked(
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index d7c07b9..6529a4e 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -139,7 +139,7 @@
ISurfaceComposerClient::eOpaque);
mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
flags, mHandle, {}, &ignore);
- mBbq = new BLASTBufferQueue("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
+ mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 3ab1ee1..0981e76 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -90,7 +90,7 @@
void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
const std::vector<SurfaceControlStats>& stats);
void releaseBufferCallback(uint64_t graphicBufferId, const sp<Fence>& releaseFence,
- uint32_t transformHint);
+ uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount);
void setNextTransaction(SurfaceComposerClient::Transaction *t);
void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber);
void setTransactionCompleteCallback(uint64_t frameNumber,
@@ -132,7 +132,7 @@
// BufferQueue internally allows 1 more than
// the max to be acquired
- static const int MAX_ACQUIRED_BUFFERS = 1;
+ int32_t mMaxAcquiredBuffers = 1;
int32_t mNumFrameAvailable GUARDED_BY(mMutex);
int32_t mNumAcquired GUARDED_BY(mMutex);
@@ -141,6 +141,15 @@
// buffer or the buffer has been presented and a new buffer is ready to be presented.
std::unordered_map<uint64_t /* bufferId */, BufferItem> mSubmitted GUARDED_BY(mMutex);
+ // Keep a queue of the released buffers instead of immediately releasing
+ // the buffers back to the buffer queue. This would be controlled by SF
+ // setting the max acquired buffer count.
+ struct ReleasedBuffer {
+ uint64_t bufferId;
+ sp<Fence> releaseFence;
+ };
+ std::deque<ReleasedBuffer> mPendingRelease GUARDED_BY(mMutex);
+
ui::Size mSize GUARDED_BY(mMutex);
ui::Size mRequestedSize GUARDED_BY(mMutex);
int32_t mFormat GUARDED_BY(mMutex);
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 439d90a..2a3f6a4 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -537,22 +537,21 @@
virtual int getGPUContextPriority() = 0;
/**
- * Gets the extra buffers a client would need to allocate if it passes
- * the Choreographer#getVsyncId with its buffers.
- *
- * When Choreographer#getVsyncId is passed to SurfaceFlinger, it is used
- * as an indication of when to latch the buffer. SurfaceFlinger will make
- * sure that it will give the app at least the time configured as the
- * 'appDuration' before trying to latch the buffer.
+ * Gets the number of buffers SurfaceFlinger would need acquire. This number
+ * would be propagated to the client via MIN_UNDEQUEUED_BUFFERS so that the
+ * client could allocate enough buffers to match SF expectations of the
+ * pipeline depth. SurfaceFlinger will make sure that it will give the app at
+ * least the time configured as the 'appDuration' before trying to latch
+ * the buffer.
*
* The total buffers needed for a given configuration is basically the
* numbers of vsyncs a single buffer is used across the stack. For the default
* configuration a buffer is held ~1 vsync by the app, ~1 vsync by SurfaceFlinger
* and 1 vsync by the display. The extra buffers are calculated as the
- * number of additional buffers on top of the 3 buffers already allocated
- * by the app.
+ * number of additional buffers on top of the 2 buffers already present
+ * in MIN_UNDEQUEUED_BUFFERS.
*/
- virtual status_t getExtraBufferCount(int* extraBuffers) const = 0;
+ virtual status_t getMaxAcquiredBufferCount(int* buffers) const = 0;
};
// ----------------------------------------------------------------------------
@@ -615,7 +614,7 @@
SET_FRAME_TIMELINE_INFO,
ADD_TRANSACTION_TRACE_LISTENER,
GET_GPU_CONTEXT_PRIORITY,
- GET_EXTRA_BUFFER_COUNT,
+ GET_MAX_ACQUIRED_BUFFER_COUNT,
GET_DYNAMIC_DISPLAY_INFO,
ADD_FPS_LISTENER,
REMOVE_FPS_LISTENER,
diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h
index 3bfeef1..d286c34 100644
--- a/libs/gui/include/gui/ITransactionCompletedListener.h
+++ b/libs/gui/include/gui/ITransactionCompletedListener.h
@@ -101,12 +101,14 @@
SurfaceStats() = default;
SurfaceStats(const sp<IBinder>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence,
- uint32_t hint, FrameEventHistoryStats frameEventStats,
- std::vector<JankData> jankData, uint64_t previousBufferId)
+ uint32_t hint, uint32_t currentMaxAcquiredBuffersCount,
+ FrameEventHistoryStats frameEventStats, std::vector<JankData> jankData,
+ uint64_t previousBufferId)
: surfaceControl(sc),
acquireTime(time),
previousReleaseFence(prevReleaseFence),
transformHint(hint),
+ currentMaxAcquiredBufferCount(currentMaxAcquiredBuffersCount),
eventStats(frameEventStats),
jankData(std::move(jankData)),
previousBufferId(previousBufferId) {}
@@ -115,6 +117,7 @@
nsecs_t acquireTime = -1;
sp<Fence> previousReleaseFence;
uint32_t transformHint = 0;
+ uint32_t currentMaxAcquiredBufferCount = 0;
FrameEventHistoryStats eventStats;
std::vector<JankData> jankData;
uint64_t previousBufferId;
@@ -159,7 +162,8 @@
virtual void onTransactionCompleted(ListenerStats stats) = 0;
virtual void onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence,
- uint32_t transformHint) = 0;
+ uint32_t transformHint,
+ uint32_t currentMaxAcquiredBufferCount) = 0;
};
class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> {
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 48885eb..7e4143b 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -190,7 +190,6 @@
virtual status_t setFrameRate(float frameRate, int8_t compatibility,
int8_t changeFrameRateStrategy);
virtual status_t setFrameTimelineInfo(const FrameTimelineInfo& info);
- virtual status_t getExtraBufferCount(int* extraBuffers) const;
protected:
virtual ~Surface();
@@ -278,7 +277,6 @@
int dispatchGetLastQueuedBuffer(va_list args);
int dispatchGetLastQueuedBuffer2(va_list args);
int dispatchSetFrameTimelineInfo(va_list args);
- int dispatchGetExtraBufferCount(va_list args);
protected:
virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 5aa132c..fa91bfa 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -83,7 +83,7 @@
const std::vector<SurfaceControlStats>& /*stats*/)>;
using ReleaseBufferCallback =
std::function<void(uint64_t /* graphicsBufferId */, const sp<Fence>& /*releaseFence*/,
- uint32_t transformHint)>;
+ uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount)>;
using SurfaceStatsCallback =
std::function<void(void* /*context*/, nsecs_t /*latchTime*/,
@@ -729,7 +729,7 @@
// BnTransactionCompletedListener overrides
void onTransactionCompleted(ListenerStats stats) override;
void onReleaseBuffer(uint64_t /* graphicsBufferId */, sp<Fence> releaseFence,
- uint32_t transformHint) override;
+ uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) override;
private:
ReleaseBufferCallback popReleaseBufferCallbackLocked(uint64_t /* graphicsBufferId */);
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index 5a5da97..06660b8 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -394,7 +394,11 @@
setUpProducer(adapter, igbProducer);
std::vector<std::pair<int, sp<Fence>>> allocated;
- for (int i = 0; i < 3; i++) {
+ int minUndequeuedBuffers = 0;
+ ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
+ const auto bufferCount = minUndequeuedBuffers + 2;
+
+ for (int i = 0; i < bufferCount; i++) {
int slot;
sp<Fence> fence;
sp<GraphicBuffer> buf;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index b8d34c3..59b0c04 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -902,7 +902,7 @@
int getGPUContextPriority() override { return 0; };
- status_t getExtraBufferCount(int* /*extraBuffers*/) const override { return NO_ERROR; }
+ status_t getMaxAcquiredBufferCount(int* /*buffers*/) const override { return NO_ERROR; }
protected:
IBinder* onAsBinder() override { return nullptr; }
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 935eded..7f01135 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -256,8 +256,7 @@
NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER = 46, /* private */
NATIVE_WINDOW_SET_QUERY_INTERCEPTOR = 47, /* private */
NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO = 48, /* private */
- NATIVE_WINDOW_GET_EXTRA_BUFFER_COUNT = 49, /* private */
- NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER2 = 50, /* private */
+ NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER2 = 49, /* private */
// clang-format on
};
@@ -1032,11 +1031,6 @@
frameTimelineVsyncId, inputEventId);
}
-static inline int native_window_get_extra_buffer_count(
- struct ANativeWindow* window, int* extraBuffers) {
- return window->perform(window, NATIVE_WINDOW_GET_EXTRA_BUFFER_COUNT, extraBuffers);
-}
-
// ------------------------------------------------------------------------------------------------
// Candidates for APEX visibility
// These functions are planned to be made stable for APEX modules, but have not
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index d28d623..cb80ef4 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -552,10 +552,25 @@
iter->second--;
+ // Swap contexts if needed prior to deleting this buffer
+ // See Issue 1 of
+ // https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_protected_content.txt: even
+ // when a protected context and an unprotected context are part of the same share group,
+ // protected surfaces may not be accessed by an unprotected context, implying that protected
+ // surfaces may only be freed when a protected context is active.
+ const bool inProtected = mInProtectedContext;
+ useProtectedContext(buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+
if (iter->second == 0) {
mTextureCache.erase(buffer->getId());
mGraphicBufferExternalRefs.erase(buffer->getId());
}
+
+ // Swap back to the previous context so that cached values of isProtected in SurfaceFlinger
+ // are up-to-date.
+ if (inProtected != mInProtectedContext) {
+ useProtectedContext(inProtected);
+ }
}
}
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index e7f373f..c64371b 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -223,7 +223,7 @@
// buffer mode.
bool queuedBuffer = false;
const int32_t layerId = getSequence();
- LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
+ LayerRejecter r(mDrawingState, getDrawingState(), recomputeVisibleRegions,
getProducerStickyTransform() != 0, mName,
getTransformToDisplayInverse());
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 6213a8a..a3b7b13 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -45,12 +45,12 @@
namespace {
void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
const sp<GraphicBuffer>& buffer, const sp<Fence>& releaseFence,
- uint32_t transformHint) {
+ uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) {
if (!listener) {
return;
}
listener->onReleaseBuffer(buffer->getId(), releaseFence ? releaseFence : Fence::NO_FENCE,
- transformHint);
+ transformHint, currentMaxAcquiredBufferCount);
}
} // namespace
@@ -65,7 +65,7 @@
BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
: BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) {
- mCurrentState.dataspace = ui::Dataspace::V0_SRGB;
+ mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
}
BufferStateLayer::~BufferStateLayer() {
@@ -76,7 +76,9 @@
if (mBufferInfo.mBuffer != nullptr && !isClone()) {
callReleaseBufferCallback(mDrawingState.releaseBufferListener,
mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFence,
- mTransformHint);
+ mTransformHint,
+ mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
+ mOwnerUid));
}
}
@@ -200,6 +202,8 @@
for (const auto& handle : mDrawingState.callbackHandles) {
handle->transformHint = mTransformHint;
handle->dequeueReadyTime = dequeueReadyTime;
+ handle->currentMaxAcquiredBufferCount =
+ mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
}
// If there are multiple transactions in this frame, set the previous id on the earliest
@@ -253,8 +257,8 @@
bool BufferStateLayer::willPresentCurrentTransaction() const {
// Returns true if the most recent Transaction applied to CurrentState will be presented.
return (getSidebandStreamChanged() || getAutoRefresh() ||
- (mCurrentState.modified &&
- (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr)));
+ (mDrawingState.modified &&
+ (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr)));
}
Rect BufferStateLayer::getCrop(const Layer::State& s) const {
@@ -262,65 +266,72 @@
}
bool BufferStateLayer::setTransform(uint32_t transform) {
- if (mCurrentState.bufferTransform == transform) return false;
- mCurrentState.bufferTransform = transform;
- mCurrentState.modified = true;
+ if (mDrawingState.bufferTransform == transform) return false;
+ mDrawingState.bufferTransform = transform;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
- if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
- mCurrentState.sequence++;
- mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
- mCurrentState.modified = true;
+ if (mDrawingState.transformToDisplayInverse == transformToDisplayInverse) return false;
+ mDrawingState.sequence++;
+ mDrawingState.transformToDisplayInverse = transformToDisplayInverse;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setCrop(const Rect& crop) {
- if (mCurrentState.crop == crop) return false;
- mCurrentState.sequence++;
- mCurrentState.crop = crop;
+ if (mDrawingState.crop == crop) return false;
+ mDrawingState.sequence++;
+ mDrawingState.crop = crop;
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) {
- if (mCurrentState.bufferCrop == bufferCrop) return false;
+ if (mDrawingState.bufferCrop == bufferCrop) return false;
- mCurrentState.sequence++;
- mCurrentState.bufferCrop = bufferCrop;
+ mDrawingState.sequence++;
+ mDrawingState.bufferCrop = bufferCrop;
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setDestinationFrame(const Rect& destinationFrame) {
- if (mCurrentState.destinationFrame == destinationFrame) return false;
+ if (mDrawingState.destinationFrame == destinationFrame) return false;
- mCurrentState.sequence++;
- mCurrentState.destinationFrame = destinationFrame;
+ mDrawingState.sequence++;
+ mDrawingState.destinationFrame = destinationFrame;
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
+static bool assignTransform(ui::Transform* dst, ui::Transform& from) {
+ if (*dst == from) {
+ return false;
+ }
+ *dst = from;
+ return true;
+}
+
// Translate destination frame into scale and position. If a destination frame is not set, use the
// provided scale and position
-void BufferStateLayer::updateGeometry() {
- if (mCurrentState.destinationFrame.isEmpty()) {
+bool BufferStateLayer::updateGeometry() {
+ if (mDrawingState.destinationFrame.isEmpty()) {
// If destination frame is not set, use the requested transform set via
// BufferStateLayer::setPosition and BufferStateLayer::setMatrix.
- mCurrentState.transform = mRequestedTransform;
- return;
+ return assignTransform(&mDrawingState.transform, mRequestedTransform);
}
- Rect destRect = mCurrentState.destinationFrame;
+ Rect destRect = mDrawingState.destinationFrame;
int32_t destW = destRect.width();
int32_t destH = destRect.height();
if (destRect.left < 0) {
@@ -332,21 +343,20 @@
destRect.bottom = destH;
}
- if (!mCurrentState.buffer) {
+ if (!mDrawingState.buffer) {
ui::Transform t;
t.set(destRect.left, destRect.top);
- mCurrentState.transform = t;
- return;
+ return assignTransform(&mDrawingState.transform, t);
}
- uint32_t bufferWidth = mCurrentState.buffer->getBuffer()->getWidth();
- uint32_t bufferHeight = mCurrentState.buffer->getBuffer()->getHeight();
+ uint32_t bufferWidth = mDrawingState.buffer->getBuffer()->getWidth();
+ uint32_t bufferHeight = mDrawingState.buffer->getBuffer()->getHeight();
// Undo any transformations on the buffer.
- if (mCurrentState.bufferTransform & ui::Transform::ROT_90) {
+ if (mDrawingState.bufferTransform & ui::Transform::ROT_90) {
std::swap(bufferWidth, bufferHeight);
}
uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
- if (mCurrentState.transformToDisplayInverse) {
+ if (mDrawingState.transformToDisplayInverse) {
if (invTransform & ui::Transform::ROT_90) {
std::swap(bufferWidth, bufferHeight);
}
@@ -357,8 +367,7 @@
ui::Transform t;
t.set(sx, 0, 0, sy);
t.set(destRect.left, destRect.top);
- mCurrentState.transform = t;
- return;
+ return assignTransform(&mDrawingState.transform, t);
}
bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix,
@@ -379,8 +388,8 @@
mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -393,8 +402,8 @@
mRequestedTransform.set(x, y);
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -406,7 +415,7 @@
mAcquireTimeline.updateSignalTimes();
std::shared_ptr<FenceTime> acquireFenceTime =
std::make_shared<FenceTime>((acquireFence ? acquireFence : Fence::NO_FENCE));
- NewFrameEventsEntry newTimestamps = {mCurrentState.frameNumber, postedTime, desiredPresentTime,
+ NewFrameEventsEntry newTimestamps = {mDrawingState.frameNumber, postedTime, desiredPresentTime,
acquireFenceTime};
mFrameEventHistory.setProducerWantsEvents();
mFrameEventHistory.addQueue(newTimestamps);
@@ -421,37 +430,39 @@
const sp<ITransactionCompletedListener>& releaseBufferListener) {
ATRACE_CALL();
- if (mCurrentState.buffer) {
+ if (mDrawingState.buffer) {
mReleasePreviousBuffer = true;
- if (!mDrawingState.buffer ||
- mCurrentState.buffer->getBuffer() != mDrawingState.buffer->getBuffer()) {
- // If mCurrentState has a buffer, and we are about to update again
+ if (mDrawingState.buffer != mBufferInfo.mBuffer) {
+ // If mDrawingState has a buffer, and we are about to update again
// before swapping to drawing state, then the first buffer will be
// dropped and we should decrement the pending buffer count and
// call any release buffer callbacks if set.
- callReleaseBufferCallback(mCurrentState.releaseBufferListener,
- mCurrentState.buffer->getBuffer(),
- mCurrentState.acquireFence,
- mTransformHint);
+ callReleaseBufferCallback(mDrawingState.releaseBufferListener,
+ mDrawingState.buffer->getBuffer(), mDrawingState.acquireFence,
+ mTransformHint,
+ mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
+ mOwnerUid));
decrementPendingBufferCount();
- if (mCurrentState.bufferSurfaceFrameTX != nullptr) {
- addSurfaceFrameDroppedForBuffer(mCurrentState.bufferSurfaceFrameTX);
- mCurrentState.bufferSurfaceFrameTX.reset();
+ if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
+ mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
+ addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX);
+ mDrawingState.bufferSurfaceFrameTX.reset();
}
}
}
- mCurrentState.frameNumber = frameNumber;
- mCurrentState.releaseBufferListener = releaseBufferListener;
- mCurrentState.buffer = buffer;
- mCurrentState.clientCacheId = clientCacheId;
- mCurrentState.modified = true;
+
+ mDrawingState.frameNumber = frameNumber;
+ mDrawingState.releaseBufferListener = releaseBufferListener;
+ mDrawingState.buffer = buffer;
+ mDrawingState.clientCacheId = clientCacheId;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
const int32_t layerId = getSequence();
- mFlinger->mTimeStats->setPostTime(layerId, mCurrentState.frameNumber, getName().c_str(),
+ mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
mOwnerUid, postTime, getGameMode());
- mCurrentState.desiredPresentTime = desiredPresentTime;
- mCurrentState.isAutoTimestamp = isAutoTimestamp;
+ mDrawingState.desiredPresentTime = desiredPresentTime;
+ mDrawingState.isAutoTimestamp = isAutoTimestamp;
const nsecs_t presentTime = [&] {
if (!isAutoTimestamp) return desiredPresentTime;
@@ -478,59 +489,59 @@
FrameTracer::FrameEvent::QUEUE);
}
- mCurrentState.width = mCurrentState.buffer->getBuffer()->getWidth();
- mCurrentState.height = mCurrentState.buffer->getBuffer()->getHeight();
+ mDrawingState.width = mDrawingState.buffer->getBuffer()->getWidth();
+ mDrawingState.height = mDrawingState.buffer->getBuffer()->getHeight();
return true;
}
bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
- mCurrentState.acquireFence = fence;
- mCurrentState.acquireFenceTime = std::make_unique<FenceTime>(fence);
+ mDrawingState.acquireFence = fence;
+ mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(fence);
// The acquire fences of BufferStateLayers have already signaled before they are set
- mCallbackHandleAcquireTime = mCurrentState.acquireFenceTime->getSignalTime();
+ mCallbackHandleAcquireTime = mDrawingState.acquireFenceTime->getSignalTime();
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
- if (mCurrentState.dataspace == dataspace) return false;
- mCurrentState.dataspace = dataspace;
- mCurrentState.modified = true;
+ if (mDrawingState.dataspace == dataspace) return false;
+ mDrawingState.dataspace = dataspace;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
- if (mCurrentState.hdrMetadata == hdrMetadata) return false;
- mCurrentState.hdrMetadata = hdrMetadata;
- mCurrentState.modified = true;
+ if (mDrawingState.hdrMetadata == hdrMetadata) return false;
+ mDrawingState.hdrMetadata = hdrMetadata;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
- mCurrentState.surfaceDamageRegion = surfaceDamage;
- mCurrentState.modified = true;
+ mDrawingState.surfaceDamageRegion = surfaceDamage;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setApi(int32_t api) {
- if (mCurrentState.api == api) return false;
- mCurrentState.api = api;
- mCurrentState.modified = true;
+ if (mDrawingState.api == api) return false;
+ mDrawingState.api = api;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
- if (mCurrentState.sidebandStream == sidebandStream) return false;
- mCurrentState.sidebandStream = sidebandStream;
- mCurrentState.modified = true;
+ if (mDrawingState.sidebandStream == sidebandStream) return false;
+ mDrawingState.sidebandStream = sidebandStream;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
if (!mSidebandStreamChanged.exchange(true)) {
@@ -558,14 +569,14 @@
if (willPresent) {
// If this transaction set an acquire fence on this layer, set its acquire time
handle->acquireTime = mCallbackHandleAcquireTime;
- handle->frameNumber = mCurrentState.frameNumber;
+ handle->frameNumber = mDrawingState.frameNumber;
// Notify the transaction completed thread that there is a pending latched callback
// handle
mFlinger->getTransactionCallbackInvoker().registerPendingCallbackHandle(handle);
// Store so latched time and release fence can be set
- mCurrentState.callbackHandles.push_back(handle);
+ mDrawingState.callbackHandles.push_back(handle);
} else { // If this layer will NOT need to be relatched and presented this frame
// Notify the transaction completed thread this handle is done
@@ -580,8 +591,8 @@
}
bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
- mCurrentState.transparentRegionHint = transparent;
- mCurrentState.modified = true;
+ mDrawingState.transparentRegionHint = transparent;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -640,7 +651,7 @@
return true;
}
- return mCurrentState.isAutoTimestamp || mCurrentState.desiredPresentTime <= expectedPresentTime;
+ return mDrawingState.isAutoTimestamp || mDrawingState.desiredPresentTime <= expectedPresentTime;
}
bool BufferStateLayer::onPreComposition(nsecs_t refreshStartTime) {
@@ -669,7 +680,7 @@
* }
* Now imagine getHeadFrameNumber returned mDrawingState.mFrameNumber (or mCurrentFrameNumber).
* Prior to doTransaction SurfaceFlinger will call notifyAvailableFrames, but because we
- * haven't swapped mCurrentState to mDrawingState yet we will think the sync point
+ * haven't swapped mDrawingState to mDrawingState yet we will think the sync point
* is not ready. So we will return false from applyPendingState and not swap
* current state to drawing state. But because we don't swap current state
* to drawing state the number will never update and we will be stuck. This way
@@ -677,7 +688,7 @@
* to apply.
*/
uint64_t BufferStateLayer::getHeadFrameNumber(nsecs_t /* expectedPresentTime */) const {
- return mCurrentState.frameNumber;
+ return mDrawingState.frameNumber;
}
void BufferStateLayer::setAutoRefresh(bool autoRefresh) {
@@ -707,8 +718,8 @@
}
bool BufferStateLayer::hasFrameUpdate() const {
- const State& c(getCurrentState());
- return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr);
+ const State& c(getDrawingState());
+ return mDrawingStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr);
}
status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
@@ -751,6 +762,7 @@
addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
mDrawingState.acquireFenceTime->getSignalTime(),
latchTime);
+ mDrawingState.bufferSurfaceFrameTX.reset();
}
std::deque<sp<CallbackHandle>> remainingHandles;
@@ -758,7 +770,7 @@
.finalizeOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
mDrawingState.callbackHandles = remainingHandles;
- mCurrentStateModified = false;
+ mDrawingStateModified = false;
return NO_ERROR;
}
@@ -952,7 +964,9 @@
// call any release buffer callbacks if set.
callReleaseBufferCallback(mDrawingState.releaseBufferListener,
mDrawingState.buffer->getBuffer(), mDrawingState.acquireFence,
- mTransformHint);
+ mTransformHint,
+ mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
+ mOwnerUid));
decrementPendingBufferCount();
}
}
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 2e48452..2747018 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -47,10 +47,6 @@
bool isBufferDue(nsecs_t /*expectedPresentTime*/) const override { return true; }
- uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override {
- return flags;
- }
-
Region getActiveTransparentRegion(const Layer::State& s) const override {
return s.transparentRegionHint;
}
@@ -87,7 +83,7 @@
bool setBufferCrop(const Rect& bufferCrop) override;
bool setDestinationFrame(const Rect& destinationFrame) override;
- void updateGeometry() override;
+ bool updateGeometry() override;
// -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/EffectLayer.cpp b/services/surfaceflinger/EffectLayer.cpp
index 0cc5f33..86c6b21 100644
--- a/services/surfaceflinger/EffectLayer.cpp
+++ b/services/surfaceflinger/EffectLayer.cpp
@@ -78,28 +78,28 @@
}
bool EffectLayer::setColor(const half3& color) {
- if (mCurrentState.color.r == color.r && mCurrentState.color.g == color.g &&
- mCurrentState.color.b == color.b) {
+ if (mDrawingState.color.r == color.r && mDrawingState.color.g == color.g &&
+ mDrawingState.color.b == color.b) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.color.r = color.r;
- mCurrentState.color.g = color.g;
- mCurrentState.color.b = color.b;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.color.r = color.r;
+ mDrawingState.color.g = color.g;
+ mDrawingState.color.b = color.b;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool EffectLayer::setDataspace(ui::Dataspace dataspace) {
- if (mCurrentState.dataspace == dataspace) {
+ if (mDrawingState.dataspace == dataspace) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.dataspace = dataspace;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.dataspace = dataspace;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
diff --git a/services/surfaceflinger/FpsReporter.cpp b/services/surfaceflinger/FpsReporter.cpp
index 23db805..e12835f 100644
--- a/services/surfaceflinger/FpsReporter.cpp
+++ b/services/surfaceflinger/FpsReporter.cpp
@@ -55,7 +55,7 @@
std::vector<std::pair<TrackedListener, sp<Layer>>> listenersAndLayersToReport;
mFlinger.mCurrentState.traverse([&](Layer* layer) {
- auto& currentState = layer->getCurrentState();
+ auto& currentState = layer->getDrawingState();
if (currentState.metadata.has(METADATA_TASK_ID)) {
int32_t taskId = currentState.metadata.getInt32(METADATA_TASK_ID, 0);
if (seenTasks.count(taskId) == 0) {
@@ -100,4 +100,4 @@
mListeners.erase(wp<IBinder>(IInterface::asBinder(listener)));
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4beb526..b819dbe 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -98,52 +98,49 @@
if (args.flags & ISurfaceComposerClient::eSkipScreenshot)
layerFlags |= layer_state_t::eLayerSkipScreenshot;
- mCurrentState.active_legacy.w = args.w;
- mCurrentState.active_legacy.h = args.h;
- mCurrentState.flags = layerFlags;
- mCurrentState.active_legacy.transform.set(0, 0);
- mCurrentState.crop.makeInvalid();
- mCurrentState.requestedCrop = mCurrentState.crop;
- mCurrentState.z = 0;
- mCurrentState.color.a = 1.0f;
- mCurrentState.layerStack = 0;
- mCurrentState.sequence = 0;
- mCurrentState.requested_legacy = mCurrentState.active_legacy;
- mCurrentState.width = UINT32_MAX;
- mCurrentState.height = UINT32_MAX;
- mCurrentState.transform.set(0, 0);
- mCurrentState.frameNumber = 0;
- mCurrentState.bufferTransform = 0;
- mCurrentState.transformToDisplayInverse = false;
- mCurrentState.crop.makeInvalid();
- mCurrentState.acquireFence = sp<Fence>::make(-1);
- mCurrentState.acquireFenceTime = std::make_shared<FenceTime>(mCurrentState.acquireFence);
- mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
- mCurrentState.hdrMetadata.validTypes = 0;
- mCurrentState.surfaceDamageRegion = Region::INVALID_REGION;
- mCurrentState.cornerRadius = 0.0f;
- mCurrentState.backgroundBlurRadius = 0;
- mCurrentState.api = -1;
- mCurrentState.hasColorTransform = false;
- mCurrentState.colorSpaceAgnostic = false;
- mCurrentState.frameRateSelectionPriority = PRIORITY_UNSET;
- mCurrentState.metadata = args.metadata;
- mCurrentState.shadowRadius = 0.f;
- mCurrentState.fixedTransformHint = ui::Transform::ROT_INVALID;
- mCurrentState.frameTimelineInfo = {};
- mCurrentState.postTime = -1;
- mCurrentState.destinationFrame.makeInvalid();
+ mDrawingState.active_legacy.w = args.w;
+ mDrawingState.active_legacy.h = args.h;
+ mDrawingState.flags = layerFlags;
+ mDrawingState.active_legacy.transform.set(0, 0);
+ mDrawingState.crop.makeInvalid();
+ mDrawingState.requestedCrop = mDrawingState.crop;
+ mDrawingState.z = 0;
+ mDrawingState.color.a = 1.0f;
+ mDrawingState.layerStack = 0;
+ mDrawingState.sequence = 0;
+ mDrawingState.requested_legacy = mDrawingState.active_legacy;
+ mDrawingState.width = UINT32_MAX;
+ mDrawingState.height = UINT32_MAX;
+ mDrawingState.transform.set(0, 0);
+ mDrawingState.frameNumber = 0;
+ mDrawingState.bufferTransform = 0;
+ mDrawingState.transformToDisplayInverse = false;
+ mDrawingState.crop.makeInvalid();
+ mDrawingState.acquireFence = sp<Fence>::make(-1);
+ mDrawingState.acquireFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence);
+ mDrawingState.dataspace = ui::Dataspace::UNKNOWN;
+ mDrawingState.hdrMetadata.validTypes = 0;
+ mDrawingState.surfaceDamageRegion = Region::INVALID_REGION;
+ mDrawingState.cornerRadius = 0.0f;
+ mDrawingState.backgroundBlurRadius = 0;
+ mDrawingState.api = -1;
+ mDrawingState.hasColorTransform = false;
+ mDrawingState.colorSpaceAgnostic = false;
+ mDrawingState.frameRateSelectionPriority = PRIORITY_UNSET;
+ mDrawingState.metadata = args.metadata;
+ mDrawingState.shadowRadius = 0.f;
+ mDrawingState.fixedTransformHint = ui::Transform::ROT_INVALID;
+ mDrawingState.frameTimelineInfo = {};
+ mDrawingState.postTime = -1;
+ mDrawingState.destinationFrame.makeInvalid();
if (args.flags & ISurfaceComposerClient::eNoColorFill) {
// Set an invalid color so there is no color fill.
- mCurrentState.color.r = -1.0_hf;
- mCurrentState.color.g = -1.0_hf;
- mCurrentState.color.b = -1.0_hf;
+ mDrawingState.color.r = -1.0_hf;
+ mDrawingState.color.g = -1.0_hf;
+ mDrawingState.color.b = -1.0_hf;
}
- // drawing state & current state are identical
- mDrawingState = mCurrentState;
-
CompositorTiming compositorTiming;
args.flinger->getCompositorTiming(&compositorTiming);
mFrameEventHistory.initializeCompositorTiming(compositorTiming);
@@ -203,11 +200,11 @@
void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {}
void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) {
- if (mCurrentState.zOrderRelativeOf == nullptr) {
+ if (mDrawingState.zOrderRelativeOf == nullptr) {
return;
}
- sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+ sp<Layer> strongRelative = mDrawingState.zOrderRelativeOf.promote();
if (strongRelative == nullptr) {
setZOrderRelativeOf(nullptr);
return;
@@ -221,8 +218,8 @@
}
void Layer::removeFromCurrentState() {
- if (!mRemovedFromCurrentState) {
- mRemovedFromCurrentState = true;
+ if (!mRemovedFromDrawingState) {
+ mRemovedFromDrawingState = true;
mFlinger->mScheduler->deregisterLayer(this);
}
@@ -249,8 +246,8 @@
}
void Layer::addToCurrentState() {
- if (mRemovedFromCurrentState) {
- mRemovedFromCurrentState = false;
+ if (mRemovedFromDrawingState) {
+ mRemovedFromDrawingState = false;
mFlinger->mScheduler->registerLayer(this);
}
@@ -679,78 +676,6 @@
// transaction
// ----------------------------------------------------------------------------
-uint32_t Layer::doTransactionResize(uint32_t flags, State* stateToCommit) {
- const State& s(getDrawingState());
-
- const bool sizeChanged = (stateToCommit->requested_legacy.w != s.requested_legacy.w) ||
- (stateToCommit->requested_legacy.h != s.requested_legacy.h);
-
- if (sizeChanged) {
- // the size changed, we need to ask our client to request a new buffer
- ALOGD_IF(DEBUG_RESIZE,
- "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
- " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
- " requested={ wh={%4u,%4u} }}\n"
- " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
- " requested={ wh={%4u,%4u} }}\n",
- this, getName().c_str(), getBufferTransform(), getEffectiveScalingMode(),
- stateToCommit->active_legacy.w, stateToCommit->active_legacy.h,
- stateToCommit->crop.left, stateToCommit->crop.top, stateToCommit->crop.right,
- stateToCommit->crop.bottom, stateToCommit->crop.getWidth(),
- stateToCommit->crop.getHeight(), stateToCommit->requested_legacy.w,
- stateToCommit->requested_legacy.h, s.active_legacy.w, s.active_legacy.h,
- s.crop.left, s.crop.top, s.crop.right, s.crop.bottom, s.crop.getWidth(),
- s.crop.getHeight(), s.requested_legacy.w, s.requested_legacy.h);
- }
-
- // Don't let Layer::doTransaction update the drawing state
- // if we have a pending resize, unless we are in fixed-size mode.
- // the drawing state will be updated only once we receive a buffer
- // with the correct size.
- //
- // In particular, we want to make sure the clip (which is part
- // of the geometry state) is latched together with the size but is
- // latched immediately when no resizing is involved.
- //
- // If a sideband stream is attached, however, we want to skip this
- // optimization so that transactions aren't missed when a buffer
- // never arrives
- //
- // In the case that we don't have a buffer we ignore other factors
- // and avoid entering the resizePending state. At a high level the
- // resizePending state is to avoid applying the state of the new buffer
- // to the old buffer. However in the state where we don't have an old buffer
- // there is no such concern but we may still be being used as a parent layer.
- const bool resizePending =
- ((stateToCommit->requested_legacy.w != stateToCommit->active_legacy.w) ||
- (stateToCommit->requested_legacy.h != stateToCommit->active_legacy.h)) &&
- (getBuffer() != nullptr);
- if (!isFixedSize()) {
- if (resizePending && mSidebandStream == nullptr) {
- flags |= eDontUpdateGeometryState;
- }
- }
-
- // Here we apply various requested geometry states, depending on our
- // latching configuration. See Layer.h for a detailed discussion of
- // how geometry latching is controlled.
- if (!(flags & eDontUpdateGeometryState)) {
- State& editCurrentState(getCurrentState());
-
- // There is an awkward asymmetry in the handling of the crop states in the position
- // states, as can be seen below. Largely this arises from position and transform
- // being stored in the same data structure while having different latching rules.
- // b/38182305
- //
- // Careful that "stateToCommit" and editCurrentState may not begin as equivalent due to
- // applyPendingStates in the presence of deferred transactions.
- editCurrentState.active_legacy = editCurrentState.requested_legacy;
- stateToCommit->active_legacy = stateToCommit->requested_legacy;
- }
-
- return flags;
-}
-
uint32_t Layer::doTransaction(uint32_t flags) {
ATRACE_CALL();
@@ -760,77 +685,37 @@
}
// TODO: This is unfortunate.
- mCurrentStateModified = mCurrentState.modified;
- mCurrentState.modified = false;
-
- flags = doTransactionResize(flags, &mCurrentState);
+ mDrawingStateModified = mDrawingState.modified;
+ mDrawingState.modified = false;
const State& s(getDrawingState());
- State& c(getCurrentState());
- // Translates dest frame into scale and position updates. This helps align geometry calculations
- // for BufferStateLayer with other layers. This should ideally happen in the client once client
- // has the display orientation details from WM.
- updateGeometry();
-
- if (c.width != s.width || c.height != s.height || !(c.transform == s.transform)) {
+ if (updateGeometry()) {
// invalidate and recompute the visible regions if needed
flags |= Layer::eVisibleRegion;
}
- if (c.sequence != s.sequence) {
+ if (s.sequence != mLastCommittedTxSequence) {
// invalidate and recompute the visible regions if needed
+ mLastCommittedTxSequence = s.sequence;
flags |= eVisibleRegion;
this->contentDirty = true;
// we may use linear filtering, if the matrix scales us
- mNeedsFiltering = getActiveTransform(c).needsBilinearFiltering();
+ mNeedsFiltering = getActiveTransform(s).needsBilinearFiltering();
}
- if (mCurrentState.inputInfoChanged) {
+ if (mDrawingState.inputInfoChanged) {
flags |= eInputInfoChanged;
- mCurrentState.inputInfoChanged = false;
+ mDrawingState.inputInfoChanged = false;
}
- // Add the callbacks from the drawing state into the current state. This is so when the current
- // state gets copied to drawing, we don't lose the callback handles that are still in drawing.
- for (auto& handle : s.callbackHandles) {
- c.callbackHandles.push_back(handle);
- }
-
- // Allow BufferStateLayer to release any unlatched buffers in drawing state.
- bufferMayChange(c.buffer->getBuffer());
-
- // Commit the transaction
- commitTransaction(c);
- mCurrentState.callbackHandles = {};
+ commitTransaction(mDrawingState);
return flags;
}
-void Layer::commitTransaction(State& stateToCommit) {
- if (auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
- ((mDrawingState.buffer && stateToCommit.buffer &&
- mDrawingState.buffer->getBuffer() != stateToCommit.buffer->getBuffer()) ||
- (mDrawingState.buffer && !stateToCommit.buffer) ||
- (!mDrawingState.buffer && stateToCommit.buffer)) &&
- bufferSurfaceFrame != nullptr &&
- bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
- // If the previous buffer was committed but not latched (refreshPending - happens during
- // back to back invalidates), it gets silently dropped here. Mark the corresponding
- // SurfaceFrame as dropped to prevent it from getting stuck in the pending classification
- // list.
- addSurfaceFrameDroppedForBuffer(bufferSurfaceFrame);
- }
- const bool frameRateVoteChanged =
- mDrawingState.frameRateForLayerTree != stateToCommit.frameRateForLayerTree;
- mDrawingState = stateToCommit;
-
- if (frameRateVoteChanged) {
- mFlinger->mScheduler->recordLayerHistory(this, systemTime(),
- LayerHistory::LayerUpdateType::SetFrameRate);
- }
-
+void Layer::commitTransaction(State&) {
// Set the present state for all bufferlessSurfaceFramesTX to Presented. The
// bufferSurfaceFrameTX will be presented in latchBuffer.
for (auto& [token, surfaceFrame] : mDrawingState.bufferlessSurfaceFramesTX) {
@@ -841,9 +726,7 @@
mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
}
}
- // Clear the surfaceFrames from the old state now that it has been copied into DrawingState.
- stateToCommit.bufferSurfaceFrameTX.reset();
- stateToCommit.bufferlessSurfaceFramesTX.clear();
+ mDrawingState.bufferlessSurfaceFramesTX.clear();
}
uint32_t Layer::getTransactionFlags(uint32_t flags) {
@@ -857,20 +740,11 @@
}
bool Layer::setPosition(float x, float y) {
- if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) return false;
- mCurrentState.sequence++;
+ if (mDrawingState.transform.tx() == x && mDrawingState.transform.ty() == y) return false;
+ mDrawingState.sequence++;
+ mDrawingState.transform.set(x, y);
- // We update the requested and active position simultaneously because
- // we want to apply the position portion of the transform matrix immediately,
- // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
- mCurrentState.transform.set(x, y);
- // Here we directly update the active state
- // unlike other setters, because we store it within
- // the transform, but use different latching rules.
- // b/38182305
- mCurrentState.transform.set(x, y);
-
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -903,14 +777,14 @@
}
bool Layer::setLayer(int32_t z) {
- if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
- mCurrentState.sequence++;
- mCurrentState.z = z;
- mCurrentState.modified = true;
+ if (mDrawingState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
+ mDrawingState.sequence++;
+ mDrawingState.z = z;
+ mDrawingState.modified = true;
// Discard all relative layering.
- if (mCurrentState.zOrderRelativeOf != nullptr) {
- sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+ if (mDrawingState.zOrderRelativeOf != nullptr) {
+ sp<Layer> strongRelative = mDrawingState.zOrderRelativeOf.promote();
if (strongRelative != nullptr) {
strongRelative->removeZOrderRelative(this);
}
@@ -921,24 +795,24 @@
}
void Layer::removeZOrderRelative(const wp<Layer>& relative) {
- mCurrentState.zOrderRelatives.remove(relative);
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ mDrawingState.zOrderRelatives.remove(relative);
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
}
void Layer::addZOrderRelative(const wp<Layer>& relative) {
- mCurrentState.zOrderRelatives.add(relative);
- mCurrentState.modified = true;
- mCurrentState.sequence++;
+ mDrawingState.zOrderRelatives.add(relative);
+ mDrawingState.modified = true;
+ mDrawingState.sequence++;
setTransactionFlags(eTransactionNeeded);
}
void Layer::setZOrderRelativeOf(const wp<Layer>& relativeOf) {
- mCurrentState.zOrderRelativeOf = relativeOf;
- mCurrentState.sequence++;
- mCurrentState.modified = true;
- mCurrentState.isRelativeOf = relativeOf != nullptr;
+ mDrawingState.zOrderRelativeOf = relativeOf;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
+ mDrawingState.isRelativeOf = relativeOf != nullptr;
setTransactionFlags(eTransactionNeeded);
}
@@ -953,16 +827,16 @@
return false;
}
- if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
- mCurrentState.zOrderRelativeOf == relative) {
+ if (mDrawingState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
+ mDrawingState.zOrderRelativeOf == relative) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.modified = true;
- mCurrentState.z = relativeZ;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
+ mDrawingState.z = relativeZ;
- auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
+ auto oldZOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote();
if (oldZOrderRelativeOf != nullptr) {
oldZOrderRelativeOf->removeZOrderRelative(this);
}
@@ -975,82 +849,82 @@
}
bool Layer::setSize(uint32_t w, uint32_t h) {
- if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h)
+ if (mDrawingState.requested_legacy.w == w && mDrawingState.requested_legacy.h == h)
return false;
- mCurrentState.requested_legacy.w = w;
- mCurrentState.requested_legacy.h = h;
- mCurrentState.modified = true;
+ mDrawingState.requested_legacy.w = w;
+ mDrawingState.requested_legacy.h = h;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
// record the new size, from this point on, when the client request
// a buffer, it'll get the new size.
- setDefaultBufferSize(mCurrentState.requested_legacy.w, mCurrentState.requested_legacy.h);
+ setDefaultBufferSize(mDrawingState.requested_legacy.w, mDrawingState.requested_legacy.h);
return true;
}
bool Layer::setAlpha(float alpha) {
- if (mCurrentState.color.a == alpha) return false;
- mCurrentState.sequence++;
- mCurrentState.color.a = alpha;
- mCurrentState.modified = true;
+ if (mDrawingState.color.a == alpha) return false;
+ mDrawingState.sequence++;
+ mDrawingState.color.a = alpha;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace) {
- if (!mCurrentState.bgColorLayer && alpha == 0) {
+ if (!mDrawingState.bgColorLayer && alpha == 0) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
- if (!mCurrentState.bgColorLayer && alpha != 0) {
+ if (!mDrawingState.bgColorLayer && alpha != 0) {
// create background color layer if one does not yet exist
uint32_t flags = ISurfaceComposerClient::eFXSurfaceEffect;
std::string name = mName + "BackgroundColorLayer";
- mCurrentState.bgColorLayer = mFlinger->getFactory().createEffectLayer(
+ mDrawingState.bgColorLayer = mFlinger->getFactory().createEffectLayer(
LayerCreationArgs(mFlinger.get(), nullptr, std::move(name), 0, 0, flags,
LayerMetadata()));
// add to child list
- addChild(mCurrentState.bgColorLayer);
+ addChild(mDrawingState.bgColorLayer);
mFlinger->mLayersAdded = true;
// set up SF to handle added color layer
if (isRemovedFromCurrentState()) {
- mCurrentState.bgColorLayer->onRemovedFromCurrentState();
+ mDrawingState.bgColorLayer->onRemovedFromCurrentState();
}
mFlinger->setTransactionFlags(eTransactionNeeded);
- } else if (mCurrentState.bgColorLayer && alpha == 0) {
- mCurrentState.bgColorLayer->reparent(nullptr);
- mCurrentState.bgColorLayer = nullptr;
+ } else if (mDrawingState.bgColorLayer && alpha == 0) {
+ mDrawingState.bgColorLayer->reparent(nullptr);
+ mDrawingState.bgColorLayer = nullptr;
return true;
}
- mCurrentState.bgColorLayer->setColor(color);
- mCurrentState.bgColorLayer->setLayer(std::numeric_limits<int32_t>::min());
- mCurrentState.bgColorLayer->setAlpha(alpha);
- mCurrentState.bgColorLayer->setDataspace(dataspace);
+ mDrawingState.bgColorLayer->setColor(color);
+ mDrawingState.bgColorLayer->setLayer(std::numeric_limits<int32_t>::min());
+ mDrawingState.bgColorLayer->setAlpha(alpha);
+ mDrawingState.bgColorLayer->setDataspace(dataspace);
return true;
}
bool Layer::setCornerRadius(float cornerRadius) {
- if (mCurrentState.cornerRadius == cornerRadius) return false;
+ if (mDrawingState.cornerRadius == cornerRadius) return false;
- mCurrentState.sequence++;
- mCurrentState.cornerRadius = cornerRadius;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.cornerRadius = cornerRadius;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setBackgroundBlurRadius(int backgroundBlurRadius) {
- if (mCurrentState.backgroundBlurRadius == backgroundBlurRadius) return false;
+ if (mDrawingState.backgroundBlurRadius == backgroundBlurRadius) return false;
- mCurrentState.sequence++;
- mCurrentState.backgroundBlurRadius = backgroundBlurRadius;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.backgroundBlurRadius = backgroundBlurRadius;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -1065,81 +939,82 @@
"ROTATE_SURFACE_FLINGER ignored");
return false;
}
- mCurrentState.sequence++;
- mCurrentState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
+ mDrawingState.modified = true;
+
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setTransparentRegionHint(const Region& transparent) {
- mCurrentState.requestedTransparentRegion_legacy = transparent;
- mCurrentState.modified = true;
+ mDrawingState.requestedTransparentRegion_legacy = transparent;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setBlurRegions(const std::vector<BlurRegion>& blurRegions) {
- mCurrentState.sequence++;
- mCurrentState.blurRegions = blurRegions;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.blurRegions = blurRegions;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setFlags(uint32_t flags, uint32_t mask) {
- const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
- if (mCurrentState.flags == newFlags) return false;
- mCurrentState.sequence++;
- mCurrentState.flags = newFlags;
- mCurrentState.modified = true;
+ const uint32_t newFlags = (mDrawingState.flags & ~mask) | (flags & mask);
+ if (mDrawingState.flags == newFlags) return false;
+ mDrawingState.sequence++;
+ mDrawingState.flags = newFlags;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setCrop(const Rect& crop) {
- if (mCurrentState.requestedCrop == crop) return false;
- mCurrentState.sequence++;
- mCurrentState.requestedCrop = crop;
- mCurrentState.crop = crop;
+ if (mDrawingState.requestedCrop == crop) return false;
+ mDrawingState.sequence++;
+ mDrawingState.requestedCrop = crop;
+ mDrawingState.crop = crop;
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setMetadata(const LayerMetadata& data) {
- if (!mCurrentState.metadata.merge(data, true /* eraseEmpty */)) return false;
- mCurrentState.modified = true;
+ if (!mDrawingState.metadata.merge(data, true /* eraseEmpty */)) return false;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setLayerStack(uint32_t layerStack) {
- if (mCurrentState.layerStack == layerStack) return false;
- mCurrentState.sequence++;
- mCurrentState.layerStack = layerStack;
- mCurrentState.modified = true;
+ if (mDrawingState.layerStack == layerStack) return false;
+ mDrawingState.sequence++;
+ mDrawingState.layerStack = layerStack;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setColorSpaceAgnostic(const bool agnostic) {
- if (mCurrentState.colorSpaceAgnostic == agnostic) {
+ if (mDrawingState.colorSpaceAgnostic == agnostic) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.colorSpaceAgnostic = agnostic;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.colorSpaceAgnostic = agnostic;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setFrameRateSelectionPriority(int32_t priority) {
- if (mCurrentState.frameRateSelectionPriority == priority) return false;
- mCurrentState.frameRateSelectionPriority = priority;
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ if (mDrawingState.frameRateSelectionPriority == priority) return false;
+ mDrawingState.frameRateSelectionPriority = priority;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -1171,25 +1046,25 @@
}
bool Layer::setShadowRadius(float shadowRadius) {
- if (mCurrentState.shadowRadius == shadowRadius) {
+ if (mDrawingState.shadowRadius == shadowRadius) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.shadowRadius = shadowRadius;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.shadowRadius = shadowRadius;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool Layer::setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint) {
- if (mCurrentState.fixedTransformHint == fixedTransformHint) {
+ if (mDrawingState.fixedTransformHint == fixedTransformHint) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.fixedTransformHint = fixedTransformHint;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.fixedTransformHint = fixedTransformHint;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -1197,12 +1072,12 @@
bool Layer::setStretchEffect(const StretchEffect& effect) {
StretchEffect temp = effect;
temp.sanitize();
- if (mCurrentState.stretchEffect == temp) {
+ if (mDrawingState.stretchEffect == temp) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.stretchEffect = temp;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.stretchEffect = temp;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -1239,12 +1114,12 @@
int layersWithVote = 0;
traverseTree([&layersWithVote](Layer* layer) {
const auto layerVotedWithDefaultCompatibility =
- layer->mCurrentState.frameRate.rate.isValid() &&
- layer->mCurrentState.frameRate.type == FrameRateCompatibility::Default;
+ layer->mDrawingState.frameRate.rate.isValid() &&
+ layer->mDrawingState.frameRate.type == FrameRateCompatibility::Default;
const auto layerVotedWithNoVote =
- layer->mCurrentState.frameRate.type == FrameRateCompatibility::NoVote;
+ layer->mDrawingState.frameRate.type == FrameRateCompatibility::NoVote;
const auto layerVotedWithExactCompatibility =
- layer->mCurrentState.frameRate.type == FrameRateCompatibility::Exact;
+ layer->mDrawingState.frameRate.type == FrameRateCompatibility::Exact;
// We do not count layers that are ExactOrMultiple for the same reason
// we are allowing touch boost for those layers. See
@@ -1258,6 +1133,7 @@
// Now we can update the tree frame rate vote for each layer in the tree
const bool treeHasFrameRateVote = layersWithVote > 0;
bool transactionNeeded = false;
+
traverseTree([treeHasFrameRateVote, &transactionNeeded](Layer* layer) {
transactionNeeded = layer->updateFrameRateForLayerTree(treeHasFrameRateVote);
});
@@ -1271,13 +1147,13 @@
if (!mFlinger->useFrameRateApi) {
return false;
}
- if (mCurrentState.frameRate == frameRate) {
+ if (mDrawingState.frameRate == frameRate) {
return false;
}
- mCurrentState.sequence++;
- mCurrentState.frameRate = frameRate;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.frameRate = frameRate;
+ mDrawingState.modified = true;
updateTreeHasFrameRateVote();
@@ -1287,33 +1163,33 @@
void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info,
nsecs_t postTime) {
- mCurrentState.postTime = postTime;
+ mDrawingState.postTime = postTime;
// Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if
// there are two transactions with the same token, the first one without a buffer and the
// second one with a buffer. We promote the bufferlessSurfaceFrame to a bufferSurfaceFrameTX
// in that case.
- auto it = mCurrentState.bufferlessSurfaceFramesTX.find(info.vsyncId);
- if (it != mCurrentState.bufferlessSurfaceFramesTX.end()) {
+ auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
+ if (it != mDrawingState.bufferlessSurfaceFramesTX.end()) {
// Promote the bufferlessSurfaceFrame to a bufferSurfaceFrameTX
- mCurrentState.bufferSurfaceFrameTX = it->second;
- mCurrentState.bufferlessSurfaceFramesTX.erase(it);
- mCurrentState.bufferSurfaceFrameTX->promoteToBuffer();
- mCurrentState.bufferSurfaceFrameTX->setActualQueueTime(postTime);
+ mDrawingState.bufferSurfaceFrameTX = it->second;
+ mDrawingState.bufferlessSurfaceFramesTX.erase(it);
+ mDrawingState.bufferSurfaceFrameTX->promoteToBuffer();
+ mDrawingState.bufferSurfaceFrameTX->setActualQueueTime(postTime);
} else {
- mCurrentState.bufferSurfaceFrameTX =
+ mDrawingState.bufferSurfaceFrameTX =
createSurfaceFrameForBuffer(info, postTime, mTransactionName);
}
}
void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
nsecs_t postTime) {
- mCurrentState.frameTimelineInfo = info;
- mCurrentState.postTime = postTime;
- mCurrentState.modified = true;
+ mDrawingState.frameTimelineInfo = info;
+ mDrawingState.postTime = postTime;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
- if (const auto& bufferSurfaceFrameTX = mCurrentState.bufferSurfaceFrameTX;
+ if (const auto& bufferSurfaceFrameTX = mDrawingState.bufferSurfaceFrameTX;
bufferSurfaceFrameTX != nullptr) {
if (bufferSurfaceFrameTX->getToken() == info.vsyncId) {
// BufferSurfaceFrame takes precedence over BufferlessSurfaceFrame. If the same token is
@@ -1324,10 +1200,10 @@
// For Transactions without a buffer, we create only one SurfaceFrame per vsyncId. If multiple
// transactions use the same vsyncId, we just treat them as one SurfaceFrame (unless they are
// targeting different vsyncs).
- auto it = mCurrentState.bufferlessSurfaceFramesTX.find(info.vsyncId);
- if (it == mCurrentState.bufferlessSurfaceFramesTX.end()) {
+ auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
+ if (it == mDrawingState.bufferlessSurfaceFramesTX.end()) {
auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime);
- mCurrentState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame;
+ mDrawingState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame;
} else {
if (it->second->getPresentState() == PresentState::Presented) {
// If the SurfaceFrame was already presented, its safe to overwrite it since it must
@@ -1389,36 +1265,41 @@
}
bool Layer::updateFrameRateForLayerTree(bool treeHasFrameRateVote) {
- const auto updateCurrentState = [&](FrameRate frameRate) {
- if (mCurrentState.frameRateForLayerTree == frameRate) {
+ const auto updateDrawingState = [&](FrameRate frameRate) {
+ if (mDrawingState.frameRateForLayerTree == frameRate) {
return false;
}
- mCurrentState.frameRateForLayerTree = frameRate;
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+
+ mDrawingState.frameRateForLayerTree = frameRate;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
+
+ mFlinger->mScheduler->recordLayerHistory(this, systemTime(),
+ LayerHistory::LayerUpdateType::SetFrameRate);
+
return true;
};
- const auto frameRate = mCurrentState.frameRate;
+ const auto frameRate = mDrawingState.frameRate;
if (frameRate.rate.isValid() || frameRate.type == FrameRateCompatibility::NoVote) {
- return updateCurrentState(frameRate);
+ return updateDrawingState(frameRate);
}
// This layer doesn't have a frame rate. Check if its ancestors have a vote
for (sp<Layer> parent = getParent(); parent; parent = parent->getParent()) {
- if (parent->mCurrentState.frameRate.rate.isValid()) {
- return updateCurrentState(parent->mCurrentState.frameRate);
+ if (parent->mDrawingState.frameRate.rate.isValid()) {
+ return updateDrawingState(parent->mDrawingState.frameRate);
}
}
// This layer and its ancestors don't have a frame rate. If one of successors
// has a vote, return a NoVote for successors to set the vote
if (treeHasFrameRateVote) {
- return updateCurrentState(FrameRate(Fps(0.0f), FrameRateCompatibility::NoVote));
+ return updateDrawingState(FrameRate(Fps(0.0f), FrameRateCompatibility::NoVote));
}
- return updateCurrentState(frameRate);
+ return updateDrawingState(frameRate);
}
Layer::FrameRate Layer::getFrameRateForLayerTree() const {
@@ -1670,7 +1551,7 @@
void Layer::setGameModeForTree(int parentGameMode) {
int gameMode = parentGameMode;
- auto& currentState = getCurrentState();
+ auto& currentState = getDrawingState();
if (currentState.metadata.has(METADATA_GAME_MODE)) {
gameMode = currentState.metadata.getInt32(METADATA_GAME_MODE, 0);
}
@@ -1749,13 +1630,13 @@
bool Layer::setColorTransform(const mat4& matrix) {
static const mat4 identityMatrix = mat4();
- if (mCurrentState.colorTransform == matrix) {
+ if (mDrawingState.colorTransform == matrix) {
return false;
}
- ++mCurrentState.sequence;
- mCurrentState.colorTransform = matrix;
- mCurrentState.hasColorTransform = matrix != identityMatrix;
- mCurrentState.modified = true;
+ ++mDrawingState.sequence;
+ mDrawingState.colorTransform = matrix;
+ mDrawingState.hasColorTransform = matrix != identityMatrix;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -1787,15 +1668,13 @@
mCurrentParent = layer;
}
-int32_t Layer::getZ(LayerVector::StateSet stateSet) const {
- const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
- const State& state = useDrawing ? mDrawingState : mCurrentState;
- return state.z;
+int32_t Layer::getZ(LayerVector::StateSet) const {
+ return mDrawingState.z;
}
bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) const {
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
- const State& state = useDrawing ? mDrawingState : mCurrentState;
+ const State& state = useDrawing ? mDrawingState : mDrawingState;
return state.isRelativeOf;
}
@@ -1805,7 +1684,7 @@
"makeTraversalList received invalid stateSet");
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
- const State& state = useDrawing ? mDrawingState : mCurrentState;
+ const State& state = useDrawing ? mDrawingState : mDrawingState;
if (state.zOrderRelatives.size() == 0) {
*outSkipRelativeZUsers = true;
@@ -1904,7 +1783,7 @@
void Layer::traverse(LayerVector::StateSet state, const LayerVector::Visitor& visitor) {
visitor(this);
const LayerVector& children =
- state == LayerVector::StateSet::Drawing ? mDrawingChildren : mCurrentChildren;
+ state == LayerVector::StateSet::Drawing ? mDrawingChildren : mCurrentChildren;
for (const sp<Layer>& child : children) {
child->traverse(state, visitor);
}
@@ -1916,7 +1795,7 @@
"makeTraversalList received invalid stateSet");
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
- const State& state = useDrawing ? mDrawingState : mCurrentState;
+ const State& state = useDrawing ? mDrawingState : mDrawingState;
LayerVector traverse(stateSet);
for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
@@ -1929,7 +1808,7 @@
}
for (const sp<Layer>& child : children) {
- const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+ const State& childState = useDrawing ? child->mDrawingState : child->mDrawingState;
// If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
// descendent of the top most parent of the tree. If it's not a descendent, then just add
// the child here since it won't be added later as a relative.
@@ -1997,7 +1876,7 @@
}
ui::Transform::RotationFlags Layer::getFixedTransformHint() const {
- ui::Transform::RotationFlags fixedTransformHint = mCurrentState.fixedTransformHint;
+ ui::Transform::RotationFlags fixedTransformHint = mDrawingState.fixedTransformHint;
if (fixedTransformHint != ui::Transform::ROT_INVALID) {
return fixedTransformHint;
}
@@ -2109,10 +1988,10 @@
}
void Layer::setInputInfo(const InputWindowInfo& info) {
- mCurrentState.inputInfo = info;
- mCurrentState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
- mCurrentState.modified = true;
- mCurrentState.inputInfoChanged = true;
+ mDrawingState.inputInfo = info;
+ mDrawingState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
+ mDrawingState.modified = true;
+ mDrawingState.inputInfoChanged = true;
setTransactionFlags(eTransactionNeeded);
}
@@ -2190,7 +2069,7 @@
uint32_t traceFlags) {
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
- const State& state = useDrawing ? mDrawingState : mCurrentState;
+ const State& state = useDrawing ? mDrawingState : mDrawingState;
ui::Transform requestedTransform = state.transform;
@@ -2278,7 +2157,7 @@
}
bool Layer::isRemovedFromCurrentState() const {
- return mRemovedFromCurrentState;
+ return mRemovedFromDrawingState;
}
ui::Transform Layer::getInputTransform() const {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5669049..9b30fcb 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1,3 +1,4 @@
+
/*
* Copyright (C) 2007 The Android Open Source Project
*
@@ -732,8 +733,7 @@
void updateTransformHint(ui::Transform::RotationFlags);
inline const State& getDrawingState() const { return mDrawingState; }
- inline const State& getCurrentState() const { return mCurrentState; }
- inline State& getCurrentState() { return mCurrentState; }
+ inline State& getDrawingState() { return mDrawingState; }
LayerDebugInfo getLayerDebugInfo(const DisplayDevice*) const;
@@ -884,7 +884,7 @@
virtual bool setDestinationFrame(const Rect& /* destinationFrame */) { return false; }
virtual std::atomic<int32_t>* getPendingBufferCounter() { return nullptr; }
virtual std::string getPendingBufferCounterName() { return ""; }
- virtual void updateGeometry() {}
+ virtual bool updateGeometry() { return false; }
protected:
friend class impl::SurfaceInterceptor;
@@ -902,7 +902,6 @@
compositionengine::LayerFE::ClientCompositionTargetSettings&);
virtual void preparePerFrameCompositionState();
virtual void commitTransaction(State& stateToCommit);
- virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit);
virtual void onSurfaceFrameCreated(const std::shared_ptr<frametimeline::SurfaceFrame>&) {}
// Returns mCurrentScaling mode (originating from the
@@ -958,9 +957,11 @@
// These are only accessed by the main thread or the tracing thread.
State mDrawingState;
- // these are protected by an external lock (mStateLock)
- State mCurrentState;
uint32_t mTransactionFlags{0};
+ // Updated in doTransaction, used to track the last sequence number we
+ // committed. Currently this is really only used for updating visible
+ // regions.
+ int32_t mLastCommittedTxSequence = -1;
// Timestamp history for UIAutomation. Thread safe.
FrameTracker mFrameTracker;
@@ -983,7 +984,7 @@
// Whether filtering is needed b/c of the drawingstate
bool mNeedsFiltering{false};
- std::atomic<bool> mRemovedFromCurrentState{false};
+ std::atomic<bool> mRemovedFromDrawingState{false};
// page-flip thread (currently main thread)
bool mProtectedByApp{false}; // application requires protected path to external sink
@@ -996,9 +997,7 @@
// This layer can be a cursor on some displays.
bool mPotentialCursor{false};
- // Child list about to be committed/used for editing.
- LayerVector mCurrentChildren{LayerVector::StateSet::Current};
- // Child list used for rendering.
+ LayerVector mCurrentChildren{LayerVector::StateSet::Drawing};
LayerVector mDrawingChildren{LayerVector::StateSet::Drawing};
wp<Layer> mCurrentParent;
@@ -1022,7 +1021,7 @@
// Used in buffer stuffing analysis in FrameTimeline.
nsecs_t mLastLatchTime = 0;
- mutable bool mCurrentStateModified = false;
+ mutable bool mDrawingStateModified = false;
private:
virtual void setTransformHint(ui::Transform::RotationFlags) {}
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index 9b94920..aee820a 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -42,10 +42,8 @@
const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);
const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);
- const auto& lState =
- (mStateSet == StateSet::Current) ? l->getCurrentState() : l->getDrawingState();
- const auto& rState =
- (mStateSet == StateSet::Current) ? r->getCurrentState() : r->getDrawingState();
+ const auto& lState = l->getDrawingState();
+ const auto& rState = r->getDrawingState();
uint32_t ls = lState.layerStack;
uint32_t rs = rState.layerStack;
@@ -66,8 +64,7 @@
void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
for (size_t i = 0; i < size(); i++) {
const auto& layer = (*this)[i];
- auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
- : layer->getDrawingState();
+ auto& state = layer->getDrawingState();
if (state.isRelativeOf) {
continue;
}
@@ -78,8 +75,7 @@
void LayerVector::traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const {
for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
const auto& layer = (*this)[i];
- auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
- : layer->getDrawingState();
+ auto& state = layer->getDrawingState();
if (state.isRelativeOf) {
continue;
}
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index a9fd16c..663e62a 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -199,10 +199,10 @@
mLayer->setFrameRate(Layer::FrameRate(Fps(0.0f), Layer::FrameRateCompatibility::NoVote));
// setting Layer's Z requires resorting layersSortedByZ
- ssize_t idx = mFlinger.mCurrentState.layersSortedByZ.indexOf(mLayer);
+ ssize_t idx = mFlinger.mDrawingState.layersSortedByZ.indexOf(mLayer);
if (mLayer->setLayer(INT32_MAX - 2) && idx >= 0) {
- mFlinger.mCurrentState.layersSortedByZ.removeAt(idx);
- mFlinger.mCurrentState.layersSortedByZ.add(mLayer);
+ mFlinger.mDrawingState.layersSortedByZ.removeAt(idx);
+ mFlinger.mDrawingState.layersSortedByZ.add(mLayer);
}
return true;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 9746076..0eb16e2 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -422,7 +422,15 @@
// actually increase the refresh rate over the normal selection.
const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked();
- bool touchBoostForExplicitExact = explicitExact == 0 || mSupportsFrameRateOverride;
+ const bool touchBoostForExplicitExact = [&] {
+ if (mSupportsFrameRateOverride) {
+ // Enable touch boost if there are other layers besides exact
+ return explicitExact + noVoteLayers != layers.size();
+ } else {
+ // Enable touch boost if there are no exact layers
+ return explicitExact == 0;
+ }
+ }();
if (globalSignals.touch && explicitDefaultVoteLayers == 0 && touchBoostForExplicitExact &&
bestRefreshRate->fps.lessThanWithMargin(touchRefreshRate.fps)) {
setTouchConsidered();
@@ -859,11 +867,6 @@
return RefreshRateConfigs::KernelIdleTimerAction::TurnOff;
}
if (minByPolicy == maxByPolicy) {
- // Do not sent the call to toggle off kernel idle timer if the device min and policy min and
- // max are all the same. This saves us extra unnecessary calls to sysprop.
- if (deviceMin == minByPolicy) {
- return RefreshRateConfigs::KernelIdleTimerAction::NoChange;
- }
return RefreshRateConfigs::KernelIdleTimerAction::TurnOff;
}
// Turn on the timer in all other cases.
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 342fde0..6cd0f42 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -318,7 +318,6 @@
// Class to enumerate options around toggling the kernel timer on and off. We have an option
// for no change to avoid extra calls to kernel.
enum class KernelIdleTimerAction {
- NoChange, // Do not change the idle timer.
TurnOff, // Turn off the idle timer.
TurnOn // Turn on the idle timer.
};
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 4b8cbfb..e0b3640 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -205,6 +205,10 @@
}
std::optional<Fps> Scheduler::getFrameRateOverride(uid_t uid) const {
+ if (!mRefreshRateConfigs.supportsFrameRateOverride()) {
+ return std::nullopt;
+ }
+
std::lock_guard lock(mFrameRateOverridesMutex);
{
const auto iter = mFrameRateOverridesFromBackdoor.find(uid);
@@ -224,10 +228,6 @@
}
bool Scheduler::isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const {
- if (!mRefreshRateConfigs.supportsFrameRateOverride()) {
- return true;
- }
-
const auto frameRate = getFrameRateOverride(uid);
if (!frameRate.has_value()) {
return true;
diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp b/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp
index cb57aea..43e0297 100644
--- a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp
@@ -59,7 +59,7 @@
}
void VsyncConfiguration::dump(std::string& result) const {
- const auto [early, earlyGpu, late] = getCurrentConfigs();
+ const auto [early, earlyGpu, late, hwcMinWorkDuration] = getCurrentConfigs();
using base::StringAppendF;
StringAppendF(&result,
" app phase: %9" PRId64 " ns\t SF phase: %9" PRId64
@@ -70,7 +70,8 @@
" early app duration: %9lld ns\t early SF duration: %9lld ns\n"
" GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64
" ns\n"
- " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n",
+ " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n"
+ " HWC min duration: %9lld ns\n",
late.appOffset, late.sfOffset,
late.appWorkDuration.count(), late.sfWorkDuration.count(),
@@ -81,7 +82,9 @@
earlyGpu.appOffset, earlyGpu.sfOffset,
- earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count());
+ earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count(),
+
+ hwcMinWorkDuration.count());
}
PhaseOffsets::PhaseOffsets(Fps currentRefreshRate)
@@ -103,7 +106,8 @@
// offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW
// vsync.
getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns")
- .value_or(std::numeric_limits<nsecs_t>::max())) {}
+ .value_or(std::numeric_limits<nsecs_t>::max()),
+ getProperty("debug.sf.hwc.min.duration").value_or(0)) {}
PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
std::optional<nsecs_t> earlySfOffsetNs,
@@ -115,7 +119,7 @@
std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,
std::optional<nsecs_t> highFpsEarlyAppOffsetNs,
std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs,
- nsecs_t thresholdForNextVsync)
+ nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration)
: VsyncConfiguration(currentFps),
mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs),
mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs),
@@ -129,7 +133,8 @@
mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs),
mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs),
mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs),
- mThresholdForNextVsync(thresholdForNextVsync) {}
+ mThresholdForNextVsync(thresholdForNextVsync),
+ mHwcMinWorkDuration(hwcMinWorkDuration) {}
PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const {
if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) {
@@ -189,6 +194,7 @@
.sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration),
.appWorkDuration =
appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration)},
+ .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration),
};
}
@@ -234,6 +240,7 @@
.appWorkDuration =
appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration),
},
+ .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration),
};
}
@@ -342,6 +349,7 @@
.sfWorkDuration = sfDuration,
.appWorkDuration = appDuration,
},
+ .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration),
};
}
@@ -351,19 +359,22 @@
getProperty("debug.sf.early.sf.duration").value_or(mSfDuration),
getProperty("debug.sf.early.app.duration").value_or(mAppDuration),
getProperty("debug.sf.earlyGl.sf.duration").value_or(mSfDuration),
- getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration)) {
+ getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration),
+ getProperty("debug.sf.hwc.min.duration").value_or(0)) {
validateSysprops();
}
WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration,
nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration,
- nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration)
+ nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration,
+ nsecs_t hwcMinWorkDuration)
: VsyncConfiguration(currentRefreshRate),
mSfDuration(sfDuration),
mAppDuration(appDuration),
mSfEarlyDuration(sfEarlyDuration),
mAppEarlyDuration(appEarlyDuration),
mSfEarlyGpuDuration(sfEarlyGpuDuration),
- mAppEarlyGpuDuration(appEarlyGpuDuration) {}
+ mAppEarlyGpuDuration(appEarlyGpuDuration),
+ mHwcMinWorkDuration(hwcMinWorkDuration) {}
} // namespace android::scheduler::impl
diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.h b/services/surfaceflinger/Scheduler/VsyncConfiguration.h
index d9d206d..3e53b3f 100644
--- a/services/surfaceflinger/Scheduler/VsyncConfiguration.h
+++ b/services/surfaceflinger/Scheduler/VsyncConfiguration.h
@@ -111,7 +111,8 @@
nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs,
std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,
std::optional<nsecs_t> highFpsEarlyAppOffsetNs,
- std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync);
+ std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync,
+ nsecs_t hwcMinWorkDuration);
private:
VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
@@ -134,6 +135,7 @@
const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs;
const nsecs_t mThresholdForNextVsync;
+ const nsecs_t mHwcMinWorkDuration;
};
/*
@@ -148,7 +150,8 @@
protected:
// Used for unit tests
WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration,
- nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration);
+ nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration,
+ nsecs_t hwcMinWorkDuration);
private:
VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
@@ -161,6 +164,8 @@
const nsecs_t mSfEarlyGpuDuration;
const nsecs_t mAppEarlyGpuDuration;
+
+ const nsecs_t mHwcMinWorkDuration;
};
} // namespace impl
diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.h b/services/surfaceflinger/Scheduler/VsyncModulator.h
index fcde279..9410768 100644
--- a/services/surfaceflinger/Scheduler/VsyncModulator.h
+++ b/services/surfaceflinger/Scheduler/VsyncModulator.h
@@ -69,9 +69,12 @@
VsyncConfig early; // Used for early transactions, and during refresh rate change.
VsyncConfig earlyGpu; // Used during GPU composition.
VsyncConfig late; // Default.
+ std::chrono::nanoseconds hwcMinWorkDuration; // Used for calculating the
+ // earliest present time
bool operator==(const VsyncConfigSet& other) const {
- return early == other.early && earlyGpu == other.earlyGpu && late == other.late;
+ return early == other.early && earlyGpu == other.earlyGpu && late == other.late &&
+ hwcMinWorkDuration == other.hwcMinWorkDuration;
}
bool operator!=(const VsyncConfigSet& other) const { return !(*this == other); }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4fcec16..c6841ed 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2066,7 +2066,9 @@
std::chrono::milliseconds(mDebugRegion > 1 ? mDebugRegion : 0);
}
- refreshArgs.earliestPresentTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime);
+ const auto prevVsyncTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime);
+ const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
+ refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
refreshArgs.nextInvalidateTime = mEventQueue->nextExpectedInvalidate();
mGeometryInvalid = false;
@@ -3198,6 +3200,7 @@
}
void SurfaceFlinger::commitTransaction() {
+ ATRACE_CALL();
commitTransactionLocked();
signalSynchronousTransactions(CountDownLatch::eSyncTransaction);
mAnimTransactionPending = false;
@@ -5247,7 +5250,7 @@
case CAPTURE_DISPLAY:
case SET_FRAME_TIMELINE_INFO:
case GET_GPU_CONTEXT_PRIORITY:
- case GET_EXTRA_BUFFER_COUNT: {
+ case GET_MAX_ACQUIRED_BUFFER_COUNT: {
// This is not sensitive information, so should not require permission control.
return OK;
}
@@ -5808,8 +5811,6 @@
mKernelIdleTimerEnabled = true;
}
break;
- case KernelIdleTimerAction::NoChange:
- break;
}
}
@@ -6048,12 +6049,12 @@
}
if (!canCaptureBlackoutContent &&
- parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
+ parent->getDrawingState().flags & layer_state_t::eLayerSecure) {
ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
return PERMISSION_DENIED;
}
- Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getCurrentState());
+ Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState());
if (args.sourceCrop.width() <= 0) {
crop.left = 0;
crop.right = parentSourceBounds.getWidth();
@@ -6292,7 +6293,7 @@
Region clearRegion = Region::INVALID_REGION;
bool disableBlurs = false;
traverseLayers([&](Layer* layer) {
- disableBlurs |= layer->getCurrentState().sidebandStream != nullptr;
+ disableBlurs |= layer->getDrawingState().sidebandStream != nullptr;
Region clip(renderArea.getBounds());
compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{
@@ -6800,25 +6801,38 @@
return getRenderEngine().getContextPriority();
}
-int SurfaceFlinger::calculateExtraBufferCount(Fps maxSupportedRefreshRate,
- std::chrono::nanoseconds presentLatency) {
- auto pipelineDepth = presentLatency.count() / maxSupportedRefreshRate.getPeriodNsecs();
- if (presentLatency.count() % maxSupportedRefreshRate.getPeriodNsecs()) {
+int SurfaceFlinger::calculateMaxAcquiredBufferCount(Fps refreshRate,
+ std::chrono::nanoseconds presentLatency) {
+ auto pipelineDepth = presentLatency.count() / refreshRate.getPeriodNsecs();
+ if (presentLatency.count() % refreshRate.getPeriodNsecs()) {
pipelineDepth++;
}
- return std::max(0ll, pipelineDepth - 2);
+ return std::max(1ll, pipelineDepth - 1);
}
-status_t SurfaceFlinger::getExtraBufferCount(int* extraBuffers) const {
+status_t SurfaceFlinger::getMaxAcquiredBufferCount(int* buffers) const {
const auto maxSupportedRefreshRate = mRefreshRateConfigs->getSupportedRefreshRateRange().max;
- const auto vsyncConfig =
- mVsyncConfiguration->getConfigsForRefreshRate(maxSupportedRefreshRate).late;
- const auto presentLatency = vsyncConfig.appWorkDuration + vsyncConfig.sfWorkDuration;
-
- *extraBuffers = calculateExtraBufferCount(maxSupportedRefreshRate, presentLatency);
+ *buffers = getMaxAcquiredBufferCountForRefreshRate(maxSupportedRefreshRate);
return NO_ERROR;
}
+int SurfaceFlinger::getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const {
+ const auto refreshRate = [&] {
+ const auto frameRateOverride = mScheduler->getFrameRateOverride(uid);
+ if (frameRateOverride.has_value()) {
+ return frameRateOverride.value();
+ }
+ return mRefreshRateConfigs->getCurrentRefreshRate().getFps();
+ }();
+ return getMaxAcquiredBufferCountForRefreshRate(refreshRate);
+}
+
+int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const {
+ const auto vsyncConfig = mVsyncConfiguration->getConfigsForRefreshRate(refreshRate).late;
+ const auto presentLatency = vsyncConfig.appWorkDuration + vsyncConfig.sfWorkDuration;
+ return calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
+}
+
void SurfaceFlinger::TransactionState::traverseStatesWithBuffers(
std::function<void(const layer_state_t&)> visitor) {
for (const auto& state : states) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index a3fa8d6..22d17eb 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -708,7 +708,7 @@
int getGPUContextPriority() override;
- status_t getExtraBufferCount(int* extraBuffers) const override;
+ status_t getMaxAcquiredBufferCount(int* buffers) const override;
// Implements IBinder::DeathRecipient.
void binderDied(const wp<IBinder>& who) override;
@@ -923,6 +923,8 @@
size_t getMaxTextureSize() const;
size_t getMaxViewportDims() const;
+ int getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;
+
/*
* Display and layer stack management
*/
@@ -1062,6 +1064,7 @@
// Calculates the expected present time for this frame. For negative offsets, performs a
// correction using the predicted vsync for the next frame instead.
+
nsecs_t calculateExpectedPresentTime(DisplayStatInfo) const;
/*
@@ -1177,8 +1180,9 @@
std::vector<ui::ColorMode> getDisplayColorModes(PhysicalDisplayId displayId)
REQUIRES(mStateLock);
- static int calculateExtraBufferCount(Fps maxSupportedRefreshRate,
- std::chrono::nanoseconds presentLatency);
+ static int calculateMaxAcquiredBufferCount(Fps refreshRate,
+ std::chrono::nanoseconds presentLatency);
+ int getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const;
sp<StartPropertySetThread> mStartPropertySetThread;
surfaceflinger::Factory& mFactory;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index c5f1598..8ca241e 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -130,25 +130,25 @@
transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation);
const int32_t layerId(getLayerId(layer));
- addPositionLocked(transaction, layerId, layer->mCurrentState.transform.tx(),
- layer->mCurrentState.transform.ty());
- addDepthLocked(transaction, layerId, layer->mCurrentState.z);
- addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a);
+ addPositionLocked(transaction, layerId, layer->mDrawingState.transform.tx(),
+ layer->mDrawingState.transform.ty());
+ addDepthLocked(transaction, layerId, layer->mDrawingState.z);
+ addAlphaLocked(transaction, layerId, layer->mDrawingState.color.a);
addTransparentRegionLocked(transaction, layerId,
- layer->mCurrentState.activeTransparentRegion_legacy);
- addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
- addCropLocked(transaction, layerId, layer->mCurrentState.crop);
- addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius);
- addBackgroundBlurRadiusLocked(transaction, layerId, layer->mCurrentState.backgroundBlurRadius);
- addBlurRegionsLocked(transaction, layerId, layer->mCurrentState.blurRegions);
- addFlagsLocked(transaction, layerId, layer->mCurrentState.flags,
+ layer->mDrawingState.activeTransparentRegion_legacy);
+ addLayerStackLocked(transaction, layerId, layer->mDrawingState.layerStack);
+ addCropLocked(transaction, layerId, layer->mDrawingState.crop);
+ addCornerRadiusLocked(transaction, layerId, layer->mDrawingState.cornerRadius);
+ addBackgroundBlurRadiusLocked(transaction, layerId, layer->mDrawingState.backgroundBlurRadius);
+ addBlurRegionsLocked(transaction, layerId, layer->mDrawingState.blurRegions);
+ addFlagsLocked(transaction, layerId, layer->mDrawingState.flags,
layer_state_t::eLayerHidden | layer_state_t::eLayerOpaque |
layer_state_t::eLayerSecure);
- addReparentLocked(transaction, layerId, getLayerIdFromWeakRef(layer->mCurrentParent));
+ addReparentLocked(transaction, layerId, getLayerIdFromWeakRef(layer->mDrawingParent));
addRelativeParentLocked(transaction, layerId,
- getLayerIdFromWeakRef(layer->mCurrentState.zOrderRelativeOf),
- layer->mCurrentState.z);
- addShadowRadiusLocked(transaction, layerId, layer->mCurrentState.shadowRadius);
+ getLayerIdFromWeakRef(layer->mDrawingState.zOrderRelativeOf),
+ layer->mDrawingState.z);
+ addShadowRadiusLocked(transaction, layerId, layer->mDrawingState.shadowRadius);
}
void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment,
@@ -511,8 +511,8 @@
SurfaceCreation* creation(increment->mutable_surface_creation());
creation->set_id(getLayerId(layer));
creation->set_name(layer->getName());
- creation->set_w(layer->mCurrentState.active_legacy.w);
- creation->set_h(layer->mCurrentState.active_legacy.h);
+ creation->set_w(layer->mDrawingState.active_legacy.w);
+ creation->set_h(layer->mDrawingState.active_legacy.h);
}
void SurfaceInterceptor::addSurfaceDeletionLocked(Increment* increment,
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 4f4c02b..fdf16a7 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -235,8 +235,9 @@
handle->dequeueReadyTime);
transactionStats->surfaceStats.emplace_back(surfaceControl, handle->acquireTime,
handle->previousReleaseFence,
- handle->transformHint, eventStats, jankData,
- handle->previousBufferId);
+ handle->transformHint,
+ handle->currentMaxAcquiredBufferCount,
+ eventStats, jankData, handle->previousBufferId);
}
return NO_ERROR;
}
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h
index 184b151..444bec6 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.h
+++ b/services/surfaceflinger/TransactionCallbackInvoker.h
@@ -45,6 +45,7 @@
nsecs_t acquireTime = -1;
nsecs_t latchTime = -1;
uint32_t transformHint = 0;
+ uint32_t currentMaxAcquiredBufferCount = 0;
std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE};
CompositorTiming compositorTiming;
nsecs_t refreshStartTime = 0;
diff --git a/services/surfaceflinger/TunnelModeEnabledReporter.cpp b/services/surfaceflinger/TunnelModeEnabledReporter.cpp
index 1b3ddf7..48e3216 100644
--- a/services/surfaceflinger/TunnelModeEnabledReporter.cpp
+++ b/services/surfaceflinger/TunnelModeEnabledReporter.cpp
@@ -31,8 +31,8 @@
void TunnelModeEnabledReporter::updateTunnelModeStatus() {
bool tunnelModeEnabled = false;
mFlinger.mCurrentState.traverse([&](Layer* layer) {
- auto& currentState = layer->getCurrentState();
- if (currentState.sidebandStream != nullptr) {
+ auto& state = layer->getDrawingState();
+ if (state.sidebandStream != nullptr) {
tunnelModeEnabled = true;
return;
}
diff --git a/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp b/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp
index fb7d41c..5aa809d 100644
--- a/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp
+++ b/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp
@@ -30,7 +30,8 @@
class ReleaseBufferCallbackHelper {
public:
static void function(void* callbackContext, uint64_t graphicsBufferId,
- const sp<Fence>& releaseFence) {
+ const sp<Fence>& releaseFence,
+ uint32_t /*currentMaxAcquiredBufferCount*/) {
if (!callbackContext) {
FAIL() << "failed to get callback context";
}
@@ -66,7 +67,7 @@
android::ReleaseBufferCallback getCallback() {
return std::bind(function, static_cast<void*>(this) /* callbackContext */,
- std::placeholders::_1, std::placeholders::_2);
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
}
std::mutex mMutex;
diff --git a/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h b/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h
index e890a62..f6f3c07 100644
--- a/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h
+++ b/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h
@@ -34,7 +34,8 @@
{FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS,
FAKE_DURATION_OFFSET_NS},
{FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS,
- FAKE_DURATION_OFFSET_NS}};
+ FAKE_DURATION_OFFSET_NS},
+ FAKE_DURATION_OFFSET_NS};
}
void reset() override {}
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index d04a7d7..d4b229f 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -144,6 +144,7 @@
mConfig30DifferentGroup,
mConfig25DifferentGroup,
mConfig50};
+ DisplayModes m60_120Device = {mConfig60, mConfig120};
// Expected RefreshRate objects
RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, Fps(60),
@@ -1844,6 +1845,38 @@
ASSERT_FALSE(detaultSignals == lastInvocation->outSignalsConsidered);
}
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) {
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(m60_120Device,
+ /*currentConfigId=*/HWC_CONFIG_ID_60,
+ /*enableFrameRateOverride=*/true);
+
+ auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
+ LayerRequirement{.weight = 0.5f}};
+ auto& explicitExactLayer = layers[0];
+ auto& explicitExactOrMultipleLayer = layers[1];
+
+ explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
+ explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
+ explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60);
+
+ explicitExactLayer.vote = LayerVoteType::ExplicitExact;
+ explicitExactLayer.name = "ExplicitExact";
+ explicitExactLayer.desiredRefreshRate = Fps(30);
+
+ EXPECT_EQ(mExpected60Config,
+ refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+ EXPECT_EQ(mExpected120Config,
+ refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
+
+ explicitExactOrMultipleLayer.vote = LayerVoteType::NoVote;
+
+ EXPECT_EQ(mExpected60Config,
+ refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+ EXPECT_EQ(mExpected60Config,
+ refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
+}
+
TEST_F(RefreshRateConfigsTest, testComparisonOperator) {
EXPECT_TRUE(mExpected60Config < mExpected90Config);
EXPECT_FALSE(mExpected60Config < mExpected60Config);
@@ -1864,10 +1897,10 @@
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction());
- // SetPolicy(60, 60), current 60Hz => NoChange, avoid extra calls.
+ // SetPolicy(60, 60), current 60Hz => TurnOff
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}),
0);
- EXPECT_EQ(KernelIdleTimerAction::NoChange, refreshRateConfigs->getIdleTimerAction());
+ EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction());
// SetPolicy(90, 90), current 90Hz => TurnOff.
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(90), Fps(90)}}),
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
index fd3e564..35033ea 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -116,7 +116,7 @@
}
void RefreshRateSelectionTest::commitTransaction(Layer* layer) {
- auto c = layer->getCurrentState();
+ auto c = layer->getDrawingState();
layer->commitTransaction(c);
}
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 423d0cc..f680d80 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -210,14 +210,14 @@
EXPECT_CALL(*mEventThread, onModeChanged(_, _, _)).Times(0);
}
-TEST_F(SchedulerTest, calculateExtraBufferCount) {
- EXPECT_EQ(0, mFlinger.calculateExtraBufferCount(Fps(60), 30ms));
- EXPECT_EQ(1, mFlinger.calculateExtraBufferCount(Fps(90), 30ms));
- EXPECT_EQ(2, mFlinger.calculateExtraBufferCount(Fps(120), 30ms));
+TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
+ EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 30ms));
+ EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(Fps(90), 30ms));
+ EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(Fps(120), 30ms));
- EXPECT_EQ(1, mFlinger.calculateExtraBufferCount(Fps(60), 40ms));
+ EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 40ms));
- EXPECT_EQ(0, mFlinger.calculateExtraBufferCount(Fps(60), 10ms));
+ EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 10ms));
}
MATCHER(Is120Hz, "") {
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index 46ef750..1ed52ea 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -152,7 +152,7 @@
void SetFrameRateTest::commitTransaction() {
for (auto layer : mLayers) {
- auto c = layer->getCurrentState();
+ auto c = layer->getDrawingState();
layer->commitTransaction(c);
}
}
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp
index 0614434..e2be074 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp
@@ -74,4 +74,4 @@
}
} // namespace
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index d78f36c..7f6e05e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -259,7 +259,6 @@
memcpy(&mFlinger->mInternalDisplayPrimaries, &primaries, sizeof(ui::DisplayPrimaries));
}
- static auto& mutableLayerCurrentState(const sp<Layer>& layer) { return layer->mCurrentState; }
static auto& mutableLayerDrawingState(const sp<Layer>& layer) { return layer->mDrawingState; }
auto& mutableStateLock() { return mFlinger->mStateLock; }
@@ -272,7 +271,6 @@
static void setLayerSidebandStream(const sp<Layer>& layer,
const sp<NativeHandle>& sidebandStream) {
layer->mDrawingState.sidebandStream = sidebandStream;
- layer->mCurrentState.sidebandStream = sidebandStream;
layer->mSidebandStream = sidebandStream;
layer->editCompositionState()->sidebandStream = sidebandStream;
}
@@ -391,9 +389,9 @@
auto getGPUContextPriority() { return mFlinger->getGPUContextPriority(); }
- auto calculateExtraBufferCount(Fps maxSupportedRefreshRate,
- std::chrono::nanoseconds presentLatency) const {
- return SurfaceFlinger::calculateExtraBufferCount(maxSupportedRefreshRate, presentLatency);
+ auto calculateMaxAcquiredBufferCount(Fps refreshRate,
+ std::chrono::nanoseconds presentLatency) const {
+ return SurfaceFlinger::calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
}
/* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
index 546bc4a..2845d0a 100644
--- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
@@ -62,7 +62,7 @@
}
void commitTransaction(Layer* layer) {
- auto c = layer->getCurrentState();
+ auto c = layer->getDrawingState();
layer->commitTransaction(c);
}
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index c1123cd..7bf224d 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -62,7 +62,7 @@
}
void commitTransaction(Layer* layer) {
- auto c = layer->getCurrentState();
+ auto c = layer->getDrawingState();
layer->commitTransaction(c);
}
@@ -101,9 +101,9 @@
sp<BufferStateLayer> layer = createBufferStateLayer();
layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0},
10);
- EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_TRUE(layer->mCurrentState.bufferSurfaceFrameTX == nullptr);
- const auto surfaceFrame = layer->mCurrentState.bufferlessSurfaceFramesTX.at(/*token*/ 1);
+ EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_TRUE(layer->mDrawingState.bufferSurfaceFrameTX == nullptr);
+ const auto surfaceFrame = layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*token*/ 1);
commitTransaction(layer.get());
EXPECT_EQ(1, surfaceFrame->getToken());
EXPECT_EQ(false, surfaceFrame->getIsBuffer());
@@ -123,9 +123,9 @@
acquireFence->signalForTest(12);
commitTransaction(layer.get());
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto& surfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto surfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
// Buffers are presented only at latch time.
EXPECT_EQ(PresentState::Unknown, surfaceFrame->getPresentState());
@@ -148,9 +148,9 @@
mRenderEngine, false);
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto droppedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto droppedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
@@ -164,9 +164,9 @@
nsecs_t end = systemTime();
acquireFence2->signalForTest(12);
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto& presentedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto presentedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
commitTransaction(layer.get());
bool computeVisisbleRegions;
@@ -190,8 +190,8 @@
layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0},
10);
- EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_EQ(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
+ EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
@@ -203,9 +203,9 @@
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence->signalForTest(12);
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto& surfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto surfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
commitTransaction(layer.get());
EXPECT_EQ(1, surfaceFrame->getToken());
@@ -229,29 +229,29 @@
mRenderEngine, false);
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0},
10);
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
}
void MultipleSurfaceFramesPresentedTogether() {
sp<BufferStateLayer> layer = createBufferStateLayer();
layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0},
10);
- EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_EQ(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
+ EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
const auto bufferlessSurfaceFrame1 =
- layer->mCurrentState.bufferlessSurfaceFramesTX.at(/*token*/ 1);
+ layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*token*/ 1);
layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 4, /*inputEventId*/ 0},
10);
- EXPECT_EQ(2u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_EQ(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto bufferlessSurfaceFrame2 = layer->mCurrentState.bufferlessSurfaceFramesTX[4];
+ EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto bufferlessSurfaceFrame2 = layer->mDrawingState.bufferlessSurfaceFramesTX[4];
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
@@ -261,9 +261,9 @@
mRenderEngine, false);
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 3, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
- EXPECT_EQ(2u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto& bufferSurfaceFrameTX = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto bufferSurfaceFrameTX = layer->mDrawingState.bufferSurfaceFrameTX;
acquireFence->signalForTest(12);
@@ -299,8 +299,8 @@
mRenderEngine, false);
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto droppedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto droppedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
@@ -312,8 +312,8 @@
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence2->signalForTest(12);
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- auto& presentedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ auto presentedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
commitTransaction(layer.get());
bool computeVisisbleRegions;
@@ -340,9 +340,9 @@
mRenderEngine, false);
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto droppedSurfaceFrame1 = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto droppedSurfaceFrame1 = layer->mDrawingState.bufferSurfaceFrameTX;
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
@@ -355,9 +355,9 @@
{/*vsyncId*/ FrameTimelineInfo::INVALID_VSYNC_ID, /*inputEventId*/ 0},
nullptr /* releaseBufferCallback */);
auto dropEndTime1 = systemTime();
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto droppedSurfaceFrame2 = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto droppedSurfaceFrame2 = layer->mDrawingState.bufferSurfaceFrameTX;
sp<Fence> fence3(new Fence());
auto acquireFence3 = fenceFactory.createFenceTimeForTest(fence3);
@@ -371,9 +371,9 @@
auto dropEndTime2 = systemTime();
acquireFence3->signalForTest(12);
- EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- const auto& presentedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX;
+ EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ const auto presentedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
commitTransaction(layer.get());
bool computeVisisbleRegions;
@@ -415,10 +415,10 @@
layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 2,
/*inputEventId*/ 0},
10);
- ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
- EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
+ ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
+ EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
auto& bufferlessSurfaceFrame =
- layer->mCurrentState.bufferlessSurfaceFramesTX.at(/*vsyncId*/ 2);
+ layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*vsyncId*/ 2);
bufferlessSurfaceFrames.push_back(bufferlessSurfaceFrame);
commitTransaction(layer.get());
diff --git a/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp b/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp
index bb7578d..41a4d30 100644
--- a/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp
@@ -34,16 +34,18 @@
public:
TestableWorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration,
nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration,
- nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration)
+ nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration,
+ nsecs_t hwcMinWorkDuration)
: impl::WorkDuration(currentFps, sfDuration, appDuration, sfEarlyDuration,
- appEarlyDuration, sfEarlyGlDuration, appEarlyGlDuration) {}
+ appEarlyDuration, sfEarlyGlDuration, appEarlyGlDuration,
+ hwcMinWorkDuration) {}
};
class WorkDurationTest : public testing::Test {
protected:
WorkDurationTest()
: mWorkDuration(Fps(60.0f), 10'500'000, 20'500'000, 16'000'000, 16'500'000, 13'500'000,
- 21'000'000) {}
+ 21'000'000, 1234) {}
~WorkDurationTest() = default;
@@ -104,7 +106,7 @@
}
TEST_F(WorkDurationTest, getConfigsForRefreshRate_DefaultOffsets) {
- TestableWorkDuration phaseOffsetsWithDefaultValues(Fps(60.0f), -1, -1, -1, -1, -1, -1);
+ TestableWorkDuration phaseOffsetsWithDefaultValues(Fps(60.0f), -1, -1, -1, -1, -1, -1, 0);
auto validateOffsets = [](const auto& offsets, std::chrono::nanoseconds vsyncPeriod) {
EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
@@ -124,6 +126,8 @@
EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, vsyncPeriod - 1'000'000ns);
EXPECT_EQ(offsets.earlyGpu.appWorkDuration, vsyncPeriod);
+
+ EXPECT_EQ(offsets.hwcMinWorkDuration, 0ns);
};
const auto testForRefreshRate = [&](Fps refreshRate) {
@@ -160,6 +164,10 @@
EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'000'000ns);
}
+TEST_F(WorkDurationTest, minHwcWorkDuration) {
+ EXPECT_EQ(mWorkDuration.getCurrentConfigs().hwcMinWorkDuration, 1234ns);
+}
+
class TestablePhaseOffsets : public impl::PhaseOffsets {
public:
TestablePhaseOffsets(nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
@@ -172,13 +180,14 @@
std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,
std::optional<nsecs_t> highFpsEarlyAppOffsetNs,
std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs,
- nsecs_t thresholdForNextVsync)
+ nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration)
: impl::PhaseOffsets(Fps(60.0f), vsyncPhaseOffsetNs, sfVSyncPhaseOffsetNs,
earlySfOffsetNs, earlyGpuSfOffsetNs, earlyAppOffsetNs,
earlyGpuAppOffsetNs, highFpsVsyncPhaseOffsetNs,
highFpsSfVSyncPhaseOffsetNs, highFpsEarlySfOffsetNs,
highFpsEarlyGpuSfOffsetNs, highFpsEarlyAppOffsetNs,
- highFpsEarlyGpuAppOffsetNs, thresholdForNextVsync) {}
+ highFpsEarlyGpuAppOffsetNs, thresholdForNextVsync,
+ hwcMinWorkDuration) {}
};
class PhaseOffsetsTest : public testing::Test {
@@ -186,9 +195,9 @@
PhaseOffsetsTest() = default;
~PhaseOffsetsTest() = default;
- TestablePhaseOffsets mPhaseOffsets{2'000'000, 6'000'000, 7'000'000, 8'000'000, 3'000'000,
- 4'000'000, 2'000'000, 1'000'000, 2'000'000, 3'000'000,
- 3'000'000, 4'000'000, 10'000'000};
+ TestablePhaseOffsets mPhaseOffsets{2'000'000, 6'000'000, 7'000'000, 8'000'000, 3'000'000,
+ 4'000'000, 2'000'000, 1'000'000, 2'000'000, 3'000'000,
+ 3'000'000, 4'000'000, 10'000'000, 1234};
};
TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_unknownRefreshRate) {
@@ -258,8 +267,8 @@
}
TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_60Hz) {
- TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
- 1'000'000, {}, {}, {}, {}, 10'000'000};
+ TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
+ 1'000'000, {}, {}, {}, {}, 10'000'000, 1234};
auto offsets = phaseOffsets.getConfigsForRefreshRate(Fps(60.0f));
EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
@@ -282,8 +291,8 @@
}
TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_90Hz) {
- TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
- 1'000'000, {}, {}, {}, {}, 10'000'000};
+ TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
+ 1'000'000, {}, {}, {}, {}, 10'000'000, 1234};
auto offsets = phaseOffsets.getConfigsForRefreshRate(Fps(90.0f));
EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
@@ -305,4 +314,10 @@
EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'222'222ns);
}
+TEST_F(PhaseOffsetsTest, minHwcWorkDuration) {
+ TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
+ 1'000'000, {}, {}, {}, {}, 10'000'000, 1234};
+ EXPECT_EQ(phaseOffsets.getCurrentConfigs().hwcMinWorkDuration, 1234ns);
+}
+
} // namespace android::scheduler
diff --git a/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp b/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp
index 17648d5..60952bf 100644
--- a/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp
@@ -35,6 +35,7 @@
APP_OFFSET_EARLY_GPU,
SF_DURATION_EARLY_GPU,
APP_DURATION_EARLY_GPU,
+ HWC_MIN_WORK_DURATION,
};
static VsyncModulator::TimePoint Now() {
@@ -57,7 +58,8 @@
nanos(SF_DURATION_EARLY_GPU),
nanos(APP_DURATION_EARLY_GPU)};
- const VsyncModulator::VsyncConfigSet mOffsets = {kEarly, kEarlyGpu, kLate};
+ const VsyncModulator::VsyncConfigSet mOffsets = {kEarly, kEarlyGpu, kLate,
+ nanos(HWC_MIN_WORK_DURATION)};
VsyncModulator mVsyncModulator{mOffsets, Now};
void SetUp() override { EXPECT_EQ(kLate, mVsyncModulator.setVsyncConfigSet(mOffsets)); }