SF TimeStats: optimize mTimeStatsTracker to use layerID as hash key
The current mTimeStatsTracker map is using layer name as the hash key,
which is not as fast and reliable as the unique layer sequence id.
Test: dumpsys SurfaceFlinger --timestats <see go/sf-timestats for args>
Bug: b/79872109
Change-Id: I409414909e7dd7ee11b37a35a441c070cfce3fa6
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index a0a07ec..397540a 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -71,7 +71,7 @@
destroyAllHwcLayers();
}
- mTimeStats.onDestroy(getName().c_str());
+ mTimeStats.onDestroy(getSequence());
}
void BufferLayer::useSurfaceDamage() {
@@ -293,8 +293,8 @@
nsecs_t desiredPresentTime = getDesiredPresentTime();
mFrameTracker.setDesiredPresentTime(desiredPresentTime);
- const std::string layerName(getName().c_str());
- mTimeStats.setDesiredTime(layerName, mCurrentFrameNumber, desiredPresentTime);
+ const int32_t layerID = getSequence();
+ mTimeStats.setDesiredTime(layerID, mCurrentFrameNumber, desiredPresentTime);
std::shared_ptr<FenceTime> frameReadyFence = getCurrentFenceTime();
if (frameReadyFence->isValid()) {
@@ -306,14 +306,14 @@
}
if (presentFence->isValid()) {
- mTimeStats.setPresentFence(layerName, mCurrentFrameNumber, presentFence);
+ mTimeStats.setPresentFence(layerID, mCurrentFrameNumber, presentFence);
mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
} else if (mFlinger->getHwComposer().isConnected(HWC_DISPLAY_PRIMARY)) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
const nsecs_t actualPresentTime =
mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
- mTimeStats.setPresentTime(layerName, mCurrentFrameNumber, actualPresentTime);
+ mTimeStats.setPresentTime(layerID, mCurrentFrameNumber, actualPresentTime);
mFrameTracker.setActualPresentTime(actualPresentTime);
}
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index e75fbdf..ca3859e 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -227,6 +227,7 @@
// BufferItem's that weren't actually queued. This can happen in shared
// buffer mode.
bool queuedBuffer = false;
+ const int32_t layerID = getSequence();
LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
getTransformToDisplayInverse(), mFreezeGeometryUpdates);
@@ -247,7 +248,7 @@
// and return early
if (queuedBuffer) {
Mutex::Autolock lock(mQueueItemLock);
- mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
+ mTimeStats.removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
mQueueItems.removeAt(0);
mQueuedFrames--;
}
@@ -261,7 +262,7 @@
Mutex::Autolock lock(mQueueItemLock);
mQueueItems.clear();
mQueuedFrames = 0;
- mTimeStats.clearLayerRecord(getName().c_str());
+ mTimeStats.clearLayerRecord(layerID);
}
// Once we have hit this state, the shadow queue may no longer
@@ -282,14 +283,13 @@
// Remove any stale buffers that have been dropped during
// updateTexImage
while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
- mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
+ mTimeStats.removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
mQueueItems.removeAt(0);
mQueuedFrames--;
}
- const std::string layerName(getName().c_str());
- mTimeStats.setAcquireFence(layerName, currentFrameNumber, mQueueItems[0].mFenceTime);
- mTimeStats.setLatchTime(layerName, currentFrameNumber, latchTime);
+ mTimeStats.setAcquireFence(layerID, currentFrameNumber, mQueueItems[0].mFenceTime);
+ mTimeStats.setLatchTime(layerID, currentFrameNumber, latchTime);
mQueueItems.removeAt(0);
}
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index e52b35a..5df8ade 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -377,6 +377,8 @@
return NO_ERROR;
}
+ const int32_t layerID = getSequence();
+
// Reject if the layer is invalid
uint32_t bufferWidth = s.buffer->width;
uint32_t bufferHeight = s.buffer->height;
@@ -397,7 +399,7 @@
ALOGE("[%s] rejecting buffer: "
"bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h);
- mTimeStats.removeTimeRecord(getName().c_str(), getFrameNumber());
+ mTimeStats.removeTimeRecord(layerID, getFrameNumber());
return BAD_VALUE;
}
@@ -405,7 +407,7 @@
if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
// TODO(alecmouri): Fail somewhere upstream if the fence is invalid.
if (!releaseFence->isValid()) {
- mTimeStats.clearLayerRecord(getName().c_str());
+ mTimeStats.clearLayerRecord(layerID);
return UNKNOWN_ERROR;
}
@@ -415,7 +417,7 @@
auto currentStatus = s.acquireFence->getStatus();
if (currentStatus == Fence::Status::Invalid) {
ALOGE("Existing fence has invalid state");
- mTimeStats.clearLayerRecord(getName().c_str());
+ mTimeStats.clearLayerRecord(layerID);
return BAD_VALUE;
}
@@ -423,7 +425,7 @@
if (incomingStatus == Fence::Status::Invalid) {
ALOGE("New fence has invalid state");
mDrawingState.acquireFence = releaseFence;
- mTimeStats.clearLayerRecord(getName().c_str());
+ mTimeStats.clearLayerRecord(layerID);
return BAD_VALUE;
}
@@ -439,7 +441,7 @@
// synchronization is broken, the best we can do is hope fences
// signal in order so the new fence will act like a union
mDrawingState.acquireFence = releaseFence;
- mTimeStats.clearLayerRecord(getName().c_str());
+ mTimeStats.clearLayerRecord(layerID);
return BAD_VALUE;
}
mDrawingState.acquireFence = mergedFence;
@@ -462,16 +464,16 @@
// a GL-composited layer) not at all.
status_t err = bindTextureImage();
if (err != NO_ERROR) {
- mTimeStats.clearLayerRecord(getName().c_str());
+ mTimeStats.clearLayerRecord(layerID);
return BAD_VALUE;
}
}
// TODO(marissaw): properly support mTimeStats
- const std::string layerName(getName().c_str());
- mTimeStats.setPostTime(getName().c_str(), getFrameNumber(), latchTime);
- mTimeStats.setAcquireFence(layerName, getFrameNumber(), getCurrentFenceTime());
- mTimeStats.setLatchTime(layerName, getFrameNumber(), latchTime);
+ mTimeStats.setLayerName(layerID, getName().c_str());
+ mTimeStats.setPostTime(layerID, getFrameNumber(), latchTime);
+ mTimeStats.setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
+ mTimeStats.setLatchTime(layerID, getFrameNumber(), latchTime);
return NO_ERROR;
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8afd3b3..7b9cd01 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1428,14 +1428,15 @@
void Layer::onDisconnect() {
Mutex::Autolock lock(mFrameEventHistoryMutex);
mFrameEventHistory.onDisconnect();
- mTimeStats.onDisconnect(getName().c_str());
+ mTimeStats.onDisconnect(getSequence());
}
void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
FrameEventHistoryDelta* outDelta) {
if (newTimestamps) {
- mTimeStats.setPostTime(getName().c_str(), newTimestamps->frameNumber,
- newTimestamps->postedTime);
+ const int32_t layerID = getSequence();
+ mTimeStats.setLayerName(layerID, getName().c_str());
+ mTimeStats.setPostTime(layerID, newTimestamps->frameNumber, newTimestamps->postedTime);
}
Mutex::Autolock lock(mFrameEventHistoryMutex);
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index f754d47..43fa262 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -104,9 +104,9 @@
mTimeStats.clientCompositionFrames++;
}
-bool TimeStats::recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord) {
+bool TimeStats::recordReadyLocked(int32_t layerID, TimeRecord* timeRecord) {
if (!timeRecord->ready) {
- ALOGV("[%s]-[%" PRIu64 "]-presentFence is still not received", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-presentFence is still not received", layerID,
timeRecord->frameTime.frameNumber);
return false;
}
@@ -119,7 +119,7 @@
timeRecord->frameTime.acquireTime = timeRecord->acquireFence->getSignalTime();
timeRecord->acquireFence = nullptr;
} else {
- ALOGV("[%s]-[%" PRIu64 "]-acquireFence signal time is invalid", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-acquireFence signal time is invalid", layerID,
timeRecord->frameTime.frameNumber);
}
}
@@ -132,7 +132,7 @@
timeRecord->frameTime.presentTime = timeRecord->presentFence->getSignalTime();
timeRecord->presentFence = nullptr;
} else {
- ALOGV("[%s]-[%" PRIu64 "]-presentFence signal time invalid", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-presentFence signal time invalid", layerID,
timeRecord->frameTime.frameNumber);
}
}
@@ -162,18 +162,19 @@
return "";
}
-void TimeStats::flushAvailableRecordsToStatsLocked(const std::string& layerName) {
+void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerID) {
ATRACE_CALL();
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
TimeRecord& prevTimeRecord = layerRecord.prevTimeRecord;
std::deque<TimeRecord>& timeRecords = layerRecord.timeRecords;
while (!timeRecords.empty()) {
- if (!recordReadyLocked(layerName, &timeRecords[0])) break;
- ALOGV("[%s]-[%" PRIu64 "]-presentFenceTime[%" PRId64 "]", layerName.c_str(),
+ if (!recordReadyLocked(layerID, &timeRecords[0])) break;
+ ALOGV("[%d]-[%" PRIu64 "]-presentFenceTime[%" PRId64 "]", layerID,
timeRecords[0].frameTime.frameNumber, timeRecords[0].frameTime.presentTime);
if (prevTimeRecord.ready) {
+ const std::string& layerName = layerRecord.layerName;
if (!mTimeStats.stats.count(layerName)) {
mTimeStats.stats[layerName].layerName = layerName;
mTimeStats.stats[layerName].packageName = getPackageName(layerName);
@@ -185,37 +186,37 @@
const int32_t postToAcquireMs = msBetween(timeRecords[0].frameTime.postTime,
timeRecords[0].frameTime.acquireTime);
- ALOGV("[%s]-[%" PRIu64 "]-post2acquire[%d]", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-post2acquire[%d]", layerID,
timeRecords[0].frameTime.frameNumber, postToAcquireMs);
timeStatsLayer.deltas["post2acquire"].insert(postToAcquireMs);
const int32_t postToPresentMs = msBetween(timeRecords[0].frameTime.postTime,
timeRecords[0].frameTime.presentTime);
- ALOGV("[%s]-[%" PRIu64 "]-post2present[%d]", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-post2present[%d]", layerID,
timeRecords[0].frameTime.frameNumber, postToPresentMs);
timeStatsLayer.deltas["post2present"].insert(postToPresentMs);
const int32_t acquireToPresentMs = msBetween(timeRecords[0].frameTime.acquireTime,
timeRecords[0].frameTime.presentTime);
- ALOGV("[%s]-[%" PRIu64 "]-acquire2present[%d]", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-acquire2present[%d]", layerID,
timeRecords[0].frameTime.frameNumber, acquireToPresentMs);
timeStatsLayer.deltas["acquire2present"].insert(acquireToPresentMs);
const int32_t latchToPresentMs = msBetween(timeRecords[0].frameTime.latchTime,
timeRecords[0].frameTime.presentTime);
- ALOGV("[%s]-[%" PRIu64 "]-latch2present[%d]", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-latch2present[%d]", layerID,
timeRecords[0].frameTime.frameNumber, latchToPresentMs);
timeStatsLayer.deltas["latch2present"].insert(latchToPresentMs);
const int32_t desiredToPresentMs = msBetween(timeRecords[0].frameTime.desiredTime,
timeRecords[0].frameTime.presentTime);
- ALOGV("[%s]-[%" PRIu64 "]-desired2present[%d]", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-desired2present[%d]", layerID,
timeRecords[0].frameTime.frameNumber, desiredToPresentMs);
timeStatsLayer.deltas["desired2present"].insert(desiredToPresentMs);
const int32_t presentToPresentMs = msBetween(prevTimeRecord.frameTime.presentTime,
timeRecords[0].frameTime.presentTime);
- ALOGV("[%s]-[%" PRIu64 "]-present2present[%d]", layerName.c_str(),
+ ALOGV("[%d]-[%" PRIu64 "]-present2present[%d]", layerID,
timeRecords[0].frameTime.frameNumber, presentToPresentMs);
timeStatsLayer.deltas["present2present"].insert(presentToPresentMs);
}
@@ -240,23 +241,33 @@
return std::regex_match(layerName.begin(), layerName.end(), layerNameRegex);
}
-void TimeStats::setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime) {
+void TimeStats::setLayerName(int32_t layerID, const std::string& layerName) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-PostTime[%" PRId64 "]", layerName.c_str(), frameNumber, postTime);
+ ALOGV("[%d]-[%s]", layerID, layerName.c_str());
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName) && !layerNameIsValid(layerName)) {
- return;
+ if (!mTimeStatsTracker.count(layerID) && layerNameIsValid(layerName)) {
+ mTimeStatsTracker[layerID].layerName = layerName;
}
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+}
+
+void TimeStats::setPostTime(int32_t layerID, uint64_t frameNumber, nsecs_t postTime) {
+ if (!mEnabled.load()) return;
+
+ ATRACE_CALL();
+ ALOGV("[%d]-[%" PRIu64 "]-PostTime[%" PRId64 "]", layerID, frameNumber, postTime);
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
if (layerRecord.timeRecords.size() == MAX_NUM_TIME_RECORDS) {
- ALOGV("[%s]-timeRecords is already at its maximum size[%zu]", layerName.c_str(),
- MAX_NUM_TIME_RECORDS);
- // TODO(zzyiwei): if this happens, there must be a present fence missing
- // or waitData is not in the correct position. Need to think out a
- // reasonable way to recover from this state.
+ ALOGE("[%d]-[%s]-timeRecords is already at its maximum size[%zu]. Please file a bug.",
+ layerID, layerRecord.layerName.c_str(), MAX_NUM_TIME_RECORDS);
+ layerRecord.timeRecords.clear();
+ layerRecord.prevTimeRecord.ready = false;
+ layerRecord.waitData = -1;
return;
}
// For most media content, the acquireFence is invalid because the buffer is
@@ -276,84 +287,77 @@
layerRecord.waitData = layerRecord.timeRecords.size() - 1;
}
-void TimeStats::setLatchTime(const std::string& layerName, uint64_t frameNumber,
- nsecs_t latchTime) {
+void TimeStats::setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-LatchTime[%" PRId64 "]", layerName.c_str(), frameNumber, latchTime);
+ ALOGV("[%d]-[%" PRIu64 "]-LatchTime[%" PRId64 "]", layerID, frameNumber, latchTime);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.latchTime = latchTime;
}
}
-void TimeStats::setDesiredTime(const std::string& layerName, uint64_t frameNumber,
- nsecs_t desiredTime) {
+void TimeStats::setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-DesiredTime[%" PRId64 "]", layerName.c_str(), frameNumber,
- desiredTime);
+ ALOGV("[%d]-[%" PRIu64 "]-DesiredTime[%" PRId64 "]", layerID, frameNumber, desiredTime);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.desiredTime = desiredTime;
}
}
-void TimeStats::setAcquireTime(const std::string& layerName, uint64_t frameNumber,
- nsecs_t acquireTime) {
+void TimeStats::setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-AcquireTime[%" PRId64 "]", layerName.c_str(), frameNumber,
- acquireTime);
+ ALOGV("[%d]-[%" PRIu64 "]-AcquireTime[%" PRId64 "]", layerID, frameNumber, acquireTime);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.acquireTime = acquireTime;
}
}
-void TimeStats::setAcquireFence(const std::string& layerName, uint64_t frameNumber,
+void TimeStats::setAcquireFence(int32_t layerID, uint64_t frameNumber,
const std::shared_ptr<FenceTime>& acquireFence) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-AcquireFenceTime[%" PRId64 "]", layerName.c_str(), frameNumber,
+ ALOGV("[%d]-[%" PRIu64 "]-AcquireFenceTime[%" PRId64 "]", layerID, frameNumber,
acquireFence->getSignalTime());
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.acquireFence = acquireFence;
}
}
-void TimeStats::setPresentTime(const std::string& layerName, uint64_t frameNumber,
- nsecs_t presentTime) {
+void TimeStats::setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-PresentTime[%" PRId64 "]", layerName.c_str(), frameNumber,
- presentTime);
+ ALOGV("[%d]-[%" PRIu64 "]-PresentTime[%" PRId64 "]", layerID, frameNumber, presentTime);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.presentTime = presentTime;
@@ -361,20 +365,20 @@
layerRecord.waitData++;
}
- flushAvailableRecordsToStatsLocked(layerName);
+ flushAvailableRecordsToStatsLocked(layerID);
}
-void TimeStats::setPresentFence(const std::string& layerName, uint64_t frameNumber,
+void TimeStats::setPresentFence(int32_t layerID, uint64_t frameNumber,
const std::shared_ptr<FenceTime>& presentFence) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-PresentFenceTime[%" PRId64 "]", layerName.c_str(), frameNumber,
+ ALOGV("[%d]-[%" PRIu64 "]-PresentFenceTime[%" PRId64 "]", layerID, frameNumber,
presentFence->getSignalTime());
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.presentFence = presentFence;
@@ -382,57 +386,57 @@
layerRecord.waitData++;
}
- flushAvailableRecordsToStatsLocked(layerName);
+ flushAvailableRecordsToStatsLocked(layerID);
}
-void TimeStats::onDisconnect(const std::string& layerName) {
+void TimeStats::onDisconnect(int32_t layerID) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-onDisconnect", layerName.c_str());
+ ALOGV("[%d]-onDisconnect", layerID);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- flushAvailableRecordsToStatsLocked(layerName);
- mTimeStatsTracker.erase(layerName);
+ if (!mTimeStatsTracker.count(layerID)) return;
+ flushAvailableRecordsToStatsLocked(layerID);
+ mTimeStatsTracker.erase(layerID);
}
-void TimeStats::onDestroy(const std::string& layerName) {
+void TimeStats::onDestroy(int32_t layerID) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-onDestroy", layerName.c_str());
+ ALOGV("[%d]-onDestroy", layerID);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- flushAvailableRecordsToStatsLocked(layerName);
- mTimeStatsTracker.erase(layerName);
+ if (!mTimeStatsTracker.count(layerID)) return;
+ flushAvailableRecordsToStatsLocked(layerID);
+ mTimeStatsTracker.erase(layerID);
}
-void TimeStats::clearLayerRecord(const std::string& layerName) {
+void TimeStats::clearLayerRecord(int32_t layerID) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-clearLayerRecord", layerName.c_str());
+ ALOGV("[%d]-clearLayerRecord", layerID);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
layerRecord.timeRecords.clear();
layerRecord.prevTimeRecord.ready = false;
layerRecord.waitData = -1;
layerRecord.droppedFrames = 0;
}
-void TimeStats::removeTimeRecord(const std::string& layerName, uint64_t frameNumber) {
+void TimeStats::removeTimeRecord(int32_t layerID, uint64_t frameNumber) {
if (!mEnabled.load()) return;
ATRACE_CALL();
- ALOGV("[%s]-[%" PRIu64 "]-removeTimeRecord", layerName.c_str(), frameNumber);
+ ALOGV("[%d]-[%" PRIu64 "]-removeTimeRecord", layerID, frameNumber);
std::lock_guard<std::mutex> lock(mMutex);
- if (!mTimeStatsTracker.count(layerName)) return;
- LayerRecord& layerRecord = mTimeStatsTracker[layerName];
+ if (!mTimeStatsTracker.count(layerID)) return;
+ LayerRecord& layerRecord = mTimeStatsTracker[layerID];
size_t removeAt = 0;
for (const TimeRecord& record : layerRecord.timeRecords) {
if (record.frameTime.frameNumber == frameNumber) break;
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index c78d84e..d1e554c 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -59,6 +59,7 @@
};
struct LayerRecord {
+ std::string layerName;
// This is the index in timeRecords, at which the timestamps for that
// specific frame are still not fully received. This is not waiting for
// fences to signal, but rather waiting to receive those fences/timestamps.
@@ -85,23 +86,24 @@
void incrementMissedFrames();
void incrementClientCompositionFrames();
- void setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime);
- void setLatchTime(const std::string& layerName, uint64_t frameNumber, nsecs_t latchTime);
- void setDesiredTime(const std::string& layerName, uint64_t frameNumber, nsecs_t desiredTime);
- void setAcquireTime(const std::string& layerName, uint64_t frameNumber, nsecs_t acquireTime);
- void setAcquireFence(const std::string& layerName, uint64_t frameNumber,
+ void setLayerName(int32_t layerID, const std::string& layerName);
+ void setPostTime(int32_t layerID, uint64_t frameNumber, nsecs_t postTime);
+ void setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime);
+ void setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime);
+ void setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime);
+ void setAcquireFence(int32_t layerID, uint64_t frameNumber,
const std::shared_ptr<FenceTime>& acquireFence);
- void setPresentTime(const std::string& layerName, uint64_t frameNumber, nsecs_t presentTime);
- void setPresentFence(const std::string& layerName, uint64_t frameNumber,
+ void setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime);
+ void setPresentFence(int32_t layerID, uint64_t frameNumber,
const std::shared_ptr<FenceTime>& presentFence);
// On producer disconnect with BufferQueue.
- void onDisconnect(const std::string& layerName);
+ void onDisconnect(int32_t layerID);
// On layer tear down.
- void onDestroy(const std::string& layerName);
+ void onDestroy(int32_t layerID);
// When SF is cleaning up the queue, clear the LayerRecord as well.
- void clearLayerRecord(const std::string& layerName);
+ void clearLayerRecord(int32_t layerID);
// If SF skips or rejects a buffer, remove the corresponding TimeRecord.
- void removeTimeRecord(const std::string& layerName, uint64_t frameNumber);
+ void removeTimeRecord(int32_t layerID, uint64_t frameNumber);
void setPowerMode(int32_t powerMode);
void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence);
@@ -109,8 +111,8 @@
private:
TimeStats() = default;
- bool recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord);
- void flushAvailableRecordsToStatsLocked(const std::string& layerName);
+ bool recordReadyLocked(int32_t layerID, TimeRecord* timeRecord);
+ void flushAvailableRecordsToStatsLocked(int32_t layerID);
void flushPowerTimeLocked();
void flushAvailableGlobalRecordsToStatsLocked();
@@ -123,7 +125,8 @@
std::atomic<bool> mEnabled = false;
std::mutex mMutex;
TimeStatsHelper::TimeStatsGlobal mTimeStats;
- std::unordered_map<std::string, LayerRecord> mTimeStatsTracker;
+ // Hashmap for LayerRecord with layerID as the hash key
+ std::unordered_map<int32_t, LayerRecord> mTimeStatsTracker;
PowerTime mPowerTime;
GlobalRecord mGlobalRecord;
};