mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 02:19:56 -06:00
Canvas: a pan by whole pixels copies the pixels that stay on screen
Squashed from #6070 onto main.
This commit is contained in:
@@ -1416,6 +1416,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- **Zooming in on large images (#4155):** when an image is drawn from pixels (its mip, or its full pixels) more than 1,024 pixels on a side, and their colours are made again for the frame (separated into a CMYK document's ink planes, colorized, or shown through Separations Preview's plates), only the 1,024-pixel tiles in view are made, each kept with the images under its own key, and the tiles in view are drawn as one pixmap so their edges don't show. The colours are made pixel by pixel, so the result is the same as making them for the whole image (`a_tiled_image_draws_what_the_whole_image_draws`, across a tile edge); `a_zoomed_in_image_is_separated_only_where_it_shows` checks the tiles out of view are not made. A CMYK image painting its own inks is still made whole. On the file of #4155 (an 11,339 × 12,424 photo, M3 Pro, one run each), the sharp frame after zooming in to 50%, 100% and 200% went from 9.0, 8.6 and 8.7 s to 0.78, 0.05 and 0.05 s, and the app's memory after zooming from 4.4 GB to 2.6 GB; the screens at 100% match (p99 difference 0).
|
||||
- **Large images in CMYK documents (#4155):** the canvas draws a reduced image from a mip (halved while still at least as fine as the screen) and, in a CMYK document, separates that mip into its ink planes, colorizes it or shows it through Separations Preview's plates, instead of doing that to the full pixels and shrinking the result. A CMYK image's own inks are halved with its pixels, so it still paints them. Exports draw without mips and are unchanged. On the file of #4155 (one 11,339 × 12,424 image), measured on an M3 Pro under load, one run each: first frame 9.2 s → 1.6 s, opening to the first frame 11.7 s → 3.9 s, the sharp frame after a pan 3.9 s → 8 ms and after a zoom 3.5 s → 0.16 s; the fitted view's pixels differ by at most 5 levels (p99 2). `a_reduced_image_is_separated_from_its_mip_not_its_full_pixels`, `a_reduced_cmyk_image_paints_its_own_inks` and `a_reduced_image_on_the_ink_planes_shows_its_average` (`crates/render/src/tests/memory.rs`) cover the order, the inks and the colour: 1-pixel black and white lines show as the mid grey they average to, where separating first showed them 44 levels darker.
|
||||
- **Panning over a cropped effect raster:** when a pan makes a shadow, glow or filtered content raster cropped to the view again at the same zoom and rotation, the renderer makes it over a margin around the view too (up to half the view's longer side, within 8.4 million pixels), and later pans that keep the view inside that margin draw the raster instead of making it again. Zooming and the first frame at a zoom make the raster without the margin. The canvas pans by whole device pixels: the wheel, a trackpad, a touch screen and the scroll bars add the part of a pixel left over to the next scroll of the same view, and Hand tool and scroll bar thumb drags round the distance dragged. A Drop Shadow or Outer Glow raster holds the shadow or glow of group members outside the view, so a pan that shows a member draws its shadow or glow from the raster. `pans_within_a_cropped_rasters_margin_draw_it_kept` covers Drop Shadow, Gaussian Blur and Feather on a large image at 100%. `a_groups_shadow_raster_holds_the_members_outside_the_view` covers a group's members, `fractional_scrolls_moved_in_whole_pixels_draw_a_cropped_raster_kept` covers scrolls by fractions of a pixel, and `scrolls_and_pans_move_the_view_by_whole_device_pixels` covers the canvas.
|
||||
- **Panning a heavy document:** when the render worker draws a frame for a view moved by whole device pixels at the same zoom and rotation, it copies the pixels that stay on screen from its last frame and renders only the parts the pan exposes, grown to whole eighths of the frame, as long as those parts are at most half of it. A pan renders whole when the last frame or a part it exposes draws art in a way that depends on the frame's size, such as an effect raster cropped to the view or made at a lower resolution. A copied frame can differ from a whole render of the view (by at most one level in the tests), so the canvas renders the frame whole once it has been shown for 0.2 s with the view unmoved. The worker keeps one extra frame, up to 16 million pixels (64 MiB). A frame after a zoom or an edit holds no pixels, so the first pan step after one renders whole. Scores and estimates unchanged. `a_whole_pixel_pan_copies_the_pixels_that_stay_on_screen`, `a_frame_renders_whole_when_anything_but_a_whole_pixel_pan_changed`, `worker_frames_match_a_fresh_render_through_a_session`, `a_pan_over_art_the_frame_size_decides_renders_whole`, `a_frame_after_a_zoom_or_an_edit_holds_no_pixels` and `a_frame_with_copied_pixels_renders_whole_once_the_view_stops` (`crates/ui-egui/src/canvas/tests.rs`) cover the copy, the frames that render whole, the frames that hold no pixels and the frame after the view stops.
|
||||
|
||||
- **Moving objects with raster effects (#1257):** during a drag or a dialog's preview, an object whose content only moved draws its cached drop shadows, outer glows and filtered content (Gaussian Blur, Feather and the Photoshop-style filters) from the rasters of an earlier frame at the nearest whole pixel, without running the effects again. The renderer first draws the moved content where the old content lies in its raster and compares the pixels. De-Interlace runs again. The frame after the drag runs the effects again and draws what a fresh renderer draws; on the desktop, the canvas renders that frame on the render worker. `texture_drag_perf` times a drag's frames and the frame after it.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user