summaryrefslogtreecommitdiff
path: root/libs/hwui/renderthread/CanvasContext.cpp
diff options
context:
space:
mode:
authorScott Lobdell <slobdell@google.com>2021-04-25 19:53:32 +0000
committerDaniel Norman <danielnorman@google.com>2021-04-29 09:44:07 -0700
commit2051462f672b5986ef321bf1de3657e7653864e8 (patch)
tree1dee6334f2b0a68d3cc2e532e6f89bb16149aa7d /libs/hwui/renderthread/CanvasContext.cpp
parentb22baa1593b2ee33200d009f7f56d1c44a75ac6d (diff)
parentab6136865a519a27d731b4caa3e782bdf02cfd91 (diff)
Merge SP1A.210425.001
Change-Id: I8d45e47c131320cac5e794fd629fdef84dd3bcfc
Diffstat (limited to 'libs/hwui/renderthread/CanvasContext.cpp')
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp62
1 files changed, 43 insertions, 19 deletions
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index aedb5c28dc3e..bba22071ecef 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -56,6 +56,22 @@ namespace android {
namespace uirenderer {
namespace renderthread {
+namespace {
+class ScopedActiveContext {
+public:
+ ScopedActiveContext(CanvasContext* context) { sActiveContext = context; }
+
+ ~ScopedActiveContext() { sActiveContext = nullptr; }
+
+ static CanvasContext* getActiveContext() { return sActiveContext; }
+
+private:
+ static CanvasContext* sActiveContext;
+};
+
+CanvasContext* ScopedActiveContext::sActiveContext = nullptr;
+} /* namespace */
+
CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory) {
auto renderType = Properties::getRenderPipelineType();
@@ -473,6 +489,10 @@ void CanvasContext::draw() {
return;
}
+ ScopedActiveContext activeContext(this);
+ mCurrentFrameInfo->set(FrameInfoIndex::FrameInterval) =
+ mRenderThread.timeLord().frameIntervalNanos();
+
mCurrentFrameInfo->markIssueDrawCommandsStart();
Frame frame = mRenderPipeline->getFrame();
@@ -591,25 +611,13 @@ void CanvasContext::draw() {
mCurrentFrameInfo->markFrameCompleted();
mCurrentFrameInfo->set(FrameInfoIndex::GpuCompleted)
= mCurrentFrameInfo->get(FrameInfoIndex::FrameCompleted);
- finishFrame(mCurrentFrameInfo);
+ mJankTracker.finishFrame(*mCurrentFrameInfo, mFrameMetricsReporter);
}
}
mRenderThread.cacheManager().onFrameCompleted();
}
-void CanvasContext::finishFrame(FrameInfo* frameInfo) {
- // TODO (b/169858044): Consolidate this into a single call.
- mJankTracker.finishFrame(*frameInfo);
- mJankTracker.finishGpuDraw(*frameInfo);
-
- // TODO (b/169858044): Move this into JankTracker to adjust deadline when queue is
- // double-stuffed.
- if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) {
- mFrameMetricsReporter->reportFrameMetrics(frameInfo->data(), false /*hasPresentTime*/);
- }
-}
-
void CanvasContext::reportMetricsWithPresentTime() {
if (mFrameMetricsReporter == nullptr) {
return;
@@ -667,15 +675,19 @@ void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* cont
if (gpuCompleteTime == -1) {
gpuCompleteTime = frameInfo->get(FrameInfoIndex::SwapBuffersCompleted);
}
- if (gpuCompleteTime < frameInfo->get(FrameInfoIndex::SwapBuffers)) {
- // TODO (b/180488606): Investigate why this can happen for first frames.
- ALOGW("Impossible GPU complete time swapBuffers=%" PRIi64 " gpuComplete=%" PRIi64,
- frameInfo->get(FrameInfoIndex::SwapBuffers), gpuCompleteTime);
+ if (gpuCompleteTime < frameInfo->get(FrameInfoIndex::IssueDrawCommandsStart)) {
+ // On Vulkan the GPU commands are flushed to the GPU during IssueDrawCommands rather
+ // than after SwapBuffers. So if the GPU signals before issue draw commands, then
+ // something probably went wrong. Anything after that could just be expected
+ // pipeline differences
+ ALOGW("Impossible GPU complete time issueCommandsStart=%" PRIi64
+ " gpuComplete=%" PRIi64,
+ frameInfo->get(FrameInfoIndex::IssueDrawCommandsStart), gpuCompleteTime);
gpuCompleteTime = frameInfo->get(FrameInfoIndex::SwapBuffersCompleted);
}
frameInfo->set(FrameInfoIndex::FrameCompleted) = gpuCompleteTime;
frameInfo->set(FrameInfoIndex::GpuCompleted) = gpuCompleteTime;
- instance->finishFrame(frameInfo);
+ instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter);
}
}
@@ -704,10 +716,11 @@ void CanvasContext::prepareAndDraw(RenderNode* node) {
nsecs_t vsync = mRenderThread.timeLord().computeFrameTimeNanos();
int64_t vsyncId = mRenderThread.timeLord().lastVsyncId();
int64_t frameDeadline = mRenderThread.timeLord().lastFrameDeadline();
+ int64_t frameInterval = mRenderThread.timeLord().frameIntervalNanos();
int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE];
UiFrameInfoBuilder(frameInfo)
.addFlag(FrameInfoFlags::RTAnimation)
- .setVsync(vsync, vsync, vsyncId, frameDeadline);
+ .setVsync(vsync, vsync, vsyncId, frameDeadline, frameInterval);
TreeInfo info(TreeInfo::MODE_RT_ONLY, *this);
prepareTree(info, frameInfo, systemTime(SYSTEM_TIME_MONOTONIC), node);
@@ -884,6 +897,17 @@ SkRect CanvasContext::computeDirtyRect(const Frame& frame, SkRect* dirty) {
return windowDirty;
}
+CanvasContext* CanvasContext::getActiveContext() {
+ return ScopedActiveContext::getActiveContext();
+}
+
+bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control) {
+ if (!mASurfaceTransactionCallback) return false;
+ std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
+ reinterpret_cast<int64_t>(control), getFrameNumber());
+ return true;
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */