From c01f65affbb6e7efed3af69b36b0a5285ede3b2e Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Wed, 4 Jun 2025 17:16:28 +0200 Subject: [PATCH] canvas: Use `Cow<[u8]>` for bytes() getter (#37249) I fell into trap of over-generalization in https://github.com/servo/servo/pull/36793, but https://github.com/servo/servo/pull/36821 showed `Cow<[u8]>` is all we need (to reuse existing vec alloc or pass on a slice). Testing: There are WPT tests, but it's just refactor so rust keeps us safe. Split of https://github.com/servo/servo/pull/36821 Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- components/canvas/backend.rs | 5 +++-- components/canvas/canvas_data.rs | 2 +- components/canvas/raqote_backend.rs | 8 +++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/components/canvas/backend.rs b/components/canvas/backend.rs index 7e348fbc9b9..b7296b81ba3 100644 --- a/components/canvas/backend.rs +++ b/components/canvas/backend.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::borrow::Cow; + use canvas_traits::canvas::{ CompositionOrBlending, FillOrStrokeStyle, LineCapStyle, LineJoinStyle, }; @@ -21,7 +23,6 @@ pub(crate) trait Backend: Clone + Sized { type DrawTarget: GenericDrawTarget; type PathBuilder: GenericPathBuilder; type SourceSurface; - type Bytes<'a>: AsRef<[u8]>; type Path: PathHelpers + Clone; type GradientStop; type GradientStops; @@ -122,7 +123,7 @@ pub(crate) trait GenericDrawTarget { draw_options: &B::DrawOptions, ); fn surface(&self) -> B::SourceSurface; - fn bytes(&'_ self) -> B::Bytes<'_>; + fn bytes(&self) -> Cow<[u8]>; } /// A generic PathBuilder that abstracts the interface for azure's and raqote's PathBuilder. diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index ea30589d0af..dd28b902efd 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -1327,7 +1327,7 @@ impl<'a, B: Backend> CanvasData<'a, B> { .to_vec() } } else { - self.drawtarget.bytes().as_ref().to_vec() + self.drawtarget.bytes().into_owned() }; Snapshot::from_vec( diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index ecf780c36d5..51075f1c63a 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::borrow::Cow; use std::cell::RefCell; use std::collections::HashMap; @@ -41,7 +42,6 @@ impl Backend for RaqoteBackend { type DrawTarget = raqote::DrawTarget; type PathBuilder = PathBuilder; type SourceSurface = Vec; // TODO: See if we can avoid the alloc (probably?) - type Bytes<'a> = &'a [u8]; type Path = raqote::Path; type GradientStop = raqote::GradientStop; type GradientStops = Vec; @@ -656,9 +656,11 @@ impl GenericDrawTarget for raqote::DrawTarget { ); } #[allow(unsafe_code)] - fn bytes(&self) -> &[u8] { + fn bytes(&self) -> Cow<[u8]> { let v = self.get_data(); - unsafe { std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of_val(v)) } + Cow::Borrowed(unsafe { + std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of_val(v)) + }) } }