fix a freezing bug
parent
407879c389
commit
0b2eb860c5
|
@ -131,6 +131,29 @@ struct PreviewQueueEntry {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VisualWorkUnit {
|
||||||
|
Point2i offset;
|
||||||
|
Vector2i size;
|
||||||
|
int worker;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct block_comparator : std::binary_function<VisualWorkUnit, VisualWorkUnit, bool> {
|
||||||
|
static int compare(const VisualWorkUnit &v1, const VisualWorkUnit &v2) {
|
||||||
|
if (v1.offset.x < v2.offset.x) return -1;
|
||||||
|
else if (v1.offset.x > v2.offset.x) return 1;
|
||||||
|
if (v1.offset.y < v2.offset.y) return -1;
|
||||||
|
else if (v1.offset.y > v2.offset.y) return 1;
|
||||||
|
if (v1.size.x < v2.size.x) return -1;
|
||||||
|
else if (v1.size.x > v2.size.x) return 1;
|
||||||
|
if (v1.size.y < v2.size.y) return -1;
|
||||||
|
else if (v1.size.y > v2.size.y) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const VisualWorkUnit &v1, const VisualWorkUnit &v2) const {
|
||||||
|
return compare(v1, v2) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct SceneContext {
|
struct SceneContext {
|
||||||
/* Scene-related */
|
/* Scene-related */
|
||||||
|
@ -147,6 +170,7 @@ struct SceneContext {
|
||||||
float progress;
|
float progress;
|
||||||
QString eta, progressName;
|
QString eta, progressName;
|
||||||
ref<Bitmap> framebuffer;
|
ref<Bitmap> framebuffer;
|
||||||
|
std::set<VisualWorkUnit, block_comparator> workUnits;
|
||||||
EMode mode, cancelMode;
|
EMode mode, cancelMode;
|
||||||
Float gamma, exposure, clamping;
|
Float gamma, exposure, clamping;
|
||||||
bool srgb;
|
bool srgb;
|
||||||
|
|
|
@ -831,8 +831,10 @@ bool MainWindow::on_tabBar_tabCloseRequested(int index) {
|
||||||
SceneContext *context = m_context[index];
|
SceneContext *context = m_context[index];
|
||||||
if (context->renderJob != NULL) {
|
if (context->renderJob != NULL) {
|
||||||
QMessageBox box(QMessageBox::Question, tr("Really close?"),
|
QMessageBox box(QMessageBox::Question, tr("Really close?"),
|
||||||
tr("Rendering of scene \"%1\" is unfinished - all progress will be lost. Are you sure you want to continue?").arg(context->shortName),
|
tr("Rendering of scene \"%1\" is unfinished - all progress "
|
||||||
QMessageBox::Yes | QMessageBox::No, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::Sheet);
|
"will be lost. Are you sure you want to continue?").arg(context->shortName),
|
||||||
|
QMessageBox::Yes | QMessageBox::No, this,
|
||||||
|
Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::Sheet);
|
||||||
box.setWindowModality(Qt::WindowModal);
|
box.setWindowModality(Qt::WindowModal);
|
||||||
if (box.exec() == QMessageBox::No)
|
if (box.exec() == QMessageBox::No)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1120,11 +1122,16 @@ void MainWindow::on_actionSettings_triggered() {
|
||||||
|
|
||||||
void MainWindow::on_actionStop_triggered() {
|
void MainWindow::on_actionStop_triggered() {
|
||||||
SceneContext *context = m_context[ui->tabBar->currentIndex()];
|
SceneContext *context = m_context[ui->tabBar->currentIndex()];
|
||||||
|
m_contextMutex.lock();
|
||||||
|
context->workUnits.clear();
|
||||||
if (context->renderJob) {
|
if (context->renderJob) {
|
||||||
context->cancelled = true;
|
context->cancelled = true;
|
||||||
context->renderJob->cancel();
|
ref<RenderJob> renderJob = context->renderJob;
|
||||||
|
m_contextMutex.unlock();
|
||||||
|
renderJob->cancel();
|
||||||
} else if (context->mode == ERender) {
|
} else if (context->mode == ERender) {
|
||||||
context->mode = EPreview;
|
context->mode = EPreview;
|
||||||
|
m_contextMutex.unlock();
|
||||||
}
|
}
|
||||||
ui->glView->resumePreview();
|
ui->glView->resumePreview();
|
||||||
|
|
||||||
|
@ -1370,6 +1377,7 @@ void MainWindow::onJobFinished(const RenderJob *job, bool cancelled) {
|
||||||
m_renderQueue->join();
|
m_renderQueue->join();
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
|
context->workUnits.clear();
|
||||||
if (cancelled) {
|
if (cancelled) {
|
||||||
if (!context->cancelled) {
|
if (!context->cancelled) {
|
||||||
QMessageBox::critical(this, tr("Error while rendering"),
|
QMessageBox::critical(this, tr("Error while rendering"),
|
||||||
|
@ -1427,15 +1435,30 @@ void MainWindow::onWorkBegin(const RenderJob *job, const RectangularWorkUnit *wu
|
||||||
SceneContext *context = getContext(job, false);
|
SceneContext *context = getContext(job, false);
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
|
VisualWorkUnit vwu;
|
||||||
|
/* This is not executed in the event loop -- take some precautions */
|
||||||
|
m_contextMutex.lock();
|
||||||
|
vwu.offset = wu->getOffset();
|
||||||
|
vwu.size = wu->getSize();
|
||||||
|
vwu.worker = worker;
|
||||||
|
context->workUnits.insert(vwu);
|
||||||
|
drawVisualWorkUnit(context, vwu);
|
||||||
|
bool isCurrentView = ui->tabBar->currentIndex() < m_context.size() &&
|
||||||
|
m_context[ui->tabBar->currentIndex()] == context;
|
||||||
|
m_contextMutex.unlock();
|
||||||
|
if (isCurrentView)
|
||||||
|
emit updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::drawVisualWorkUnit(SceneContext *context, const VisualWorkUnit &vwu) {
|
||||||
Film *film = context->scene->getFilm();
|
Film *film = context->scene->getFilm();
|
||||||
int ox = wu->getOffset().x - film->getCropOffset().x,
|
Point2i co = film->getCropOffset();
|
||||||
oy = wu->getOffset().y - film->getCropOffset().y,
|
int ox = vwu.offset.x - co.x, oy = vwu.offset.y - co.y,
|
||||||
ex = ox + wu->getSize().x, ey = oy + wu->getSize().y;
|
ex = ox + vwu.size.x, ey = oy + vwu.size.y;
|
||||||
const float *color = NULL;
|
const float *color = NULL;
|
||||||
|
|
||||||
/* Use desaturated colors to highlight the host
|
/* Use desaturated colors to highlight the host
|
||||||
responsible for rendering the current image block */
|
responsible for rendering the current image vwu */
|
||||||
const float white[] = { 1.0f, 1.0f, 1.0f };
|
const float white[] = { 1.0f, 1.0f, 1.0f };
|
||||||
const float red[] = { 1.0f, 0.3f, 0.3f };
|
const float red[] = { 1.0f, 0.3f, 0.3f };
|
||||||
const float green[] = { 0.3f, 1.0f, 0.3f };
|
const float green[] = { 0.3f, 1.0f, 0.3f };
|
||||||
|
@ -1445,7 +1468,7 @@ void MainWindow::onWorkBegin(const RenderJob *job, const RectangularWorkUnit *wu
|
||||||
const float magenta[] = { 1.0f, 0.3f, 1.0f };
|
const float magenta[] = { 1.0f, 0.3f, 1.0f };
|
||||||
const float turquoise[] = { 0.3f, 1.0f, 1.0f };
|
const float turquoise[] = { 0.3f, 1.0f, 1.0f };
|
||||||
|
|
||||||
switch (worker % 8) {
|
switch (vwu.worker % 8) {
|
||||||
case 1: color = green; break;
|
case 1: color = green; break;
|
||||||
case 2: color = yellow; break;
|
case 2: color = yellow; break;
|
||||||
case 3: color = blue; break;
|
case 3: color = blue; break;
|
||||||
|
@ -1459,7 +1482,7 @@ void MainWindow::onWorkBegin(const RenderJob *job, const RectangularWorkUnit *wu
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wu->getSize().x < 3 || wu->getSize().y < 3)
|
if (vwu.size.x < 3 || vwu.size.y < 3)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
drawHLine(context, ox, oy, ox + 3, color);
|
drawHLine(context, ox, oy, ox + 3, color);
|
||||||
|
@ -1470,23 +1493,14 @@ void MainWindow::onWorkBegin(const RenderJob *job, const RectangularWorkUnit *wu
|
||||||
drawVLine(context, ex - 1, oy, oy + 3, color);
|
drawVLine(context, ex - 1, oy, oy + 3, color);
|
||||||
drawVLine(context, ex - 1, ey - 4, ey - 1, color);
|
drawVLine(context, ex - 1, ey - 4, ey - 1, color);
|
||||||
drawVLine(context, ox, ey - 4, ey - 1, color);
|
drawVLine(context, ox, ey - 4, ey - 1, color);
|
||||||
|
|
||||||
/* This is not executed in the event loop -- take some precautions */
|
|
||||||
m_contextMutex.lock();
|
|
||||||
bool isCurrentView = ui->tabBar->currentIndex() < m_context.size() &&
|
|
||||||
m_context[ui->tabBar->currentIndex()] == context;
|
|
||||||
m_contextMutex.unlock();
|
|
||||||
if (isCurrentView)
|
|
||||||
emit updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_glView_loadFileRequest(const QString &string) {
|
|
||||||
loadFile(string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onWorkEnd(const RenderJob *job, const ImageBlock *block) {
|
void MainWindow::onWorkEnd(const RenderJob *job, const ImageBlock *block) {
|
||||||
int ox = block->getOffset().x, oy = block->getOffset().y,
|
int ox = block->getOffset().x, oy = block->getOffset().y,
|
||||||
ex = ox + block->getSize().x, ey = oy + block->getSize().y;
|
ex = ox + block->getSize().x, ey = oy + block->getSize().y;
|
||||||
|
VisualWorkUnit vwu;
|
||||||
|
vwu.offset = block->getOffset();
|
||||||
|
vwu.size = block->getSize();
|
||||||
SceneContext *context = getContext(job, false);
|
SceneContext *context = getContext(job, false);
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -1512,6 +1526,12 @@ void MainWindow::onWorkEnd(const RenderJob *job, const ImageBlock *block) {
|
||||||
m_contextMutex.lock();
|
m_contextMutex.lock();
|
||||||
bool isCurrentView = ui->tabBar->currentIndex() < m_context.size() &&
|
bool isCurrentView = ui->tabBar->currentIndex() < m_context.size() &&
|
||||||
m_context[ui->tabBar->currentIndex()] == context;
|
m_context[ui->tabBar->currentIndex()] == context;
|
||||||
|
if (context->workUnits.find(vwu) != context->workUnits.end()) {
|
||||||
|
context->workUnits.erase(vwu);
|
||||||
|
} else if (!context->cancelled) {
|
||||||
|
SLog(EWarn, "Internal error: unable to find previously scheduled"
|
||||||
|
" rectangular work unit.");
|
||||||
|
}
|
||||||
m_contextMutex.unlock();
|
m_contextMutex.unlock();
|
||||||
if (isCurrentView)
|
if (isCurrentView)
|
||||||
emit updateView();
|
emit updateView();
|
||||||
|
@ -1537,11 +1557,23 @@ void MainWindow::onRefresh(const RenderJob *job) {
|
||||||
fbOffset += 4;
|
fbOffset += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_context[ui->tabBar->currentIndex()] == context)
|
/* This is executed by worker threads -- take some precautions */
|
||||||
|
m_contextMutex.lock();
|
||||||
|
bool isCurrentView = ui->tabBar->currentIndex() < m_context.size() &&
|
||||||
|
m_context[ui->tabBar->currentIndex()] == context;
|
||||||
|
for (std::set<VisualWorkUnit, block_comparator>::const_iterator it =
|
||||||
|
context->workUnits.begin(); it != context->workUnits.end(); ++it)
|
||||||
|
drawVisualWorkUnit(context, *it);
|
||||||
|
m_contextMutex.unlock();
|
||||||
|
if (isCurrentView)
|
||||||
emit updateView();
|
emit updateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_glView_loadFileRequest(const QString &string) {
|
||||||
|
loadFile(string);
|
||||||
|
}
|
||||||
|
|
||||||
bool ServerConnection::createWorker(QWidget *parent) {
|
bool ServerConnection::createWorker(QWidget *parent) {
|
||||||
ref<Stream> stream;
|
ref<Stream> stream;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -94,6 +94,7 @@ protected:
|
||||||
SceneContext *getContext(const RenderJob *job, bool failIfNotFound = true);
|
SceneContext *getContext(const RenderJob *job, bool failIfNotFound = true);
|
||||||
void drawHLine(SceneContext *ctx, int x1, int y, int x2, const float *color);
|
void drawHLine(SceneContext *ctx, int x1, int y, int x2, const float *color);
|
||||||
void drawVLine(SceneContext *ctx, int x, int y1, int y2, const float *color);
|
void drawVLine(SceneContext *ctx, int x, int y1, int y2, const float *color);
|
||||||
|
void drawVisualWorkUnit(SceneContext *context, const VisualWorkUnit &block);
|
||||||
void checkForUpdates(bool notifyIfNone = false);
|
void checkForUpdates(bool notifyIfNone = false);
|
||||||
void saveAs(SceneContext *ctx, const QString &targetFile);
|
void saveAs(SceneContext *ctx, const QString &targetFile);
|
||||||
QSize sizeHint() const;
|
QSize sizeHint() const;
|
||||||
|
|
Loading…
Reference in New Issue