Loading libs/hwui/renderthread/CanvasContext.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -472,11 +472,11 @@ void CanvasContext::notifyFramePending() { mRenderThread.pushBackFrameCallback(this); } nsecs_t CanvasContext::draw() { std::optional<nsecs_t> CanvasContext::draw() { if (auto grContext = getGrContext()) { if (grContext->abandoned()) { LOG_ALWAYS_FATAL("GrContext is abandoned/device lost at start of CanvasContext::draw"); return 0; return std::nullopt; } } SkRect dirty; Loading @@ -498,7 +498,7 @@ nsecs_t CanvasContext::draw() { std::invoke(func, false /* didProduceBuffer */); } mFrameCommitCallbacks.clear(); return 0; return std::nullopt; } ScopedActiveContext activeContext(this); Loading Loading @@ -543,6 +543,8 @@ nsecs_t CanvasContext::draw() { } bool requireSwap = false; bool didDraw = false; int error = OK; bool didSwap = mRenderPipeline->swapBuffers(frame, drawResult.success, windowDirty, mCurrentFrameInfo, &requireSwap); Loading @@ -553,7 +555,7 @@ nsecs_t CanvasContext::draw() { mIsDirty = false; if (requireSwap) { bool didDraw = true; didDraw = true; // Handle any swapchain errors error = mNativeSurface->getAndClearError(); if (error == TIMED_OUT) { Loading Loading @@ -649,7 +651,9 @@ nsecs_t CanvasContext::draw() { } mRenderThread.cacheManager().onFrameCompleted(); return mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration); return didDraw ? std::make_optional( mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration)) : std::nullopt; } void CanvasContext::reportMetricsWithPresentTime() { Loading libs/hwui/renderthread/CanvasContext.h +1 −1 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ public: bool makeCurrent(); void prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t syncQueued, RenderNode* target); // Returns the DequeueBufferDuration. nsecs_t draw(); std::optional<nsecs_t> draw(); void destroy(); // IFrameCallback, Choreographer-driven frame callback entry point Loading libs/hwui/renderthread/DrawFrameTask.cpp +18 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <dlfcn.h> #include <gui/TraceUtils.h> #include <utils/Log.h> #include <algorithm> #include "../DeferredLayerUpdater.h" Loading @@ -28,6 +29,7 @@ #include "CanvasContext.h" #include "RenderThread.h" #include "thread/CommonPool.h" #include "utils/TimeUtils.h" namespace android { namespace uirenderer { Loading Loading @@ -146,6 +148,7 @@ void DrawFrameTask::run() { bool canUnblockUiThread; bool canDrawThisFrame; bool didDraw = false; { TreeInfo info(TreeInfo::MODE_FULL, *mContext); info.forceDrawFrame = mForceDrawFrame; Loading Loading @@ -188,7 +191,9 @@ void DrawFrameTask::run() { nsecs_t dequeueBufferDuration = 0; if (CC_LIKELY(canDrawThisFrame)) { dequeueBufferDuration = context->draw(); std::optional<nsecs_t> drawResult = context->draw(); didDraw = drawResult.has_value(); dequeueBufferDuration = drawResult.value_or(0); } else { // Do a flush in case syncFrameState performed any texture uploads. Since we skipped // the draw() call, those uploads (or deletes) will end up sitting in the queue. Loading @@ -209,8 +214,9 @@ void DrawFrameTask::run() { } if (!mHintSessionWrapper) mHintSessionWrapper.emplace(mUiThreadId, mRenderThreadId); constexpr int64_t kSanityCheckLowerBound = 100000; // 0.1ms constexpr int64_t kSanityCheckUpperBound = 10000000000; // 10s constexpr int64_t kSanityCheckLowerBound = 100_us; constexpr int64_t kSanityCheckUpperBound = 10_s; int64_t targetWorkDuration = frameDeadline - intendedVsync; targetWorkDuration = targetWorkDuration * Properties::targetCpuTimePercentage / 100; if (targetWorkDuration > kSanityCheckLowerBound && Loading @@ -219,6 +225,8 @@ void DrawFrameTask::run() { mLastTargetWorkDuration = targetWorkDuration; mHintSessionWrapper->updateTargetWorkDuration(targetWorkDuration); } if (didDraw) { int64_t frameDuration = systemTime(SYSTEM_TIME_MONOTONIC) - frameStartTime; int64_t actualDuration = frameDuration - (std::min(syncDelayDuration, mLastDequeueBufferDuration)) - Loading @@ -226,6 +234,7 @@ void DrawFrameTask::run() { if (actualDuration > kSanityCheckLowerBound && actualDuration < kSanityCheckUpperBound) { mHintSessionWrapper->reportActualWorkDuration(actualDuration); } } mLastDequeueBufferDuration = dequeueBufferDuration; } Loading Loading
libs/hwui/renderthread/CanvasContext.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -472,11 +472,11 @@ void CanvasContext::notifyFramePending() { mRenderThread.pushBackFrameCallback(this); } nsecs_t CanvasContext::draw() { std::optional<nsecs_t> CanvasContext::draw() { if (auto grContext = getGrContext()) { if (grContext->abandoned()) { LOG_ALWAYS_FATAL("GrContext is abandoned/device lost at start of CanvasContext::draw"); return 0; return std::nullopt; } } SkRect dirty; Loading @@ -498,7 +498,7 @@ nsecs_t CanvasContext::draw() { std::invoke(func, false /* didProduceBuffer */); } mFrameCommitCallbacks.clear(); return 0; return std::nullopt; } ScopedActiveContext activeContext(this); Loading Loading @@ -543,6 +543,8 @@ nsecs_t CanvasContext::draw() { } bool requireSwap = false; bool didDraw = false; int error = OK; bool didSwap = mRenderPipeline->swapBuffers(frame, drawResult.success, windowDirty, mCurrentFrameInfo, &requireSwap); Loading @@ -553,7 +555,7 @@ nsecs_t CanvasContext::draw() { mIsDirty = false; if (requireSwap) { bool didDraw = true; didDraw = true; // Handle any swapchain errors error = mNativeSurface->getAndClearError(); if (error == TIMED_OUT) { Loading Loading @@ -649,7 +651,9 @@ nsecs_t CanvasContext::draw() { } mRenderThread.cacheManager().onFrameCompleted(); return mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration); return didDraw ? std::make_optional( mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration)) : std::nullopt; } void CanvasContext::reportMetricsWithPresentTime() { Loading
libs/hwui/renderthread/CanvasContext.h +1 −1 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ public: bool makeCurrent(); void prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t syncQueued, RenderNode* target); // Returns the DequeueBufferDuration. nsecs_t draw(); std::optional<nsecs_t> draw(); void destroy(); // IFrameCallback, Choreographer-driven frame callback entry point Loading
libs/hwui/renderthread/DrawFrameTask.cpp +18 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <dlfcn.h> #include <gui/TraceUtils.h> #include <utils/Log.h> #include <algorithm> #include "../DeferredLayerUpdater.h" Loading @@ -28,6 +29,7 @@ #include "CanvasContext.h" #include "RenderThread.h" #include "thread/CommonPool.h" #include "utils/TimeUtils.h" namespace android { namespace uirenderer { Loading Loading @@ -146,6 +148,7 @@ void DrawFrameTask::run() { bool canUnblockUiThread; bool canDrawThisFrame; bool didDraw = false; { TreeInfo info(TreeInfo::MODE_FULL, *mContext); info.forceDrawFrame = mForceDrawFrame; Loading Loading @@ -188,7 +191,9 @@ void DrawFrameTask::run() { nsecs_t dequeueBufferDuration = 0; if (CC_LIKELY(canDrawThisFrame)) { dequeueBufferDuration = context->draw(); std::optional<nsecs_t> drawResult = context->draw(); didDraw = drawResult.has_value(); dequeueBufferDuration = drawResult.value_or(0); } else { // Do a flush in case syncFrameState performed any texture uploads. Since we skipped // the draw() call, those uploads (or deletes) will end up sitting in the queue. Loading @@ -209,8 +214,9 @@ void DrawFrameTask::run() { } if (!mHintSessionWrapper) mHintSessionWrapper.emplace(mUiThreadId, mRenderThreadId); constexpr int64_t kSanityCheckLowerBound = 100000; // 0.1ms constexpr int64_t kSanityCheckUpperBound = 10000000000; // 10s constexpr int64_t kSanityCheckLowerBound = 100_us; constexpr int64_t kSanityCheckUpperBound = 10_s; int64_t targetWorkDuration = frameDeadline - intendedVsync; targetWorkDuration = targetWorkDuration * Properties::targetCpuTimePercentage / 100; if (targetWorkDuration > kSanityCheckLowerBound && Loading @@ -219,6 +225,8 @@ void DrawFrameTask::run() { mLastTargetWorkDuration = targetWorkDuration; mHintSessionWrapper->updateTargetWorkDuration(targetWorkDuration); } if (didDraw) { int64_t frameDuration = systemTime(SYSTEM_TIME_MONOTONIC) - frameStartTime; int64_t actualDuration = frameDuration - (std::min(syncDelayDuration, mLastDequeueBufferDuration)) - Loading @@ -226,6 +234,7 @@ void DrawFrameTask::run() { if (actualDuration > kSanityCheckLowerBound && actualDuration < kSanityCheckUpperBound) { mHintSessionWrapper->reportActualWorkDuration(actualDuration); } } mLastDequeueBufferDuration = dequeueBufferDuration; } Loading