Просмотр исходного кода

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.
kleines Filmröllchen 3 лет назад
Родитель
Сommit
5294fd671e

+ 5 - 5
Userland/Applications/PixelPaint/Filters/Filter.cpp

@@ -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()

+ 4 - 0
Userland/Applications/PixelPaint/Filters/Filter.h

@@ -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;

+ 1 - 1
Userland/Applications/PixelPaint/ImageProcessor.cpp

@@ -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()));
     });
 }