Serenity Operating System
at master 67 lines 2.2 kB view raw
1/* 2 * Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "ImageProcessor.h" 8 9namespace PixelPaint { 10 11FilterApplicationCommand::FilterApplicationCommand(NonnullRefPtr<Filter> filter, NonnullRefPtr<Layer> target_layer) 12 : m_filter(move(filter)) 13 , m_target_layer(move(target_layer)) 14{ 15} 16 17void FilterApplicationCommand::execute() 18{ 19 m_filter->apply(m_target_layer->get_scratch_edited_bitmap(), m_target_layer->get_scratch_edited_bitmap()); 20 m_filter->m_editor->gui_event_loop().deferred_invoke([strong_this = NonnullRefPtr(*this)]() { 21 // HACK: we can't tell strong_this to not be const 22 (*const_cast<NonnullRefPtr<Layer>*>(&strong_this->m_target_layer))->did_modify_bitmap(strong_this->m_target_layer->rect()); 23 strong_this->m_filter->m_editor->did_complete_action(DeprecatedString::formatted("Filter {}", strong_this->m_filter->filter_name())); 24 }); 25} 26 27static Singleton<ImageProcessor> s_image_processor; 28 29ImageProcessor::ImageProcessor() 30 : m_command_queue(MUST(Queue::create())) 31 , m_processor_thread(Threading::Thread::construct([this]() { 32 while (true) { 33 if (auto next_command = m_command_queue.dequeue(); !next_command.is_error()) { 34 next_command.value()->execute(); 35 } else { 36 Threading::MutexLocker locker { m_wakeup_mutex }; 37 m_wakeup_variable.wait_while([this]() { return m_command_queue.weak_used() == 0; }); 38 } 39 } 40 return 0; 41 }, 42 "Image Processor"sv)) 43 , m_wakeup_variable(m_wakeup_mutex) 44{ 45} 46 47ImageProcessor* ImageProcessor::the() 48{ 49 return s_image_processor; 50} 51 52ErrorOr<void> ImageProcessor::enqueue_command(NonnullRefPtr<ImageProcessingCommand> command) 53{ 54 if (auto queue_status = m_command_queue.enqueue(move(command)); queue_status.is_error()) 55 return ENOSPC; 56 57 if (!m_processor_thread->is_started()) { 58 m_processor_thread->start(); 59 m_processor_thread->detach(); 60 } 61 62 Threading::MutexLocker const locker(m_wakeup_mutex); 63 m_wakeup_variable.signal(); 64 return {}; 65} 66 67}