Skip to content

Commit

Permalink
Bug 1511661 - Update webrender to commit 1619d945e853db14a9d62ed75dce…
Browse files Browse the repository at this point in the history
…7216ff3cdbc2 (WR PR #3366). r=kats

servo/webrender#3366

Differential Revision: https://phabricator.services.mozilla.com/D13627
  • Loading branch information
WR Updater Bot committed Dec 2, 2018
1 parent 3574e3b commit bf9b17d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 28 deletions.
2 changes: 1 addition & 1 deletion gfx/webrender_bindings/revision.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dbaa10971f08f964120ba339f5b0ab3e7ace77d6
1619d945e853db14a9d62ed75dce7216ff3cdbc2
52 changes: 26 additions & 26 deletions gfx/wr/webrender/src/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ use internal_types::FastHashMap;
use std::fmt::Debug;
use std::hash::Hash;
use std::marker::PhantomData;
use std::mem;
use std::ops;
use std::u64;
use std::{mem, ops, u64};
use util::VecHelper;

/*
Expand Down Expand Up @@ -60,7 +59,9 @@ pub struct UpdateList<S> {
/// The current epoch of the scene builder.
epoch: Epoch,
/// The additions and removals to apply.
updates: Vec<Update<S>>,
updates: Vec<Update>,
/// Actual new data to insert.
data: Vec<S>,
}

#[cfg_attr(feature = "capture", derive(Serialize))]
Expand Down Expand Up @@ -89,17 +90,17 @@ impl <T> Handle<T> where T: Copy {

#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum UpdateKind<S> {
Insert(S),
pub enum UpdateKind {
Insert,
Remove,
UpdateEpoch,
}

#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct Update<S> {
pub struct Update {
index: usize,
kind: UpdateKind<S>,
kind: UpdateKind,
}

/// The data item is stored with an epoch, for validating
Expand Down Expand Up @@ -137,18 +138,14 @@ impl<S, T, M> DataStore<S, T, M> where S: Debug, T: From<S>, M: Debug {
&mut self,
update_list: UpdateList<S>,
) {
let mut data_iter = update_list.data.into_iter();
for update in update_list.updates {
match update.kind {
UpdateKind::Insert(data) => {
let item = Item {
data: T::from(data),
UpdateKind::Insert => {
self.items.entry(update.index).set(Item {
data: T::from(data_iter.next().unwrap()),
epoch: update_list.epoch,
};
if self.items.len() == update.index {
self.items.push(item)
} else {
self.items[update.index] = item;
}
});
}
UpdateKind::Remove => {
self.items[update.index].epoch = Epoch::INVALID;
Expand All @@ -158,6 +155,7 @@ impl<S, T, M> DataStore<S, T, M> where S: Debug, T: From<S>, M: Debug {
}
}
}
debug_assert!(data_iter.next().is_none());
}
}

Expand Down Expand Up @@ -194,7 +192,9 @@ pub struct Interner<S : Eq + Hash + Clone + Debug, D, M> {
/// List of free slots in the data store for re-use.
free_list: Vec<usize>,
/// Pending list of updates that need to be applied.
updates: Vec<Update<S>>,
updates: Vec<Update>,
/// Pending new data to insert.
update_data: Vec<S>,
/// The current epoch for the interner.
current_epoch: Epoch,
/// Incrementing counter for identifying stable values.
Expand All @@ -211,6 +211,7 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
map: FastHashMap::default(),
free_list: Vec::new(),
updates: Vec::new(),
update_data: Vec::new(),
current_epoch: Epoch(1),
next_uid: 0,
local_data: Vec::new(),
Expand Down Expand Up @@ -259,8 +260,9 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
// Add a pending update to insert the new data.
self.updates.push(Update {
index,
kind: UpdateKind::Insert(data.clone()),
kind: UpdateKind::Insert,
});
self.update_data.alloc().init(data.clone());

// Generate a handle for access via the data store.
let handle = Handle {
Expand All @@ -280,15 +282,10 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De

// Create the local data for this item that is
// being interned.
let local_item = Item {
self.local_data.entry(index).set(Item {
epoch: self.current_epoch,
data: f(),
};
if self.local_data.len() == index {
self.local_data.push(local_item);
} else {
self.local_data[index] = local_item;
}
});

handle
}
Expand All @@ -298,6 +295,8 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
/// a GC step that removes old entries.
pub fn end_frame_and_get_pending_updates(&mut self) -> UpdateList<S> {
let mut updates = mem::replace(&mut self.updates, Vec::new());
let data = mem::replace(&mut self.update_data, Vec::new());

let free_list = &mut self.free_list;
let current_epoch = self.current_epoch.0;

Expand Down Expand Up @@ -327,6 +326,7 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De

let updates = UpdateList {
updates,
data,
epoch: self.current_epoch,
};

Expand Down
32 changes: 31 additions & 1 deletion gfx/wr/webrender/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ 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,
Expand All @@ -37,8 +36,28 @@ impl<'a, T> Allocation<'a, T> {
}
}

/// An entry into a vector, similar to `std::collections::hash_map::Entry`.
pub enum VecEntry<'a, T: 'a> {
Vacant(Allocation<'a, T>),
Occupied(&'a mut T),
}

impl<'a, T> VecEntry<'a, T> {
#[inline(always)]
pub fn set(self, value: T) {
match self {
VecEntry::Vacant(alloc) => { alloc.init(value); }
VecEntry::Occupied(slot) => { *slot = value; }
}
}
}

pub trait VecHelper<T> {
/// Growns the vector by a single entry, returning the allocation.
fn alloc(&mut self) -> Allocation<T>;
/// Either returns an existing elemenet, or grows the vector by one.
/// Doesn't expect indices to be higher than the current length.
fn entry(&mut self, index: usize) -> VecEntry<T>;
}

impl<T> VecHelper<T> for Vec<T> {
Expand All @@ -52,6 +71,17 @@ impl<T> VecHelper<T> for Vec<T> {
index,
}
}

fn entry(&mut self, index: usize) -> VecEntry<T> {
if index < self.len() {
VecEntry::Occupied(unsafe {
self.get_unchecked_mut(index)
})
} else {
assert_eq!(index, self.len());
VecEntry::Vacant(self.alloc())
}
}
}


Expand Down

0 comments on commit bf9b17d

Please sign in to comment.