PixelPaint: Use the parallel ImageProcessor to apply filters

The main advantage of this change is that heavy-weight filters do not
lock up the GUI anymore.

This first cut has several flaws:
- We do not account for modification of the referenced images while the
  filter is running. Depending on the exact filter behavior this might
  have all sorts of weird effects. A simple fix would be to show a
  progress dialog to the user, preventing them from performing other
  modifications in the meantime.
- We do not use the image processor for previews. Preview behavior has a
  couple of other considerations that are intentionally not addressed in
  this commit or pull request.
This commit is contained in:
kleines Filmröllchen 2022-08-13 13:07:53 +02:00 committed by Sam Atkins
parent ade868aa56
commit 5294fd671e
Notes: sideshowbarker 2024-07-17 06:37:03 +09:00
3 changed files with 10 additions and 6 deletions

View file

@ -6,6 +6,7 @@
*/
#include "Filter.h"
#include "../ImageProcessor.h"
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Label.h>
@ -40,11 +41,10 @@ void Filter::apply() const
{
if (!m_editor)
return;
if (auto* layer = m_editor->active_layer()) {
apply(layer->content_bitmap(), layer->content_bitmap());
layer->did_modify_bitmap(layer->rect());
m_editor->did_complete_action(String::formatted("Filter {}", filter_name()));
}
// FIXME: I am not thread-safe!
// If you try to edit the bitmap while the image processor is still running... :yaksplode:
if (auto* layer = m_editor->active_layer())
MUST(ImageProcessor::the()->enqueue_command(make_ref_counted<FilterApplicationCommand>(*this, *layer)));
}
void Filter::update_preview()

View file

@ -13,7 +13,11 @@
namespace PixelPaint {
class FilterApplicationCommand;
class Filter : public RefCounted<Filter> {
friend class FilterApplicationCommand;
public:
virtual void apply() const;
virtual void apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap) const = 0;

View file

@ -20,7 +20,7 @@ void FilterApplicationCommand::execute()
m_filter->m_editor->gui_event_loop().deferred_invoke([strong_this = NonnullRefPtr(*this)]() {
// HACK: we can't tell strong_this to not be const
(*const_cast<NonnullRefPtr<Layer>*>(&strong_this->m_target_layer))->did_modify_bitmap(strong_this->m_target_layer->rect());
strong_this->m_filter->m_editor->did_complete_action();
strong_this->m_filter->m_editor->did_complete_action(String::formatted("Filter {}", strong_this->m_filter->filter_name()));
});
}