summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/FrameMetrics.java25
-rw-r--r--graphics/java/android/graphics/FrameInfo.java3
-rw-r--r--libs/hwui/FrameInfo.cpp5
-rw-r--r--libs/hwui/FrameInfo.h9
-rw-r--r--libs/hwui/JankTracker.cpp2
-rw-r--r--libs/hwui/Properties.cpp8
-rw-r--r--libs/hwui/Properties.h1
-rw-r--r--libs/hwui/aconfig/hwui_flags.aconfig11
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp8
-rw-r--r--libs/hwui/tests/unit/JankTrackerTests.cpp13
10 files changed, 67 insertions, 18 deletions
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
index 58b2a67ec69e..a4fc342756ef 100644
--- a/core/java/android/view/FrameMetrics.java
+++ b/core/java/android/view/FrameMetrics.java
@@ -259,19 +259,20 @@ public final class FrameMetrics {
int FRAME_DEADLINE = 9;
int FRAME_START_TIME = 10;
int FRAME_INTERVAL = 11;
- int SYNC_QUEUED = 12;
- int SYNC_START = 13;
- int ISSUE_DRAW_COMMANDS_START = 14;
- int SWAP_BUFFERS = 15;
- int FRAME_COMPLETED = 16;
- int DEQUEUE_BUFFER_DURATION = 17;
- int QUEUE_BUFFER_DURATION = 18;
- int GPU_COMPLETED = 19;
- int SWAP_BUFFERS_COMPLETED = 20;
- int DISPLAY_PRESENT_TIME = 21;
- int COMMAND_SUBMISSION_COMPLETED = 22;
+ int WORKLOAD_TARGET = 12;
+ int SYNC_QUEUED = 13;
+ int SYNC_START = 14;
+ int ISSUE_DRAW_COMMANDS_START = 15;
+ int SWAP_BUFFERS = 16;
+ int FRAME_COMPLETED = 17;
+ int DEQUEUE_BUFFER_DURATION = 18;
+ int QUEUE_BUFFER_DURATION = 19;
+ int GPU_COMPLETED = 20;
+ int SWAP_BUFFERS_COMPLETED = 21;
+ int DISPLAY_PRESENT_TIME = 22;
+ int COMMAND_SUBMISSION_COMPLETED = 23;
- int FRAME_STATS_COUNT = 23; // must always be last and in sync with
+ int FRAME_STATS_COUNT = 24; // must always be last and in sync with
// FrameInfoIndex::NumIndexes in libs/hwui/FrameInfo.h
}
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index 8f1282897780..7d236d203201 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -95,7 +95,8 @@ public final class FrameInfo {
// Must be the last one
// This value must be in sync with `UI_THREAD_FRAME_INFO_SIZE` in FrameInfo.h
- private static final int FRAME_INFO_SIZE = FRAME_INTERVAL + 1;
+ // In calculating size, + 1 for Flags, and + 1 for WorkloadTarget from FrameInfo.h
+ private static final int FRAME_INFO_SIZE = FRAME_INTERVAL + 2;
/** checkstyle */
public void setVsync(long intendedVsync, long usedVsync, long frameTimelineVsyncId,
diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp
index a958a091a830..36feabde07eb 100644
--- a/libs/hwui/FrameInfo.cpp
+++ b/libs/hwui/FrameInfo.cpp
@@ -32,8 +32,9 @@ const std::array FrameInfoNames{"Flags",
"PerformTraversalsStart",
"DrawStart",
"FrameDeadline",
- "FrameInterval",
"FrameStartTime",
+ "FrameInterval",
+ "WorkloadTarget",
"SyncQueued",
"SyncStart",
"IssueDrawCommandsStart",
@@ -48,7 +49,7 @@ const std::array FrameInfoNames{"Flags",
};
-static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 23,
+static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 24,
"Must update value in FrameMetrics.java#FRAME_STATS_COUNT (and here)");
void FrameInfo::importUiThreadInfo(int64_t* info) {
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index f7ad13978a30..61c30b803b00 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -30,7 +30,8 @@
namespace android {
namespace uirenderer {
-static constexpr size_t UI_THREAD_FRAME_INFO_SIZE = 12;
+// This value must be in sync with `FRAME_INFO_SIZE` in FrameInfo.Java
+static constexpr size_t UI_THREAD_FRAME_INFO_SIZE = 13;
enum class FrameInfoIndex {
Flags = 0,
@@ -47,6 +48,11 @@ enum class FrameInfoIndex {
FrameInterval,
// End of UI frame info
+ // The target workload duration based on the original frame deadline and
+ // and intended vsync. Counted in UI_THREAD_FRAME_INFO_SIZE so its value
+ // can be set in setVsync().
+ WorkloadTarget,
+
SyncQueued,
SyncStart,
@@ -109,6 +115,7 @@ public:
set(FrameInfoIndex::FrameStartTime) = vsyncTime;
set(FrameInfoIndex::FrameDeadline) = frameDeadline;
set(FrameInfoIndex::FrameInterval) = frameInterval;
+ set(FrameInfoIndex::WorkloadTarget) = frameDeadline - intendedVsync;
return *this;
}
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index 638a060bdb1c..80eb6bc986d6 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -201,7 +201,7 @@ void JankTracker::finishFrame(FrameInfo& frame, std::unique_ptr<FrameMetricsRepo
// If we are in triple buffering, we have enough buffers in queue to sustain a single frame
// drop without jank, so adjust the frame interval to the deadline.
if (isTripleBuffered) {
- int64_t originalDeadlineDuration = deadline - frame[FrameInfoIndex::IntendedVsync];
+ int64_t originalDeadlineDuration = frame[FrameInfoIndex::WorkloadTarget];
deadline = mNextFrameStartUnstuffed + originalDeadlineDuration;
frame.set(FrameInfoIndex::FrameDeadline) = deadline;
}
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 7d01dfbb446f..21430f7e6777 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -57,6 +57,9 @@ constexpr bool query_global_priority() {
constexpr bool early_preload_gl_context() {
return false;
}
+constexpr bool calc_workload_orig_deadline() {
+ return false;
+}
} // namespace hwui_flags
#endif
@@ -299,5 +302,10 @@ bool Properties::earlyPreloadGlContext() {
hwui_flags::early_preload_gl_context());
}
+bool Properties::calcWorkloadOrigDeadline() {
+ static bool sCalcWorkloadOrigDeadline = base::GetBoolProperty(
+ "debug.hwui.calc_workload_orig_deadline", hwui_flags::calc_workload_orig_deadline());
+ return sCalcWorkloadOrigDeadline;
+}
} // namespace uirenderer
} // namespace android
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 280a75a28e65..a7a564428636 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -384,6 +384,7 @@ public:
static bool initializeGlAlways();
static bool resampleGainmapRegions();
static bool earlyPreloadGlContext();
+ static bool calcWorkloadOrigDeadline();
private:
static StretchEffectBehavior stretchEffectBehavior;
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index 2851dd8b1003..62fd7d358123 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -176,4 +176,15 @@ flag {
namespace: "core_graphics"
description: "Initialize GL context and GraphicBufferAllocater init on renderThread preload. This improves app startup time for apps using GL."
bug: "383612849"
+}
+
+flag {
+ name: "calc_workload_orig_deadline"
+ namespace: "window_surfaces"
+ description: "Use original frame deadline to calculate the workload target deadline for jank tracking"
+ bug: "389939827"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b36b8be10779..e3e393c4fdfb 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -789,7 +789,13 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) {
int64_t frameDeadline = mCurrentFrameInfo->get(FrameInfoIndex::FrameDeadline);
int64_t dequeueBufferDuration = mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration);
- mHintSessionWrapper->updateTargetWorkDuration(frameDeadline - intendedVsync);
+ if (Properties::calcWorkloadOrigDeadline()) {
+ // Uses the unmodified frame deadline in calculating workload target duration
+ mHintSessionWrapper->updateTargetWorkDuration(
+ mCurrentFrameInfo->get(FrameInfoIndex::WorkloadTarget));
+ } else {
+ mHintSessionWrapper->updateTargetWorkDuration(frameDeadline - intendedVsync);
+ }
if (didDraw) {
int64_t frameStartTime = mCurrentFrameInfo->get(FrameInfoIndex::FrameStartTime);
diff --git a/libs/hwui/tests/unit/JankTrackerTests.cpp b/libs/hwui/tests/unit/JankTrackerTests.cpp
index b67e419e7d4a..c289d67fbef6 100644
--- a/libs/hwui/tests/unit/JankTrackerTests.cpp
+++ b/libs/hwui/tests/unit/JankTrackerTests.cpp
@@ -45,6 +45,7 @@ TEST(JankTracker, noJank) {
info->set(FrameInfoIndex::FrameCompleted) = 115_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
info = jankTracker.startFrame();
@@ -55,6 +56,7 @@ TEST(JankTracker, noJank) {
info->set(FrameInfoIndex::FrameCompleted) = 131_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(2, container.get()->totalFrameCount());
@@ -79,6 +81,7 @@ TEST(JankTracker, jank) {
info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(1, container.get()->totalFrameCount());
@@ -102,6 +105,7 @@ TEST(JankTracker, legacyJankButNoRealJank) {
info->set(FrameInfoIndex::FrameCompleted) = 118_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(1, container.get()->totalFrameCount());
@@ -127,6 +131,7 @@ TEST(JankTracker, doubleStuffed) {
info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(1, container.get()->jankFrameCount());
@@ -140,6 +145,7 @@ TEST(JankTracker, doubleStuffed) {
info->set(FrameInfoIndex::FrameCompleted) = 137_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(2, container.get()->totalFrameCount());
@@ -164,6 +170,7 @@ TEST(JankTracker, doubleStuffedThenPauseThenJank) {
info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(1, container.get()->jankFrameCount());
@@ -177,6 +184,7 @@ TEST(JankTracker, doubleStuffedThenPauseThenJank) {
info->set(FrameInfoIndex::FrameCompleted) = 137_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(1, container.get()->jankFrameCount());
@@ -190,6 +198,7 @@ TEST(JankTracker, doubleStuffedThenPauseThenJank) {
info->set(FrameInfoIndex::FrameCompleted) = 169_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 168_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(3, container.get()->totalFrameCount());
@@ -214,6 +223,7 @@ TEST(JankTracker, doubleStuffedTwoIntervalBehind) {
info->set(FrameInfoIndex::FrameCompleted) = 117_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 116_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(1, container.get()->jankFrameCount());
@@ -228,6 +238,7 @@ TEST(JankTracker, doubleStuffedTwoIntervalBehind) {
info->set(FrameInfoIndex::FrameCompleted) = 133_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 132_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(1, container.get()->jankFrameCount());
@@ -242,6 +253,7 @@ TEST(JankTracker, doubleStuffedTwoIntervalBehind) {
info->set(FrameInfoIndex::FrameCompleted) = 165_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 148_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(2, container.get()->jankFrameCount());
@@ -256,6 +268,7 @@ TEST(JankTracker, doubleStuffedTwoIntervalBehind) {
info->set(FrameInfoIndex::FrameCompleted) = 181_ms;
info->set(FrameInfoIndex::FrameInterval) = 16_ms;
info->set(FrameInfoIndex::FrameDeadline) = 164_ms;
+ info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
ASSERT_EQ(2, container.get()->jankFrameCount());