#pragma once #include #include #include #include #include #include // Triple-buffer software texture for Windows. // // The capture thread calls Update() with new BGRA32 pixels. // The Flutter render thread calls the pixel-buffer callback to read frames. // Triple buffering avoids any locking between writer and reader: // - write_idx : capture thread writes here // - ready_idx : swapped by capture thread after write (latest frame) // - read_idx : Flutter render thread reads from here class CameraTexture { public: explicit CameraTexture(flutter::TextureRegistrar* registrar); ~CameraTexture(); // Registers the texture with Flutter and returns the texture ID. int64_t Register(); // Updates the texture with a new BGRA32 frame. // Called from the capture thread. void Update(const uint8_t* bgra, int width, int height); // Unregisters the texture from Flutter. void Unregister(); // Asynchronously unregisters the texture; |on_done| runs once Flutter has removed // it (on the raster thread). The caller MUST keep this object alive until then, // because Flutter's pixel-buffer callback can still fire on the raster thread after // an ordinary Unregister() returns. See CRASH.md. void UnregisterAsync(std::function on_done); int64_t texture_id() const { return texture_id_; } private: const FlutterDesktopPixelBuffer* ObtainPixelBuffer(size_t width, size_t height); flutter::TextureRegistrar* registrar_; std::unique_ptr texture_variant_; int64_t texture_id_ = -1; // Triple buffer, same pattern as linux/camera_texture.cc. std::vector bufs_[3]; int write_idx_ = 0; int ready_idx_ = 1; int read_idx_ = 2; bool has_new_frame_ = false; std::mutex mutex_; int width_ = 0; int height_ = 0; FlutterDesktopPixelBuffer pixel_buffer_{}; };