CaptureMoment 0.1.0
Free and open-source non-destructive photo editor
Loading...
Searching...
No Matches
pipeline_halide_operation_manager.cpp
Go to the documentation of this file.
1
9
10#include <spdlog/spdlog.h>
11
13
15 : m_operation_factory(std::make_unique<Operations::OperationFactory>())
16{
17 // Register all available operations (Concrete Creators)
19 spdlog::debug("PipelineHalideOperationManager: Constructed with Pipeline and Worker contexts.");
20
22
23 if (!base_executor) {
24 spdlog::error("PipelineHalideOperationManager::PipelineHalideOperationManager: Builder returned null.");
25 return;
26 }
27
28 // Downcasting to the concrete type. This is safe because we know the builder returns the correct type for this pipeline.
29 auto* concrete_ptr { dynamic_cast<Pipeline::OperationPipelineExecutor*>(base_executor.get()) };
30
31 if (!concrete_ptr) {
32 spdlog::error("PipelineHalideOperationManager::PipelineHalideOperationManager: Critical type mismatch.");
33 return;
34 }
35
36 // Release ownership from base_executor and transfer to m_executor
37 base_executor.release();
38 m_executor.reset(concrete_ptr);
39}
40
41void PipelineHalideOperationManager::init(std::vector<Operations::OperationDescriptor>&& operations)
42{
43 // 1. Detect structural changes (type, name, enabled) vs value changes (params)
44 bool structure_changed { true };
45
46 spdlog::debug("[PipelineHalideOperationManager::init]: m_last_operations.size() = {}, operations.size() = {}",
47 m_last_operations.size(), operations.size());
48
49 if (m_last_operations.size() == operations.size()) {
50 structure_changed = false;
51 for (size_t i = 0; i < operations.size(); ++i)
52 {
53
54 // Compare type, name, enabled. Ignore params for this check.
55 spdlog::debug("[PipelineHalideOperationManager::init]: Op[{}]: | last=({},{}) | new=({},{})",
56 operations[i].id,m_last_operations[i].name, m_last_operations[i].enabled, operations[i].name, operations[i].enabled);
57
58 if (operations[i].id != m_last_operations[i].id ||
59 operations[i].enabled != m_last_operations[i].enabled) {
60 structure_changed = true;
61 spdlog::debug("[PipelineHalideOperationManager::init]: Structure change detected at index {}", i);
62 break;
63 }
64 }
65 }
66 spdlog::debug("[PipelineHalideOperationManager::init]: structure_changed = {}", structure_changed);
67
68 // 2. Update the cache with the new operations (for future structural change detection)
69 // This should be done before the lock to minimize time spent in critical section, as it's just a vector copy.
70 // Note: We are moving the operations into the cache, which is fine because we will move it again into the executor if structure changed.
71 m_last_operations = operations;
72
73 // 3. Lock and update the executor based on whether the structure changed or not.
74 std::lock_guard lock(m_mutex);
75
76 if (structure_changed) {
77 spdlog::info("[PipelineHalideOperationManager::init]: Structure changed. Recompiling pipeline.");
78 // If the structure changed, we need to recompile the pipeline, which is more expensive. We call init() which will rebuild the graph and recompile.
79 m_executor->init(std::move(operations), *m_operation_factory);
80 } else {
81 spdlog::trace("[PipelineHalideOperationManager::init]: Values only. Updating runtime params.");
82 // If only values changed, we can skip recompilation and just update the parameters in the existing pipeline. This is the fast path.
83 m_executor->updateRuntimeParams(std::move(operations));
84 }
85}
86
88{
89 std::lock_guard lock(m_mutex);
90
91 if (!m_executor) {
92 spdlog::debug("[PipelineHalideOperationManager::execute]: error call m_executor->execute");
93 return false;
94 }
95
96 spdlog::debug("[PipelineHalideOperationManager::execute]: call m_executor->execute");
97 return m_executor->execute(working_image);
98}
99
100} // namespace CaptureMoment::Core::Strategies
Abstract interface representing an image used as a working buffer.
static void registerAll(OperationFactory &factory)
Register all available operations.
Concrete executor for fused Halide adjustment pipelines.
static std::unique_ptr< IPipelineExecutor > build(PipelineType type)
Retrieves an instance of the executor for the specified type.
void init(std::vector< Operations::OperationDescriptor > &&operations)
Initializes the manager with a new list of operations (Thread-Safe).
virtual bool execute(ImageProcessing::IWorkingImageHardware &working_image) override
Executes the Halide pipeline on the image (Thread-Safe).
@ HalideOperation
Halide-based pipeline for fused pixel operations (Brightness, Contrast, etc.).
Concrete manager for Halide-based adjustment operations.
CaptureMoment — footer