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>
This commit is contained in:
sagudev 2025-06-04 17:16:28 +02:00 committed by GitHub
parent 9083d58061
commit c01f65affb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 9 additions and 6 deletions

View file

@ -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<Self>;
type PathBuilder: GenericPathBuilder<Self>;
type SourceSurface;
type Bytes<'a>: AsRef<[u8]>;
type Path: PathHelpers<Self> + Clone;
type GradientStop;
type GradientStops;
@ -122,7 +123,7 @@ pub(crate) trait GenericDrawTarget<B: Backend> {
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.

View file

@ -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(

View file

@ -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<u8>; // 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<raqote::GradientStop>;
@ -656,9 +656,11 @@ impl GenericDrawTarget<RaqoteBackend> 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))
})
}
}