paysages : Improved previews thread distribution.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@407 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-08-09 17:45:39 +00:00 committed by ThunderK
parent 20bbe4f7ba
commit c734512e34
3 changed files with 58 additions and 23 deletions

View file

@ -1,12 +1,13 @@
#include "basepreview.h" #include "basepreview.h"
#include <math.h>
#include <QVector> #include <QVector>
#include <QPainter> #include <QPainter>
#include <QTimer> #include <QTimer>
#include <QWheelEvent> #include <QWheelEvent>
#include <QLabel> #include <QLabel>
#include <QMenu> #include <QMenu>
#include <assert.h>
#include <math.h>
#include "tools.h" #include "tools.h"
#include "../lib_paysages/system.h" #include "../lib_paysages/system.h"
@ -24,7 +25,9 @@ public:
_ysize = ysize; _ysize = ysize;
_need_render = true; _need_render = true;
_rendering = false;
_alive = true; _alive = true;
_priority = xstart;
} }
inline BasePreview* preview() inline BasePreview* preview()
@ -32,6 +35,11 @@ public:
return _preview; return _preview;
} }
inline int priority()
{
return _priority;
}
inline bool isOnFront() inline bool isOnFront()
{ {
return _preview->isVisible() && _preview->window()->isActiveWindow(); return _preview->isVisible() && _preview->window()->isActiveWindow();
@ -49,6 +57,7 @@ public:
void update() void update()
{ {
_priority = _xstart;
_need_render = true; _need_render = true;
} }
@ -57,10 +66,20 @@ public:
bool changed = false; bool changed = false;
int revision; int revision;
if (_rendering)
{
return false;
}
_rendering = true;
_alive = true;
if (_need_render) if (_need_render)
{ {
if (!isOnFront()) if (!isOnFront())
{ {
_priority = -1;
_rendering = false;
return false; return false;
} }
@ -75,7 +94,10 @@ public:
QRgb col = pixbuf.pixel(x, y); QRgb col = pixbuf.pixel(x, y);
if (!_alive) if (!_alive)
{ {
return false; _need_render = true;
_preview->rollbackChunkTransaction();
_rendering = false;
return true;
} }
if (qAlpha(col) < 255) if (qAlpha(col) < 255)
{ {
@ -91,7 +113,7 @@ public:
if (changed) if (changed)
{ {
_preview->commitChunkTransaction(&pixbuf, _xstart, _ystart, _xsize, _ysize, revision); _need_render = not _preview->commitChunkTransaction(&pixbuf, _xstart, _ystart, _xsize, _ysize, revision);
} }
else else
{ {
@ -99,12 +121,20 @@ public:
} }
} }
return changed; if (not _need_render)
{
_priority = -1;
}
_rendering = false;
return _need_render;
} }
private: private:
BasePreview* _preview; BasePreview* _preview;
int _priority;
bool _alive; bool _alive;
bool _need_render; bool _need_render;
bool _rendering;
int _xstart; int _xstart;
int _ystart; int _ystart;
int _xsize; int _xsize;
@ -139,7 +169,6 @@ void PreviewDrawingThread::run()
PreviewDrawingManager::PreviewDrawingManager() PreviewDrawingManager::PreviewDrawingManager()
{ {
_thread_count = systemGetCoreCount(); _thread_count = systemGetCoreCount();
_lastRendered = NULL;
} }
void PreviewDrawingManager::startThreads() void PreviewDrawingManager::startThreads()
@ -154,6 +183,7 @@ void PreviewDrawingManager::startThreads()
void PreviewDrawingManager::stopThreads() void PreviewDrawingManager::stopThreads()
{ {
logDebug(QString("[Previews] Stopping all render threads"));
for (int i = 0; i < _threads.size(); i++) for (int i = 0; i < _threads.size(); i++)
{ {
_threads.at(i)->askStop(); _threads.at(i)->askStop();
@ -211,7 +241,10 @@ void PreviewDrawingManager::suspendChunks(BasePreview* preview)
i--; i--;
} }
} }
// TODO Interrupt currently processing chunks for (int i = 0; i < _chunks.size(); i++)
{
_chunks.at(i)->interrupt();
}
_lock.unlock(); _lock.unlock();
} }
@ -236,6 +269,7 @@ void PreviewDrawingManager::updateChunks(BasePreview* preview)
void PreviewDrawingManager::updateAllChunks() void PreviewDrawingManager::updateAllChunks()
{ {
logDebug(QString("[Previews] Reviving all %1 preview chunks").arg(_chunks.size()));
for (int i = 0; i < _chunks.size(); i++) for (int i = 0; i < _chunks.size(); i++)
{ {
PreviewChunk* chunk; 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() void PreviewDrawingManager::performOneThreadJob()
{ {
PreviewChunk* chunk; PreviewChunk* chunk;
@ -261,25 +301,22 @@ void PreviewDrawingManager::performOneThreadJob()
_lock.lock(); _lock.lock();
if (!_updateQueue.isEmpty()) if (!_updateQueue.isEmpty())
{ {
for (int i = _updateQueue.size(); i > 0; i--) qSort(_updateQueue.begin(), _updateQueue.end(), _cmpChunkPriority);
{
chunk = _updateQueue.takeFirst(); chunk = _updateQueue.takeFirst();
if (chunk && i > 1 && chunk->preview() == _lastRendered)
{
_updateQueue.append(chunk);
}
else
{
break;
}
}
} }
_lock.unlock(); _lock.unlock();
if (chunk) if (chunk)
{ {
_lastRendered = chunk->preview(); if (chunk->render())
chunk->render(); {
_lock.lock();
if (!_updateQueue.contains(chunk))
{
_updateQueue.append(chunk);
}
_lock.unlock();
}
} }
} }
@ -383,7 +420,6 @@ void BasePreview::stopDrawers()
void BasePreview::reviveAll() void BasePreview::reviveAll()
{ {
logDebug("[Previews] Reviving all previews");
_drawing_manager->updateAllChunks(); _drawing_manager->updateAllChunks();
} }

View file

@ -166,7 +166,6 @@ private:
QVector<PreviewDrawingThread*> _threads; QVector<PreviewDrawingThread*> _threads;
QVector<PreviewChunk*> _chunks; QVector<PreviewChunk*> _chunks;
QList<PreviewChunk*> _updateQueue; QList<PreviewChunk*> _updateQueue;
BasePreview* _lastRendered;
QMutex _lock; QMutex _lock;
}; };

View file

@ -238,7 +238,7 @@ void DialogHeightMap::changeResolution()
{ {
current = 3; 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()) if (!result.isEmpty())
{ {
int new_res_x, new_res_z; int new_res_x, new_res_z;