Skip to content

fix(stats): improve presentation pacing observability - #66

Merged
qiin2333 merged 3 commits into
masterfrom
codex/observe-presentation-pacing
Jul 21, 2026
Merged

fix(stats): improve presentation pacing observability#66
qiin2333 merged 3 commits into
masterfrom
codex/observe-presentation-pacing

Conversation

@qiin2333

@qiin2333 qiin2333 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

改了啥呀

  • 把 Rx/Rd 从 1 秒翻滚计数改成最近 3 秒的滚动速率,解码器成组回调不再把正常帧挤到相邻窗口里呀。
  • 每 250ms 最多请求一次只读 NativeVSync 样本,记录真实周期和样本年龄。
  • 给 host-paced 日志补上同槽碰撞、槽位倒退、目标时间倒退、最大倒退和最大未来队列槽数。
  • 新增纯 C++ 观测组件与测试;现有 PTS 调度、CATCH_UP 和丢帧策略完全没动。

为啥要改

之前那个杂鱼 1 秒窗口会把 120 FPS 的批量回调显示成偶发 115–117,害我们拿统计抖动去调未来余量。现在先把统计口径和 VSync 证据补齐,下一轮才能区分是真掉帧、同槽覆盖,还是目标时间倒退啦。

验证

  • c++ -std=c++17 -Wall -Wextra -Werror nativelib/src/main/cpp/rolling_frame_rate.cpp nativelib/src/main/cpp/presentation_diagnostics.cpp nativelib/src/test/cpp/presentation_observability_test.cpp -I nativelib/src/main/cpp -o /tmp/moonlight_presentation_observability_test && /tmp/moonlight_presentation_observability_test
  • c++ -std=c++17 -Wall -Wextra -Werror nativelib/src/main/cpp/presentation_scheduler.cpp nativelib/src/test/cpp/presentation_scheduler_test.cpp -I nativelib/src/main/cpp -o /tmp/moonlight_presentation_scheduler_test && /tmp/moonlight_presentation_scheduler_test
  • npm run check
  • env JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home OHOS_SDK_HOME=/Users/mac/ohos-sdk-cache/6.1-Release-mac/sdk-ci-shape HOS_SDK_HOME=/Users/mac/ohos-sdk-cache/6.1-Release-mac/sdk-ci-shape OHOS_BASE_SDK_HOME=/Users/mac/ohos-sdk-cache/6.1-Release-mac/sdk-ci-shape DEVECO_SDK_HOME=/Users/mac/ohos-sdk-cache/6.1-Release-mac/sdk-ci-shape node hvigorw.js assembleApp --mode project -p product=default -p buildMode=debug --no-daemon

Summary by CodeRabbit

  • 改进
    • 优化视频接收与渲染帧率统计:引入滚动窗口机制,提升实时性与稳定性。
    • 增强呈现时序与垂直同步监测:在渲染侧采样并记录 VSync 观测与失败情况,输出更细粒度统计。
    • 改进统计刷新与重置策略,确保在时间变化、采样不足或回退场景下结果更可靠。
  • 新增
    • 增加呈现诊断统计能力,用于衡量目标时间回归与队列深度等表现。
  • 测试
    • 新增呈现可观测性相关测试用例,覆盖滚动帧率与时序诊断结果校验。

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@qiin2333, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f77d422-9de7-45eb-a8d7-b9e491e4c746

📥 Commits

Reviewing files that changed from the base of the PR and between 378e592 and ddb3938.

📒 Files selected for processing (5)
  • nativelib/src/main/cpp/native_render.cpp
  • nativelib/src/main/cpp/native_render.h
  • nativelib/src/main/cpp/presentation_scheduler.cpp
  • nativelib/src/main/cpp/presentation_scheduler.h
  • nativelib/src/test/cpp/presentation_scheduler_test.cpp
📝 Walkthrough

Walkthrough

本次变更新增呈现时序诊断与滚动帧率跟踪,接入 NativeRender 的 Host-paced VSync 采样路径及 VideoDecoder 的接收、呈现帧率统计流程,并增加构建配置和行为测试。

Changes

呈现可观测性与帧率统计

Layer / File(s) Summary
呈现时序诊断
nativelib/src/main/cpp/presentation_diagnostics.*, nativelib/src/test/cpp/presentation_observability_test.cpp
新增 VSync 锚点、槽位、目标回归、同槽位和队列深度统计,并覆盖相关测试。
NativeVSync 采样与 Host-paced 接入
nativelib/src/main/cpp/native_render.*
新增带代次校验和间隔节流的 VSync 采样请求,在 Host-paced 调度中记录诊断数据并扩展统计日志。
滚动帧率跟踪与解码器统计
nativelib/src/main/cpp/rolling_frame_rate.*, nativelib/src/main/cpp/video_decoder.*, nativelib/src/test/cpp/presentation_observability_test.cpp, nativelib/src/main/cpp/CMakeLists.txt
新增环形样本滚动帧率计算,将接收和呈现帧率接入 VideoDecoder,并纳入构建与测试。

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了本次对呈现节奏可观测性与统计逻辑的增强。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/observe-presentation-pacing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
nativelib/src/main/cpp/native_render.cpp (1)

34-53: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

注意全局变量在多实例场景下的副作用

这里使用全局原子变量和代次(generation)计数器来管理 VSync 回调状态,这是一种非常聪明且实用的做法,能够有效避免 OH_NativeVSync_Destroy 后残留回调导致的悬挂 this 指针(dangling pointer)问题。

但是,请留意如果应用在生命周期中会同时存在多个 NativeRender 实例:

  1. 只有最新创建的实例能成功接收到 VSync 回调(因为它的代次匹配最新的全局 g_vsyncSampleGeneration)。
  2. 当销毁任意一个实例时,ReleaseNativeVSync 会自增全局代次,从而导致所有其他仍在活跃的实例的 VSync 采样也会被永久阻断。

如果该组件在业务中严格作为单例使用(或者同一时间只有一个实例存在),这种实现是完全安全且高效的。如果未来需要支持多实例同时渲染,建议考虑使用基于堆分配的控制块(结合 std::shared_ptr 管理),或使用实例 ID 注册表来安全地分发回调上下文。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nativelib/src/main/cpp/native_render.cpp` around lines 34 - 53, 调整
NativeRender 的 VSync 回调状态管理,避免全局 g_vsyncSampleGeneration
及相关全局采样变量让多个实例相互阻断:为每个实例使用独立且生命周期安全的回调上下文(例如堆分配控制块配合 shared_ptr),并确保
ReleaseNativeVSync 仅使对应实例失效,不影响其他活跃实例的采样。
nativelib/src/main/cpp/video_decoder.cpp (1)

1611-1614: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

将计数器递增移入锁内以保证时序与数据一致性

decodedFrames_ 的递增操作目前在获取 renderedRateMutex_ 锁之前执行。如果在极端并发情况下有多个解码输出回调交错,可能会导致写入 renderedFrameRate_ 时的 cumulativeFrames 出现倒挂,从而触发 RollingFrameRateTracker 内部的防抖逻辑(清空历史记录 Reset())。

建议将 fetch_add 移入锁保护范围内,以确保帧数递增和写入记录操作的严格一致性。

♻️ 建议的重构方案
-        const uint64_t decodedFrames =
-            decodedFrames_.fetch_add(1, std::memory_order_relaxed) + 1;
         std::lock_guard<std::mutex> lock(renderedRateMutex_);
+        const uint64_t decodedFrames =
+            decodedFrames_.fetch_add(1, std::memory_order_relaxed) + 1;
         renderedFrameRate_.Record(currentTimeMs, decodedFrames);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nativelib/src/main/cpp/video_decoder.cpp` around lines 1611 - 1614, Move the
decodedFrames_ fetch_add operation inside the renderedRateMutex_ lock in the
decode-output callback, keeping the increment immediately before
renderedFrameRate_.Record. Ensure both the counter update and rate-record write
are serialized together so cumulativeFrames remains monotonic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nativelib/src/main/cpp/rolling_frame_rate.cpp`:
- Around line 75-84: Update the frame-rate calculation around
baseline.timestampMs, cutoffMs, and elapsedMs so the effective interval starts
at the later of baseline.timestampMs and cutoffMs. Preserve the existing
invalid-interval and counter-regression checks, and calculate elapsedMs and
frame rate using this window-bounded start time.

---

Nitpick comments:
In `@nativelib/src/main/cpp/native_render.cpp`:
- Around line 34-53: 调整 NativeRender 的 VSync 回调状态管理,避免全局 g_vsyncSampleGeneration
及相关全局采样变量让多个实例相互阻断:为每个实例使用独立且生命周期安全的回调上下文(例如堆分配控制块配合 shared_ptr),并确保
ReleaseNativeVSync 仅使对应实例失效,不影响其他活跃实例的采样。

In `@nativelib/src/main/cpp/video_decoder.cpp`:
- Around line 1611-1614: Move the decodedFrames_ fetch_add operation inside the
renderedRateMutex_ lock in the decode-output callback, keeping the increment
immediately before renderedFrameRate_.Record. Ensure both the counter update and
rate-record write are serialized together so cumulativeFrames remains monotonic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 702ae83d-d013-44e3-8b43-0cf592c5d044

📥 Commits

Reviewing files that changed from the base of the PR and between d52d920 and 197aa0d.

📒 Files selected for processing (10)
  • nativelib/src/main/cpp/CMakeLists.txt
  • nativelib/src/main/cpp/native_render.cpp
  • nativelib/src/main/cpp/native_render.h
  • nativelib/src/main/cpp/presentation_diagnostics.cpp
  • nativelib/src/main/cpp/presentation_diagnostics.h
  • nativelib/src/main/cpp/rolling_frame_rate.cpp
  • nativelib/src/main/cpp/rolling_frame_rate.h
  • nativelib/src/main/cpp/video_decoder.cpp
  • nativelib/src/main/cpp/video_decoder.h
  • nativelib/src/test/cpp/presentation_observability_test.cpp

Comment thread nativelib/src/main/cpp/rolling_frame_rate.cpp
* fix(render): schedule frames on unique vsync slots

* fix(render): preserve late-frame rebuffer threshold
@qiin2333
qiin2333 merged commit 918b0a5 into master Jul 21, 2026
1 of 2 checks passed
@qiin2333
qiin2333 deleted the codex/observe-presentation-pacing branch July 21, 2026 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant