drivers/graphics: Exclusively use V2DisplayMap in the public api of console-draw
This commit is contained in:
@@ -2,10 +2,11 @@ extern crate ransid;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::{cmp, ptr};
|
||||
use std::{cmp, io, mem, ptr};
|
||||
|
||||
use drm::buffer::Buffer;
|
||||
use drm::control::dumbbuffer::{DumbBuffer, DumbMapping};
|
||||
use drm::control::Device;
|
||||
use graphics_ipc::v1::Damage;
|
||||
use graphics_ipc::v2::V2GraphicsHandle;
|
||||
use orbclient::FONT;
|
||||
@@ -17,7 +18,7 @@ pub struct V2DisplayMap {
|
||||
}
|
||||
|
||||
impl V2DisplayMap {
|
||||
pub unsafe fn console_map(&mut self) -> DisplayMap {
|
||||
unsafe fn console_map(&mut self) -> DisplayMap {
|
||||
DisplayMap {
|
||||
offscreen: ptr::slice_from_raw_parts_mut(
|
||||
self.mapping.as_mut_ptr() as *mut u32,
|
||||
@@ -138,7 +139,14 @@ impl TextScreen {
|
||||
}
|
||||
|
||||
impl TextScreen {
|
||||
pub fn write(&mut self, map: &mut DisplayMap, buf: &[u8], input: &mut VecDeque<u8>) -> Damage {
|
||||
pub fn write(
|
||||
&mut self,
|
||||
map: &mut V2DisplayMap,
|
||||
buf: &[u8],
|
||||
input: &mut VecDeque<u8>,
|
||||
) -> Damage {
|
||||
let map = unsafe { &mut map.console_map() };
|
||||
|
||||
let mut min_changed = map.height;
|
||||
let mut max_changed = 0;
|
||||
let mut line_changed = |line| {
|
||||
@@ -249,7 +257,7 @@ impl TextScreen {
|
||||
damage
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, old_map: &mut DisplayMap, new_map: &mut DisplayMap) {
|
||||
pub fn resize(&mut self, old_map: &mut V2DisplayMap, mut new_fb: DumbBuffer) -> io::Result<()> {
|
||||
// FIXME fold row when target is narrower and maybe unfold when it is wider
|
||||
fn copy_row(
|
||||
old_map: &mut DisplayMap,
|
||||
@@ -266,20 +274,45 @@ impl TextScreen {
|
||||
}
|
||||
}
|
||||
|
||||
if new_map.height >= old_map.height {
|
||||
for row in 0..old_map.height {
|
||||
copy_row(old_map, new_map, row, row);
|
||||
}
|
||||
} else {
|
||||
let deleted_rows = (old_map.height - new_map.height).div_ceil(16);
|
||||
for row in 0..new_map.height {
|
||||
if row + (deleted_rows + 1) * 16 >= old_map.height {
|
||||
break;
|
||||
let new_mapping = old_map.display_handle.map_dumb_buffer(&mut new_fb)?;
|
||||
let mut new_mapping =
|
||||
unsafe { mem::transmute::<DumbMapping<'_>, DumbMapping<'static>>(new_mapping) };
|
||||
|
||||
new_mapping.fill(0);
|
||||
|
||||
{
|
||||
let old_map = unsafe { &mut old_map.console_map() };
|
||||
let new_map = &mut DisplayMap {
|
||||
offscreen: ptr::slice_from_raw_parts_mut(
|
||||
new_mapping.as_mut_ptr() as *mut u32,
|
||||
new_mapping.len() / 4,
|
||||
),
|
||||
width: new_fb.size().0 as usize,
|
||||
height: new_fb.size().1 as usize,
|
||||
};
|
||||
|
||||
if new_map.height >= old_map.height {
|
||||
for row in 0..old_map.height {
|
||||
copy_row(old_map, new_map, row, row);
|
||||
}
|
||||
copy_row(old_map, new_map, row + deleted_rows * 16, row);
|
||||
} else {
|
||||
let deleted_rows = (old_map.height - new_map.height).div_ceil(16);
|
||||
for row in 0..new_map.height {
|
||||
if row + (deleted_rows + 1) * 16 >= old_map.height {
|
||||
break;
|
||||
}
|
||||
copy_row(old_map, new_map, row + deleted_rows * 16, row);
|
||||
}
|
||||
self.console.state.y = self.console.state.y.saturating_sub(deleted_rows);
|
||||
}
|
||||
self.console.state.y = self.console.state.y.saturating_sub(deleted_rows);
|
||||
}
|
||||
|
||||
let old_fb = mem::replace(&mut old_map.fb, new_fb);
|
||||
old_map.mapping = new_mapping;
|
||||
|
||||
let _ = old_map.display_handle.destroy_dumb_buffer(old_fb);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::{cmp, mem, ptr};
|
||||
use std::{cmp, mem};
|
||||
|
||||
use console_draw::{TextScreen, V2DisplayMap};
|
||||
use drm::buffer::{Buffer, DrmFourcc};
|
||||
@@ -129,26 +129,25 @@ impl FbbootlogScheme {
|
||||
return;
|
||||
};
|
||||
let buffer_len = self.text_buffer.lines.len();
|
||||
let dmap = unsafe { &mut map.console_map() };
|
||||
// for both extra space on wrapping text and a scrollback indicator
|
||||
let spare_lines = 3;
|
||||
self.is_scrollback = true;
|
||||
self.scrollback_offset = cmp::min(
|
||||
self.scrollback_offset,
|
||||
buffer_len - dmap.height / 16 + spare_lines,
|
||||
buffer_len - map.fb.size().1 as usize / 16 + spare_lines,
|
||||
);
|
||||
let mut i = self.scrollback_offset;
|
||||
self.text_screen
|
||||
.write(dmap, b"\x1B[1;1H\x1B[2J", &mut VecDeque::new());
|
||||
.write(map, b"\x1B[1;1H\x1B[2J", &mut VecDeque::new());
|
||||
while i < buffer_len {
|
||||
let mut damage =
|
||||
self.text_screen
|
||||
.write(dmap, &self.text_buffer.lines[i][..], &mut VecDeque::new());
|
||||
.write(map, &self.text_buffer.lines[i][..], &mut VecDeque::new());
|
||||
i += 1;
|
||||
let yd = (damage.y + damage.height) as usize;
|
||||
if i == buffer_len || yd + spare_lines * 16 > dmap.height {
|
||||
if i == buffer_len || yd + spare_lines * 16 > map.fb.size().1 as usize {
|
||||
// render until end of screen
|
||||
damage.height = (dmap.height as u32) - damage.y;
|
||||
damage.height = map.fb.size().1 - damage.y;
|
||||
map.display_handle
|
||||
.update_plane(0, u32::from(map.fb.handle()), damage)
|
||||
.unwrap();
|
||||
@@ -178,38 +177,13 @@ impl FbbootlogScheme {
|
||||
.display_handle
|
||||
.create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32)
|
||||
{
|
||||
Ok(mut fb) => {
|
||||
let mut new_map = match map.display_handle.map_dumb_buffer(&mut fb) {
|
||||
Ok(new_map) => unsafe {
|
||||
mem::transmute::<DumbMapping<'_>, DumbMapping<'static>>(new_map)
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("fbbootlogd: failed to open display: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
new_map.fill(0);
|
||||
|
||||
text_screen.resize(
|
||||
unsafe { &mut map.console_map() },
|
||||
&mut console_draw::DisplayMap {
|
||||
offscreen: ptr::slice_from_raw_parts_mut(
|
||||
new_map.as_mut_ptr() as *mut u32,
|
||||
new_map.len() / 4,
|
||||
),
|
||||
width: fb.size().0 as usize,
|
||||
height: fb.size().1 as usize,
|
||||
},
|
||||
);
|
||||
|
||||
let old_fb = mem::replace(&mut map.fb, fb);
|
||||
map.mapping = new_map;
|
||||
|
||||
let _ = map.display_handle.destroy_dumb_buffer(old_fb);
|
||||
|
||||
eprintln!("fbbootlogd: mapped display");
|
||||
}
|
||||
Ok(fb) => match text_screen.resize(map, fb) {
|
||||
Ok(()) => eprintln!("fbbootlogd: mapped display"),
|
||||
Err(err) => {
|
||||
eprintln!("fbbootlogd: failed to open display: {}", err);
|
||||
return;
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("fbbootlogd: failed to create framebuffer: {}", err);
|
||||
return;
|
||||
@@ -271,11 +245,7 @@ impl SchemeSync for FbbootlogScheme {
|
||||
self.text_buffer.write(buf);
|
||||
|
||||
if !self.is_scrollback {
|
||||
let damage = self.text_screen.write(
|
||||
unsafe { &mut map.console_map() },
|
||||
buf,
|
||||
&mut VecDeque::new(),
|
||||
);
|
||||
let damage = self.text_screen.write(map, buf, &mut VecDeque::new());
|
||||
|
||||
if let Some(map) = &self.display_map {
|
||||
map.display_handle
|
||||
|
||||
@@ -4,7 +4,7 @@ use drm::control::dumbbuffer::DumbMapping;
|
||||
use drm::control::Device;
|
||||
use graphics_ipc::v2::{Damage, V2GraphicsHandle};
|
||||
use inputd::ConsumerHandle;
|
||||
use std::{io, mem, ptr};
|
||||
use std::{io, mem};
|
||||
|
||||
pub struct Display {
|
||||
pub input_handle: ConsumerHandle,
|
||||
@@ -76,37 +76,14 @@ impl Display {
|
||||
.display_handle
|
||||
.create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32)
|
||||
{
|
||||
Ok(mut fb) => {
|
||||
let mut new_map = match map.display_handle.map_dumb_buffer(&mut fb) {
|
||||
Ok(new_map) => unsafe {
|
||||
mem::transmute::<DumbMapping<'_>, DumbMapping<'static>>(new_map)
|
||||
},
|
||||
Ok(fb) => {
|
||||
match text_screen.resize(map, fb) {
|
||||
Ok(()) => eprintln!("fbcond: mapped display"),
|
||||
Err(err) => {
|
||||
eprintln!("fbcond: failed to open display: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
new_map.fill(0);
|
||||
|
||||
text_screen.resize(
|
||||
unsafe { &mut map.console_map() },
|
||||
&mut console_draw::DisplayMap {
|
||||
offscreen: ptr::slice_from_raw_parts_mut(
|
||||
new_map.as_mut_ptr() as *mut u32,
|
||||
new_map.len() / 4,
|
||||
),
|
||||
width: fb.size().0 as usize,
|
||||
height: fb.size().1 as usize,
|
||||
},
|
||||
);
|
||||
|
||||
let old_fb = mem::replace(&mut map.fb, fb);
|
||||
map.mapping = new_map;
|
||||
|
||||
let _ = map.display_handle.destroy_dumb_buffer(old_fb);
|
||||
|
||||
eprintln!("fbcond: mapped display");
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("fbcond: failed to create framebuffer: {}", err);
|
||||
|
||||
@@ -124,9 +124,7 @@ impl TextScreen {
|
||||
if let Some(map) = &mut self.display.map {
|
||||
Display::handle_resize(map, &mut self.inner);
|
||||
|
||||
let damage = self
|
||||
.inner
|
||||
.write(unsafe { &mut map.console_map() }, buf, &mut self.input);
|
||||
let damage = self.inner.write(map, buf, &mut self.input);
|
||||
|
||||
self.display.sync_rect(damage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user