-
Notifications
You must be signed in to change notification settings - Fork 287
Avoid picture primitive copies via VecHelper #3362
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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.