Merge "Skip sending HWUI hints when frame does not draw"
This commit is contained in:
@@ -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;
|
||||
@@ -498,7 +498,7 @@ nsecs_t CanvasContext::draw() {
|
||||
std::invoke(func, false /* didProduceBuffer */);
|
||||
}
|
||||
mFrameCommitCallbacks.clear();
|
||||
return 0;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
ScopedActiveContext activeContext(this);
|
||||
@@ -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);
|
||||
@@ -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) {
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <gui/TraceUtils.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "../DeferredLayerUpdater.h"
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "CanvasContext.h"
|
||||
#include "RenderThread.h"
|
||||
#include "thread/CommonPool.h"
|
||||
#include "utils/TimeUtils.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
@@ -146,6 +148,7 @@ void DrawFrameTask::run() {
|
||||
|
||||
bool canUnblockUiThread;
|
||||
bool canDrawThisFrame;
|
||||
bool didDraw = false;
|
||||
{
|
||||
TreeInfo info(TreeInfo::MODE_FULL, *mContext);
|
||||
info.forceDrawFrame = mForceDrawFrame;
|
||||
@@ -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.
|
||||
@@ -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 &&
|
||||
@@ -219,12 +225,15 @@ void DrawFrameTask::run() {
|
||||
mLastTargetWorkDuration = targetWorkDuration;
|
||||
mHintSessionWrapper->updateTargetWorkDuration(targetWorkDuration);
|
||||
}
|
||||
int64_t frameDuration = systemTime(SYSTEM_TIME_MONOTONIC) - frameStartTime;
|
||||
int64_t actualDuration = frameDuration -
|
||||
(std::min(syncDelayDuration, mLastDequeueBufferDuration)) -
|
||||
dequeueBufferDuration;
|
||||
if (actualDuration > kSanityCheckLowerBound && actualDuration < kSanityCheckUpperBound) {
|
||||
mHintSessionWrapper->reportActualWorkDuration(actualDuration);
|
||||
|
||||
if (didDraw) {
|
||||
int64_t frameDuration = systemTime(SYSTEM_TIME_MONOTONIC) - frameStartTime;
|
||||
int64_t actualDuration = frameDuration -
|
||||
(std::min(syncDelayDuration, mLastDequeueBufferDuration)) -
|
||||
dequeueBufferDuration;
|
||||
if (actualDuration > kSanityCheckLowerBound && actualDuration < kSanityCheckUpperBound) {
|
||||
mHintSessionWrapper->reportActualWorkDuration(actualDuration);
|
||||
}
|
||||
}
|
||||
|
||||
mLastDequeueBufferDuration = dequeueBufferDuration;
|
||||
|
||||
Reference in New Issue
Block a user