Files
Just-DataInspector/Documents
DeepSeek V4.1 Flash 7344bbe9c4 修复长距离中键拖拽的绘制错误与抽搐("距离太远"不再退化成排队重画)
症状(用户报告 + TestData/PROBLEM_IMG):按住中键把视界纵向移动好几个网格高(或横向拖很远),
不松开再挪回来时出现大量绘制错误与持续抽搐。

根因:RollWideBuffer 对"位移超出图层余量"只做"排队等后续帧重画"(QueueLaneRebuild + continue):
  * 该帧 BlitWideBuffer 的 srcY = marginY + vOffset 已落在画布之外 → 只能贴出/贴不到像素
    → 网格里出现空白条带(截图里的白色块);
  * 下一帧位移依旧超限 → 每帧都重新入队,而 RenderPendingLaneRebuilds(1) 一帧只补 1 个网格
    → 5 个网格永远补不完 = 持续抽搐;
  * 纵向余量只有 ±marginY(半个网格高 ≈80px),中键纵向拖拽每帧很容易移动 20~150px
    → 几乎必现;横向同理(余量 ±半屏,快速拖拽会超过)。

修法:只有"内容真的变了"(contentStale:外观/网格几何/幅值跨度/可见性…)才排队(那时画面本身
仍是旧内容、不缺口);距离类问题一律本帧就地解决:
  * |shift| < bitmapWidth 且 |vOffset| < 画布高 → 滚动:BitBlt 整块平移 + 只补画暴露的细条
    (横向条 / 纵向条),并同步锚点记账(wideMin / anchorYMax);
  * 任一超出画布(内容整体滚出)→ 本帧立刻整块重画并重新居中
    (RenderLaneLayerRegion(i, layer, 0, bitmapWidth, 0, 0, LayerDefaultWideMin()),实测 0.4ms/网格)。

探针(.preflight/dragcheck,按用户要求"全程按住中键不放"):
  * 图层条带 vs 同锚点新渲染:逐像素(滚动是纯整数平移,必须相同);
  * 覆盖率:(ViewMin - layer.wideMin) * scale == marginX(±1px)且 marginY + vOffset 起的一整个
    网格高都落在画布内 —— 任一条不成立,BlitWideBuffer 就会留下空白条带;
  * 画面结构:网格内"无墨迹行数"与"墨迹占比"对比整幅重绘参考帧(空白条带 / 内容错位探测器)。
场景:上拖半个网格高;按住拖左右/上下/斜向并拖出窗口;纵向拖 4 个网格高再拖回来并小幅摆动;
快速大位移对角拖拽(每帧 150×110px)。A/B 验证探针有效性:临时把纵向滚动关掉
(kLayerRollQuantum = 100000)→ 立刻报 worst layer band diff 76221 / drawing errors 11;
恢复后 0 错误。

两点说明(避免误判):
1. dragcheck 的"画面像素 diff"会稳定出现 ~2.5 万像素(一个网格的 ~11%)差异 —— 那是图层与整幅
   重绘的列相位差(图层画布 2449px 按 1px 列聚合,整幅重绘 1224px 列,相位差 ≤0.5px),对稠密脉冲
   信号(256kHz 编码器)会放大成大片边缘差异;这是长期存在、由"结算帧"收敛的现象,不是本轮缺陷,
   因此画面检查用结构化指标而不是像素 diff。
2. 截图里"整条网格被信号色填满"是正确渲染:把幅值窗口平移到与稠密信号相交的区间时,每列的
   min/max 包络本来就覆盖整个网格(示波器上同样如此)。

验证(全部离屏,不占用鼠标/键盘/屏幕):dragcheck PASS(0 绘制错误;长拖拽 80 帧 + 快速对角 24 帧);
uitest 463/463;panperf PASS(竖直中位 4.4ms、水平 7-10ms);layercheck clobbers=0/24、
pan frames wrong=0/4;cursorcheck 30/30;make clean && make all 零警告。
2026-10-12 20:44:51 +08:00
..