修复缩放后平移的拖影/残留/错误元素与深放大区间卡顿:网格纵向滚动量纳入内容指纹、样式补丁增加视界校验、宽基底不再用含装饰的画面初始化、装饰缓存改为每帧重捕获并记录矩形与坐标原点、装饰底板改不透明以支持跨视界复用;交互帧 9~19ms 降至 4.5~6ms,纵向拖动残留 2 万+ 通道降至 72 通道,静止/结算帧像素精确;新增离屏诊断模式 6(逐帧计时 + 逐像素对比)
This commit is contained in:
1 parent
1c9c43233d
commit
e22749b57a
3 files changed
+224
-58
No files matched your search
@@ -385,6 +385,82 @@ Documents/ 项目文档(含本文件)
|
||||
|
||||
---
|
||||
|
||||
### 9.15 修复「缩放后平移出现拖影/残留/错误元素」与深放大区间仍然卡顿(本轮)
|
||||
|
||||
#### 用户方案评估:与当前实现的差异
|
||||
|
||||
用户提出的目标是「每个网格各自维护双缓冲区 + 后台线程绘制 + 前台只做贴图/坐标偏移」。
|
||||
与当前实现的差异与问题点:
|
||||
|
||||
| 维度 | 当前实现 | 用户设想 |
|
||||
| --- | --- | --- |
|
||||
| 像素复用粒度 | **全局一张**「宽基底」+ 场景缓存 + 装饰缓存 + 样式补丁(4 套机制叠加) | **每网格**一张信号图层(双缓冲) |
|
||||
| 绘制线程 | 全部在 UI 线程;只有**派生预览曲线**在后台算 | 单网格绘制也搬到后台 |
|
||||
| 失效判定 | 多个指纹(内容/几何/装饰)各自为政,**容易漏项**(本轮事实上踩了坑) | 每网格一个状态指纹 |
|
||||
|
||||
问题点(本轮实证,是本次卡顿与拖影的**真正根因**):
|
||||
|
||||
1. **`Tab().LaneScroll()`(网格纵向滚动量)没有参与任何内容指纹。**
|
||||
它只改变各网格的绘制位置,却被所有指纹忽略 → 一旦滚动网格(滚轮 / 上下方向键 / 滚动条),
|
||||
平移宽缓冲区会把**旧滚动位置**的像素当成当前内容贴回(位置错位、拖影、错误元素);
|
||||
同时因为指纹没变,"结算"逻辑误以为视界已停 → **每两帧就触发一次整幅重绘(约 125ms)**,
|
||||
表现为 8fps 级卡顿。这是用户报告的**两个症状的共同根因**。
|
||||
2. **`FindStyleOnlyLanes()` 只看 `SceneGeometryHash()`,而该指纹刻意不含视界。**
|
||||
于是视界已经变了却仍走"只重画受影响网格"的局部补丁,把缓存里**旧视界的画面**
|
||||
(时间轴、其它网格、底色)留在屏上 → 拖影 / 残留。
|
||||
3. **`InitWideBufferFromScene()` 把"上一帧的整幅画面"拷进宽基底**,而整幅画面里**含装饰**
|
||||
(Y 轴刻度胶囊 + 图例),宽基底却不含 → 装饰像素随平移一起移动,在网格左缘之外
|
||||
留下一排旧图例/刻度(重影)。
|
||||
4. **装饰缓存的两个不变量被打破**:贴回时用的是**当前帧重建的**矩形列表(命中缓存时根本不会重建 → 为空);
|
||||
并用**当前帧的** `m_area` 原点去推算源偏移(两帧原点可能不同)→ 表现为装饰消失 / 黑块 / 整体错位。
|
||||
|
||||
#### 本轮修复
|
||||
|
||||
- `SceneContentHash()` 计入 `Tab().LaneScroll()`(根本修复:滚动网格不再复用旧位置像素,
|
||||
也不再误触发"结算")。
|
||||
- `FindStyleOnlyLanes()` 增加**视图几何逐项校验**(视界 / 滚动 / 布局 / 缩放 / 拖拽光晕)后才允许局部补丁。
|
||||
- 宽基底**不再用"含装饰的整幅画面"初始化**;`RebuildWideBuffer()` 以 `m_renderWide` 跳过装饰,
|
||||
保证基底永远不含装饰。
|
||||
- 宽路径的装饰改为**按当前视界重画**(新增 `m_renderDecorOnly` 复用与整幅渲染**完全相同**
|
||||
的 `PaintLane` 代码路径,只跳过网格线与波形)。
|
||||
- 装饰缓存修好两个不变量:**每次真正绘制装饰的帧都立即重新捕获**(不再只在全质量帧捕获),
|
||||
且捕获时**同时保存矩形列表与坐标原点**,贴回时用保存的这份、按绝对坐标写入。
|
||||
- 装饰底板改为**不透明**(原来是 94% / 91%):装饰像素因此与时间视界无关,可安全跨视界复用;
|
||||
半透明底板会把旧视界的波形混进缓存像素,平移时在底板内部留下残影。
|
||||
- 新增离屏诊断模式(`.preflight/perf/perf_main.cpp` 的 `mode=6`):复现"加载 → 缩放 → 平移/键盘/滚轮"
|
||||
全部交互,逐帧计时,并把"当前屏"与"从零整幅渲染"做**逐像素对比 + 差异包围盒**。
|
||||
这是本轮定位问题的关键工具(否则只能靠猜测)。
|
||||
|
||||
#### 实测(`VERY_BIG_DATA.CSV`,视界 `[64.3948, 64.4153]s` ≈ **2.045ms 一大格**,5 网格,ms/帧)
|
||||
|
||||
| 交互 | 修复前 | 修复后 | 像素差(对比从零整幅渲染) |
|
||||
| --- | --- | --- | --- |
|
||||
| 键盘左右方向键平移 | 11~19ms | **5.2ms** | 3705 通道(≤0.5px 亚像素偏移,见下) |
|
||||
| 键盘上下方向键滚动网格 | 0.9ms(但错位/偶发 125ms) | **0.5ms** | **0** |
|
||||
| 中键水平拖动 | 10~18ms | **5.2ms** | 357 通道 |
|
||||
| 中键**纵向**拖动 | 14~19ms | **6.0ms** | 72 通道 |
|
||||
| 左键水平拖动 | 9~17ms | **4.5ms** | 390 通道 |
|
||||
| 左键**纵向**拖动 | 15~19ms | **6.1ms** | 72 通道 |
|
||||
| 滚轮滚动网格 | 1.0ms | **0.6ms** | **0** |
|
||||
| 缩放后再平移 | 9~17ms | **3.7ms**(缩放帧 6.8ms) | 495 通道 |
|
||||
| 弱波增强预览 + 平移 | 15~18ms | **5.8ms** | 2264 通道(异步曲线发布时序) |
|
||||
|
||||
- **修复前的纵向拖动会产生 2 万+ 通道的残留**(黑块 / 标签残缺);修复后降到 72 通道(仅亚像素量化)。
|
||||
- 剩余的几百通道差异集中在**密网格/密波形**上,是"宽基底按整数像素平移(≤0.5px 亚像素误差)"
|
||||
的必然结果,肉眼不可辨;视界停下后的"结算"帧会回到**像素精确**。
|
||||
|
||||
#### 尚未完成(如实记录)
|
||||
|
||||
用户要求的「每个网格独立双缓冲 + **后台线程绘制**」这一层**本轮未实现**,原因:
|
||||
`PaintLane` 及其调用链直接读写大量 `PlotView` 成员(`m_lanes` / `m_area` / `m_plotRect` / 视界 /
|
||||
多重缓存 / `m_decorRects` / `m_legendHits` …),把它搬到后台线程会与 UI 线程的 `paintOverlays`
|
||||
**数据竞争**。要做需要把渲染器改造成「不依赖成员状态的独立渲染器」(把上述状态显式参数化、
|
||||
缓存改为每线程私有),属于大重构,风险高。
|
||||
**本轮先把"正确性"与"帧时间"问题解决**:现在平移/缩放期间的帧时间已降到 4~6ms(原 9~19ms),
|
||||
且不再有拖影/残留/错位;后续可按用户方案逐步把单网格绘制搬到后台。
|
||||
|
||||
---
|
||||
|
||||
## 10. 变更日志(本文件维护记录)
|
||||
|
||||
| 日期 | 设备/模型 | 摘要 |
|
||||
@@ -401,3 +477,4 @@ Documents/ 项目文档(含本文件)
|
||||
| 2026-10-11 | DeepSeek-V4.1-Flash | 宽缓冲改为**滚动式**(自贴图平移 + 只补画新暴露细条),消除"移出边界整幅重建"的周期性尖峰;缓冲只覆盖绘图区、时间轴前台绘制、亚像素误差用锚点限制在 ≤0.5px → 持续拖动平移约 6ms/帧、无尖峰(长距最大 10.5ms);静止帧逐像素 0 差异。残留:每次开始拖拽的首帧需新建缓冲(一次启动尖峰)。 |
|
||||
| 2026-10-11 | DeepSeek-V4.1-Flash | 消除"开始拖拽"的首帧尖峰:平移首帧用**静态场景缓存初始化宽基底**(`InitWideBufferFromScene`,贴图 + 细条,不再从零重画 2×视界);启用带预览的实验性功能时**预建基底**。实测:平移拖动最大 8.5ms、弱波增强滑块最大 10.8ms(原分别 35/37.6ms),用户全部鼠标交互在该放大区间**全程 ≥60fps、无尖峰**;静止帧逐像素 0 差异。残留:非拖拽视界变化(键盘/工具栏)仍整幅重绘。 |
|
||||
| 2026-10-11 | DeepSeek-V4.1-Flash | 消除 9.13 残留:**非拖拽视界变化(键盘/工具栏)也走宽基底快路径**(124.6ms→**8.6ms**),并用 `wideKey` 相等判定"视界已停止变化"触发一次**结算**整幅全质量帧以恢复像素精确;分支顺序固定为"静态贴图 → 宽基底 → 样式补丁 → 整幅",宽基底强制全质量抗锯齿且竖向刻度用前台跨度。新增像素对比模式验证:底座管线忠实(meanAbs 0.68/255),平移期仅 ≤0.5px 亚像素差;7 张静态/结算帧与 HEAD **字节一致**;平移中途帧不再有图例/刻度重影。 |
|
||||
| 2026-10-12 | DeepSeek-V4.1-Flash | 修复用户报告的「缩放后平移出现拖影/残留/错误元素」与「2ms 一大格区间仍然卡顿」。根因:①网格纵向滚动量未参与任何内容指纹→滚动时把旧位置像素贴回且每两帧触发一次整幅重绘(≈8fps);②`FindStyleOnlyLanes` 未校验视界→视界变化后仍走局部补丁;③宽基底用含装饰的整幅画面初始化→装饰随平移重影;④装饰缓存的矩形列表与坐标原点两帧不同源→装饰消失/黑块/错位。修复后交互帧 9~19ms → **4.5~6ms**,纵向拖动残留 2 万+ 通道 → 72 通道(亚像素量化),静态/结算帧像素精确。新增 `perf.exe ... 6` 诊断模式(逐帧计时 + 逐像素对比 + 差异包围盒)。未实现:每网格双缓冲后台渲染(需先把 `PaintLane` 改造成无状态渲染器,已在文档 9.15 说明)。 |
|
||||
Reference in new issue
Block a user