fix(plotview): 边沿计数表格归位、统计面板悬停时持续更新、加载不再被统计阻塞、统计提速
1) 表格改造归位(上一轮误做在中心轴上) - 「边沿计数」改为表格:表头(信号名/上升沿计数/下降沿计数)、每信号一行、 行底色取信号配色、三列对齐、内容可滚动(Lane::edgeCountScroll)。 - 「中心轴边沿计数」恢复为可滚动分组列表(条目栏 + 复选框 + 展开后统计行 + 两行滑块), Lane::EnsureEdgeCenterItem 恢复默认展开。 - EdgePanelWidth / EdgePanelLayoutFor / PaintEdgeCursor 统一 listStyle / countTable 判定; EdgeCenterTableHeader 更名为 EdgeCountTableHeader。 2) 鼠标持续移动时统计面板不更新 - 根因:交互态(拖拽或 140ms 内移动)把统计数字整段从面板缓存键中跳过, 只要鼠标不停移动就永远命中旧缓存。 - 修法:扫描推进/完成时自增 m_edgeScanRevision,Paint 开头转为 m_panelStatsVersion (非交互帧立即同步,交互帧按 kEdgeScanStatsRefreshFrames=4 节流), PanelSlotKey 对 COUNT/CENTER 仅混入该版本号(O(1),不再逐信号查询)。 3) 统计进行中无法加载文件 - 新增 PlotView::SetLoadingBusy:加载期间统计时间预算归零、跳过浮动面板绘制、 不再自请求扫描帧;Application::LoadFileAsync 进出各设置一次。实测加载 22~31ms。 4) 统计提速 - 扫描预算由固定采样对改为 QPC 时间片(非交互 6ms / 交互 1.5ms,每块检查超时), 采样对配额改为按未完成状态数公平分摊并把上限提到 8M(交互 2M)。 - 真实 MF4-Record.MF4(283 信号)全部统计状态在 1 帧内完成;悬停+移动帧中位 2~3ms。 验证:离屏探针 p20/p20c/p20d/p21/p22/p23/p25 全绿(新增 p25 12 项); make release / make debug 零 warning;Release 808,960 B。共享规则已同步到 Documents/agent_mem.md。
This commit is contained in:
1 parent
8de8a8fb85
commit
ea704b03ea
9 files changed
+424
-553
No files matched your search
@@ -9310,3 +9310,96 @@ make release / make debug 零 warning;Release 813,568 B(< 1MB 红线)
|
||||
要验证"某个面板的悬停"必须先把另一块的 `panel.x/y` 挪开。
|
||||
* ⚠️ 改完 `TabBar` 的 `SetState` 签名要同步 `ArrangeWidgets` 唯一调用点;
|
||||
探针 A/B 时**先确认 `make` 真的重编了**(过滤输出只看 error 会漏掉"没重编")。
|
||||
|
||||
---
|
||||
|
||||
## 2026-11-02 第二十二轮(本机):表格改造归位(边沿计数表格 / 中心轴回列表)+ 统计面板"悬停时永不更新" + 加载被统计阻塞 + 统计提速
|
||||
|
||||
### 1. ⚠️ 上轮把表格改造放错了面板(用户指出)
|
||||
|
||||
上一轮误把「表格(信号名 / 上升沿计数 / 下降沿计数、行底色=信号配色、列对齐、
|
||||
单击行展开参数)」做在了**中心轴边沿计数**上。本轮**按用户要求归位**:
|
||||
|
||||
| 面板 | 现在的布局 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| **边沿计数(COUNT)** | **表格**(表头固定 + 每信号一行 + 内容可滚动) | 只有滚动条可交互;新增 `Lane::edgeCountScroll` |
|
||||
| **中心轴边沿计数(CENTER)** | **恢复为可滚动分组列表**(条目栏 + 复选框 + 展开后「统计行 + 两行滑块」) | 与均值滤波/弱峰调整同风格;`rowStats` 恢复 |
|
||||
| 均值滤波 / 弱峰调整 | 可滚动分组列表 | 不变 |
|
||||
|
||||
* `EdgePanelWidth` / `EdgePanelLayoutFor` / `PaintEdgeCursor` 里 `listStyle = (centerAxis || meanFilter || weakPeak)`、
|
||||
`countTable = (kind == COUNT)`;`EdgeCenterTableHeader` → **`EdgeCountTableHeader`**。
|
||||
* **`Lane::EnsureEdgeCenterItem` 恢复 `collapsed = false`**(上轮为了表格默认收起,现在列表式要默认展开)。
|
||||
* `PanelSlotKey` / `BuildBoxes` 的 `tableHeader` / `tableColumns[3]` 现在只由 COUNT 填。
|
||||
|
||||
### 2. ⭐⭐ 统计面板"鼠标一直在信号上移动时永不更新"
|
||||
|
||||
现象(用户报):鼠标停在某条信号上方、在其能触发高亮提示的范围内**持续移动**,统计面板就一直不更新。
|
||||
|
||||
根因:第十九轮为了提高交互帧率,把**统计数字从面板缓存键里整段跳过**(`interactiveKey`)。
|
||||
`InputIsInteractive()` 的定义是"正在拖拽 **或** 鼠标在 140ms 内移动过"——只要鼠标一直动,
|
||||
它就**永远为真** ⇒ 键永远不含统计 ⇒ 面板永远贴旧像素。
|
||||
|
||||
修法(不再逐信号查询,也不会每帧重画上百行):
|
||||
* `EdgeScanState` 推进/完成时自增 `m_edgeScanRevision`(`EdgeScanFor` 里 +3 处);
|
||||
* `Paint` 开头把它转成 `m_panelStatsVersion`:**非交互帧立刻同步**,
|
||||
**交互帧按 `kEdgeScanStatsRefreshFrames`(=4) 节流**;
|
||||
* `PanelSlotKey` 对 COUNT / CENTER 只 `mix(m_panelStatsVersion)`(O(1)、零查询)——
|
||||
统计推进 ⇒ 版本号变 ⇒ 面板重绘;没推进 ⇒ 键稳定 ⇒ 贴回缓存。
|
||||
|
||||
A/B:关掉"交互期同步" ⇒ 探针 `changes` 从 **29 掉到 0**(面板确实不再更新)。
|
||||
|
||||
### 3. ⭐⭐ 统计没算完时"无法加载文件"
|
||||
|
||||
现象(用户报):统计面板还在"统计中…"时点「导入文件」,无论文件大小都要等统计完成才能加载。
|
||||
|
||||
根因:`LoadFileAsync` 的主循环每 15ms `UpdateWindow` 触发整帧绘制,而 `Paint` 里
|
||||
`PaintEdgeCursor` 会**推进统计预算 + 重绘上百行面板**(283 信号时单帧 20ms+)⇒
|
||||
加载进度被统计抢走 CPU,表现为"必须先等统计算完"。
|
||||
(另外加载完成后 `InvalidateDerivedCaches` 会清空累积状态,于是又开始重算 —— 这是预期行为。)
|
||||
|
||||
修法:新增 `PlotView::SetLoadingBusy(bool)`(`Application::LoadFileAsync` 进出各设一次):
|
||||
* `Paint` 里统计预算与时间预算都置 0;
|
||||
* `PaintEdgeCursor` 提前返回(加载遮罩本来盖住整个界面,面板看不见);
|
||||
* `RequestEdgeScanFrame` 不再自请求(避免加载期间的重绘风暴)。
|
||||
|
||||
实测(283 信号 + 扫描进行中):小文件 `LoadFile` **22~31ms**。
|
||||
|
||||
### 4. ⭐⭐ 统计太慢(VERY_BIG_DATA)
|
||||
|
||||
根因:旧的"每帧采样对配额"在**普通计数**(1~2ns/对)下把一帧限得太死;而在**中心轴**
|
||||
(每个采样对还要算 `points × iterations` 窗口均值,≈7 倍成本)下同样的配额又嫌太大。
|
||||
一个数字无法同时适配两种成本。
|
||||
|
||||
修法:**按时间切**(`m_edgeScanDeadline`,QPC):扫描循环**每处理一个块**检查一次是否超时;
|
||||
采样对配额只保留"公平分摊"作用(`budget / 未完成状态数`,状态完成后让出配额):
|
||||
* 非交互帧时间预算 **6ms**,交互帧 **1.5ms**;
|
||||
* 配额上限提高:`kEdgeScanPairsPerFrame` 8,000,000 / 交互 2,000,000。
|
||||
|
||||
实测(本机):
|
||||
* 合成 300k×4:**1 帧**扫完(≈13ms 含整帧绘制)。
|
||||
* **真实 `TestData/MF4-Record.MF4`(283 信号、合并成 1 个网格、同时开边沿计数 + 中心轴):
|
||||
全部统计状态 1 帧(5.6~8ms)内完成**(上轮需要持续多帧且卡在"统计中")。
|
||||
* 悬停 + 持续移动时的帧耗时:中位 **2.1~3.0ms**、p90 ≈ 5ms(283 信号,两个面板都开着)。
|
||||
|
||||
### 5. 验证(离屏探针,`SW_HIDE` + 合成消息,不占用鼠标/键盘/屏幕)
|
||||
|
||||
```
|
||||
.preflight/p25.exe 12/12
|
||||
A 鼠标持续移动时面板持续更新(changes=29,帧 2.2ms);A/B 关掉交互期同步 ⇒ 0
|
||||
B 扫描进行中加载文件 22ms、加载忙标志正确清除
|
||||
C 300k 采样 1 帧扫完,pairs/frame ≥ 60k(实测 300k)
|
||||
D 283 信号:面板在悬停+移动时仍被缓存、帧中位 2.5ms
|
||||
E 真实 MF4-Record:283 信号、COUNT 表格 + CENTER 列表都限高;
|
||||
悬停+移动帧中位 2.1ms;全部统计 1 帧完成
|
||||
.preflight/p20 9/9 · p20c 11/11 · p20d 5/5 · p21 9/9 · p22 14/14 · p23 8/8(含中心轴统计行断言)
|
||||
make release / make debug 零 warning;Release 808,960 B
|
||||
```
|
||||
|
||||
### 6. 踩坑
|
||||
|
||||
* ⚠️ `SetAllVisible(false)` + `SetGroupVisible(last, true)` 才是"只显示最后加载的那个分组";
|
||||
直接 `SetGroupVisible(0, true)` 会把之前加载的分组一起显示(探针里"283 信号"变成 4 信号)。
|
||||
* ⚠️ 统计重放很快收敛后,"悬停时必须更新"这类断言要用**确定性的版本号推进**来测,
|
||||
否则会因"扫描早已完成"而假失败(真实场景的更新路径是同一条)。
|
||||
* ⚠️ PowerShell 5.1 按 ANSI 读 `.ps1`:脚本里**不能出现中文**(连正则里带中文都会解析失败),
|
||||
要把中文内容放进 UTF-8 数据文件再读取。
|
||||
Reference in new issue
Block a user