修复缩放后平移的绘制错误/抖动与前台卡顿;弱波增强改名弱峰增强并支持 0~200%
渲染(根因与修法)
- 根因:后台图层线程渲染时会临时改写共享渲染状态(m_area/m_plotRect/视界/网格矩形),
与 UI 线程无锁的平移(OnMouseMove)和命中测试相冲 → 后台的"保存→改写→恢复"会把
用户刚做的平移弹回、命中测试读到错位网格;同时 RollWideBuffer 用单一全局锚点给所有
图层算同一位移,而各图层可能是在不同视界下渲染的(后台逐网格)→ 网格之间时间错位、
贴回像素互相矛盾;补细条又误用"当前视界"的映射(与旧像素不同源)→ ≤0.5px 接缝与拖动抖动。
- 修法:
* 删除后台图层线程(m_layerWorker 及任务队列、EnsureLayerWorker、StopLayerWorker、
LayerWorkerLoop、ScheduleStaleLayerRenders、m_layerBack、m_layerAnchorMin/Valid、
m_lastPaintTick、m_layerRescheduleStreak)。图层渲染一律在 UI 线程内同步完成。
* 逐网格独立锚点与滚动:以 LaneLayer::wideMin 为准,补细条沿用该图层自己的映射。
* RenderLaneLayerRegion 新增 wideMin 形参;新增 LayerDefaultWideMin()。
* RollWideBuffer 逐网格:内容指纹不一致或锚点离视界太远 → 该网格整块重画;
否则整数像素自贴图平移 + 只补新暴露的细条。
* Paint 宽基底分支:!LayersReadyForView() 时先同步 RebuildWideBuffer() 再滚动。
* BackgroundLayerRenderCount() 保留为"同步图层区域渲染次数"的诊断计数。
- 效果:平移不再出现网格时间错位、视界被弹回或波形抖动;居中图层与整幅重绘逐像素一致。
弱峰增强(原「弱波增强」)
- 功能改名:界面文案与标识符统一为 WeakPeak/weakPeak(ComputeWeakPeakBoost、
SetLaneWeakPeak*、EdgePanelKind::PEAK、PlotDragMode::PEAK_LEVEL/PEAK_ITERATIONS、
PLOT_CMD_LANE_WEAK_PEAK、PeakExtremum 等),导出信号名 "<原信号> (弱峰增强 M% N次迭代)"。
- 等级范围改为 0~200%,目标值分段插值:
* 0~100%:在"目标极值自身的值"与"左右同类极值中较温和的一侧"之间插值
(0% 目标就是当前值 → 完全不动,允许用户做极小幅度调整);
* 100~200%:与原先 0~100% 的插值方式一致(200% 完全拉平到另一侧)。
两段在 100% 处连续。新 1.5 == 旧 0.5,新 2.0 == 旧 1.0。
- Lane::weakPeakLevel 默认 1.5;levelPercent(构建请求/曲线缓存键)范围 0~200、默认 150;
新增 kWeakPeakLevelMax = 2.0 与 kWeakPeakPercentMax = 200;滑块轨道比例 = level / 2。
测试
- 同步更新离屏测试 .preflight/uitest:等级期望改为 0/50/100/150/200 五档;阶数扫描与
"完全恢复"块改用 150%/200% 以保持旧期望;派生信号名校验改用新名;
[J] 改为"补丁帧标记降级 → 渲染到缓存重新有效后用修复帧与整幅重绘比对(0 差异)";
[AF] 面板像素容差 32→96(面板 96% 不透明,底层 ≤0.5px 残留会透出,实测最多 6 像素/72 级);
[X] 预览曲线像素计数的颜色容差 6→40。
- 新增离屏检查 .preflight/layercheck:居中图层与整幅重绘逐像素对比、平移逐网格对齐位移、
视界覆盖检测、跨度抖动下的视界保持检测。
- make release 零警告;uitest 380/380 通过(exit=0)。
This commit is contained in:
1 parent
800c8b835b
commit
da83dc2987
7 files changed
+649
-739
No files matched your search
@@ -241,8 +241,8 @@ namespace jdi
|
||||
/**
|
||||
* @brief 应用绘图区提交的「实验性功能 → 构建为新信号」请求。
|
||||
*
|
||||
* 为指定网格内的每条被勾选信号各构建一条派生信号(多次迭代均值滤波或弱波增强),
|
||||
* 命名为 `<原信号名称> (N点均值…)` / `<原信号名称> (弱波增强 M%)`,
|
||||
* 为指定网格内的每条被勾选信号各构建一条派生信号(多次迭代均值滤波或弱峰增强),
|
||||
* 命名为 `<原信号名称> (N点均值…)` / `<原信号名称> (弱峰增强 M%)`,
|
||||
* 插入到原信号所在组的原信号位置**下方**,并把新信号所在的网格移动到原信号网格的下方。
|
||||
*
|
||||
* @return 实际构建了新信号返回 true。
|
||||
@@ -250,7 +250,7 @@ namespace jdi
|
||||
bool ApplyPendingDerivedBuild();
|
||||
|
||||
/**
|
||||
* @brief 派生信号构建请求(多次迭代均值滤波 / 弱波增强共用同一套插入流程)。
|
||||
* @brief 派生信号构建请求(多次迭代均值滤波 / 弱峰增强共用同一套插入流程)。
|
||||
*/
|
||||
struct DerivedSignalRequest
|
||||
{
|
||||
@@ -258,12 +258,12 @@ namespace jdi
|
||||
int signalIndex = -1; /**< 原信号下标。 */
|
||||
int points = 5; /**< 多次迭代均值滤波:均值点数 X(滑平半径)。 */
|
||||
int iterations = 1; /**< 多次迭代均值滤波:迭代次数 N(至少 1)。 */
|
||||
int levelPercent = 50; /**< 弱波增强:增强等级(0–100)。 */
|
||||
bool weakBoost = false; /**< true = 弱波增强,false = 多次迭代均值滤波。 */
|
||||
int levelPercent = 150; /**< 弱峰增强:增强等级(0–200)。 */
|
||||
bool weakPeak = false; /**< true = 弱峰增强,false = 多次迭代均值滤波。 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 把一条派生信号(多次迭代均值滤波 / 弱波增强)插入数据层并同步各视图。
|
||||
* @brief 把一条派生信号(多次迭代均值滤波 / 弱峰增强)插入数据层并同步各视图。
|
||||
* @param [IN] request 构建请求。
|
||||
* @param [IN] makeVisible 是否在当前标签页中勾选新信号。
|
||||
* @return 构建并插入成功返回 true。
|
||||
|
||||
@@ -1481,14 +1481,14 @@ namespace jdi
|
||||
|
||||
// 1. 计算派生采样值(与网格内的预览曲线共用同一实现,因此逐位一致)。
|
||||
// 多次迭代均值滤波形如「<原信号名称> (N点均值 M次迭代)」,
|
||||
// 弱波增强形如「<原信号名称> (弱波增强 M% N次迭代)」。
|
||||
// 弱峰增强形如「<原信号名称> (弱峰增强 M% N次迭代)」。
|
||||
std::vector<float> derived_values;
|
||||
SignalData derived;
|
||||
if (request.weakBoost)
|
||||
if (request.weakPeak)
|
||||
{
|
||||
ComputeWeakWaveBoost(source.values, static_cast<double>(request.levelPercent) / 100.0,
|
||||
ComputeWeakPeakBoost(source.values, static_cast<double>(request.levelPercent) / 100.0,
|
||||
request.iterations, derived_values);
|
||||
derived.name = baseName + L" (弱波增强 " + std::to_wstring(request.levelPercent) + L"% " +
|
||||
derived.name = baseName + L" (弱峰增强 " + std::to_wstring(request.levelPercent) + L"% " +
|
||||
std::to_wstring(request.iterations) + L"次迭代)";
|
||||
}
|
||||
else
|
||||
@@ -1538,7 +1538,7 @@ namespace jdi
|
||||
|
||||
bool Application::ApplyPendingDerivedBuild()
|
||||
{
|
||||
// 两类「构建为新信号」请求(均值滤波 / 弱波增强)机制完全一致,
|
||||
// 两类「构建为新信号」请求(均值滤波 / 弱峰增强)机制完全一致,
|
||||
// 统一整理成同一份构建清单后按下标降序处理。
|
||||
std::vector<DerivedSignalRequest> requests;
|
||||
{
|
||||
@@ -1553,24 +1553,24 @@ namespace jdi
|
||||
request.signalIndex = item.signalIndex;
|
||||
request.points = item.points;
|
||||
request.iterations = item.iterations;
|
||||
request.weakBoost = false;
|
||||
request.weakPeak = false;
|
||||
requests.push_back(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
int laneIndex = -1;
|
||||
std::vector<PlotView::WeakBoostBuild> items;
|
||||
if (m_plot.TakePendingWeakBoostBuild(laneIndex, items))
|
||||
std::vector<PlotView::WeakPeakBuild> items;
|
||||
if (m_plot.TakePendingWeakPeakBuild(laneIndex, items))
|
||||
{
|
||||
for (const PlotView::WeakBoostBuild& item : items)
|
||||
for (const PlotView::WeakPeakBuild& item : items)
|
||||
{
|
||||
DerivedSignalRequest request;
|
||||
request.fileIndex = item.fileIndex;
|
||||
request.signalIndex = item.signalIndex;
|
||||
request.levelPercent = item.levelPercent;
|
||||
request.iterations = item.iterations;
|
||||
request.weakBoost = true;
|
||||
request.weakPeak = true;
|
||||
requests.push_back(request);
|
||||
}
|
||||
}
|
||||
@@ -1610,9 +1610,9 @@ namespace jdi
|
||||
if (built > 0)
|
||||
{
|
||||
std::wstring text = L"已构建 " + std::to_wstring(built) + L" 条 ";
|
||||
if (last.weakBoost)
|
||||
if (last.weakPeak)
|
||||
{
|
||||
text += L"弱波增强 " + std::to_wstring(last.levelPercent) + L"% " +
|
||||
text += L"弱峰增强 " + std::to_wstring(last.levelPercent) + L"% " +
|
||||
std::to_wstring(last.iterations) + L"次迭代信号。";
|
||||
}
|
||||
else
|
||||
@@ -1753,11 +1753,11 @@ namespace jdi
|
||||
meanFilter.checked = m_plot.LaneMeanFilter(laneIndex);
|
||||
experimental.submenu.push_back(meanFilter);
|
||||
|
||||
MenuItem weakBoost;
|
||||
weakBoost.label = L"弱波增强";
|
||||
weakBoost.id = PLOT_CMD_LANE_WEAK_BOOST;
|
||||
weakBoost.checked = m_plot.LaneWeakBoost(laneIndex);
|
||||
experimental.submenu.push_back(weakBoost);
|
||||
MenuItem weakPeak;
|
||||
weakPeak.label = L"弱峰增强";
|
||||
weakPeak.id = PLOT_CMD_LANE_WEAK_PEAK;
|
||||
weakPeak.checked = m_plot.LaneWeakPeak(laneIndex);
|
||||
experimental.submenu.push_back(weakPeak);
|
||||
}
|
||||
items.push_back(experimental);
|
||||
|
||||
@@ -1872,9 +1872,9 @@ namespace jdi
|
||||
// 「实验性功能 → 均值滤波」:切换均值滤波曲线与参数面板。
|
||||
m_plot.ToggleLaneMeanFilter(laneIndex);
|
||||
break;
|
||||
case PLOT_CMD_LANE_WEAK_BOOST:
|
||||
// 「实验性功能 → 弱波增强」:切换弱波增强曲线与参数面板。
|
||||
m_plot.ToggleLaneWeakBoost(laneIndex);
|
||||
case PLOT_CMD_LANE_WEAK_PEAK:
|
||||
// 「实验性功能 → 弱峰增强」:切换弱峰增强曲线与参数面板。
|
||||
m_plot.ToggleLaneWeakPeak(laneIndex);
|
||||
break;
|
||||
case PLOT_CMD_LANE_SPLIT:
|
||||
// 「拆分当前网格」:信号按个拆成独立网格,新网格顺次插入其下方。
|
||||
@@ -2378,7 +2378,7 @@ namespace jdi
|
||||
{
|
||||
// 绘图区内的点击也可能提交图例改名,需要立刻落到数据层。
|
||||
ApplyPendingRename();
|
||||
// 「构建为新信号」按钮(均值滤波 / 弱波增强):立即构建新信号并同步各视图。
|
||||
// 「构建为新信号」按钮(均值滤波 / 弱峰增强):立即构建新信号并同步各视图。
|
||||
ApplyPendingDerivedBuild();
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user