perf(display): present copies window rows as-is (scanout R8G8B8X8 = window byte order, Host hands out row bytes, Framebuffer::write_rgba_row); Window copy_from/copy_to one fenced memcpy; full present ~65ms -> ~3ms
This commit is contained in:
@@ -104,18 +104,24 @@ impl Window {
|
||||
Window { base, len }
|
||||
}
|
||||
|
||||
/// `src` into the window at `offset`, as one copy: for memory (pages,
|
||||
/// DMA buffers), not device registers. Fenced, so a device told
|
||||
/// afterwards sees all of it.
|
||||
pub fn copy_from(&self, offset: ByteOffset, src: &[u8]) {
|
||||
self.at(offset, src.len(), 1);
|
||||
for (i, b) in src.iter().enumerate() {
|
||||
self.write(offset + i, *b);
|
||||
}
|
||||
let addr = self.at(offset, src.len(), 1);
|
||||
// SAFETY: in range of memory mapped for this process; `src` is
|
||||
// ordinary memory, so the two cannot overlap.
|
||||
unsafe { core::ptr::copy_nonoverlapping(src.as_ptr(), addr as *mut u8, src.len()) }
|
||||
core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
|
||||
/// The window's bytes at `offset` into `dst`, as one copy (see
|
||||
/// `copy_from`); what a device wrote before is seen.
|
||||
pub fn copy_to(&self, offset: ByteOffset, dst: &mut [u8]) {
|
||||
self.at(offset, dst.len(), 1);
|
||||
for (i, b) in dst.iter_mut().enumerate() {
|
||||
*b = self.read(offset + i);
|
||||
}
|
||||
let addr = self.at(offset, dst.len(), 1);
|
||||
core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
|
||||
// SAFETY: as above.
|
||||
unsafe { core::ptr::copy_nonoverlapping(addr as *const u8, dst.as_mut_ptr(), dst.len()) }
|
||||
}
|
||||
|
||||
/// `count` u32s from `offset` set to `value`: one check, then a run of
|
||||
|
||||
Reference in New Issue
Block a user