修复深放大下样式/参数滑块卡顿(探针定位:样式补丁用抗锯齿 + 后台发布整幅作废)
复现:VERY_BIG_DATA 全信号在视界 [40.1756,40.1885]s(Δt≈12.9ms)下拖透明度/粗细/自定义颜色/拾色/弱波增强滑块极卡,但拖光标流畅(光标命中场景缓存)。用 JDI_PERF_PROBE 门控的临时探针精确拆解:整幅/补丁耗时几乎全在包络带 FillPath(抗锯齿 ≈29ms/网格,关掉 ≈5.4ms)。 两个根因:① 样式补丁(拖透明度/粗细/颜色)不在拖拽态 → m_fastFrame=false → 用抗锯齿重画该网格包络带 ≈72ms;② 拖弱波增强/均值滤波滑块时后台每算完一条就 InvalidateSceneCache → 每帧退化成整幅重绘(150ms+)。 修复:① 样式补丁强制快速帧并置 m_sceneDegraded(补丁 72→14ms,静止后自动补全质量);② 拖拽中后台发布只标记降级、不整幅作废(弱波增强滑块 96–176→26ms);③ 交互期间省略浮动面板投影。 同一负载机器实测:透明度/粗细/颜色 77→16ms,弱波增强滑块 96–176→26ms,平移拖动 34ms(快速帧,空闲机约 8ms)。全质量/结算帧与修复前逐像素 0 差异(LockBits 验证)。
This commit is contained in:
1 parent
c794967b02
commit
aefaaef6fa
2 files changed
+53
-7
No files matched your search
@@ -5487,10 +5487,22 @@ namespace jdi
|
||||
std::lock_guard<std::mutex> lock(m_curveMutex);
|
||||
PruneCurveEntriesLocked();
|
||||
}
|
||||
// 后台算好了新曲线:静态场景缓存里仍是旧曲线(或还没有曲线),作废一次以纳入最新结果。
|
||||
// 后台算好了新曲线:
|
||||
// * **静止**时:整幅作废一次,让新曲线(与新的静态场景缓存)立刻出现。
|
||||
// * **拖拽中**(拖弱波增强/均值滤波参数滑块):**不作废整幅** —— 拖拽时参数每帧都在变,
|
||||
// 本来就每帧走"样式补丁"路径,补丁会直接取到最新曲线;若此时还整幅作废,
|
||||
// 每帧会退化成整幅重绘(实测单帧 150ms+,与"拖动要跟手"直接冲突)。
|
||||
// 改为标记"已降级",等拖拽结束后再补一帧全质量。
|
||||
if (m_curveSceneDirty.exchange(false, std::memory_order_relaxed))
|
||||
{
|
||||
InvalidateSceneCache();
|
||||
if (m_dragMode == PlotDragMode::NONE)
|
||||
{
|
||||
InvalidateSceneCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sceneDegraded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_lanes.empty())
|
||||
@@ -5567,7 +5579,6 @@ namespace jdi
|
||||
paintOverlays();
|
||||
return;
|
||||
}
|
||||
|
||||
// 只有"外观样式"变化(典型场景:拖动自定义颜色滑块实时调色):网格结构、视图几何、
|
||||
// 波形采样都没变,只是颜色/不透明度/线宽/模式不同 —— 此时只重画受影响的网格,
|
||||
// 再写回缓存。(VERY_BIG_DATA 实测:整幅重绘 30ms+,单网格重画约 4ms。)
|
||||
@@ -5575,7 +5586,14 @@ namespace jdi
|
||||
std::vector<int> patchLanes;
|
||||
if (FindStyleOnlyLanes(patchLanes) && BlitSceneCache(g))
|
||||
{
|
||||
// ⚠️ 样式/参数**正在连续变化**(拖透明度/粗细/拾色/实验性功能滑块):这本身就是
|
||||
// 一种"交互中"。若不切换快速帧,本帧会用**抗锯齿**重画波形包络带 —— 实测
|
||||
// 单条网格的包络带 AA 填充 ≈29ms(本机负载下 72ms),而关掉 AA 只要 ≈5.6ms。
|
||||
// 因此补丁阶段强制快速帧,并在补丁后把场景缓存标记为"已降级",
|
||||
// 下一帧(参数稳定后)自动补一帧全质量 —— 既保证拖动手感,又不牺牲最终画质。
|
||||
m_fastFrame = true;
|
||||
RepaintSceneCachePatch(g, patchLanes);
|
||||
m_sceneDegraded = true;
|
||||
paintOverlays();
|
||||
return;
|
||||
}
|
||||
@@ -6942,7 +6960,7 @@ namespace jdi
|
||||
|
||||
const DrawMode mode = resolved.style->mode;
|
||||
// 顶点由“几何键”缓存提供:同一视图下重复绘制不再重算全量采样。
|
||||
const PolylineCacheEntry* cached = AcquirePolyline(ref, resolved, lane);
|
||||
const PolylineCacheEntry* cached = AcquirePolyline(ref, resolved, lane);
|
||||
if (cached == nullptr)
|
||||
{
|
||||
continue;
|
||||
@@ -9162,9 +9180,14 @@ namespace jdi
|
||||
const float pad = kEdgePanelPad * m_scale;
|
||||
|
||||
// 面板主体 + 标题栏。
|
||||
UiFillRoundRect(g, gd::RectF(panel.X + 1.0f * m_scale, panel.Y + 2.0f * m_scale,
|
||||
panel.Width, panel.Height),
|
||||
5.0f * m_scale, 0x14000000u);
|
||||
// 投影响用两张大面积的半透明圆角矩形模拟,代价不低;交互期间(快速帧)省略它,
|
||||
// 让拖动参数滑块时面板重绘不再被投影拖累(松手后的全质量帧会补回投影)。
|
||||
if (!m_fastFrame)
|
||||
{
|
||||
UiFillRoundRect(g, gd::RectF(panel.X + 1.0f * m_scale, panel.Y + 2.0f * m_scale,
|
||||
panel.Width, panel.Height),
|
||||
5.0f * m_scale, 0x14000000u);
|
||||
}
|
||||
UiFillRoundRect(g, panel, 5.0f * m_scale, WithAlpha(m_theme->cardBg, 0xF4));
|
||||
UiDrawRoundRect(g, panel, 5.0f * m_scale, m_theme->borderStrong, 1.0f);
|
||||
UiFillRoundRect(g, gd::RectF(panel.X, panel.Y, panel.Width, titleHeight), 5.0f * m_scale,
|
||||
|
||||
Reference in new issue
Block a user