Merge "swapchain: increase the minimal buffer count to 3" into sc-dev
diff --git a/cmds/installd/run_dex2oat.cpp b/cmds/installd/run_dex2oat.cpp
index a27fd10..e847626 100644
--- a/cmds/installd/run_dex2oat.cpp
+++ b/cmds/installd/run_dex2oat.cpp
@@ -324,6 +324,12 @@
AddRuntimeArg(MapPropertyToArg("dalvik.vm.dex2oat-Xms", "-Xms%s"));
AddRuntimeArg(MapPropertyToArg("dalvik.vm.dex2oat-Xmx", "-Xmx%s"));
+
+ // Enable compiling dex files in isolation on low ram devices.
+ // It takes longer but reduces the memory footprint.
+ if (GetBoolProperty("ro.config.low_ram", false)) {
+ AddArg("--compile-individually");
+ }
}
void RunDex2Oat::Exec(int exit_code) {
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 52d3fa3..364c939 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -151,6 +151,7 @@
1, false);
static int32_t id = 0;
auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
+ mPendingBufferTrace = "PendingBuffer - " + mName + "BLAST#" + std::to_string(id);
id++;
mBufferItemConsumer->setName(String8(consumerName.c_str()));
mBufferItemConsumer->setFrameAvailableListener(this);
@@ -168,7 +169,6 @@
.setFlags(surface, layer_state_t::eEnableBackpressure,
layer_state_t::eEnableBackpressure)
.apply();
-
mNumAcquired = 0;
mNumFrameAvailable = 0;
}
@@ -205,6 +205,11 @@
applyTransaction = true;
}
+ if (mSurfaceControl != nullptr) {
+ mTransformHint = mSurfaceControl->getTransformHint();
+ mBufferItemConsumer->setTransformHint(mTransformHint);
+ }
+
ui::Size newSize(width, height);
if (mRequestedSize != newSize) {
mRequestedSize.set(newSize);
@@ -259,15 +264,18 @@
mTransformHint = stat.transformHint;
mBufferItemConsumer->setTransformHint(mTransformHint);
- mBufferItemConsumer
- ->updateFrameTimestamps(stat.frameEventStats.frameNumber,
- stat.frameEventStats.refreshStartTime,
- stat.frameEventStats.gpuCompositionDoneFence,
- stat.presentFence, stat.previousReleaseFence,
- stat.frameEventStats.compositorTiming,
- stat.latchTime,
- stat.frameEventStats.dequeueReadyTime);
-
+ // Update frametime stamps if the frame was latched and presented, indicated by a
+ // valid latch time.
+ if (stat.latchTime > 0) {
+ mBufferItemConsumer
+ ->updateFrameTimestamps(stat.frameEventStats.frameNumber,
+ stat.frameEventStats.refreshStartTime,
+ stat.frameEventStats.gpuCompositionDoneFence,
+ stat.presentFence, stat.previousReleaseFence,
+ stat.frameEventStats.compositorTiming,
+ stat.latchTime,
+ stat.frameEventStats.dequeueReadyTime);
+ }
currFrameNumber = stat.frameEventStats.frameNumber;
if (mTransactionCompleteCallback &&
@@ -361,6 +369,7 @@
ATRACE_INT("PendingRelease", mPendingRelease.size());
mNumAcquired--;
+ ATRACE_INT(mPendingBufferTrace.c_str(), mNumFrameAvailable + mNumAcquired);
processNextBufferLocked(false /* useNextTransaction */);
mCallbackCV.notify_all();
}
@@ -529,6 +538,7 @@
}
// add to shadow queue
mNumFrameAvailable++;
+ ATRACE_INT(mPendingBufferTrace.c_str(), mNumFrameAvailable + mNumAcquired);
BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " nextTransactionSet=%s", item.mFrameNumber,
toString(nextTransactionSet));
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 0981e76..cb0e65e 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -125,6 +125,7 @@
static PixelFormat convertBufferFormat(PixelFormat& format);
std::string mName;
+ std::string mPendingBufferTrace;
sp<SurfaceControl> mSurfaceControl;
std::mutex mMutex;
diff --git a/libs/gui/include/gui/FrameTimestamps.h b/libs/gui/include/gui/FrameTimestamps.h
index 0750080..dd3de58 100644
--- a/libs/gui/include/gui/FrameTimestamps.h
+++ b/libs/gui/include/gui/FrameTimestamps.h
@@ -131,6 +131,7 @@
// Public for testing.
static nsecs_t snapToNextTick(
nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval);
+ nsecs_t getReportedCompositeDeadline() const { return mCompositorTiming.deadline; };
nsecs_t getNextCompositeDeadline(const nsecs_t now) const;
nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; }
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index 06660b8..6ff67aa 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -948,21 +948,22 @@
class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
public:
void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
- nsecs_t* requestedPresentTime, nsecs_t* postedTime,
+ nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
IGraphicBufferProducer::QueueBufferOutput* qbOutput,
- bool getFrameTimestamps, nsecs_t requestedPresentTimeDelay = 0) {
+ bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
int slot;
sp<Fence> fence;
sp<GraphicBuffer> buf;
auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
nullptr, nullptr);
- ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
- ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
+ if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
+ ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
+ }
- nsecs_t requestedTime = systemTime() + requestedPresentTimeDelay;
- if (requestedPresentTime) *requestedPresentTime = requestedTime;
- IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
+ *outRequestedPresentTime = requestedPresentTime;
+ IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
+ HAL_DATASPACE_UNKNOWN,
Rect(mDisplayWidth, mDisplayHeight),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
Fence::NO_FENCE, /*sticky*/ 0,
@@ -1034,9 +1035,11 @@
IGraphicBufferProducer::QueueBufferOutput qbOutput;
nsecs_t requestedPresentTimeA = 0;
nsecs_t postedTimeA = 0;
- nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
+ // Present the frame sometime in the future so we can add two frames to the queue so the older
+ // one will be dropped.
+ nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
- presentTimeDelay);
+ presentTime);
history.applyDelta(qbOutput.frameTimestamps);
FrameEvents* events = nullptr;
@@ -1049,7 +1052,10 @@
// queue another buffer so the first can be dropped
nsecs_t requestedPresentTimeB = 0;
nsecs_t postedTimeB = 0;
- setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
+ adapter.setTransactionCompleteCallback(2);
+ presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
+ setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
+ presentTime);
history.applyDelta(qbOutput.frameTimestamps);
events = history.getFrame(1);
ASSERT_NE(nullptr, events);
@@ -1059,20 +1065,75 @@
ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
ASSERT_GE(events->postedTime, postedTimeA);
- // a valid latchtime should not be set
+ // a valid latchtime and pre and post composition info should not be set for the dropped frame
ASSERT_FALSE(events->hasLatchInfo());
ASSERT_FALSE(events->hasDequeueReadyInfo());
+ ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
+ ASSERT_FALSE(events->hasDisplayPresentInfo());
+ ASSERT_FALSE(events->hasReleaseInfo());
- ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
- ASSERT_NE(nullptr, events->displayPresentFence);
- ASSERT_NE(nullptr, events->releaseFence);
+ // wait for the last transaction to be completed.
+ adapter.waitForCallback(2);
- // we should also have gotten the initial values for the next frame
+ // queue another buffer so we query for frame event deltas
+ nsecs_t requestedPresentTimeC = 0;
+ nsecs_t postedTimeC = 0;
+ setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
+ history.applyDelta(qbOutput.frameTimestamps);
+
+ // frame number, requestedPresentTime, and postTime should not have changed
+ ASSERT_EQ(1, events->frameNumber);
+ ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
+ ASSERT_GE(events->postedTime, postedTimeA);
+
+ // a valid latchtime and pre and post composition info should not be set for the dropped frame
+ ASSERT_FALSE(events->hasLatchInfo());
+ ASSERT_FALSE(events->hasDequeueReadyInfo());
+ ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
+ ASSERT_FALSE(events->hasDisplayPresentInfo());
+ ASSERT_FALSE(events->hasReleaseInfo());
+
+ // we should also have gotten values for the presented frame
events = history.getFrame(2);
ASSERT_NE(nullptr, events);
ASSERT_EQ(2, events->frameNumber);
ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
ASSERT_GE(events->postedTime, postedTimeB);
+ ASSERT_GE(events->latchTime, postedTimeB);
+ ASSERT_GE(events->dequeueReadyTime, events->latchTime);
+ ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
+ ASSERT_NE(nullptr, events->displayPresentFence);
+ ASSERT_NE(nullptr, events->releaseFence);
+
+ // wait for any callbacks that have not been received
+ adapter.waitForCallbacks();
+}
+
+TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
+ BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
+ sp<IGraphicBufferProducer> igbProducer;
+ ProducerFrameEventHistory history;
+ setUpProducer(adapter, igbProducer);
+
+ IGraphicBufferProducer::QueueBufferOutput qbOutput;
+ nsecs_t requestedPresentTimeA = 0;
+ nsecs_t postedTimeA = 0;
+ adapter.setTransactionCompleteCallback(1);
+ setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
+ history.applyDelta(qbOutput.frameTimestamps);
+ adapter.waitForCallback(1);
+
+ // queue another buffer so we query for frame event deltas
+ nsecs_t requestedPresentTimeB = 0;
+ nsecs_t postedTimeB = 0;
+ setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
+ history.applyDelta(qbOutput.frameTimestamps);
+
+ // check for a valid compositor deadline
+ ASSERT_NE(0, history.getReportedCompositeDeadline());
+
+ // wait for any callbacks that have not been received
+ adapter.waitForCallbacks();
}
} // namespace android
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/inputflinger/dispatcher/FocusResolver.cpp b/services/inputflinger/dispatcher/FocusResolver.cpp
index 2db8c13..fb19435 100644
--- a/services/inputflinger/dispatcher/FocusResolver.cpp
+++ b/services/inputflinger/dispatcher/FocusResolver.cpp
@@ -216,4 +216,9 @@
return dump;
}
+void FocusResolver::displayRemoved(int32_t displayId) {
+ mFocusRequestByDisplay.erase(displayId);
+ mLastFocusResultByDisplay.erase(displayId);
+}
+
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/FocusResolver.h b/services/inputflinger/dispatcher/FocusResolver.h
index dc5eeeb..afe16b3 100644
--- a/services/inputflinger/dispatcher/FocusResolver.h
+++ b/services/inputflinger/dispatcher/FocusResolver.h
@@ -62,6 +62,9 @@
std::optional<FocusResolver::FocusChanges> setFocusedWindow(
const FocusRequest& request, const std::vector<sp<InputWindowHandle>>& windows);
+ // Display has been removed from the system, clean up old references.
+ void displayRemoved(int32_t displayId);
+
// exposed for debugging
bool hasFocusedWindowTokens() const { return !mFocusedWindowTokenByDisplay.empty(); }
std::string dumpFocusedWindows() const;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index d2b8739..c0010ab 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4613,30 +4613,34 @@
}
{ // acquire lock
std::scoped_lock _l(mLock);
-
- std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
- getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
-
- if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
- return; // This application is already focused. No need to wake up or change anything.
- }
-
- // Set the new application handle.
- if (inputApplicationHandle != nullptr) {
- mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
- } else {
- mFocusedApplicationHandlesByDisplay.erase(displayId);
- }
-
- // No matter what the old focused application was, stop waiting on it because it is
- // no longer focused.
- resetNoFocusedWindowTimeoutLocked();
+ setFocusedApplicationLocked(displayId, inputApplicationHandle);
} // release lock
// Wake up poll loop since it may need to make new input dispatching choices.
mLooper->wake();
}
+void InputDispatcher::setFocusedApplicationLocked(
+ int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
+ std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
+ getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
+
+ if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
+ return; // This application is already focused. No need to wake up or change anything.
+ }
+
+ // Set the new application handle.
+ if (inputApplicationHandle != nullptr) {
+ mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
+ } else {
+ mFocusedApplicationHandlesByDisplay.erase(displayId);
+ }
+
+ // No matter what the old focused application was, stop waiting on it because it is
+ // no longer focused.
+ resetNoFocusedWindowTimeoutLocked();
+}
+
/**
* Sets the focused display, which is responsible for receiving focus-dispatched input events where
* the display not specified.
@@ -6208,4 +6212,19 @@
mLock.lock();
}
+void InputDispatcher::displayRemoved(int32_t displayId) {
+ { // acquire lock
+ std::scoped_lock _l(mLock);
+ // Set an empty list to remove all handles from the specific display.
+ setInputWindowsLocked(/* window handles */ {}, displayId);
+ setFocusedApplicationLocked(displayId, nullptr);
+ // Call focus resolver to clean up stale requests. This must be called after input windows
+ // have been removed for the removed display.
+ mFocusResolver.displayRemoved(displayId);
+ } // release lock
+
+ // Wake up poll loop since it may need to make new input dispatching choices.
+ mLooper->wake();
+}
+
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index bb3f3e6..9edf41c 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -139,6 +139,8 @@
std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const;
+ void displayRemoved(int32_t displayId) override;
+
private:
enum class DropReason {
NOT_DROPPED,
@@ -343,6 +345,9 @@
std::unordered_map<int32_t, TouchState> mTouchStatesByDisplay GUARDED_BY(mLock);
std::unique_ptr<DragState> mDragState GUARDED_BY(mLock);
+ void setFocusedApplicationLocked(
+ int32_t displayId,
+ const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) REQUIRES(mLock);
// Focused applications.
std::unordered_map<int32_t, std::shared_ptr<InputApplicationHandle>>
mFocusedApplicationHandlesByDisplay GUARDED_BY(mLock);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 7f85e53..43428a0 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -209,6 +209,11 @@
* Returns true on success.
*/
virtual bool flushSensor(int deviceId, InputDeviceSensorType sensorType) = 0;
+
+ /**
+ * Called when a display has been removed from the system.
+ */
+ virtual void displayRemoved(int32_t displayId) = 0;
};
} // namespace android
diff --git a/services/inputflinger/tests/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index 17efb5b..9051ff1 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -256,5 +256,37 @@
// dropped.
ASSERT_FALSE(changes);
}
+TEST(FocusResolverTest, FocusRequestsAreClearedWhenWindowIsRemoved) {
+ sp<IBinder> windowToken = new BBinder();
+ std::vector<sp<InputWindowHandle>> windows;
+
+ sp<FakeWindowHandle> window = new FakeWindowHandle("Test Window", windowToken,
+ true /* focusable */, true /* visible */);
+ windows.push_back(window);
+
+ FocusRequest request;
+ request.displayId = 42;
+ request.token = windowToken;
+ FocusResolver focusResolver;
+ std::optional<FocusResolver::FocusChanges> changes =
+ focusResolver.setFocusedWindow(request, windows);
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
+ ASSERT_EQ(request.displayId, changes->displayId);
+
+ // Start with a focused window
+ window->setFocusable(true);
+ changes = focusResolver.setInputWindows(request.displayId, windows);
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
+
+ // When a display is removed, all windows are removed from the display
+ // and our focused window loses focus
+ changes = focusResolver.setInputWindows(request.displayId, {});
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ windowToken, /*to*/ nullptr);
+ focusResolver.displayRemoved(request.displayId);
+
+ // When a display is readded, the window does not get focus since the request was cleared.
+ changes = focusResolver.setInputWindows(request.displayId, windows);
+ ASSERT_FALSE(changes);
+}
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index d51acce..77ca12c 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2688,6 +2688,23 @@
window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
}
+TEST_F(InputDispatcherTest, DisplayRemoved) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "window", ADISPLAY_ID_DEFAULT);
+ mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
+
+ // window is granted focus.
+ window->setFocusable(true);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+ setFocusedWindow(window);
+ window->consumeFocusEvent(true);
+
+ // When a display is removed window loses focus.
+ mDispatcher->displayRemoved(ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(false);
+}
+
/**
* Launch two windows, with different owners. One window (slipperyExitWindow) has Flag::SLIPPERY,
* and overlaps the other window, slipperyEnterWindow. The window 'slipperyExitWindow' is on top
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 f8af908..6b5cf04 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -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() {
@@ -257,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 {
@@ -266,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) {
@@ -336,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);
}
@@ -361,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,
@@ -383,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;
@@ -397,8 +402,8 @@
mRequestedTransform.set(x, y);
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -410,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);
@@ -425,38 +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,
+ 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;
@@ -483,61 +489,67 @@
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;
- setTransactionFlags(eTransactionNeeded);
+ if (mDrawingState.sidebandStream == sidebandStream) return false;
+ if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
+ mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
+ } else if (sidebandStream != nullptr) {
+ mFlinger->mTunnelModeEnabledReporter->incrementTunnelModeCount();
+ }
+
+ mDrawingState.sidebandStream = sidebandStream;
+ mDrawingState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
if (!mSidebandStreamChanged.exchange(true)) {
// mSidebandStreamChanged was false
mFlinger->signalLayerUpdate();
@@ -563,14 +575,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
@@ -585,8 +597,8 @@
}
bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
- mCurrentState.transparentRegionHint = transparent;
- mCurrentState.modified = true;
+ mDrawingState.transparentRegionHint = transparent;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -645,7 +657,7 @@
return true;
}
- return mCurrentState.isAutoTimestamp || mCurrentState.desiredPresentTime <= expectedPresentTime;
+ return mDrawingState.isAutoTimestamp || mDrawingState.desiredPresentTime <= expectedPresentTime;
}
bool BufferStateLayer::onPreComposition(nsecs_t refreshStartTime) {
@@ -674,7 +686,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
@@ -682,7 +694,7 @@
* to apply.
*/
uint64_t BufferStateLayer::getHeadFrameNumber(nsecs_t /* expectedPresentTime */) const {
- return mCurrentState.frameNumber;
+ return mDrawingState.frameNumber;
}
void BufferStateLayer::setAutoRefresh(bool autoRefresh) {
@@ -712,8 +724,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,
@@ -756,6 +768,7 @@
addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
mDrawingState.acquireFenceTime->getSignalTime(),
latchTime);
+ mDrawingState.bufferSurfaceFrameTX.reset();
}
std::deque<sp<CallbackHandle>> remainingHandles;
@@ -763,7 +776,7 @@
.finalizeOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
mDrawingState.callbackHandles = remainingHandles;
- mCurrentStateModified = false;
+ mDrawingStateModified = false;
return NO_ERROR;
}
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..ad31b3f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -70,6 +70,7 @@
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
#include "TimeStats/TimeStats.h"
+#include "TunnelModeEnabledReporter.h"
#include "input/InputWindow.h"
#define DEBUG_RESIZE 0
@@ -98,52 +99,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);
@@ -175,6 +173,10 @@
mFrameTracker.logAndResetStats(mName);
mFlinger->onLayerDestroyed(this);
+
+ if (mDrawingState.sidebandStream != nullptr) {
+ mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
+ }
}
LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, std::string name,
@@ -203,11 +205,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 +223,8 @@
}
void Layer::removeFromCurrentState() {
- if (!mRemovedFromCurrentState) {
- mRemovedFromCurrentState = true;
+ if (!mRemovedFromDrawingState) {
+ mRemovedFromDrawingState = true;
mFlinger->mScheduler->deregisterLayer(this);
}
@@ -249,8 +251,8 @@
}
void Layer::addToCurrentState() {
- if (mRemovedFromCurrentState) {
- mRemovedFromCurrentState = false;
+ if (mRemovedFromDrawingState) {
+ mRemovedFromDrawingState = false;
mFlinger->mScheduler->registerLayer(this);
}
@@ -679,158 +681,36 @@
// 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();
- if (mChildrenChanged) {
- flags |= eVisibleRegion;
- mChildrenChanged = false;
- }
-
// 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) {
- flags |= eInputInfoChanged;
- mCurrentState.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 +721,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 +735,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 +772,16 @@
}
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;
+
+ mFlinger->mSomeChildrenChanged = 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 +792,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 +824,18 @@
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;
+ mFlinger->mSomeChildrenChanged = true;
- auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
+ mDrawingState.z = relativeZ;
+
+ auto oldZOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote();
if (oldZOrderRelativeOf != nullptr) {
oldZOrderRelativeOf->removeZOrderRelative(this);
}
@@ -975,82 +848,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 +938,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 +1045,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 +1071,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 +1113,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 +1132,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 +1146,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 +1162,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 +1199,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 +1264,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 +1550,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);
}
@@ -1681,7 +1561,7 @@
}
void Layer::addChild(const sp<Layer>& layer) {
- mChildrenChanged = true;
+ mFlinger->mSomeChildrenChanged = true;
setTransactionFlags(eTransactionNeeded);
mCurrentChildren.add(layer);
@@ -1691,7 +1571,7 @@
}
ssize_t Layer::removeChild(const sp<Layer>& layer) {
- mChildrenChanged = true;
+ mFlinger->mSomeChildrenChanged = true;
setTransactionFlags(eTransactionNeeded);
layer->setParent(nullptr);
@@ -1749,13 +1629,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 +1667,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 +1683,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 +1782,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 +1794,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 +1807,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 +1875,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 +1987,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;
+ mFlinger->mInputInfoChanged = true;
setTransactionFlags(eTransactionNeeded);
}
@@ -2190,7 +2068,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 +2156,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..ec9bb7c 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1,3 +1,4 @@
+
/*
* Copyright (C) 2007 The Android Open Source Project
*
@@ -185,7 +186,6 @@
float cornerRadius;
int backgroundBlurRadius;
- bool inputInfoChanged;
InputWindowInfo inputInfo;
wp<Layer> touchableRegionCrop;
@@ -732,8 +732,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 +883,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 +901,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 +956,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 +983,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,17 +996,12 @@
// 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 mDrawingChildren{LayerVector::StateSet::Drawing};
wp<Layer> mCurrentParent;
wp<Layer> mDrawingParent;
- // Can only be accessed with the SF state lock held.
- bool mChildrenChanged{false};
-
// Window types from WindowManager.LayoutParams
const InputWindowInfo::Type mWindowType;
@@ -1022,7 +1017,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/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index 18a2891..6b2d745 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -140,6 +140,11 @@
outTransformMatrix);
}
+status_t MonitoredProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence,
+ Rect* outRect, uint32_t* outTransform) {
+ return mProducer->getLastQueuedBuffer(outBuffer, outFence, outRect, outTransform);
+}
+
void MonitoredProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
mProducer->getFrameTimestamps(outDelta);
}
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index 788919b..3778277 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -64,6 +64,8 @@
virtual status_t setLegacyBufferDrop(bool drop) override;
virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
sp<Fence>* outFence, float outTransformMatrix[16]) override;
+ virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence,
+ Rect* outRect, uint32_t* outTransform) override;
virtual IBinder* onAsBinder();
virtual status_t setSharedBufferMode(bool sharedBufferMode) override;
virtual status_t setAutoRefresh(bool autoRefresh) override;
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 0234dbc..0eb16e2 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -867,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/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e7187b1..a022a8e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -342,6 +342,7 @@
mEventQueue(mFactory.createMessageQueue()),
mCompositionEngine(mFactory.createCompositionEngine()),
mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
+ mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()),
mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) {
ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
@@ -2231,18 +2232,15 @@
getBE().mDisplayTimeline.push(mPreviousPresentFences[0].fenceTime);
+ nsecs_t now = systemTime();
+
// Set presentation information before calling Layer::releasePendingBuffer, such that jank
// information from previous' frame classification is already available when sending jank info
// to clients, so they get jank classification as early as possible.
- mFrameTimeline->setSfPresent(systemTime(), mPreviousPresentFences[0].fenceTime,
+ mFrameTimeline->setSfPresent(/* sfPresentTime */ now, mPreviousPresentFences[0].fenceTime,
glCompositionDoneFenceTime);
- nsecs_t dequeueReadyTime = systemTime();
- for (const auto& layer : mLayersWithQueuedFrames) {
- layer->releasePendingBuffer(dequeueReadyTime);
- }
-
- const DisplayStatInfo stats = mScheduler->getDisplayStatInfo(systemTime());
+ const DisplayStatInfo stats = mScheduler->getDisplayStatInfo(now);
// We use the CompositionEngine::getLastFrameRefreshTimestamp() which might
// be sampled a little later than when we started doing work for this frame,
@@ -2259,6 +2257,7 @@
const bool frameLatched =
layer->onPostComposition(display, glCompositionDoneFenceTime,
mPreviousPresentFences[0].fenceTime, compositorTiming);
+ layer->releasePendingBuffer(/*dequeueReadyTime*/ now);
if (frameLatched) {
recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false));
}
@@ -2859,7 +2858,9 @@
(currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) {
display->setProjection(currentState.orientation, currentState.layerStackSpaceRect,
currentState.orientedDisplaySpaceRect);
- mDefaultDisplayTransformHint = display->getTransformHint();
+ if (display->isPrimary()) {
+ mDefaultDisplayTransformHint = display->getTransformHint();
+ }
}
if (currentState.width != drawingState.width ||
currentState.height != drawingState.height) {
@@ -2923,23 +2924,12 @@
processDisplayChangesLocked();
processDisplayHotplugEventsLocked();
}
+ mForceTraversal = false;
+ mForceTransactionDisplayChange = displayTransactionNeeded;
- // Commit layer transactions. This needs to happen after display transactions are
- // committed because some geometry logic relies on display orientation.
- if ((transactionFlags & eTraversalNeeded) || mForceTraversal || displayTransactionNeeded) {
- mForceTraversal = false;
- mCurrentState.traverse([&](Layer* layer) {
- uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
- if (!trFlags && !displayTransactionNeeded) return;
-
- const uint32_t flags = layer->doTransaction(0);
- if (flags & Layer::eVisibleRegion)
- mVisibleRegionsDirty = true;
-
- if (flags & Layer::eInputInfoChanged) {
- mInputInfoChanged = true;
- }
- });
+ if (mSomeChildrenChanged) {
+ mVisibleRegionsDirty = true;
+ mSomeChildrenChanged = false;
}
// Update transform hint
@@ -3164,7 +3154,6 @@
mRegionSamplingThread =
new RegionSamplingThread(*this, RegionSamplingThread::EnvironmentTimingTunables());
mFpsReporter = new FpsReporter(*mFrameTimeline, *this);
- mTunnelModeEnabledReporter = new TunnelModeEnabledReporter(*this);
// Dispatch a mode change request for the primary display on scheduler
// initialization, so that the EventThreads always contain a reference to a
// prior configuration.
@@ -3200,6 +3189,7 @@
}
void SurfaceFlinger::commitTransaction() {
+ ATRACE_CALL();
commitTransactionLocked();
signalSynchronousTransactions(CountDownLatch::eSyncTransaction);
mAnimTransactionPending = false;
@@ -3234,9 +3224,12 @@
// clear the "changed" flags in current state
mCurrentState.colorMatrixChanged = false;
- for (const auto& rootLayer : mDrawingState.layersSortedByZ) {
- rootLayer->commitChildList();
+ if (mVisibleRegionsDirty) {
+ for (const auto& rootLayer : mDrawingState.layersSortedByZ) {
+ rootLayer->commitChildList();
+ }
}
+
// TODO(b/163019109): See if this traversal is needed at all...
if (!mOffscreenLayers.empty()) {
mDrawingState.traverse([&](Layer* layer) {
@@ -3295,7 +3288,14 @@
// Display is now waiting on Layer 1's frame, which is behind layer 0's
// second frame. But layer 0's second frame could be waiting on display.
mDrawingState.traverse([&](Layer* layer) {
- if (layer->hasReadyFrame()) {
+ uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
+ if (trFlags || mForceTransactionDisplayChange) {
+ const uint32_t flags = layer->doTransaction(0);
+ if (flags & Layer::eVisibleRegion)
+ mVisibleRegionsDirty = true;
+ }
+
+ if (layer->hasReadyFrame()) {
frameQueued = true;
if (layer->shouldPresentNow(expectedPresentTime)) {
mLayersWithQueuedFrames.emplace(layer);
@@ -3303,10 +3303,11 @@
ATRACE_NAME("!layer->shouldPresentNow()");
layer->useEmptyDamage();
}
- } else {
+ } else {
layer->useEmptyDamage();
}
});
+ mForceTransactionDisplayChange = false;
// The client can continue submitting buffers for offscreen layers, but they will not
// be shown on screen. Therefore, we need to latch and release buffers of offscreen
@@ -4467,10 +4468,11 @@
d.height = 0;
displays.add(d);
+ nsecs_t now = systemTime();
// It should be on the main thread, apply it directly.
applyTransactionState(FrameTimelineInfo{}, state, displays, 0, mInputWindowCommands,
- systemTime(), true, {}, systemTime(), true, false, {}, getpid(), getuid(),
- 0 /* Undefined transactionId */);
+ /* desiredPresentTime */ now, true, {}, /* postTime */ now, true, false,
+ {}, getpid(), getuid(), 0 /* Undefined transactionId */);
setPowerModeInternal(display, hal::PowerMode::ON);
const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
@@ -5810,8 +5812,6 @@
mKernelIdleTimerEnabled = true;
}
break;
- case KernelIdleTimerAction::NoChange:
- break;
}
}
@@ -6050,12 +6050,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();
@@ -6294,7 +6294,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{
@@ -6909,6 +6909,8 @@
parent->addChild(layer);
}
+ layer->updateTransformHint(mDefaultDisplayTransformHint);
+
if (state->initialProducer != nullptr) {
mGraphicBufferProducerList.insert(state->initialProducer);
LOG_ALWAYS_FATAL_IF(mGraphicBufferProducerList.size() > mMaxGraphicBufferProducerListSize,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 22d17eb..f33df86 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -364,6 +364,7 @@
// For unit tests
friend class TestableSurfaceFlinger;
friend class TransactionApplicationTest;
+ friend class TunnelModeEnabledReporterTest;
using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate;
using VsyncModulator = scheduler::VsyncModulator;
@@ -1228,8 +1229,14 @@
// don't need synchronization
State mDrawingState{LayerVector::StateSet::Drawing};
bool mVisibleRegionsDirty = false;
- // Set during transaction commit stage to track if the input info for a layer has changed.
+
+ // Set during transaction application stage to track if the input info or children
+ // for a layer has changed.
+ // TODO: Also move visibleRegions over to a boolean system.
bool mInputInfoChanged = false;
+ bool mSomeChildrenChanged;
+ bool mForceTransactionDisplayChange = false;
+
bool mGeometryInvalid = false;
bool mAnimCompositionPending = false;
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/TunnelModeEnabledReporter.cpp b/services/surfaceflinger/TunnelModeEnabledReporter.cpp
index 1b3ddf7..4497caf 100644
--- a/services/surfaceflinger/TunnelModeEnabledReporter.cpp
+++ b/services/surfaceflinger/TunnelModeEnabledReporter.cpp
@@ -26,17 +26,10 @@
namespace android {
-TunnelModeEnabledReporter::TunnelModeEnabledReporter(SurfaceFlinger& flinger) : mFlinger(flinger) {}
+TunnelModeEnabledReporter::TunnelModeEnabledReporter() {}
void TunnelModeEnabledReporter::updateTunnelModeStatus() {
- bool tunnelModeEnabled = false;
- mFlinger.mCurrentState.traverse([&](Layer* layer) {
- auto& currentState = layer->getCurrentState();
- if (currentState.sidebandStream != nullptr) {
- tunnelModeEnabled = true;
- return;
- }
- });
+ bool tunnelModeEnabled = mTunnelModeCount > 0;
dispatchTunnelModeEnabled(tunnelModeEnabled);
}
diff --git a/services/surfaceflinger/TunnelModeEnabledReporter.h b/services/surfaceflinger/TunnelModeEnabledReporter.h
index d55507a..935502a 100644
--- a/services/surfaceflinger/TunnelModeEnabledReporter.h
+++ b/services/surfaceflinger/TunnelModeEnabledReporter.h
@@ -29,7 +29,7 @@
class TunnelModeEnabledReporter : public IBinder::DeathRecipient {
public:
- TunnelModeEnabledReporter(SurfaceFlinger& flinger);
+ TunnelModeEnabledReporter();
// Checks if there is a tunnel mode enabled state change and if so, dispatches the updated
// tunnel mode enabled/disabled state to the registered listeners
@@ -49,6 +49,9 @@
// Deregisters a TunnelModeEnabled listener
void removeListener(const sp<gui::ITunnelModeEnabledListener>& listener);
+ inline void incrementTunnelModeCount() { mTunnelModeCount++; }
+ inline void decrementTunnelModeCount() { mTunnelModeCount--; }
+
private:
mutable std::mutex mMutex;
struct WpHash {
@@ -57,10 +60,10 @@
}
};
- SurfaceFlinger& mFlinger;
std::unordered_map<wp<IBinder>, sp<gui::ITunnelModeEnabledListener>, WpHash> mListeners
GUARDED_BY(mMutex);
bool mTunnelModeEnabled GUARDED_BY(mMutex) = false;
+ uint32_t mTunnelModeCount = 0;
};
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 4e00e66..d4b229f 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -1897,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/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 b363146..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;
}
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/TunnelModeEnabledReporterTest.cpp b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
index d7d7ea7..e4f7469 100644
--- a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
@@ -27,6 +27,7 @@
#include "TunnelModeEnabledReporter.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockEventThread.h"
+#include "mock/MockMessageQueue.h"
namespace android {
@@ -71,15 +72,20 @@
sp<TestableTunnelModeEnabledListener> mTunnelModeEnabledListener =
new TestableTunnelModeEnabledListener();
sp<TunnelModeEnabledReporter> mTunnelModeEnabledReporter =
- new TunnelModeEnabledReporter(*(mFlinger.flinger()));
+ new TunnelModeEnabledReporter();
+
+ mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
};
TunnelModeEnabledReporterTest::TunnelModeEnabledReporterTest() {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+
+ mFlinger.mutableEventQueue().reset(mMessageQueue);
setupScheduler();
mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
+ mFlinger.flinger()->mTunnelModeEnabledReporter = mTunnelModeEnabledReporter;
mTunnelModeEnabledReporter->dispatchTunnelModeEnabled(false);
}
@@ -156,16 +162,18 @@
sp<NativeHandle> stream =
NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
false);
- mFlinger.setLayerSidebandStream(layer, stream);
+ layer->setSidebandStream(stream);
mFlinger.mutableCurrentState().layersSortedByZ.add(layer);
mTunnelModeEnabledReporter->updateTunnelModeStatus();
mTunnelModeEnabledReporter->addListener(mTunnelModeEnabledListener);
EXPECT_EQ(true, mTunnelModeEnabledListener->mTunnelModeEnabled);
mTunnelModeEnabledReporter->removeListener(mTunnelModeEnabledListener);
-
mFlinger.mutableCurrentState().layersSortedByZ.remove(layer);
+ layer = nullptr;
+
mTunnelModeEnabledReporter->updateTunnelModeStatus();
mTunnelModeEnabledReporter->addListener(mTunnelModeEnabledListener);
+
EXPECT_EQ(false, mTunnelModeEnabledListener->mTunnelModeEnabled);
}
@@ -178,7 +186,7 @@
sp<NativeHandle> stream =
NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
false);
- mFlinger.setLayerSidebandStream(layerWithSidebandStream, stream);
+ layerWithSidebandStream->setSidebandStream(stream);
mFlinger.mutableCurrentState().layersSortedByZ.add(simpleLayer);
mFlinger.mutableCurrentState().layersSortedByZ.add(layerWithSidebandStream);
@@ -186,6 +194,7 @@
EXPECT_EQ(true, mTunnelModeEnabledListener->mTunnelModeEnabled);
mFlinger.mutableCurrentState().layersSortedByZ.remove(layerWithSidebandStream);
+ layerWithSidebandStream = nullptr;
mTunnelModeEnabledReporter->updateTunnelModeStatus();
EXPECT_EQ(false, mTunnelModeEnabledListener->mTunnelModeEnabled);
}
diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp
index f15a963..a375808 100644
--- a/services/vibratorservice/VibratorHalWrapper.cpp
+++ b/services/vibratorservice/VibratorHalWrapper.cpp
@@ -135,6 +135,18 @@
if (mInfoCache.mSupportedBraking.isFailed()) {
mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
}
+ if (mInfoCache.mPrimitiveDelayMax.isFailed()) {
+ mInfoCache.mPrimitiveDelayMax = getPrimitiveDelayMaxInternal();
+ }
+ if (mInfoCache.mPwlePrimitiveDurationMax.isFailed()) {
+ mInfoCache.mPwlePrimitiveDurationMax = getPrimitiveDurationMaxInternal();
+ }
+ if (mInfoCache.mCompositionSizeMax.isFailed()) {
+ mInfoCache.mCompositionSizeMax = getCompositionSizeMaxInternal();
+ }
+ if (mInfoCache.mPwleSizeMax.isFailed()) {
+ mInfoCache.mPwleSizeMax = getPwleSizeMaxInternal();
+ }
if (mInfoCache.mMinFrequency.isFailed()) {
mInfoCache.mMinFrequency = getMinFrequencyInternal();
}
@@ -209,6 +221,26 @@
return HalResult<std::vector<milliseconds>>::unsupported();
}
+HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
+ ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
+ return HalResult<milliseconds>::unsupported();
+}
+
+HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
+ ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
+ return HalResult<milliseconds>::unsupported();
+}
+
+HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
+ ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
+ return HalResult<int32_t>::unsupported();
+}
+
+HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
+ ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
+ return HalResult<int32_t>::unsupported();
+}
+
HalResult<float> HalWrapper::getMinFrequencyInternal() {
ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
return HalResult<float>::unsupported();
@@ -383,6 +415,30 @@
return HalResult<std::vector<milliseconds>>::ok(durations);
}
+HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
+ int32_t delay = 0;
+ auto result = getHal()->getCompositionDelayMax(&delay);
+ return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
+}
+
+HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
+ int32_t delay = 0;
+ auto result = getHal()->getPwlePrimitiveDurationMax(&delay);
+ return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
+}
+
+HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
+ int32_t size = 0;
+ auto result = getHal()->getCompositionSizeMax(&size);
+ return HalResult<int32_t>::fromStatus(result, size);
+}
+
+HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
+ int32_t size = 0;
+ auto result = getHal()->getPwleCompositionSizeMax(&size);
+ return HalResult<int32_t>::fromStatus(result, size);
+}
+
HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
float minFrequency = 0;
auto result = getHal()->getFrequencyMinimum(&minFrequency);
diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
index 87bc34e..68d6647 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
@@ -182,6 +182,10 @@
const HalResult<std::vector<hardware::vibrator::Braking>> supportedBraking;
const HalResult<std::vector<hardware::vibrator::CompositePrimitive>> supportedPrimitives;
const HalResult<std::vector<std::chrono::milliseconds>> primitiveDurations;
+ const HalResult<std::chrono::milliseconds> primitiveDelayMax;
+ const HalResult<std::chrono::milliseconds> pwlePrimitiveDurationMax;
+ const HalResult<int32_t> compositionSizeMax;
+ const HalResult<int32_t> pwleSizeMax;
const HalResult<float> minFrequency;
const HalResult<float> resonantFrequency;
const HalResult<float> frequencyResolution;
@@ -194,6 +198,10 @@
supportedBraking.checkAndLogFailure("getSupportedBraking") ||
supportedPrimitives.checkAndLogFailure("getSupportedPrimitives") ||
primitiveDurations.checkAndLogFailure("getPrimitiveDuration") ||
+ primitiveDelayMax.checkAndLogFailure("getPrimitiveDelayMax") ||
+ pwlePrimitiveDurationMax.checkAndLogFailure("getPwlePrimitiveDurationMax") ||
+ compositionSizeMax.checkAndLogFailure("getCompositionSizeMax") ||
+ pwleSizeMax.checkAndLogFailure("getPwleSizeMax") ||
minFrequency.checkAndLogFailure("getMinFrequency") ||
resonantFrequency.checkAndLogFailure("getResonantFrequency") ||
frequencyResolution.checkAndLogFailure("getFrequencyResolution") ||
@@ -205,9 +213,19 @@
class InfoCache {
public:
Info get() {
- return {mCapabilities, mSupportedEffects, mSupportedBraking,
- mSupportedPrimitives, mPrimitiveDurations, mMinFrequency,
- mResonantFrequency, mFrequencyResolution, mQFactor,
+ return {mCapabilities,
+ mSupportedEffects,
+ mSupportedBraking,
+ mSupportedPrimitives,
+ mPrimitiveDurations,
+ mPrimitiveDelayMax,
+ mPwlePrimitiveDurationMax,
+ mCompositionSizeMax,
+ mPwleSizeMax,
+ mMinFrequency,
+ mResonantFrequency,
+ mFrequencyResolution,
+ mQFactor,
mMaxAmplitudes};
}
@@ -222,6 +240,12 @@
HalResult<std::vector<hardware::vibrator::CompositePrimitive>>::failed(MSG);
HalResult<std::vector<std::chrono::milliseconds>> mPrimitiveDurations =
HalResult<std::vector<std::chrono::milliseconds>>::failed(MSG);
+ HalResult<std::chrono::milliseconds> mPrimitiveDelayMax =
+ HalResult<std::chrono::milliseconds>::failed(MSG);
+ HalResult<std::chrono::milliseconds> mPwlePrimitiveDurationMax =
+ HalResult<std::chrono::milliseconds>::failed(MSG);
+ HalResult<int32_t> mCompositionSizeMax = HalResult<int>::failed(MSG);
+ HalResult<int32_t> mPwleSizeMax = HalResult<int>::failed(MSG);
HalResult<float> mMinFrequency = HalResult<float>::failed(MSG);
HalResult<float> mResonantFrequency = HalResult<float>::failed(MSG);
HalResult<float> mFrequencyResolution = HalResult<float>::failed(MSG);
@@ -285,6 +309,10 @@
getSupportedPrimitivesInternal();
virtual HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal(
const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives);
+ virtual HalResult<std::chrono::milliseconds> getPrimitiveDelayMaxInternal();
+ virtual HalResult<std::chrono::milliseconds> getPrimitiveDurationMaxInternal();
+ virtual HalResult<int32_t> getCompositionSizeMaxInternal();
+ virtual HalResult<int32_t> getPwleSizeMaxInternal();
virtual HalResult<float> getMinFrequencyInternal();
virtual HalResult<float> getResonantFrequencyInternal();
virtual HalResult<float> getFrequencyResolutionInternal();
@@ -347,6 +375,10 @@
HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal(
const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives)
override final;
+ HalResult<std::chrono::milliseconds> getPrimitiveDelayMaxInternal() override final;
+ HalResult<std::chrono::milliseconds> getPrimitiveDurationMaxInternal() override final;
+ HalResult<int32_t> getCompositionSizeMaxInternal() override final;
+ HalResult<int32_t> getPwleSizeMaxInternal() override final;
HalResult<float> getMinFrequencyInternal() override final;
HalResult<float> getResonantFrequencyInternal() override final;
HalResult<float> getFrequencyResolutionInternal() override final;
diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
index 7813303..03c9e77 100644
--- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
@@ -301,6 +301,10 @@
constexpr float F0 = 123.f;
constexpr float F_RESOLUTION = 0.5f;
constexpr float Q_FACTOR = 123.f;
+ constexpr int32_t COMPOSITION_SIZE_MAX = 10;
+ constexpr int32_t PWLE_SIZE_MAX = 20;
+ constexpr int32_t PRIMITIVE_DELAY_MAX = 100;
+ constexpr int32_t PWLE_DURATION_MAX = 200;
std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK};
std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK};
std::vector<Braking> supportedBraking = {Braking::CLAB};
@@ -331,6 +335,22 @@
EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _))
.Times(Exactly(1))
.WillRepeatedly(DoAll(SetArgPointee<1>(10), Return(Status())));
+ EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
+ .Times(Exactly(2))
+ .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
+ EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
+ .Times(Exactly(2))
+ .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
+ EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
+ .Times(Exactly(2))
+ .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
+ EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
+ .Times(Exactly(2))
+ .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
.Times(Exactly(2))
.WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
@@ -358,6 +378,10 @@
ASSERT_TRUE(failed.supportedBraking.isFailed());
ASSERT_TRUE(failed.supportedPrimitives.isFailed());
ASSERT_TRUE(failed.primitiveDurations.isFailed());
+ ASSERT_TRUE(failed.primitiveDelayMax.isFailed());
+ ASSERT_TRUE(failed.pwlePrimitiveDurationMax.isFailed());
+ ASSERT_TRUE(failed.compositionSizeMax.isFailed());
+ ASSERT_TRUE(failed.pwleSizeMax.isFailed());
ASSERT_TRUE(failed.minFrequency.isFailed());
ASSERT_TRUE(failed.resonantFrequency.isFailed());
ASSERT_TRUE(failed.frequencyResolution.isFailed());
@@ -370,6 +394,11 @@
ASSERT_EQ(supportedBraking, successful.supportedBraking.value());
ASSERT_EQ(supportedPrimitives, successful.supportedPrimitives.value());
ASSERT_EQ(primitiveDurations, successful.primitiveDurations.value());
+ ASSERT_EQ(std::chrono::milliseconds(PRIMITIVE_DELAY_MAX), successful.primitiveDelayMax.value());
+ ASSERT_EQ(std::chrono::milliseconds(PWLE_DURATION_MAX),
+ successful.pwlePrimitiveDurationMax.value());
+ ASSERT_EQ(COMPOSITION_SIZE_MAX, successful.compositionSizeMax.value());
+ ASSERT_EQ(PWLE_SIZE_MAX, successful.pwleSizeMax.value());
ASSERT_EQ(F_MIN, successful.minFrequency.value());
ASSERT_EQ(F0, successful.resonantFrequency.value());
ASSERT_EQ(F_RESOLUTION, successful.frequencyResolution.value());
@@ -380,6 +409,10 @@
TEST_F(VibratorHalWrapperAidlTest, TestGetInfoCachesResult) {
constexpr float F_MIN = 100.f;
constexpr float F0 = 123.f;
+ constexpr int32_t COMPOSITION_SIZE_MAX = 10;
+ constexpr int32_t PWLE_SIZE_MAX = 20;
+ constexpr int32_t PRIMITIVE_DELAY_MAX = 100;
+ constexpr int32_t PWLE_DURATION_MAX = 200;
std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK};
EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
@@ -395,6 +428,18 @@
EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
.Times(Exactly(1))
.WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+ EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
+ EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
+ EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
+ EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
.Times(Exactly(1))
.WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status())));
@@ -426,6 +471,10 @@
ASSERT_TRUE(info.supportedBraking.isUnsupported());
ASSERT_TRUE(info.supportedPrimitives.isUnsupported());
ASSERT_TRUE(info.primitiveDurations.isUnsupported());
+ ASSERT_EQ(std::chrono::milliseconds(PRIMITIVE_DELAY_MAX), info.primitiveDelayMax.value());
+ ASSERT_EQ(std::chrono::milliseconds(PWLE_DURATION_MAX), info.pwlePrimitiveDurationMax.value());
+ ASSERT_EQ(COMPOSITION_SIZE_MAX, info.compositionSizeMax.value());
+ ASSERT_EQ(PWLE_SIZE_MAX, info.pwleSizeMax.value());
ASSERT_EQ(F_MIN, info.minFrequency.value());
ASSERT_EQ(F0, info.resonantFrequency.value());
ASSERT_TRUE(info.frequencyResolution.isUnsupported());
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
index 96b2582..0c27fc7 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
@@ -206,6 +206,10 @@
ASSERT_TRUE(info.supportedBraking.isUnsupported());
ASSERT_TRUE(info.supportedPrimitives.isUnsupported());
ASSERT_TRUE(info.primitiveDurations.isUnsupported());
+ ASSERT_TRUE(info.primitiveDelayMax.isUnsupported());
+ ASSERT_TRUE(info.pwlePrimitiveDurationMax.isUnsupported());
+ ASSERT_TRUE(info.compositionSizeMax.isUnsupported());
+ ASSERT_TRUE(info.pwleSizeMax.isUnsupported());
ASSERT_TRUE(info.minFrequency.isUnsupported());
ASSERT_TRUE(info.resonantFrequency.isUnsupported());
ASSERT_TRUE(info.frequencyResolution.isUnsupported());