Skip to content

Experimental#6

Draft
tristanpoland wants to merge 81 commits intomainfrom
experimental
Draft

Experimental#6
tristanpoland wants to merge 81 commits intomainfrom
experimental

Conversation

@tristanpoland
Copy link
Member

This pull request removes the collections crate and cleans up related files and documentation in the repository. It also updates the main README.md to provide improved usage instructions and an overview of the project. The most important changes are:

Crate and Dependency Removal

  • Deleted the collections crate, including its Cargo.toml, LICENSE-APACHE, and source file (src/collections.rs). This removes all type re-exports and dependencies previously provided by this crate. [1] [2] [3]
  • Removed all references to the collections crate from the gpui crate's Cargo.toml, including as a dependency and in feature flags.

Documentation Updates

  • Replaced the old README.md with a new version that provides clear usage instructions, dependency setup, and an overview of the GPUI framework. This improves onboarding for new users and clarifies the project's purpose. (Ff4426b0L1)
  • Removed the outdated README.md from the gpui crate, consolidating documentation in the main project README.md.

Example Cleanup

  • Deleted the animation.rs example from the gpui crate, likely as part of cleaning up dependencies or outdated examples.

ayoubmdi and others added 30 commits December 22, 2025 12:56
This file specifies the required Rust toolchain and targets for the Zed editor and is not needed for GPUI.
* Update crate name

* wip

* reduce to just the gpui crate

* Fix misisng example images

* Delete ownership_post.rs

* Update Cargo.toml

* Update README.md

* bump to 0.3.3

* organize

* organize

* Add more learn examples

* Delete _ownership_and_data_flow.rs

* wip learn examples

* Fix colors

* tidy

* Move _template up

* add animation example

* Update examples

* remove legacy examples from toml

* Delete examples.toml
Use GPU shader for animated rainbow gradient

Replace CPU-side pixel generation and texture upload with a GPU-rendered fullscreen triangle producing an animated rainbow gradient. Adds an inline WGSL shader (vertex + fragment) that computes HSV->RGB in the fragment stage and a time uniform updated each frame. Lazily caches pipeline, bind group layout, uniform buffer and bind group in thread-local storage, writes the time uniform to the GPU each frame, and issues a 3-vertex draw. Removes the previous CPU pixel buffer, texture creation/upload, and hsv_to_rgb helper.

Update wgpu_surface.rs

Update wgpu_surface.rs

Update wgpu_surface.rs

Update wgpu_surface.rs

Update wgpu_surface.rs

Add wgpu_surface example with render thread

Register a new example in Cargo.toml and add examples/learn/wgpu_surface.rs. The example demonstrates using WgpuSurface with a dedicated secondary render thread: it creates a 400x300 RGBA surface, spawns a thread that encodes a simple per-frame clear pass (color cycling), submits to the device queue, and calls present on the surface. This provides a reference for using a WGPU back buffer from a separate render thread in the application.

Add WGPU double-buffered surface support

Introduce support for externally-rendered WGPU surfaces that the renderer can composite GPU→GPU.

- Add WgpuSurface element and WgpuSurfaceHandle for external rendering, resizing and present/swap APIs.
- New SurfaceRegistry to manage double-buffered textures and expose front/back views and resize/swap semantics.
- Integrate surfaces into the renderer: new WGSL shader, bind group/pipeline, SurfaceParams uniform and draw path for Surface primitives.
- Platform changes: wire EventLoopProxy and CrossEvent::SurfacePresent to trigger redraws, add create_wgpu_surface on CrossWindow/CrossPlatform.
- Window API: paint_wgpu_surface and create_wgpu_surface methods to paint surfaces into the scene and obtain handles.
- Scene: add SurfaceContent::Wgpu and thread surface IDs through primitives.
- Misc: export and module updates, shader and registry files added.

These changes enable zero-copy compositing of externally-produced GPU content and provide lifecycle/resize integration with the UI renderer.
Replace verbose, sleep-heavy render thread with a high-performance render loop: remove per-frame printlns and the fixed 16ms sleep, reduce the back-buffer-miss sleep to 500ns, and add a last/Instant to report FPS every 1000 frames. Minor comment and whitespace cleanup around pipeline/bind-group/uniform setup; pipeline and resource caching remain thread-local as before.
Avoid flooding the event loop by tracking outstanding present events and coalescing duplicate presents. Add an AtomicBool present_pending to DoubleBuffer and initialize it in create_double_buffer. Introduce SurfaceRegistry::set_present_pending (returns previous value) and clear_present_pending, used by WgpuSurfaceHandle::present to only request a present when none is already pending, and cleared in the renderer when the front view is consumed. Also optimize front_view/back_view to return cloned precreated TextureView objects instead of creating a new view each frame.
Pass an Arc<winit::window::Window> into WgpuSurfaceHandle so the render thread can call request_redraw() directly. Add an optional winit_window field to WgpuSurfaceHandleInner and propagate an Arc from CrossWindow (store OnceCell as Arc and set with Arc::new). present() now calls window.request_redraw() when available, falling back to the existing CrossEvent trigger otherwise. This avoids an event-bus roundtrip for redraw requests while preserving the existing coalescing behavior. Also adjust related getters and imports accordingly.
Cache per-surface bind groups for double-buffered surfaces to avoid recreating them every frame. Adds a Mutex-protected HashMap in WgpuRenderer keyed by SurfaceId to store [wgpu::BindGroup; 2], lazily creating both entries when first needed and retaining only surfaces seen in the current frame. Refactors rendering to use SurfaceRegistry.front_index and view_at helpers (added) to obtain the active texture view and index, and clears the present_pending flag after consuming a view. This reduces bind group allocation churn and improves rendering performance.
Expose present-pending state and a blocking wait on WgpuSurfaceHandle so producers can throttle until the compositor consumes the last frame (is_present_pending + wait_for_present). Add SurfaceRegistry::is_present_pending to query the pending flag. The example now calls wait_for_present to avoid overrunning the compositor.

Also make the swapchain present mode configurable via environment variables: GPUI_PRESENT_MODE=(mailbox|immediate|fifo) or GPUI_DISABLE_VSYNC=1 to pick Immediate; default remains Fifo. The renderer now reads the env var and applies the selected wgpu::PresentMode to the surface configuration.
Introduce a GPUI_BENCHMARK mode that bypasses compositor overhead for benchmarking. Add WgpuSurfaceHandle::benchmark_mode() to detect the env var, make present() a no-op after swapping buffers when benchmarking, and make wait_for_present() return immediately. Also skip inserting the WGPU PaintSurface into the next_frame.scene when GPUI_BENCHMARK is set so the render producer can drive the GPU at full speed without composition/present overhead.
Replace the hardcoded 1000-frame reporting with a configurable interval controlled by the GPUI_BENCHMARK env var. When GPUI_BENCHMARK is set, reports are emitted every 100 frames; otherwise every 1000 frames. Update FPS calculation and printed message to use the selected report interval.
Replace the fullscreen gradient triangle with a spinning, facelit cube in the wgpu_surface example. Added a Vertex POD struct and CubeResources cache to hold pipeline, buffers and bind group. Introduced a WGSL vertex/fragment shader with rotation, projection and diffuse lighting, configured a vertex buffer layout with position/normal/color attributes, created a 36-vertex cube vertex buffer and a uniform time buffer, and updated the render pass to set the vertex buffer and draw the cube. Also simplified resource caching into a thread-local entry and changed the clear color to black.
Enable proper 3D ordering by adding a depth buffer to the cube example. Introduces depth_view in CubeResources, creates a Depth24Plus texture and view, enables depth_stencil state on the render pipeline, and attaches the depth view as the render pass depth_stencil_attachment (with clear/store ops). Also updates resource creation and tuple unpacking to pass the new depth_view through.
Remove stored depth_view from CubeResources and related tuple unpacking. Instead recreate a depth texture and view every frame using the current surface size so the depth buffer matches the back-buffer dimensions (Depth24Plus, RENDER_ATTACHMENT). Also adjust destructuring and perform a small formatting cleanup around submit/present.
Add back_view_with_size and use in example

Provide an atomic API to fetch a surface back-buffer view together with its pixel dimensions to avoid races during concurrent resizes. Implements SurfaceRegistry::lock_and_get_back_with_size and WgpuSurfaceHandle::back_view_with_size, and updates the example to use the new call so depth textures are created using the returned view size instead of a separate size() query.

Increase surface preview size to 1920x1080

Update the example surface element dimensions from 400x300 to 1920x1080 to provide a higher-resolution preview of the front buffer. This improves visibility of the debug border and label in the wgpu_surface example.
Expose a shared FPS value to the UI by adding a Arc<Mutex<f64>> and importing std::sync::{Arc, Mutex}. SurfaceExample now stores fps, the render thread updates the shared fps value each report interval, and the debug overlay text is changed to display the current FPS. Adjusted thread cloning and cx.new to pass the shared fps handle.
mdeand and others added 30 commits February 27, 2026 20:26
Update to wgpu version 27 and clean up dependencies
Point wgpu dependency to a specific gfx-rs/wgpu git revision and regenerate Cargo.lock to match. The lockfile updates include: switching wgpu, wgpu-core, wgpu-hal, wgpu-types, naga and spirv sources to git revisions; bumping objc2 to 0.6.4 and adding/aligning several objc2-* crates (0.3.2), introducing dispatch2 and raw-window-metal, and normalizing block/block2 versions. Removed several now-obsolete registry entries (block, core-graphics-types, malloc_buf, metal, objc) and adjusted downstream dependency entries to the new crate names/versions so the tree is consistent with the new wgpu revision.
Adapt code to recent wgpu and macOS backend changes: adjust PipelineLayoutDescriptor bind_group_layouts to use Option<&BindGroupLayout> and update Instance::new call site. Change macOS Surface handling by mapping CVPixelBuffer into the ImageBuffer variant and temporarily stubbing direct CVPixelBuffer painting (backend now expects registered WGPU surfaces). Add a macOS-only dependency (core-video) in Cargo.toml. Files touched: src/elements/surface.rs, src/platform/cross/{render_context.rs,renderer.rs}, examples/learn/wgpu_surface.rs.
Ensure transient AnyElement values allocated in the global element arena are dropped instead of being retained across arena clears. In Img::paint we now set layout_state.replacement = None after painting the replacement so the layout state doesn't hold an AnyElement reference. In Window (after swapping frames) we clear deferred_draw.element for each deferred draw so rendered_frame won't carry live arena references across the arena-clear boundary. Added unit tests to verify the replacement is cleared after paint and deferred draws are dropped before the arena is cleared.
Minor fixes - gpu_specs, viewport_size and comments
Add support for client-side window decorations and window drag/resize operations, and implement cursor style handling.

- Add window_decorations to WindowParams and thread it through Window construction.
- Respect WindowDecorations when creating winit windows (use_client_decorations toggles winit decorations).
- Track the currently hovered window (hovered_window_id) in AppState to apply cursor changes and visibility.
- Implement set_cursor_style to map crate::CursorStyle to winit CursorIcon, handle hiding/showing the cursor for the hovered window.
- Add PlatformWindow methods: start_window_move and start_window_resize (using winit drag APIs), and window_decorations() to report server vs client decorations.

These changes enable client-decorated windows, allow moving/resizing via the platform, and ensure correct cursor behavior over the active window.
Add hover tracking to CrossWindowState and wire it into window events. Introduces is_hovered: Cell<bool>, updates CursorMoved and CursorLeft handling to set the flag and invoke on_hover_status_change callbacks when the hover status changes, and implement PlatformWindow::is_hovered() to return the tracked value (replacing the prior TODO/false). This enables proper hover enter/exit notifications.
Improve robustness of WGPU surface handling and clean up related code:

- Retry and reconfigure when get_current_texture() returns Outdated/Lost/Other; log and drop the frame on repeated failure or other errors (Timeout/OutOfMemory) instead of panicking.
- Stop using a cached per-surface bind-group array; create the bind group for the current front buffer on demand to avoid stale cache complexity.
- Configure newly created renderer surfaces immediately during window init to avoid SurfaceError::Other races before the first OS Resized event.
- Remove a benchmark-mode early-return from WgpuSurfaceHandle::present so present coalescing is applied consistently.
- Always insert PaintSurface into the scene (remove GPUI_BENCHMARK conditional) so surfaces render in all modes.
- Small formatting/whitespace and example tweaks (vertex array spacing, separate queue.submit and present calls), and minor API signature/format adjustments in surface_registry.
- Add minimal permission entries to .claude/settings.local.json.

These changes prevent panics on first/ raced frames, simplify bind-group lifecycle, and make rendering behavior more predictable across threads and resizes.
Add helio-render-v2 as a local path dev-dependency and include glam and env_logger in [dev-dependencies] of Cargo.toml. Cargo.lock was updated to record the resulting dependency graph and transitive changes.
Point wgpu dependency to the Far-Beyond-Pulsar fork with default-features disabled and enable the web/webgpu features in Cargo.toml. Add width and height fields to HelioRenderState and initialize them in examples/learn/wgpu_surface.rs so the renderer can track surface dimensions.
Refresh Cargo.lock to align with changes in dependencies: add Helio-related crates (pulled from the Helio git repo), pin wgpu v23 artifacts alongside existing wgpu v28 entries, and introduce supporting crates (wgpu-core/hal/types v23, gpu-alloc, gpu-alloc-types, metal, objc, malloc_buf, unicode-width 0.1.14, etc.). Adjust versions and sources for several packages (ndk-sys, naga, glow, gpu-allocator, cfg_aliases, codespan-reporting, spirv, etc.), remove or simplify obsolete/duplicate lock entries, and reconcile cfg_aliases/codespan-reporting/naga version mismatches. These updates reflect a dependency reconfiguration to support Helio and older wgpu stacks; expect dependency resolution and build changes accordingly.
Regenerate Cargo.lock and update dependency pins to align with recent upstream upgrades. Notable changes include upgrading wgpu/wgpu-hal to v28, migrating Apple/Metal ecosystem crates to objc2/objc2-* and raw-window-metal, updating windows/* crates and related helpers, bumping various transitive deps (gpu-allocator, spirv, allocator-api2, ordered-float, dispatch2, etc.), and updating Helio package git revisions. These updates sync the lockfile with Cargo.toml and platform changes required by newer crate APIs.
… render thread on drop

The helio_render thread held a live Arc<WgpuSurfaceHandle> and ran in an
infinite loop with no stop signal.  When the window closed the WgpuRenderer
dropped its wgpu::Surface (swapchain), but the render thread was still mid-
frame holding an acquired SurfaceTexture — causing the Vulkan swapchain
semaphore panic ("Trying to destroy a SwapchainAcquireSemaphore that is
still in use by a SurfaceTexture").

Fix:
- Add `shutdown: AtomicBool` to WgpuSurfaceHandleInner.
- `WgpuSurfaceHandle::shutdown()` sets the flag; `wait_for_present` and
  `back_view_with_size` both respect it, allowing the render loop to exit
  via `None => break` without hanging.
- SurfaceExample now stores the JoinHandle and implements Drop: calls
  `surface.shutdown()` then joins the thread, ensuring the render thread
  has released its SurfaceTexture before the wgpu surface is destroyed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace mapped-at-creation BufferInit usage with an unmapped buffer + queue.write_buffer to avoid driver issues in the mapped-at-creation path (see helio/ship_flight repro). Allocate a COPY_BUFFER_ALIGNMENT-padded buffer size, fill a temporary padded Vec with the contents and zero padding, create the buffer with COPY_SRC|COPY_DST and mapped_at_creation=false, and write the data via queue.write_buffer. Also removes the now-unused wgpu::util::DeviceExt import.
Create the upload buffer with MAP_WRITE and mapped_at_creation=true, then write the source bytes directly into the mapped range and unmap. This removes the temporary padded_contents allocation and the queue.write_buffer call, and changes the buffer usage from COPY_DST to MAP_WRITE. The change reduces heap allocation and an extra copy when preparing atlas uploads (only the unpadded_size is copied into the mapped range).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants