mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-10 21:44:22 +00:00
Use app::Task instead of raw threads on FilterPreview
We can use a thread pool (avoid creating/destroying threads) and we can continue the same task running when the filter restart (there is no need to stop/wait and restart, because the filter task keeps calling the applyStep() function anyway).
This commit is contained in:
parent
2369f36322
commit
87075296ed
2
laf
2
laf
@ -1 +1 @@
|
|||||||
Subproject commit 41476b78d001b82a72cc6556164bc20954d75636
|
Subproject commit 41822911e4091503bf22071a5ce579c2e03d52eb
|
@ -21,8 +21,6 @@
|
|||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
#include "ui/widget.h"
|
#include "ui/widget.h"
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
@ -32,8 +30,6 @@ FilterPreview::FilterPreview(FilterManagerImpl* filterMgr)
|
|||||||
: Widget(kGenericWidget)
|
: Widget(kGenericWidget)
|
||||||
, m_filterMgr(filterMgr)
|
, m_filterMgr(filterMgr)
|
||||||
, m_timer(1, this)
|
, m_timer(1, this)
|
||||||
, m_filterThread(nullptr)
|
|
||||||
, m_filterIsDone(false)
|
|
||||||
{
|
{
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}
|
}
|
||||||
@ -67,27 +63,32 @@ void FilterPreview::stop()
|
|||||||
ASSERT(m_filterMgr);
|
ASSERT(m_filterMgr);
|
||||||
m_filterMgr->end();
|
m_filterMgr->end();
|
||||||
}
|
}
|
||||||
|
m_timer.stop();
|
||||||
}
|
}
|
||||||
|
if (m_filterTask.running()) {
|
||||||
m_timer.stop();
|
m_filterTask.cancel();
|
||||||
|
m_filterTask.wait();
|
||||||
if (m_filterThread) {
|
|
||||||
m_filterThread->join();
|
|
||||||
m_filterThread.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterPreview::restartPreview()
|
void FilterPreview::restartPreview()
|
||||||
{
|
{
|
||||||
stop();
|
|
||||||
|
|
||||||
std::scoped_lock lock(m_filterMgrMutex);
|
std::scoped_lock lock(m_filterMgrMutex);
|
||||||
|
|
||||||
|
// Restart filter, timer, and task if needed (there is no need to
|
||||||
|
// restart the task if it's already running)
|
||||||
|
if (m_timer.isRunning()) {
|
||||||
|
ASSERT(m_filterMgr);
|
||||||
|
m_filterMgr->end();
|
||||||
|
}
|
||||||
m_filterMgr->beginForPreview();
|
m_filterMgr->beginForPreview();
|
||||||
m_filterIsDone = false;
|
|
||||||
m_timer.start();
|
m_timer.start();
|
||||||
m_filterThread.reset(
|
|
||||||
new std::thread([this]{ onFilterThread(); }));
|
if (!m_filterTask.running()) {
|
||||||
|
m_filterTask.run([this](base::task_token& token){
|
||||||
|
onFilterTask(token);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilterPreview::onProcessMessage(Message* msg)
|
bool FilterPreview::onProcessMessage(Message* msg)
|
||||||
@ -112,7 +113,7 @@ bool FilterPreview::onProcessMessage(Message* msg)
|
|||||||
std::scoped_lock lock(m_filterMgrMutex);
|
std::scoped_lock lock(m_filterMgrMutex);
|
||||||
if (m_filterMgr) {
|
if (m_filterMgr) {
|
||||||
m_filterMgr->flush();
|
m_filterMgr->flush();
|
||||||
if (m_filterIsDone)
|
if (m_filterTask.completed())
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -123,14 +124,13 @@ bool FilterPreview::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is executed in other thread.
|
// This is executed in other thread.
|
||||||
void FilterPreview::onFilterThread()
|
void FilterPreview::onFilterTask(base::task_token& token)
|
||||||
{
|
{
|
||||||
bool running = true;
|
while (!token.canceled()) {
|
||||||
while (running) {
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(m_filterMgrMutex);
|
std::scoped_lock lock(m_filterMgrMutex);
|
||||||
m_filterIsDone = !m_filterMgr->applyStep();
|
if (!m_filterMgr->applyStep())
|
||||||
running = (!m_filterIsDone && m_timer.isRunning());
|
token.cancel();
|
||||||
}
|
}
|
||||||
base::this_thread::yield();
|
base::this_thread::yield();
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
#define APP_COMMANDS_FILTERS_FILTER_PREVIEW_H_INCLUDED
|
#define APP_COMMANDS_FILTERS_FILTER_PREVIEW_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "app/task.h"
|
||||||
#include "ui/timer.h"
|
#include "ui/timer.h"
|
||||||
#include "ui/widget.h"
|
#include "ui/widget.h"
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
@ -34,12 +34,12 @@ namespace app {
|
|||||||
bool onProcessMessage(ui::Message* msg) override;
|
bool onProcessMessage(ui::Message* msg) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onFilterThread();
|
void onFilterTask(base::task_token& token);
|
||||||
|
|
||||||
FilterManagerImpl* m_filterMgr;
|
FilterManagerImpl* m_filterMgr;
|
||||||
ui::Timer m_timer;
|
ui::Timer m_timer;
|
||||||
std::mutex m_filterMgrMutex;
|
std::mutex m_filterMgrMutex;
|
||||||
std::unique_ptr<std::thread> m_filterThread;
|
app::Task m_filterTask;
|
||||||
bool m_filterIsDone;
|
bool m_filterIsDone;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user