-
Notifications
You must be signed in to change notification settings - Fork 288
Avoid picture primitive copies via VecHelper #3362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,12 +8,53 @@ use euclid::{Point2D, Rect, Size2D, TypedPoint2D, TypedRect, TypedSize2D, Vector | |
use euclid::{TypedTransform2D, TypedTransform3D, TypedVector2D, TypedScale}; | ||
use num_traits::Zero; | ||
use plane_split::{Clipper, Polygon}; | ||
use std::{i32, f32, fmt}; | ||
use std::{i32, f32, fmt, ptr}; | ||
use std::borrow::Cow; | ||
|
||
|
||
// Matches the definition of SK_ScalarNearlyZero in Skia. | ||
const NEARLY_ZERO: f32 = 1.0 / 4096.0; | ||
|
||
/// A typesafe helper that separates new value construction from | ||
/// vector growing, allowing LLVM to ideally construct the element in place. | ||
#[must_use] | ||
pub struct Allocation<'a, T: 'a> { | ||
vec: &'a mut Vec<T>, | ||
index: usize, | ||
} | ||
|
||
impl<'a, T> Allocation<'a, T> { | ||
// writing is safe because alloc() ensured enough capacity | ||
// and `Allocation` holds a mutable borrow to prevent anyone else | ||
// from breaking this invariant. | ||
#[inline(always)] | ||
pub fn init(self, value: T) -> usize { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure this actually avoids the memcpy / memmove? At least for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed in playground. In There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I filed rust-lang/rust#56333 for a problem contributing to the first example not working well in the playground. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like SmallVec also causes this to not work. I filed rust-lang/rust#56356 about that. |
||
unsafe { | ||
ptr::write(self.vec.as_mut_ptr().add(self.index), value); | ||
self.vec.set_len(self.index + 1); | ||
} | ||
self.index | ||
} | ||
} | ||
|
||
pub trait VecHelper<T> { | ||
fn alloc(&mut self) -> Allocation<T>; | ||
} | ||
|
||
impl<T> VecHelper<T> for Vec<T> { | ||
fn alloc(&mut self) -> Allocation<T> { | ||
let index = self.len(); | ||
if self.capacity() == index { | ||
self.reserve(1); | ||
} | ||
Allocation { | ||
vec: self, | ||
index, | ||
} | ||
} | ||
} | ||
|
||
|
||
// Represents an optimized transform where there is only | ||
// a scale and translation (which are guaranteed to maintain | ||
// an axis align rectangle under transformation). The | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be nice if this only ran if profiling was on.