64 const std::shared_ptr<Core::VKImage>&
image,
74 [[nodiscard]] uint32_t
get_layer_count()
const {
return static_cast<uint32_t
>(m_data.size()); }
88 void from_image(
const std::shared_ptr<Core::VKImage>&
image, uint32_t layer = 0);
104 const std::shared_ptr<Core::VKImage>&
image,
105 const std::shared_ptr<Buffers::VKBuffer>& staging,
118 void from_image_array(
const std::shared_ptr<Core::VKImage>&
image);
134 void from_image_array(
135 const std::shared_ptr<Core::VKImage>&
image,
136 const std::shared_ptr<Buffers::VKBuffer>& staging);
148 [[nodiscard]] std::shared_ptr<Core::VKImage> to_image(uint32_t layer = 0)
const;
160 [[nodiscard]] std::shared_ptr<Core::VKImage> to_image(
162 const std::shared_ptr<Buffers::VKBuffer>& staging)
const;
178 [[nodiscard]] std::shared_ptr<Core::VKImage> to_image_array()
const;
196 [[nodiscard]] std::shared_ptr<Core::VKImage> to_image_array(
197 const std::shared_ptr<Buffers::VKBuffer>& staging)
const;
213 const std::shared_ptr<Core::VKImage>&
image,
215 const std::shared_ptr<Buffers::VKBuffer>& staging)
const;
230 bool upload_image_array(
231 const std::shared_ptr<Core::VKImage>&
image,
232 const std::shared_ptr<Buffers::VKBuffer>& staging)
const;
249 [[nodiscard]] std::span<const uint8_t> pixel_bytes(uint32_t layer = 0)
const;
255 [[nodiscard]] std::span<uint8_t> pixel_bytes(uint32_t layer = 0);
261 [[nodiscard]] std::span<const uint8_t> as_uint8(uint32_t layer = 0)
const;
270 [[nodiscard]] std::span<const uint16_t> as_uint16(uint32_t layer = 0)
const;
276 [[nodiscard]] std::span<const float> as_float(uint32_t layer = 0)
const;
283 void set_pixels(std::span<const uint8_t> data, uint32_t layer = 0);
291 void set_pixels(std::span<const uint16_t> data, uint32_t layer = 0);
299 void set_pixels(std::span<const float> data, uint32_t layer = 0);
321 [[nodiscard]] uint32_t
get_width()
const {
return m_width; }
322 [[nodiscard]] uint32_t
get_height()
const {
return m_height; }
327 [[nodiscard]]
size_t row_stride()
const {
return static_cast<size_t>(m_width) * m_bpp; }
330 [[nodiscard]]
size_t byte_size()
const {
return static_cast<size_t>(m_width) * m_height * m_bpp; }
336 [[nodiscard]] std::vector<DataDimension> get_dimensions()
const override;
337 [[nodiscard]] uint64_t get_total_elements()
const override;
338 [[nodiscard]]
MemoryLayout get_memory_layout()
const override;
340 [[nodiscard]] uint64_t get_frame_size()
const override;
341 [[nodiscard]] uint64_t get_num_frames()
const override;
343 [[nodiscard]] std::vector<DataVariant> get_region_data(
const Region& region)
const override;
344 [[nodiscard]] std::vector<DataVariant> get_segments_data(
345 const std::vector<RegionSegment>& segments)
const override;
348 [[nodiscard]] std::type_index value_element_type()
const override;
349 [[nodiscard]] uint64_t coordinates_to_linear_index(
const std::vector<uint64_t>&
coords)
const override;
350 [[nodiscard]] std::vector<uint64_t> linear_index_to_coordinates(uint64_t
index)
const override;
351 void clear()
override;
367 void set_region_data(
const Region& region,
368 const std::vector<DataVariant>& data)
override;
372 void register_state_change_callback(
373 std::function<
void(
const std::shared_ptr<SignalSourceContainer>&,
ProcessingState)> cb)
override;
374 void unregister_state_change_callback()
override;
376 [[nodiscard]]
bool is_ready_for_processing()
const override;
377 void mark_ready_for_processing(
bool ready)
override;
379 [[nodiscard]] std::vector<DataVariant>& get_processed_data()
override;
380 [[nodiscard]]
const std::vector<DataVariant>& get_processed_data()
const override;
381 [[nodiscard]]
const std::vector<DataVariant>& get_data()
override;
389 [[nodiscard]]
DataAccess channel_data(
size_t channel_index)
override;
390 [[nodiscard]] std::vector<DataAccess> all_channel_data()
override;
401 [[nodiscard]] std::unordered_map<std::string, RegionGroup> get_all_region_groups()
const override;
404 [[nodiscard]]
const void* get_raw_data()
const override;
405 [[nodiscard]]
bool has_data()
const override;
415 return m_processing_token.compare_exchange_strong(expected, ch);
419 return m_processing_token.load() == ch;
430 std::shared_ptr<DataProcessingChain> get_processing_chain()
override;
479 uint32_t append_image_layer(std::shared_ptr<Core::VKImage>
image);
485 [[nodiscard]] std::shared_ptr<Core::VKImage> layer_image(uint32_t layer)
const;
494 void hold_layer(uint32_t layer);
498 return get_frame_typed(frame_index);
501 void get_frames_impl(
void* output,
size_t count, uint64_t start_frame, uint64_t num_frames,
const std::type_info&
type)
const override;
503 void get_value_impl(
const std::vector<uint64_t>&
coords,
504 void*
out,
const std::type_info&
type)
const override;
506 void set_value_impl(
const std::vector<uint64_t>&
coords,
507 const void* in,
const std::type_info&
type)
override;
510 void setup_dimensions();
513 uint32_t m_height {};
515 uint32_t m_channels {};
534 std::atomic<ProcessingState> m_processing_state { ProcessingState::IDLE };
535 std::atomic<bool> m_ready_for_processing {
false };
536 std::atomic<int> m_processing_token { -1 };
548 [[nodiscard]] std::shared_ptr<Core::VKImage> cached_layer_image(
549 uint32_t layer,
const std::shared_ptr<Buffers::VKBuffer>& staging)
const;
550 [[nodiscard]] std::shared_ptr<Core::VKImage> cached_array_image(
551 const std::shared_ptr<Buffers::VKBuffer>& staging)
const;
554 void ensure_cpu(uint32_t layer)
const;
555 void ensure_cpu_all()
const;
558 void claim_cpu(uint32_t layer);
560 [[nodiscard]]
auto get_frame_typed(uint64_t frame_index)
const ->
DataSpanVariant;
561 void get_frames_typed(
void* output,
size_t count, uint64_t start_frame, uint64_t num_frames,
const std::type_info&
type)
const;
563 template <
typename T>
564 [[nodiscard]]
auto get_frame_typed_as(uint64_t frame_index)
const -> std::span<const T>;
566 template <
typename T>
567 void get_frames_typed_as(std::span<T> output, uint64_t start_frame, uint64_t num_frames)
const;
void set_processing_chain(const std::shared_ptr< DataProcessingChain > &c) override
Set the processing chain for this container.
void set_structure(ContainerDataStructure s) override
Set the data structure for this container.
ContainerDataStructure & get_structure() override
Get the data structure defining this container's layout.
std::vector< std::atomic< bool > > m_cpu_stale
Per layer: the GPU image in m_layer_image_cache holds the content, m_data does not.
std::function< void(const std::shared_ptr< SignalSourceContainer > &, ProcessingState)> m_state_cb
auto get_frame_span_impl(uint64_t frame_index) const -> DataSpanVariant override
Implementation-specific method to retrieve a frame span.
void set_default_processor(const std::shared_ptr< DataProcessor > &p) override
Set the default data processor for this container.
std::shared_ptr< DataProcessor > get_default_processor() const override
Get the current default data processor.
std::vector< double > m_frame_cache
Row cache backing the double span returned by get_frame().
bool is_region_loaded(const Region &) const override
Check if a region is loaded in memory.
std::vector< DataVariant > get_region_group_data(const RegionGroup &) const override
Get data for multiple regions efficiently.
SignalSourceContainer wrapping GPU texture data as addressable pixel bytes.