MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
BufferUtils.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Buffers {
6
7/**
8 * @enum TokenEnforcementStrategy
9 * @brief Defines how strictly processing token requirements are enforced in buffer processing chains
10 *
11 * TokenEnforcementStrategy provides different levels of flexibility for handling processor-buffer
12 * compatibility based on processing tokens. This allows the system to balance performance optimization
13 * with operational flexibility depending on the application's requirements.
14 *
15 * The enforcement strategy affects how BufferProcessingChain handles processors with incompatible
16 * tokens, ranging from strict validation to complete flexibility. This enables different operational
17 * modes for development, production, and specialized processing scenarios.
18 */
20 /**
21 * @brief Strictly enforces token assignment with no cross-token sharing
22 *
23 * Processors must exactly match the buffer's processing token requirements.
24 * Any incompatibility results in immediate rejection. This provides maximum
25 * performance optimization by ensuring all processors in a chain can execute
26 * with the same backend configuration, but offers the least flexibility.
27 */
28 STRICT,
29
30 /**
31 * @brief Filters processors through token enumeration, allowing compatible combinations
32 *
33 * Uses the are_tokens_compatible() function to determine if processors can work
34 * together despite different token assignments. This allows some flexibility while
35 * maintaining performance optimization for compatible processor combinations.
36 * Incompatible processors are filtered out rather than rejected outright.
37 */
39
40 /**
41 * @brief Allows token overrides but skips processing for incompatible operations
42 *
43 * Permits processors with different tokens to be added to processing chains,
44 * but skips their execution when the tokens are incompatible. This maintains
45 * chain integrity while allowing dynamic processor management. Useful for
46 * conditional processing scenarios where not all processors need to execute.
47 */
49
50 /**
51 * @brief Allows token overrides but rejects incompatible processors from chains
52 *
53 * Similar to OVERRIDE_SKIP but removes incompatible processors from the chain
54 * entirely rather than skipping them. This provides a middle ground between
55 * flexibility and performance by cleaning up incompatible processors while
56 * allowing initial token mismatches during chain construction.
57 */
59
60 /**
61 * @brief Ignores token assignments completely, allowing any processing combination
62 *
63 * Disables all token validation and compatibility checking. Any processor can
64 * be added to any buffer's processing chain regardless of token compatibility.
65 * This provides maximum flexibility but may result in suboptimal performance
66 * or execution errors. Primarily useful for debugging or specialized scenarios.
67 */
68 IGNORE
69};
70
71/**
72 * @brief Validates that a processing token has a valid, non-conflicting configuration
73 * @param token Processing token to validate
74 * @throws std::invalid_argument if the token contains mutually exclusive flags
75 *
76 * This function ensures that processing tokens contain only compatible flag combinations.
77 * It validates three key mutual exclusions that are fundamental to the processing model:
78 *
79 * **Rate Mutual Exclusion**: SAMPLE_RATE and FRAME_RATE cannot be combined as they
80 * represent fundamentally different temporal processing models that cannot be executed
81 * simultaneously within the same processing context.
82 *
83 * **Device Mutual Exclusion**: CPU_PROCESS and GPU_PROCESS cannot be combined as they
84 * represent different execution environments that require different resource allocation
85 * and execution strategies.
86 *
87 * **Concurrency Mutual Exclusion**: SEQUENTIAL and PARALLEL cannot be combined as they
88 * represent incompatible execution patterns that would create undefined behavior in
89 * processing chains.
90 *
91 * This validation is essential for maintaining system stability and ensuring that
92 * processing tokens represent achievable execution configurations.
93 */
95{
96 if ((token & SAMPLE_RATE) && (token & FRAME_RATE)) {
97 throw std::invalid_argument("SAMPLE_RATE and FRAME_RATE are mutually exclusive.");
98 }
99
100 if ((token & CPU_PROCESS) && (token & GPU_PPOCESS)) {
101 throw std::invalid_argument("CPU_PROCESS and GPU_PROCESS are mutually exclusive.");
102 }
103
104 if ((token & SEQUENTIAL) && (token & PARALLEL)) {
105 throw std::invalid_argument("SEQUENTIAL and PARALLEL are mutually exclusive.");
106 }
107}
108
109/**
110 * @brief Determines if two processing tokens are compatible for joint execution
111 * @param preferred The preferred processing token configuration
112 * @param current The current processing token configuration being evaluated
113 * @return true if the tokens are compatible, false otherwise
114 *
115 * This function implements sophisticated compatibility logic that goes beyond simple equality
116 * checking to determine if processors with different token requirements can work together
117 * in the same processing pipeline. The compatibility rules are designed to maximize
118 * processing flexibility while maintaining system stability and performance.
119 *
120 * **Rate Compatibility Rules:**
121 * - FRAME_RATE processors require FRAME_RATE execution contexts (strict requirement)
122 * - SAMPLE_RATE processors can adapt to FRAME_RATE contexts (flexible upward compatibility)
123 * - Same-rate combinations are always compatible
124 *
125 * **Device Compatibility Rules:**
126 * - SAMPLE_RATE processing cannot execute on GPU hardware (hardware limitation)
127 * - GPU-preferred processors cannot fall back to CPU execution (performance requirement)
128 * - CPU-preferred processors can use GPU for FRAME_RATE processing only
129 *
130 * **Concurrency Compatibility Rules:**
131 * - Sequential/Parallel differences are acceptable if rate requirements align
132 * - Mismatched concurrency with incompatible rates is rejected
133 * - Same concurrency patterns are always compatible
134 *
135 * This flexibility enables the system to optimize processing chains by allowing compatible
136 * processors to share execution contexts while preventing configurations that would result
137 * in poor performance or execution failures.
138 */
140{
141 bool preferred_sample = preferred & SAMPLE_RATE;
142 bool preferred_frame = preferred & FRAME_RATE;
143 bool current_sample = current & SAMPLE_RATE;
144 bool current_frame = current & FRAME_RATE;
145
146 // If preferred is FRAME_RATE, only FRAME_RATE is compatible
147 if (preferred_frame && !current_frame)
148 return false;
149 // If preferred is SAMPLE_RATE, FRAME_RATE can be compatible (sample can "delay" to frame)
150 if (preferred_sample && current_frame)
151 return true;
152 // If both are SAMPLE_RATE or both are FRAME_RATE, compatible
153 if ((preferred_sample && current_sample) || (preferred_frame && current_frame))
154 return true;
155
156 // Device compatibility: SAMPLE_RATE can't run on GPU, but FRAME_RATE can run on CPU
157 bool preferred_cpu = preferred & CPU_PROCESS;
158 bool preferred_gpu = preferred & GPU_PPOCESS;
159 bool current_cpu = current & CPU_PROCESS;
160 bool current_gpu = current & GPU_PPOCESS;
161
162 if (preferred_sample && current_gpu)
163 return false; // Can't run sample rate on GPU
164 if (preferred_gpu && current_cpu)
165 return false; // If preferred is GPU, but current is CPU, not compatible
166 // If preferred is CPU, but current is GPU, allow only for FRAME_RATE
167 if (preferred_cpu && current_gpu && !current_frame)
168 return false;
169
170 // Sequential/Parallel compatibility: allow if rates align
171 bool preferred_seq = preferred & SEQUENTIAL;
172 bool preferred_par = preferred & PARALLEL;
173 bool current_seq = current & SEQUENTIAL;
174 bool current_par = current & PARALLEL;
175
176 if ((preferred_seq && current_par) || (preferred_par && current_seq)) {
177 // Allow if rates align (already checked above)
178 if ((preferred_sample && current_sample) || (preferred_frame && current_frame))
179 return true;
180 // If preferred is SAMPLE_RATE and current is FRAME_RATE, already handled above
181 // Otherwise, not compatible
182 return false;
183 }
184
185 // If all checks pass, compatible
186 return true;
187}
188
189/**
190 * @brief Gets the optimal processing token for a given buffer type and system configuration
191 * @param buffer_type Type identifier for the buffer (e.g., "audio", "video", "texture")
192 * @param system_capabilities Available system capabilities (GPU, multi-core CPU, etc.)
193 * @return Recommended processing token for optimal performance
194 *
195 * This function analyzes buffer characteristics and system capabilities to recommend
196 * the most appropriate processing token configuration. It considers factors like:
197 * - Buffer data type and size characteristics
198 * - Available hardware acceleration
199 * - System performance characteristics
200 * - Current system load and resource availability
201 *
202 * The recommendations help achieve optimal performance by matching processing
203 * requirements with available system capabilities.
204 */
205inline ProcessingToken get_optimal_token(const std::string& buffer_type, uint32_t system_capabilities)
206{
207 // Implementation would analyze buffer type and system capabilities
208 // This is a placeholder for the actual optimization logic
209 if (buffer_type == "audio") {
210 return (system_capabilities & 0x1) ? AUDIO_PARALLEL : AUDIO_BACKEND;
211 } else if (buffer_type == "video" || buffer_type == "texture") {
212 return GRAPHICS_BACKEND;
213 }
214 return AUDIO_BACKEND; // Safe default
215}
216
217}
218
219namespace std {
220template <>
221struct hash<std::pair<MayaFlux::Buffers::ProcessingToken, MayaFlux::Buffers::ProcessingToken>> {
222 size_t operator()(const std::pair<MayaFlux::Buffers::ProcessingToken, MayaFlux::Buffers::ProcessingToken>& pair) const
223 {
224 return hash<uint32_t>()(static_cast<uint32_t>(pair.first)) ^ (hash<uint32_t>()(static_cast<uint32_t>(pair.second)) << 1);
225 }
226};
227}
static MayaFlux::Nodes::ProcessingToken token
Definition Timers.cpp:8
bool are_tokens_compatible(ProcessingToken preferred, ProcessingToken current)
Determines if two processing tokens are compatible for joint execution.
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
@ SAMPLE_RATE
Processes data at audio sample rate with buffer-sized chunks.
@ CPU_PROCESS
Executes processing operations on CPU threads.
@ AUDIO_BACKEND
Standard audio processing backend configuration.
@ PARALLEL
Processes operations in parallel when possible.
@ SEQUENTIAL
Processes operations sequentially, one after another.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
@ FRAME_RATE
Processes data at video frame rate.
@ GPU_PPOCESS
Executes processing operations on GPU hardware.
@ AUDIO_PARALLEL
High-performance audio processing with GPU acceleration.
TokenEnforcementStrategy
Defines how strictly processing token requirements are enforced in buffer processing chains.
@ OVERRIDE_SKIP
Allows token overrides but skips processing for incompatible operations.
@ STRICT
Strictly enforces token assignment with no cross-token sharing.
@ OVERRIDE_REJECT
Allows token overrides but rejects incompatible processors from chains.
@ FILTERED
Filters processors through token enumeration, allowing compatible combinations.
@ IGNORE
Ignores token assignments completely, allowing any processing combination.
void validate_token(ProcessingToken token)
Validates that a processing token has a valid, non-conflicting configuration.
ProcessingToken get_optimal_token(const std::string &buffer_type, uint32_t system_capabilities)
Gets the optimal processing token for a given buffer type and system configuration.
size_t operator()(const std::pair< MayaFlux::Buffers::ProcessingToken, MayaFlux::Buffers::ProcessingToken > &pair) const