mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 20:18:12 +00:00
PixelPaint: Add a general-purpose parallel image processing pipeline
The ImageProcessor singleton is intended to be used by all sorts of image processing which might take some time to complete; or other background actions. We're not using BackgroundTask here because this system is specifically designed to work with task queues and PixelPaint interaction; e.g. it provides common image processing tasks such as filter application.
This commit is contained in:
parent
9483adee46
commit
ade868aa56
3 changed files with 146 additions and 0 deletions
76
Userland/Applications/PixelPaint/ImageProcessor.h
Normal file
76
Userland/Applications/PixelPaint/ImageProcessor.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Filters/Filter.h"
|
||||
#include <AK/Function.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/Singleton.h>
|
||||
#include <LibCore/SharedCircularQueue.h>
|
||||
#include <LibThreading/ConditionVariable.h>
|
||||
#include <LibThreading/Thread.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
|
||||
class ImageProcessingCommand : public RefCounted<ImageProcessingCommand> {
|
||||
public:
|
||||
virtual void execute() = 0;
|
||||
virtual ~ImageProcessingCommand() = default;
|
||||
};
|
||||
|
||||
// A command applying a filter from a source to a target bitmap.
|
||||
class FilterApplicationCommand : public ImageProcessingCommand {
|
||||
public:
|
||||
FilterApplicationCommand(NonnullRefPtr<Filter>, NonnullRefPtr<Layer>);
|
||||
|
||||
virtual void execute() override;
|
||||
virtual ~FilterApplicationCommand() = default;
|
||||
|
||||
private:
|
||||
NonnullRefPtr<Filter> m_filter;
|
||||
NonnullRefPtr<Layer> m_target_layer;
|
||||
};
|
||||
|
||||
// A command based on a custom user function.
|
||||
class FunctionCommand : public ImageProcessingCommand {
|
||||
public:
|
||||
FunctionCommand(Function<void()> function)
|
||||
: m_function(move(function))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute() override { m_function(); }
|
||||
|
||||
private:
|
||||
Function<void()> m_function;
|
||||
};
|
||||
|
||||
// A utility class that allows various PixelPaint systems to execute image processing commands asynchronously on another thread.
|
||||
class ImageProcessor final {
|
||||
friend struct AK::SingletonInstanceCreator<ImageProcessor>;
|
||||
|
||||
public:
|
||||
static ImageProcessor* the();
|
||||
|
||||
ErrorOr<void> enqueue_command(NonnullRefPtr<ImageProcessingCommand> command);
|
||||
|
||||
private:
|
||||
ImageProcessor();
|
||||
void processor_main();
|
||||
|
||||
// Only the memory in the queue is in shared memory, i.e. the smart pointers themselves.
|
||||
// The actual data will remain in normal memory, but for this application we're not using multiple processes so it's fine.
|
||||
using Queue = Core::SharedSingleProducerCircularQueue<RefPtr<ImageProcessingCommand>>;
|
||||
Queue m_command_queue;
|
||||
|
||||
NonnullRefPtr<Threading::Thread> m_processor_thread;
|
||||
Threading::Mutex m_wakeup_mutex {};
|
||||
Threading::ConditionVariable m_wakeup_variable;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue