MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ readback_region()

MAYAFLUX_API DataAccess MayaFlux::Kakshya::readback_region ( const std::shared_ptr< Core::Window > &  window,
uint32_t  x_offset,
uint32_t  y_offset,
uint32_t  pixel_width,
uint32_t  pixel_height,
DataVariant out_variant 
)

Read a pixel rectangle from the last completed swapchain frame into a DataVariant whose element type matches the live swapchain format.

Format -> DataVariant mapping: B8G8R8A8_SRGB / R8G8B8A8_SRGB / B8G8R8A8_UNORM / R8G8B8A8_UNORM -> std::vector<uint8_t> (4 bytes/pixel) R16G16B16A16_SFLOAT -> std::vector<uint16_t> (8 bytes/pixel, raw half-float bits) A2B10G10R10_UNORM -> std::vector<uint32_t> (4 bytes/pixel, packed word) R32G32B32A32_SFLOAT -> std::vector<float> (16 bytes/pixel)

The rectangle is cropped host-side from the full surface published by the per-window readback thread. The data is one frame late relative to the current render, not synchronously captured at call time. No GPU work and no staging buffer: the function reads the cached frame, validates the region against the swapchain extent, and copies the rows out. Safe to call without stalling the render pipeline. Returns failure if no frame has been captured yet or the region exceeds the surface bounds.

Dimensions on the returned DataAccess (IMAGE_COLOR convention): [0] SPATIAL_Y - pixel_height [1] SPATIAL_X - pixel_width [2] CHANNEL - channel_count derived from format traits

Parameters
windowWindow whose surface is being read.
x_offsetLeft edge of the pixel rectangle (inclusive).
y_offsetTop edge of the pixel rectangle (inclusive).
pixel_widthWidth of the rectangle in pixels.
pixel_heightHeight of the rectangle in pixels.
out_variantReceives the typed pixel data. Left unchanged on failure.
Returns
DataAccess wrapping out_variant with IMAGE_COLOR modality. Returns a default-constructed DataAccess on failure.

Definition at line 121 of file SurfaceUtils.cpp.

128{
129 static std::vector<DataDimension> s_empty_dims;
130 static DataVariant s_empty_var = std::vector<uint8_t> {};
131 static DataAccess s_fail { s_empty_var, s_empty_dims, DataModality::UNKNOWN };
132
133 auto* display = get_display_service();
134 if (!display)
135 return s_fail;
136
137 const auto window_handle = std::static_pointer_cast<void>(window);
138
139 const int raw_fmt = display->get_swapchain_format(window_handle);
140 const auto vk_fmt = static_cast<vk::Format>(raw_fmt);
141 const auto mf_fmt = Core::from_vk_format(vk_fmt);
142 const auto traits = Core::get_surface_format_traits(mf_fmt);
143 const uint32_t bpp = Core::vk_format_bytes_per_pixel(vk_fmt);
144
145 uint32_t full_w = 0, full_h = 0;
146 display->get_swapchain_extent(window_handle, full_w, full_h);
147 if (full_w == 0 || full_h == 0)
148 return s_fail;
149
150 auto frame = display->get_last_frame(window_handle);
151 if (!frame || frame->empty()) {
152 MF_RT_ERROR(Journal::Component::Kakshya, Journal::Context::ContainerProcessing,
153 "SurfaceUtils::readback_region: no captured frame for '{}'",
154 window->get_create_info().title);
155 return s_fail;
156 }
157
158 if (x_offset + pixel_width > full_w || y_offset + pixel_height > full_h) {
159 MF_RT_ERROR(Journal::Component::Kakshya, Journal::Context::ContainerProcessing,
160 "SurfaceUtils::readback_region: region {}x{} at ({},{}) exceeds surface {}x{} for '{}'",
161 pixel_width, pixel_height, x_offset, y_offset, full_w, full_h,
162 window->get_create_info().title);
163 return s_fail;
164 }
165
166 const size_t full_row = static_cast<size_t>(full_w) * bpp;
167 const size_t region_row = static_cast<size_t>(pixel_width) * bpp;
168 const size_t byte_count = region_row * pixel_height;
169
170 const size_t expected = full_row * full_h;
171 if (frame->size() < expected) {
172 MF_RT_ERROR(Journal::Component::Kakshya, Journal::Context::ContainerProcessing,
173 "SurfaceUtils::readback_region: frame {} bytes, expected {} for '{}'",
174 frame->size(), expected, window->get_create_info().title);
175 return s_fail;
176 }
177
178 std::vector<uint8_t> region(byte_count);
179 const uint8_t* base = frame->data()
180 + static_cast<size_t>(y_offset) * full_row
181 + static_cast<size_t>(x_offset) * bpp;
182
183 for (uint32_t row = 0; row < pixel_height; ++row) {
184 std::memcpy(region.data() + row * region_row,
185 base + row * full_row,
186 region_row);
187 }
188
189 fill_variant_from_raw(region.data(), byte_count, traits, out_variant);
190
191 auto dims = make_pixel_dimensions(pixel_width, pixel_height, traits.channel_count);
192 return { out_variant, dims, DataModality::IMAGE_COLOR };
193}
#define MF_RT_ERROR(comp, ctx,...)
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
Definition NDData.hpp:76

References MayaFlux::Journal::ContainerProcessing, MayaFlux::Core::from_vk_format(), MayaFlux::Core::get_surface_format_traits(), IMAGE_COLOR, MayaFlux::Journal::Kakshya, MF_RT_ERROR, UNKNOWN, and MayaFlux::Core::vk_format_bytes_per_pixel().

Referenced by MayaFlux::Kakshya::WindowAccessProcessor::process().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: