perf(vtk): 撤销防抖定时器,改合并渲染(requestRender:同事件循环多次请求只渲一帧)治滚轮卡顿-根因是逐瓦片重复Render
This commit is contained in:
parent
69a81b2eac
commit
fd43051d8d
|
|
@ -8,7 +8,6 @@
|
|||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
#include <QNetworkRequest>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
|
@ -108,10 +107,19 @@ long long TileBasemap::tileKey(int z, int x, int y) {
|
|||
|
||||
TileBasemap::TileBasemap(geopro::render::Scene& scene, vtkRenderWindow* rw,
|
||||
std::shared_ptr<geopro::core::GeoLocalFrame> frame, QObject* parent)
|
||||
: QObject(parent), scene_(scene), rw_(rw), frame_(std::move(frame)) {
|
||||
refreshTimer_ = new QTimer(this);
|
||||
refreshTimer_->setSingleShot(true);
|
||||
connect(refreshTimer_, &QTimer::timeout, this, [this]() { refresh(); });
|
||||
: QObject(parent), scene_(scene), rw_(rw), frame_(std::move(frame)) {}
|
||||
|
||||
void TileBasemap::requestRender() {
|
||||
// 合并渲染:同一事件循环轮次内的多次请求只渲染一帧(标准做法,避免逐瓦片重复 Render 卡顿)。
|
||||
if (renderPending_) return;
|
||||
renderPending_ = true;
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
renderPending_ = false;
|
||||
if (rw_) rw_->Render();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
TileBasemap::~TileBasemap() {
|
||||
|
|
@ -133,8 +141,7 @@ void TileBasemap::ensureObserver() {
|
|||
}
|
||||
|
||||
void TileBasemap::onInteractionEnd(vtkObject*, unsigned long, void* clientData, void*) {
|
||||
// 防抖:交互(滚轮/旋转/平移)停止 ~140ms 后才刷新四叉树,避免每格事件都重算卡顿。
|
||||
if (auto* self = static_cast<TileBasemap*>(clientData)) self->refreshTimer_->start(140);
|
||||
if (auto* self = static_cast<TileBasemap*>(clientData)) self->refresh();
|
||||
}
|
||||
|
||||
void TileBasemap::enqueueGet(const QString& url, std::function<void(QNetworkReply*)> onDone) {
|
||||
|
|
@ -172,7 +179,7 @@ void TileBasemap::show(Kind kind) {
|
|||
terrainProbed_ = false;
|
||||
kind_ = kind;
|
||||
if (kind == Hidden) {
|
||||
if (rw_) rw_->Render();
|
||||
requestRender();
|
||||
return;
|
||||
}
|
||||
refresh(); // 四叉树覆盖:近细远粗一次铺满(含远处粗块,无需单独粗底层)
|
||||
|
|
@ -266,7 +273,7 @@ void TileBasemap::refresh() {
|
|||
|
||||
purgeStale();
|
||||
ren->ResetCameraClippingRange(); // 交互后扩裁剪面以含新载入的底图瓦片(防被"蒙版"切)
|
||||
if (rw_) rw_->Render();
|
||||
requestRender();
|
||||
refreshing_ = false;
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +291,7 @@ void TileBasemap::purgeStale() {
|
|||
++it;
|
||||
}
|
||||
}
|
||||
if (removed && rw_) rw_->Render();
|
||||
if (removed) requestRender();
|
||||
}
|
||||
|
||||
void TileBasemap::fetchTile(int z, int x, int y, long long key) {
|
||||
|
|
@ -299,7 +306,7 @@ void TileBasemap::fetchTile(int z, int x, int y, long long key) {
|
|||
placeActor(key, buildFlat(z, x, y, tex));
|
||||
inFlight_.erase(key);
|
||||
purgeStale();
|
||||
if (rw_) rw_->Render();
|
||||
requestRender();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -331,7 +338,7 @@ void TileBasemap::fetchTile(int z, int x, int y, long long key) {
|
|||
if (!ok) {
|
||||
inFlight_.erase(key);
|
||||
purgeStale();
|
||||
if (rw_) rw_->Render();
|
||||
requestRender();
|
||||
return;
|
||||
}
|
||||
auto tex = makeTexture(img);
|
||||
|
|
@ -343,7 +350,7 @@ void TileBasemap::fetchTile(int z, int x, int y, long long key) {
|
|||
placeActor(key, buildFlat(z, x, y, tex)); // 街道图无地形 → 直接平面
|
||||
inFlight_.erase(key);
|
||||
purgeStale();
|
||||
if (rw_) rw_->Render();
|
||||
requestRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -410,7 +417,7 @@ void TileBasemap::fetchTerrain(int z, int x, int y, long long key, vtkSmartPoint
|
|||
}
|
||||
inFlight_.erase(key);
|
||||
purgeStale();
|
||||
if (rw_) rw_->Render();
|
||||
requestRender();
|
||||
};
|
||||
|
||||
// 命中缓存:同一祖先 DEM 块的多个瓦片瞬间起伏,免重复网络。
|
||||
|
|
@ -439,7 +446,7 @@ void TileBasemap::fetchTerrain(int z, int x, int y, long long key, vtkSmartPoint
|
|||
desired_.find(key) == desired_.end() || placed_.count(key)) {
|
||||
inFlight_.erase(key); // 过期/移出视野 → 不落地
|
||||
purgeStale();
|
||||
if (rw_) rw_->Render();
|
||||
requestRender();
|
||||
return;
|
||||
}
|
||||
QImage dem;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ class vtkRenderWindow;
|
|||
class vtkInteractorObserver;
|
||||
class vtkCallbackCommand;
|
||||
class QNetworkReply;
|
||||
class QTimer;
|
||||
namespace geopro::render { class Scene; }
|
||||
namespace geopro::core { class GeoLocalFrame; }
|
||||
|
||||
|
|
@ -43,6 +42,7 @@ public:
|
|||
private:
|
||||
static long long tileKey(int z, int x, int y);
|
||||
void ensureObserver(); // 首次显示时挂到交互样式的 EndInteractionEvent
|
||||
void requestRender(); // 合并渲染:同一事件循环轮次多次请求只渲染一帧
|
||||
void purgeStale(); // 本轮请求全部落地后再删旧层瓦片,避免缩放空白闪烁
|
||||
// 四叉树细分:按瓦片投影屏幕尺寸递归(近细远粗),收集叶瓦片到 out。
|
||||
void refineTile(int z, int x, int y, std::set<long long>& out, int& count);
|
||||
|
|
@ -85,7 +85,7 @@ private:
|
|||
bool terrainProbed_ = false; // 首次 fetchTerrain 打一行诊断日志
|
||||
vtkSmartPointer<vtkInteractorObserver> styleObs_; // 持引用保证回调期有效
|
||||
vtkSmartPointer<vtkCallbackCommand> observer_;
|
||||
QTimer* refreshTimer_ = nullptr; // 交互防抖:滚轮/旋转停止后才刷新四叉树(避免每格卡)
|
||||
bool renderPending_ = false; // 合并渲染:同轮多次请求只渲染一帧
|
||||
bool refreshing_ = false;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue