diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp index 46e806081c0c9..ded2b06fb3cf7 100644 --- a/libs/hwui/renderthread/CacheManager.cpp +++ b/libs/hwui/renderthread/CacheManager.cpp @@ -210,6 +210,14 @@ void CacheManager::onFrameCompleted() { } } +void CacheManager::performDeferredCleanup(nsecs_t cleanupOlderThanMillis) { + if (mGrContext) { + mGrContext->performDeferredCleanup( + std::chrono::milliseconds(cleanupOlderThanMillis), + /* scratchResourcesOnly */true); + } +} + } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h index 713ea990ff238..af82672c6f23b 100644 --- a/libs/hwui/renderthread/CacheManager.h +++ b/libs/hwui/renderthread/CacheManager.h @@ -23,6 +23,7 @@ #include #include #include +#include "utils/TimeUtils.h" namespace android { @@ -53,6 +54,8 @@ public: size_t getBackgroundCacheSize() const { return mBackgroundResourceBytes; } void onFrameCompleted(); + void performDeferredCleanup(nsecs_t cleanupOlderThanMillis); + private: friend class RenderThread; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index a0d93e928876c..8bfc2c14ad7c6 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -461,6 +461,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy } void CanvasContext::stopDrawing() { + cleanupResources(); mRenderThread.removeFrameCallback(this); mAnimationContext->pauseAnimators(); mGenerationID++; @@ -619,10 +620,25 @@ nsecs_t CanvasContext::draw() { } } + cleanupResources(); mRenderThread.cacheManager().onFrameCompleted(); return mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration); } +void CanvasContext::cleanupResources() { + auto& tracker = mJankTracker.frames(); + auto size = tracker.size(); + auto capacity = tracker.capacity(); + if (size == capacity) { + nsecs_t nowNanos = systemTime(SYSTEM_TIME_MONOTONIC); + nsecs_t frameCompleteNanos = + tracker[0].get(FrameInfoIndex::FrameCompleted); + nsecs_t frameDiffNanos = nowNanos - frameCompleteNanos; + nsecs_t cleanupMillis = ns2ms(std::max(frameDiffNanos, 10_s)); + mRenderThread.cacheManager().performDeferredCleanup(cleanupMillis); + } +} + void CanvasContext::reportMetricsWithPresentTime() { if (mFrameMetricsReporter == nullptr) { return; diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 6f90e81e51b03..4bdc2514db8c7 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -312,6 +312,7 @@ private: bool mExpectSurfaceStats = false; std::function mASurfaceTransactionCallback; + void cleanupResources(); }; } /* namespace renderthread */