diff options
| -rw-r--r-- | core/java/android/view/FrameMetrics.java | 25 | ||||
| -rw-r--r-- | graphics/java/android/graphics/FrameInfo.java | 3 | ||||
| -rw-r--r-- | libs/hwui/FrameInfo.cpp | 5 | ||||
| -rw-r--r-- | libs/hwui/FrameInfo.h | 9 | ||||
| -rw-r--r-- | libs/hwui/JankTracker.cpp | 2 | ||||
| -rw-r--r-- | libs/hwui/Properties.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/Properties.h | 1 | ||||
| -rw-r--r-- | libs/hwui/aconfig/hwui_flags.aconfig | 11 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/tests/unit/JankTrackerTests.cpp | 13 |
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()); |