修复斜向自由拖拽视界时的卡顿/质量下降/错误绘制;预览曲线恢复抗锯齿;预览曲线不再闪烁
一、斜向拖拽退化的根因(纯水平拖拽测不出来)
平移的纵向分量 ShiftLaneRange 每帧都会小改被拖网格的 yMin/yMax,而网格幅值范围同时参与
「宽基底可用性」的几何指纹(SceneGeometryHash 原本含 yMin/yMax)与每个网格图层键的基
(LaneLayerKey 原本用全局 SceneContentHash):
* 前者 → 每帧都判定宽基底不可用 → 退化成整幅重绘,且拖拽置 m_fastFrame=true → 关抗锯齿
(绘制质量下降 + 卡顿);
* 后者 → 一个网格的幅值变化让全部 5 个网格的图层作废并全部入队,而
RenderPendingLaneRebuilds(1) 一帧只补 1 个 → 长期贴内容不一致的旧图层 = 错误绘制/断线。
二、修法
- SceneContentHash(includeStyles, includeDerived, includeLaneRange) 新增 includeLaneRange;
SceneGeometryHash() = SceneContentHash(false, true, false) → 幅值范围不再参与
「能不能走宽基底快路径」的判定。
- 新增逐网格 LaneLayerHash(laneIndex)(位图高度 + 该网格 yMin/yMax + 该网格各信号的
visible/color/opacity/lineWidth/mode);LaneLayerKey(laneIndex) 的基由全局内容指纹改为它
→ 幅值变化只让那一个网格失效,其余网格保持 Ready。
- Paint 宽基底分支:RenderPendingLaneRebuilds(1) 从 BlitWideBuffer 之后移到
RollWideBuffer() 之后、贴图之前 → 本帧预算内补好的网格本帧就可见(消除「比鼠标慢半拍」与断线)。
三、预览曲线抗锯齿
- PaintDerivedCurve 不再因 m_fastFrame 关闭抗锯齿(仅保留「陡峭段占比 > 1/8」的逃生口)。
波形基底来自图层、永远是全质量抗锯齿;预览曲线是叠加层,交互期间关 AA 就会「比普通信号粗糙」。
交互期间仍把顶点预算减半(低分辨率 → 松手恢复高分辨率)。
四、预览曲线闪烁
- AcquireNewestCurve(key, begin, end, spanBegin) 改为只按「信号 + 曲线种类」匹配(参数无关),
并优先挑窗口覆盖 [begin,end] 的条目;拖参数滑块时先用上一帧的曲线顶替,后台按新参数算好后无缝替换,
不再出现「消失一会儿又画出来」。
五、验证(全部离屏,不占用鼠标/键盘/屏幕)
- uitest 新增 [AH]:逐网格图层失效 / 斜向帧走宽基底快路径 / 参数连改 10 次 0 空白帧 /
隔离抗锯齿断言(快帧混淆边缘像素 8149 vs 8404,旧实现该值为 2)→ 420/420 通过;
make clean && make all 零警告。
- panperf:水平平移中位 6.17ms;斜向拖拽中位 9.16ms、p90 10.67ms、max 11.80ms,
走宽基底快路径 40/40(修复前 0/40),像素差与水平基线同量级(仅已知的 ≤0.5px 整数像素残差)。
- layercheck:clobbers=0/24、pan frames wrong=0/4、居中图层 vs 整幅重绘逐像素 0 差异。
This commit is contained in:
1 parent
a30a6fcf4d
commit
0afa6360ae
3 files changed
+209
-29
No files matched your search
@@ -1388,11 +1388,19 @@ namespace jdi
|
||||
|
||||
/**
|
||||
* @brief 取得该曲线键下最新的已算好条目并钉住(双缓冲的「旧缓冲」)。
|
||||
* @param [IN] key 曲线键。
|
||||
*
|
||||
* ⚠️ **只按「信号 + 曲线种类」匹配,忽略参数**:拖参数滑块时每帧参数都在变,
|
||||
* 若要求键完全相同就永远找不到上一帧的曲线,本帧便无曲线可画 → 预览曲线**闪烁**。
|
||||
* 旧曲线只是参数略旧,按采样下标映射位置依然正确,先顶上再等后台算好新曲线。
|
||||
*
|
||||
* @param [IN] key 曲线键(只用其 `signal` 与 `kind`)。
|
||||
* @param [IN] begin 需要区间起点(用于优先挑「覆盖该区间」的条目)。
|
||||
* @param [IN] end 需要区间终点(不含)。
|
||||
* @param [OUT] spanBegin 命中条目的窗口起点。
|
||||
* @return 命中条目,无则返回 nullptr。
|
||||
*/
|
||||
const CurveEntry* AcquireNewestCurve(const CurveKey& key, std::size_t& spanBegin) const;
|
||||
const CurveEntry* AcquireNewestCurve(const CurveKey& key, std::size_t begin, std::size_t end,
|
||||
std::size_t& spanBegin) const;
|
||||
|
||||
/**
|
||||
* @brief 发布一条新算好的曲线窗口并钉住。
|
||||
@@ -1907,6 +1915,22 @@ namespace jdi
|
||||
*/
|
||||
bool SceneCacheMatches() const;
|
||||
|
||||
/**
|
||||
* @brief **单个网格**的内容指纹(用于该网格自己的「信号图层」)。
|
||||
*
|
||||
* 图层位图里只含该网格的内容(底色 + 网格线 + 波形),位图高度 = 该网格高度、
|
||||
* 内部以 `y=0` 为网格顶边,因此该指纹只需要「网格高度 + 幅值范围 + 本网格各信号的
|
||||
* 可见性与外观 + 图例文案」。
|
||||
*
|
||||
* ⚠️ 这**必须**是逐网格的:早期版本用全局内容指纹,于是一个网格的幅值变化
|
||||
* 会同时作废**全部**网格的图层(拖拽时纵向分量让 5 个网格排队重画 → 图层内容
|
||||
* 相互不一致 = 错误绘制;且每帧都入队 → 永远补不完)。
|
||||
*
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 指纹值。
|
||||
*/
|
||||
std::uint64_t LaneLayerHash(int laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 计算场景内容指纹(信号集合、显示样式、网格幅值、图例文案)。
|
||||
*
|
||||
@@ -1915,16 +1939,22 @@ namespace jdi
|
||||
*
|
||||
* @param [IN] includeStyles 是否把逐信号外观样式(颜色/不透明度/线宽/模式)计入指纹。
|
||||
* @param [IN] includeDerived 是否把派生预览曲线的开关与参数计入指纹。
|
||||
* @param [IN] includeLaneRange 是否把各网格的**幅值范围**(`yMin/yMax`)计入指纹。
|
||||
* ⚠️ **拖拽平移时的纵向分量**会每帧小幅修改被拖网格的幅值范围;若它参与
|
||||
* “宽基底可用性”判据,每一帧都会退化成整幅重绘(质量下降 + 卡顿)。
|
||||
* 因此宽基底判据用 `includeLaneRange = false` 的几何指纹,
|
||||
* 幅值变化改由**逐网格图层自己的指纹**处理(只有该网格需要重画)。
|
||||
* @return 指纹值。
|
||||
*/
|
||||
std::uint64_t SceneContentHash(bool includeStyles = true, bool includeDerived = true) const;
|
||||
std::uint64_t SceneContentHash(bool includeStyles = true, bool includeDerived = true,
|
||||
bool includeLaneRange = true) const;
|
||||
|
||||
/**
|
||||
* @brief 场景内容中**不含逐信号外观样式**的指纹。
|
||||
*
|
||||
* 只包含网格结构、视图几何、网格幅值、信号集合与可见性、图例文案、选中项等
|
||||
* 只包含网格结构、视图几何、信号集合与可见性、图例文案、选中项等
|
||||
* "变化后必须整幅重建"的内容;逐信号的 `color / opacity / lineWidth / mode`
|
||||
* 一律不参与。
|
||||
* 一律不参与,**各网格的幅值范围(`yMin/yMax`)也不参与**(由逐网格图层指纹负责)。
|
||||
*
|
||||
* 用途:外观样式变化时(典型场景是拖动自定义颜色的滑块)波形几何完全不变,
|
||||
* 只要该指纹一致,就可以只重画"颜色变了的那个网格"再写回缓存,
|
||||
|
||||
Reference in new issue
Block a user