From c734512e349eb81e4f46653d794332fb83343022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 9 Aug 2012 17:45:39 +0000 Subject: [PATCH] paysages : Improved previews thread distribution. git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@407 b1fd45b6-86a6-48da-8261-f70d1f35bdcc --- gui_qt/basepreview.cpp | 78 ++++++++++++++++++++++++++++---------- gui_qt/basepreview.h | 1 - gui_qt/dialogheightmap.cpp | 2 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/gui_qt/basepreview.cpp b/gui_qt/basepreview.cpp index d38e083..b6e1af7 100644 --- a/gui_qt/basepreview.cpp +++ b/gui_qt/basepreview.cpp @@ -1,12 +1,13 @@ #include "basepreview.h" -#include #include #include #include #include #include #include +#include +#include #include "tools.h" #include "../lib_paysages/system.h" @@ -24,7 +25,9 @@ public: _ysize = ysize; _need_render = true; + _rendering = false; _alive = true; + _priority = xstart; } inline BasePreview* preview() @@ -32,6 +35,11 @@ public: return _preview; } + inline int priority() + { + return _priority; + } + inline bool isOnFront() { return _preview->isVisible() && _preview->window()->isActiveWindow(); @@ -49,6 +57,7 @@ public: void update() { + _priority = _xstart; _need_render = true; } @@ -57,10 +66,20 @@ public: bool changed = false; int revision; + if (_rendering) + { + return false; + } + + _rendering = true; + _alive = true; + if (_need_render) { if (!isOnFront()) { + _priority = -1; + _rendering = false; return false; } @@ -75,7 +94,10 @@ public: QRgb col = pixbuf.pixel(x, y); if (!_alive) { - return false; + _need_render = true; + _preview->rollbackChunkTransaction(); + _rendering = false; + return true; } if (qAlpha(col) < 255) { @@ -91,7 +113,7 @@ public: if (changed) { - _preview->commitChunkTransaction(&pixbuf, _xstart, _ystart, _xsize, _ysize, revision); + _need_render = not _preview->commitChunkTransaction(&pixbuf, _xstart, _ystart, _xsize, _ysize, revision); } else { @@ -99,12 +121,20 @@ public: } } - return changed; + if (not _need_render) + { + _priority = -1; + } + + _rendering = false; + return _need_render; } private: BasePreview* _preview; + int _priority; bool _alive; bool _need_render; + bool _rendering; int _xstart; int _ystart; int _xsize; @@ -139,7 +169,6 @@ void PreviewDrawingThread::run() PreviewDrawingManager::PreviewDrawingManager() { _thread_count = systemGetCoreCount(); - _lastRendered = NULL; } void PreviewDrawingManager::startThreads() @@ -154,6 +183,7 @@ void PreviewDrawingManager::startThreads() void PreviewDrawingManager::stopThreads() { + logDebug(QString("[Previews] Stopping all render threads")); for (int i = 0; i < _threads.size(); i++) { _threads.at(i)->askStop(); @@ -211,7 +241,10 @@ void PreviewDrawingManager::suspendChunks(BasePreview* preview) i--; } } - // TODO Interrupt currently processing chunks + for (int i = 0; i < _chunks.size(); i++) + { + _chunks.at(i)->interrupt(); + } _lock.unlock(); } @@ -236,6 +269,7 @@ void PreviewDrawingManager::updateChunks(BasePreview* preview) void PreviewDrawingManager::updateAllChunks() { + logDebug(QString("[Previews] Reviving all %1 preview chunks").arg(_chunks.size())); for (int i = 0; i < _chunks.size(); i++) { PreviewChunk* chunk; @@ -253,6 +287,12 @@ void PreviewDrawingManager::updateAllChunks() } } +static bool _cmpChunkPriority(const PreviewChunk* chunk1, const PreviewChunk* chunk2) +{ + return ((PreviewChunk*)chunk1)->priority() < ((PreviewChunk*)chunk2)->priority(); +} + + void PreviewDrawingManager::performOneThreadJob() { PreviewChunk* chunk; @@ -261,25 +301,22 @@ void PreviewDrawingManager::performOneThreadJob() _lock.lock(); if (!_updateQueue.isEmpty()) { - for (int i = _updateQueue.size(); i > 0; i--) - { - chunk = _updateQueue.takeFirst(); - if (chunk && i > 1 && chunk->preview() == _lastRendered) - { - _updateQueue.append(chunk); - } - else - { - break; - } - } + qSort(_updateQueue.begin(), _updateQueue.end(), _cmpChunkPriority); + chunk = _updateQueue.takeFirst(); } _lock.unlock(); if (chunk) { - _lastRendered = chunk->preview(); - chunk->render(); + if (chunk->render()) + { + _lock.lock(); + if (!_updateQueue.contains(chunk)) + { + _updateQueue.append(chunk); + } + _lock.unlock(); + } } } @@ -383,7 +420,6 @@ void BasePreview::stopDrawers() void BasePreview::reviveAll() { - logDebug("[Previews] Reviving all previews"); _drawing_manager->updateAllChunks(); } diff --git a/gui_qt/basepreview.h b/gui_qt/basepreview.h index 110a3a5..e5290d0 100644 --- a/gui_qt/basepreview.h +++ b/gui_qt/basepreview.h @@ -166,7 +166,6 @@ private: QVector _threads; QVector _chunks; QList _updateQueue; - BasePreview* _lastRendered; QMutex _lock; }; diff --git a/gui_qt/dialogheightmap.cpp b/gui_qt/dialogheightmap.cpp index 53a2c6d..a04e237 100644 --- a/gui_qt/dialogheightmap.cpp +++ b/gui_qt/dialogheightmap.cpp @@ -238,7 +238,7 @@ void DialogHeightMap::changeResolution() { current = 3; } - result = QInputDialog::getItem(this, tr("Paysages 3D - Change heightmap resolution"), tr("Choose the new heightmap resolution. Beware that lowering the resolution may imply a loss of accuracy."), items, current, false); + result = QInputDialog::getItem(this, tr("Paysages 3D - Change heightmap resolution"), tr("Choose the new heightmap resolution.\nBeware that lowering the resolution may imply a loss of accuracy."), items, current, false); if (!result.isEmpty()) { int new_res_x, new_res_z;