1
0
Fork 0
forked from wry/wry

autocommit 2022-04-28 20:33:24 CEST

This commit is contained in:
Julian Orth 2022-04-28 20:33:24 +02:00
parent 1242a6c1e1
commit ed0beb8ff5
10 changed files with 122 additions and 72 deletions

View file

@ -7,13 +7,9 @@ use {
backends::metal::{DrmId, MetalBackend, MetalError},
edid::Descriptor,
format::{Format, XRGB8888},
ifs::{
wl_buffer::WlBufferStorage,
wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC},
},
ifs::wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC},
render::{Framebuffer, RenderContext, RenderResult, Texture},
state::State,
time::Time,
utils::{
asyncevent::AsyncEvent, bitflags::BitflagsExt, clonecell::CloneCell,
debug_fn::debug_fn, errorfmt::ErrorFmt, numcell::NumCell, oserror::OsError,
@ -37,7 +33,6 @@ use {
cell::{Cell, RefCell},
ffi::CString,
fmt::{Debug, Formatter},
ops::Deref,
rc::Rc,
},
uapi::c,
@ -199,64 +194,7 @@ impl MetalConnector {
fr.send_done();
let _ = fr.client.remove_obj(&*fr);
}
if !node.global.pending_captures.is_empty() {
let now = Time::now().unwrap();
let mut captures = vec![];
for capture in node.global.pending_captures.iter() {
captures.push(capture.deref().clone());
let wl_buffer = match capture.buffer.take() {
Some(b) => b,
_ => {
log::warn!("Capture frame is pending but has no buffer attached");
capture.send_failed();
continue;
}
};
if wl_buffer.destroyed() {
capture.send_failed();
continue;
}
let rect = capture.rect;
if let WlBufferStorage::Shm { mem, .. } = &wl_buffer.storage {
let res = mem.access(|mem| {
buffer.fb.copy_to_shm(
rect.x1(),
rect.y1(),
rect.width(),
rect.height(),
XRGB8888,
mem,
);
});
if let Err(e) = res {
capture.client.error(e);
}
// capture.send_flags(FLAGS_Y_INVERT);
} else {
let fb = match wl_buffer.famebuffer.get() {
Some(fb) => fb,
_ => {
log::warn!("Capture buffer has no framebuffer");
capture.send_failed();
continue;
}
};
fb.copy_texture(
&self.state,
&buffer.tex,
-capture.rect.x1(),
-capture.rect.y1(),
);
}
if capture.with_damage.get() {
capture.send_damage();
}
capture.send_ready(now.0.tv_sec as _, now.0.tv_nsec as _);
}
for capture in captures {
capture.output_link.take();
}
}
node.global.perform_screencopies(&buffer.fb, &buffer.tex);
}
let mut changes = self.master.change();
changes.change_object(plane.id, |c| {

View file

@ -9,7 +9,7 @@ use {
fixed::Fixed,
format::XRGB8888,
ifs::wl_seat::PX_PER_SCROLL,
render::{Framebuffer, RenderContext, RenderError, RenderResult},
render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture},
state::State,
utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
@ -87,8 +87,12 @@ pub enum XBackendError {
ImportBuffer(#[source] XconError),
#[error("Could not create an EGL context")]
CreateEgl(#[source] RenderError),
#[error("Could not create a framebuffer from a dma-buf")]
#[error("Could not create an EGL image from a dma-buf")]
CreateImage(#[source] RenderError),
#[error("Could not create a framebuffer from an EGL image")]
CreateFramebuffer(#[source] RenderError),
#[error("Could not create a texture from an EGL image")]
CreateTexture(#[source] RenderError),
#[error("Could not select input events")]
CannotSelectInputEvents(#[source] XconError),
#[error("Could not select present events")]
@ -356,10 +360,18 @@ impl XBackend {
assert!(dma.planes.len() == 1);
let plane = dma.planes.first().unwrap();
let size = plane.stride * dma.height as u32;
let fb = match self.ctx.dmabuf_fb(dma) {
let img = match self.ctx.dmabuf_img(dma) {
Ok(f) => f,
Err(e) => return Err(XBackendError::CreateImage(e)),
};
let fb = match img.to_framebuffer() {
Ok(f) => f,
Err(e) => return Err(XBackendError::CreateFramebuffer(e)),
};
let tex = match img.to_texture() {
Ok(f) => f,
Err(e) => return Err(XBackendError::CreateTexture(e)),
};
let pixmap = {
let pfb = Dri3PixmapFromBuffer {
pixmap: self.c.generate_id()?,
@ -380,6 +392,7 @@ impl XBackend {
*image = Some(XImage {
pixmap: Cell::new(pixmap),
fb: CloneCell::new(fb),
tex: CloneCell::new(tex),
idle: Cell::new(true),
render_on_idle: Cell::new(false),
last_serial: Cell::new(0),
@ -689,6 +702,7 @@ impl XBackend {
fr.send_done();
let _ = fr.client.remove_obj(&*fr);
}
node.global.perform_screencopies(&fb, &image.tex.get());
}
let pp = PresentPixmap {
@ -862,6 +876,7 @@ impl XBackend {
pixmap: old.pixmap.get(),
});
old.fb.set(new.fb.get());
old.tex.set(new.tex.get());
old.pixmap.set(new.pixmap.get());
}
output.events.push(ConnectorEvent::ModeChanged(Mode {
@ -892,6 +907,7 @@ struct XOutput {
struct XImage {
pixmap: Cell<u32>,
fb: CloneCell<Rc<Framebuffer>>,
tex: CloneCell<Rc<Texture>>,
idle: Cell<bool>,
render_on_idle: Cell<bool>,
last_serial: Cell<u32>,