消除开始拖拽的首帧尖峰:用静态场景缓存初始化宽基底 + 启用预览功能时预建基底
平移首帧不再从零重画 2×视界:平移只是整体横移,上一帧场景缓存内容依然正确,直接贴进宽基底中心再滚动到当前视界(仅当派生预览曲线参数未变时适用)。启用弱波增强/均值滤波/中心轴时预建基底,使首次拖动其参数滑块无需重建。实测 VERY_BIG_DATA 全信号、视界 [40.1756,40.1885]s、5 网格:中键平移拖动最大 8.5ms、弱波增强滑块最大 10.8ms(原分别 35/37.6ms);全部鼠标交互全程 >=60fps、无尖峰;静止帧与 HEAD 逐像素 0 差异。
This commit is contained in:
1 parent
e988da7963
commit
8b1de5d900
3 files changed
+101
-1
No files matched your search
@@ -1845,6 +1845,8 @@ namespace jdi
|
||||
{
|
||||
lane.edgeCenterPanelOpen = false;
|
||||
}
|
||||
// 预建「宽缓冲基底」,避免首次拖动参数滑块时的一次性重建尖峰。
|
||||
RebuildWideBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1988,6 +1990,8 @@ namespace jdi
|
||||
{
|
||||
lane.weakBoostPanelOpen = false;
|
||||
}
|
||||
// 预建「宽缓冲基底」(不含派生曲线),使用户首次拖动该滑块时无需从零重建(避免一次性尖峰)。
|
||||
RebuildWideBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2069,6 +2073,8 @@ namespace jdi
|
||||
{
|
||||
lane.meanFilterPanelOpen = false;
|
||||
}
|
||||
// 预建「宽缓冲基底」,避免首次拖动参数滑块时的一次性重建尖峰。
|
||||
RebuildWideBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5578,8 +5584,13 @@ namespace jdi
|
||||
if (wideUsable)
|
||||
{
|
||||
// 已有可用基底 → 滚动(只补画新暴露的细条,恒为 O(细条),无周期性大尖峰);
|
||||
// 否则(首帧 / 跨度或内容变化)整幅重建一次基底。
|
||||
// 否则优先用"上一帧场景缓存"初始化基底(平移首帧:贴图 + 细条,避免从零重画
|
||||
// 2×视界造成的一次尖峰),再不行才整幅重建。
|
||||
bool ready = (m_wideValid && WideBufferMatches()) ? RollWideBuffer() : false;
|
||||
if (!ready && InitWideBufferFromScene())
|
||||
{
|
||||
ready = RollWideBuffer();
|
||||
}
|
||||
if (!ready)
|
||||
{
|
||||
ready = RebuildWideBuffer();
|
||||
@@ -6963,6 +6974,68 @@ namespace jdi
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlotView::InitWideBufferFromScene()
|
||||
{
|
||||
if (!m_sceneValid || m_sceneDc == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const double span = Tab().ViewMax() - Tab().ViewMin();
|
||||
const double sceneSpan = m_sceneKey.viewMax - m_sceneKey.viewMin;
|
||||
if (!(span > 0.0) || std::fabs(sceneSpan - span) > 1.0e-9)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// 仅当"派生预览曲线参数未变"时可用:此时场景缓存内容(含派生曲线/图例)依然正确。
|
||||
// (拖弱波增强/均值滤波参数滑块时派生曲线会变,必须从零重建基底。)
|
||||
std::vector<SceneDerivedEntry> currentDerived;
|
||||
CollectSceneDerived(currentDerived);
|
||||
if (currentDerived.size() != m_sceneDerived.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (std::size_t i = 0; i < currentDerived.size(); ++i)
|
||||
{
|
||||
const SceneDerivedEntry& a = currentDerived[i];
|
||||
const SceneDerivedEntry& b = m_sceneDerived[i];
|
||||
if (a.edgeCenter != b.edgeCenter || a.meanFilter != b.meanFilter ||
|
||||
a.weakBoost != b.weakBoost || a.weakBoostLevelPercent != b.weakBoostLevelPercent ||
|
||||
a.weakBoostIterations != b.weakBoostIterations ||
|
||||
a.edgeCenterItems != b.edgeCenterItems || a.meanFilterItems != b.meanFilterItems ||
|
||||
a.weakBoostItems != b.weakBoostItems)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const int width = static_cast<int>(std::lround(m_plotRect.Width));
|
||||
const int margin = std::max(1, width / 2);
|
||||
const int bitmapWidth = width + 2 * margin;
|
||||
const float plotHeight = m_plotRect.Height;
|
||||
const int bitmapHeight = static_cast<int>(std::ceil(plotHeight));
|
||||
if (!EnsureWideBuffer(bitmapWidth, bitmapHeight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 场景缓存的绘图区相对其原点(m_sceneX/m_sceneY)的位置。
|
||||
const int srcX = static_cast<int>(std::floor(m_plotRect.X)) - m_sceneX;
|
||||
const int srcY = static_cast<int>(std::floor(m_plotRect.Y)) - m_sceneY;
|
||||
if (BitBlt(m_wideDc, margin, 0, width, bitmapHeight, m_sceneDc, srcX, srcY, SRCCOPY) == FALSE)
|
||||
{
|
||||
m_wideValid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
const double scale = static_cast<double>(width) / span;
|
||||
m_wideMin = m_sceneKey.viewMin - static_cast<double>(margin) / scale;
|
||||
m_wideAnchorMin = m_sceneKey.viewMin;
|
||||
m_wideSpan = span;
|
||||
m_wideKey = SceneContentHash(true, false);
|
||||
m_wideValid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlotView::RenderWideStrip(int shiftPixels)
|
||||
{
|
||||
const int width = static_cast<int>(std::lround(m_plotRect.Width));
|
||||
|
||||
Reference in new issue
Block a user