Merge "Properly protect mFrameMetricsReporter" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-07-11 08:30:13 +00:00
committed by Android (Google) Code Review
7 changed files with 40 additions and 24 deletions

View File

@@ -47,6 +47,7 @@ cc_defaults {
"-DATRACE_TAG=ATRACE_TAG_VIEW", "-DATRACE_TAG=ATRACE_TAG_VIEW",
"-DLOG_TAG=\"OpenGLRenderer\"", "-DLOG_TAG=\"OpenGLRenderer\"",
"-Wall", "-Wall",
"-Wthread-safety",
"-Wno-unused-parameter", "-Wno-unused-parameter",
"-Wunreachable-code", "-Wunreachable-code",
"-Werror", "-Werror",

View File

@@ -99,7 +99,7 @@ JankTracker::JankTracker(ProfileDataContainer* globalData)
mFrameIntervalLegacy = frameIntervalNanos; mFrameIntervalLegacy = frameIntervalNanos;
} }
void JankTracker::calculateLegacyJank(FrameInfo& frame) { void JankTracker::calculateLegacyJank(FrameInfo& frame) REQUIRES(mDataMutex) {
// Fast-path for jank-free frames // Fast-path for jank-free frames
int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::SwapBuffersCompleted); int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::SwapBuffersCompleted);
if (mDequeueTimeForgivenessLegacy && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) { if (mDequeueTimeForgivenessLegacy && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) {
@@ -257,7 +257,7 @@ void JankTracker::finishFrame(FrameInfo& frame, std::unique_ptr<FrameMetricsRepo
} }
} }
void JankTracker::recomputeThresholds(int64_t frameBudget) { void JankTracker::recomputeThresholds(int64_t frameBudget) REQUIRES(mDataMutex) {
if (mThresholdsFrameBudget == frameBudget) { if (mThresholdsFrameBudget == frameBudget) {
return; return;
} }
@@ -308,7 +308,7 @@ void JankTracker::dumpFrames(int fd) {
dprintf(fd, "\n---PROFILEDATA---\n\n"); dprintf(fd, "\n---PROFILEDATA---\n\n");
} }
void JankTracker::reset() { void JankTracker::reset() REQUIRES(mDataMutex) {
mFrames.clear(); mFrames.clear();
mData->reset(); mData->reset();
(*mGlobalData)->reset(); (*mGlobalData)->reset();

View File

@@ -62,7 +62,7 @@ public:
// Calculates the 'legacy' jank information, i.e. with outdated refresh rate information and // Calculates the 'legacy' jank information, i.e. with outdated refresh rate information and
// without GPU completion or deadlined information. // without GPU completion or deadlined information.
void calculateLegacyJank(FrameInfo& frame); void calculateLegacyJank(FrameInfo& frame);
void dumpStats(int fd) { dumpData(fd, &mDescription, mData.get()); } void dumpStats(int fd) NO_THREAD_SAFETY_ANALYSIS { dumpData(fd, &mDescription, mData.get()); }
void dumpFrames(int fd); void dumpFrames(int fd);
void reset(); void reset();

View File

@@ -27,7 +27,7 @@
namespace android { namespace android {
namespace uirenderer { namespace uirenderer {
void ProfileDataContainer::freeData() { void ProfileDataContainer::freeData() REQUIRES(mJankDataMutex) {
if (mIsMapped) { if (mIsMapped) {
munmap(mData, sizeof(ProfileData)); munmap(mData, sizeof(ProfileData));
} else { } else {

View File

@@ -37,8 +37,9 @@ public:
void rotateStorage(); void rotateStorage();
void switchStorageToAshmem(int ashmemfd); void switchStorageToAshmem(int ashmemfd);
ProfileData* get() { return mData; } ProfileData* get() NO_THREAD_SAFETY_ANALYSIS { return mData; }
ProfileData* operator->() { return mData; }
ProfileData* operator->() NO_THREAD_SAFETY_ANALYSIS { return mData; }
std::mutex& getDataMutex() { return mJankDataMutex; } std::mutex& getDataMutex() { return mJankDataMutex; }

View File

@@ -614,6 +614,7 @@ nsecs_t CanvasContext::draw() {
mCurrentFrameInfo->markFrameCompleted(); mCurrentFrameInfo->markFrameCompleted();
mCurrentFrameInfo->set(FrameInfoIndex::GpuCompleted) mCurrentFrameInfo->set(FrameInfoIndex::GpuCompleted)
= mCurrentFrameInfo->get(FrameInfoIndex::FrameCompleted); = mCurrentFrameInfo->get(FrameInfoIndex::FrameCompleted);
std::scoped_lock lock(mFrameMetricsReporterMutex);
mJankTracker.finishFrame(*mCurrentFrameInfo, mFrameMetricsReporter); mJankTracker.finishFrame(*mCurrentFrameInfo, mFrameMetricsReporter);
} }
} }
@@ -638,9 +639,12 @@ void CanvasContext::cleanupResources() {
} }
void CanvasContext::reportMetricsWithPresentTime() { void CanvasContext::reportMetricsWithPresentTime() {
if (mFrameMetricsReporter == nullptr) { { // acquire lock
return; std::scoped_lock lock(mFrameMetricsReporterMutex);
} if (mFrameMetricsReporter == nullptr) {
return;
}
} // release lock
if (mNativeSurface == nullptr) { if (mNativeSurface == nullptr) {
return; return;
} }
@@ -666,7 +670,22 @@ void CanvasContext::reportMetricsWithPresentTime() {
nullptr /*outReleaseTime*/); nullptr /*outReleaseTime*/);
forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime; forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime;
mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/); { // acquire lock
std::scoped_lock lock(mFrameMetricsReporterMutex);
if (mFrameMetricsReporter != nullptr) {
mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/);
}
} // release lock
}
FrameInfo* CanvasContext::getFrameInfoFromLast4(uint64_t frameNumber) {
std::scoped_lock lock(mLast4FrameInfosMutex);
for (size_t i = 0; i < mLast4FrameInfos.size(); i++) {
if (mLast4FrameInfos[i].second == frameNumber) {
return mLast4FrameInfos[i].first;
}
}
return nullptr;
} }
void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* control, void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
@@ -680,22 +699,13 @@ void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* cont
nsecs_t gpuCompleteTime = functions.getAcquireTimeFunc(stats); nsecs_t gpuCompleteTime = functions.getAcquireTimeFunc(stats);
uint64_t frameNumber = functions.getFrameNumberFunc(stats); uint64_t frameNumber = functions.getFrameNumberFunc(stats);
FrameInfo* frameInfo = nullptr; FrameInfo* frameInfo = instance->getFrameInfoFromLast4(frameNumber);
{
std::lock_guard(instance->mLast4FrameInfosMutex);
for (size_t i = 0; i < instance->mLast4FrameInfos.size(); i++) {
if (instance->mLast4FrameInfos[i].second == frameNumber) {
frameInfo = instance->mLast4FrameInfos[i].first;
break;
}
}
}
if (frameInfo != nullptr) { if (frameInfo != nullptr) {
frameInfo->set(FrameInfoIndex::FrameCompleted) = std::max(gpuCompleteTime, frameInfo->set(FrameInfoIndex::FrameCompleted) = std::max(gpuCompleteTime,
frameInfo->get(FrameInfoIndex::SwapBuffersCompleted)); frameInfo->get(FrameInfoIndex::SwapBuffersCompleted));
frameInfo->set(FrameInfoIndex::GpuCompleted) = gpuCompleteTime; frameInfo->set(FrameInfoIndex::GpuCompleted) = gpuCompleteTime;
std::lock_guard(instance->mFrameMetricsReporterMutex); std::scoped_lock lock(instance->mFrameMetricsReporterMutex);
instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter); instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter);
} }
} }

View File

@@ -160,6 +160,7 @@ public:
void setContentDrawBounds(const Rect& bounds) { mContentDrawBounds = bounds; } void setContentDrawBounds(const Rect& bounds) { mContentDrawBounds = bounds; }
void addFrameMetricsObserver(FrameMetricsObserver* observer) { void addFrameMetricsObserver(FrameMetricsObserver* observer) {
std::scoped_lock lock(mFrameMetricsReporterMutex);
if (mFrameMetricsReporter.get() == nullptr) { if (mFrameMetricsReporter.get() == nullptr) {
mFrameMetricsReporter.reset(new FrameMetricsReporter()); mFrameMetricsReporter.reset(new FrameMetricsReporter());
} }
@@ -168,10 +169,10 @@ public:
} }
void removeFrameMetricsObserver(FrameMetricsObserver* observer) { void removeFrameMetricsObserver(FrameMetricsObserver* observer) {
std::scoped_lock lock(mFrameMetricsReporterMutex);
if (mFrameMetricsReporter.get() != nullptr) { if (mFrameMetricsReporter.get() != nullptr) {
mFrameMetricsReporter->removeObserver(observer); mFrameMetricsReporter->removeObserver(observer);
if (!mFrameMetricsReporter->hasObservers()) { if (!mFrameMetricsReporter->hasObservers()) {
std::lock_guard lock(mFrameMetricsReporterMutex);
mFrameMetricsReporter.reset(nullptr); mFrameMetricsReporter.reset(nullptr);
} }
} }
@@ -245,6 +246,8 @@ private:
*/ */
void reportMetricsWithPresentTime(); void reportMetricsWithPresentTime();
FrameInfo* getFrameInfoFromLast4(uint64_t frameNumber);
// The same type as Frame.mWidth and Frame.mHeight // The same type as Frame.mWidth and Frame.mHeight
int32_t mLastFrameWidth = 0; int32_t mLastFrameWidth = 0;
int32_t mLastFrameHeight = 0; int32_t mLastFrameHeight = 0;
@@ -305,7 +308,8 @@ private:
std::string mName; std::string mName;
JankTracker mJankTracker; JankTracker mJankTracker;
FrameInfoVisualizer mProfiler; FrameInfoVisualizer mProfiler;
std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter; std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter
GUARDED_BY(mFrameMetricsReporterMutex);
std::mutex mFrameMetricsReporterMutex; std::mutex mFrameMetricsReporterMutex;
std::set<RenderNode*> mPrefetchedLayers; std::set<RenderNode*> mPrefetchedLayers;