render: don't require framebuffer to perform shm screencopies
This commit is contained in:
parent
69d63b7e83
commit
9de63bddf3
12 changed files with 65 additions and 76 deletions
|
|
@ -609,7 +609,6 @@ impl MetalConnector {
|
||||||
if try_direct_scanout {
|
if try_direct_scanout {
|
||||||
if let Some(dsd) = self.prepare_direct_scanout(&pass, plane) {
|
if let Some(dsd) = self.prepare_direct_scanout(&pass, plane) {
|
||||||
output.perform_screencopies(
|
output.perform_screencopies(
|
||||||
None,
|
|
||||||
&dsd.tex,
|
&dsd.tex,
|
||||||
!render_hw_cursor,
|
!render_hw_cursor,
|
||||||
dsd.position.crtc_x,
|
dsd.position.crtc_x,
|
||||||
|
|
@ -634,14 +633,7 @@ impl MetalConnector {
|
||||||
if let Some(tex) = &buffer.dev_tex {
|
if let Some(tex) = &buffer.dev_tex {
|
||||||
buffer.dev_fb.copy_texture(tex, 0, 0);
|
buffer.dev_fb.copy_texture(tex, 0, 0);
|
||||||
}
|
}
|
||||||
output.perform_screencopies(
|
output.perform_screencopies(&buffer.render_tex, !render_hw_cursor, 0, 0, None);
|
||||||
Some(&*buffer_fb),
|
|
||||||
&buffer.render_tex,
|
|
||||||
!render_hw_cursor,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
buffer.drm.clone()
|
buffer.drm.clone()
|
||||||
}
|
}
|
||||||
Some(dsd) => dsd.fb.clone(),
|
Some(dsd) => dsd.fb.clone(),
|
||||||
|
|
|
||||||
|
|
@ -150,12 +150,13 @@ pub trait GfxFramebuffer: Debug {
|
||||||
fn render(&self, ops: Vec<GfxApiOpt>, clear: Option<&Color>);
|
fn render(&self, ops: Vec<GfxApiOpt>, clear: Option<&Color>);
|
||||||
|
|
||||||
fn copy_to_shm(
|
fn copy_to_shm(
|
||||||
&self,
|
self: Rc<Self>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
format: &Format,
|
stride: i32,
|
||||||
|
format: &'static Format,
|
||||||
shm: &[Cell<u8>],
|
shm: &[Cell<u8>],
|
||||||
) -> Result<(), GfxError>;
|
) -> Result<(), GfxError>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,8 +178,8 @@ enum RenderError {
|
||||||
ExternalUnsupported,
|
ExternalUnsupported,
|
||||||
#[error("OpenGL context does not support any formats")]
|
#[error("OpenGL context does not support any formats")]
|
||||||
NoSupportedFormats,
|
NoSupportedFormats,
|
||||||
#[error("Unsupported operation")]
|
#[error("Cannot convert a shm texture into a framebuffer")]
|
||||||
UnsupportedOperation,
|
ShmTextureToFb,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use {
|
||||||
ResetStatus,
|
ResetStatus,
|
||||||
},
|
},
|
||||||
gfx_apis::gl::{
|
gfx_apis::gl::{
|
||||||
egl::{context::EglContext, display::EglDisplay},
|
egl::{context::EglContext, display::EglDisplay, image::EglImage},
|
||||||
ext::GL_OES_EGL_IMAGE_EXTERNAL,
|
ext::GL_OES_EGL_IMAGE_EXTERNAL,
|
||||||
gl::{
|
gl::{
|
||||||
program::GlProgram, render_buffer::GlRenderBuffer, sys::GLint, texture::GlTexture,
|
program::GlProgram, render_buffer::GlRenderBuffer, sys::GLint, texture::GlTexture,
|
||||||
|
|
@ -190,6 +190,20 @@ impl GlRenderContext {
|
||||||
format,
|
format,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn image_to_fb(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
img: &Rc<EglImage>,
|
||||||
|
) -> Result<Rc<Framebuffer>, RenderError> {
|
||||||
|
self.ctx.with_current(|| unsafe {
|
||||||
|
let rb = GlRenderBuffer::from_image(img, &self.ctx)?;
|
||||||
|
let fb = rb.create_framebuffer()?;
|
||||||
|
Ok(Rc::new(Framebuffer {
|
||||||
|
ctx: self.clone(),
|
||||||
|
gl: fb,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GfxContext for GlRenderContext {
|
impl GfxContext for GlRenderContext {
|
||||||
|
|
|
||||||
|
|
@ -106,15 +106,16 @@ impl GfxFramebuffer for Framebuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_to_shm(
|
fn copy_to_shm(
|
||||||
&self,
|
self: Rc<Self>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
format: &Format,
|
_stride: i32,
|
||||||
|
format: &'static Format,
|
||||||
shm: &[Cell<u8>],
|
shm: &[Cell<u8>],
|
||||||
) -> Result<(), GfxError> {
|
) -> Result<(), GfxError> {
|
||||||
self.copy_to_shm(x, y, width, height, format, shm);
|
(*self).copy_to_shm(x, y, width, height, format, shm);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
gfx_api::{GfxError, GfxFramebuffer, GfxImage, GfxTexture},
|
gfx_api::{GfxError, GfxFramebuffer, GfxImage, GfxTexture},
|
||||||
gfx_apis::gl::{
|
gfx_apis::gl::{
|
||||||
egl::image::EglImage,
|
egl::image::EglImage, gl::texture::GlTexture, Framebuffer, GlRenderContext,
|
||||||
gl::{render_buffer::GlRenderBuffer, texture::GlTexture},
|
RenderError, Texture,
|
||||||
Framebuffer, GlRenderContext, RenderError, Texture,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::rc::Rc,
|
||||||
|
|
@ -34,14 +33,7 @@ impl Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_framebuffer(&self) -> Result<Rc<Framebuffer>, RenderError> {
|
fn to_framebuffer(&self) -> Result<Rc<Framebuffer>, RenderError> {
|
||||||
self.ctx.ctx.with_current(|| unsafe {
|
self.ctx.image_to_fb(&self.gl)
|
||||||
let rb = GlRenderBuffer::from_image(&self.gl, &self.ctx.ctx)?;
|
|
||||||
let fb = rb.create_framebuffer()?;
|
|
||||||
Ok(Rc::new(Framebuffer {
|
|
||||||
ctx: self.ctx.clone(),
|
|
||||||
gl: fb,
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,11 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
format::Format,
|
format::Format,
|
||||||
gfx_api::{GfxError, GfxTexture, TextureReservations},
|
gfx_api::{GfxError, GfxTexture, TextureReservations},
|
||||||
gfx_apis::gl::{gl::texture::GlTexture, renderer::context::GlRenderContext, RenderError},
|
gfx_apis::gl::{
|
||||||
|
gl::texture::GlTexture,
|
||||||
|
renderer::{context::GlRenderContext, framebuffer::Framebuffer},
|
||||||
|
RenderError,
|
||||||
|
},
|
||||||
video::dmabuf::DmaBuf,
|
video::dmabuf::DmaBuf,
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
|
|
@ -34,6 +38,13 @@ impl Texture {
|
||||||
pub fn height(&self) -> i32 {
|
pub fn height(&self) -> i32 {
|
||||||
self.gl.height
|
self.gl.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_framebuffer(&self) -> Result<Rc<Framebuffer>, RenderError> {
|
||||||
|
match &self.gl.img {
|
||||||
|
Some(img) => self.ctx.image_to_fb(img),
|
||||||
|
_ => Err(RenderError::ShmTextureToFb),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GfxTexture for Texture {
|
impl GfxTexture for Texture {
|
||||||
|
|
@ -51,15 +62,17 @@ impl GfxTexture for Texture {
|
||||||
|
|
||||||
fn read_pixels(
|
fn read_pixels(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
_x: i32,
|
x: i32,
|
||||||
_y: i32,
|
y: i32,
|
||||||
_width: i32,
|
width: i32,
|
||||||
_height: i32,
|
height: i32,
|
||||||
_stride: i32,
|
_stride: i32,
|
||||||
_format: &Format,
|
format: &Format,
|
||||||
_shm: &[Cell<u8>],
|
shm: &[Cell<u8>],
|
||||||
) -> Result<(), GfxError> {
|
) -> Result<(), GfxError> {
|
||||||
Err(RenderError::UnsupportedOperation.into())
|
self.to_framebuffer()?
|
||||||
|
.copy_to_shm(x, y, width, height, format, shm);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dmabuf(&self) -> Option<&DmaBuf> {
|
fn dmabuf(&self) -> Option<&DmaBuf> {
|
||||||
|
|
|
||||||
|
|
@ -173,8 +173,6 @@ pub enum VulkanError {
|
||||||
height: i32,
|
height: i32,
|
||||||
stride: i32,
|
stride: i32,
|
||||||
},
|
},
|
||||||
#[error("Unsupported operation")]
|
|
||||||
UnsupportedOperation,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for GfxError {
|
impl From<VulkanError> for GfxError {
|
||||||
|
|
|
||||||
|
|
@ -533,15 +533,18 @@ impl GfxFramebuffer for VulkanImage {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_to_shm(
|
fn copy_to_shm(
|
||||||
&self,
|
self: Rc<Self>,
|
||||||
_x: i32,
|
x: i32,
|
||||||
_y: i32,
|
y: i32,
|
||||||
_width: i32,
|
width: i32,
|
||||||
_height: i32,
|
height: i32,
|
||||||
_format: &Format,
|
stride: i32,
|
||||||
_shm: &[Cell<u8>],
|
format: &'static Format,
|
||||||
|
shm: &[Cell<u8>],
|
||||||
) -> Result<(), GfxError> {
|
) -> Result<(), GfxError> {
|
||||||
return Err(VulkanError::UnsupportedOperation.into());
|
self.renderer
|
||||||
|
.read_pixels(&self, x, y, width, height, stride, format, shm)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format(&self) -> &'static Format {
|
fn format(&self) -> &'static Format {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
backend,
|
backend,
|
||||||
client::{Client, ClientError, ClientId},
|
client::{Client, ClientError, ClientId},
|
||||||
format::XRGB8888,
|
gfx_api::GfxTexture,
|
||||||
gfx_api::{GfxFramebuffer, GfxTexture},
|
|
||||||
globals::{Global, GlobalName},
|
globals::{Global, GlobalName},
|
||||||
ifs::{
|
ifs::{
|
||||||
wl_buffer::WlBufferStorage, wl_surface::WlSurface,
|
wl_buffer::WlBufferStorage, wl_surface::WlSurface,
|
||||||
|
|
@ -208,7 +207,6 @@ impl WlOutputGlobal {
|
||||||
|
|
||||||
pub fn perform_screencopies(
|
pub fn perform_screencopies(
|
||||||
&self,
|
&self,
|
||||||
fb: Option<&dyn GfxFramebuffer>,
|
|
||||||
tex: &Rc<dyn GfxTexture>,
|
tex: &Rc<dyn GfxTexture>,
|
||||||
render_hardware_cursors: bool,
|
render_hardware_cursors: bool,
|
||||||
x_off: i32,
|
x_off: i32,
|
||||||
|
|
@ -234,7 +232,6 @@ impl WlOutputGlobal {
|
||||||
capture.send_failed();
|
capture.send_failed();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let rect = capture.rect;
|
|
||||||
if let Some(WlBufferStorage::Shm { mem, stride }) =
|
if let Some(WlBufferStorage::Shm { mem, stride }) =
|
||||||
wl_buffer.storage.borrow_mut().deref()
|
wl_buffer.storage.borrow_mut().deref()
|
||||||
{
|
{
|
||||||
|
|
@ -249,34 +246,13 @@ impl WlOutputGlobal {
|
||||||
mem,
|
mem,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let mut res = match acc {
|
let res = match acc {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
capture.client.error(e);
|
capture.client.error(e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if res.is_err() {
|
|
||||||
if let Some(fb) = fb {
|
|
||||||
let acc = mem.access(|mem| {
|
|
||||||
fb.copy_to_shm(
|
|
||||||
rect.x1(),
|
|
||||||
rect.y1(),
|
|
||||||
rect.width(),
|
|
||||||
rect.height(),
|
|
||||||
XRGB8888,
|
|
||||||
mem,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
res = match acc {
|
|
||||||
Ok(res) => res,
|
|
||||||
Err(e) => {
|
|
||||||
capture.client.error(e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
log::warn!("Could not read texture to memory: {}", ErrorFmt(e));
|
log::warn!("Could not read texture to memory: {}", ErrorFmt(e));
|
||||||
capture.send_failed();
|
capture.send_failed();
|
||||||
|
|
|
||||||
|
|
@ -751,7 +751,7 @@ impl State {
|
||||||
output.global.preferred_scale.get(),
|
output.global.preferred_scale.get(),
|
||||||
render_hw_cursor,
|
render_hw_cursor,
|
||||||
);
|
);
|
||||||
output.perform_screencopies(Some(&**fb), tex, !render_hw_cursor, 0, 0, None);
|
output.perform_screencopies(tex, !render_hw_cursor, 0, 0, None);
|
||||||
rr.dispatch_frame_requests();
|
rr.dispatch_frame_requests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use {
|
||||||
client::ClientId,
|
client::ClientId,
|
||||||
cursor::KnownCursor,
|
cursor::KnownCursor,
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
gfx_api::{GfxFramebuffer, GfxTexture},
|
gfx_api::GfxTexture,
|
||||||
ifs::{
|
ifs::{
|
||||||
jay_output::JayOutput,
|
jay_output::JayOutput,
|
||||||
jay_screencast::JayScreencast,
|
jay_screencast::JayScreencast,
|
||||||
|
|
@ -80,7 +80,6 @@ pub async fn output_render_data(state: Rc<State>) {
|
||||||
impl OutputNode {
|
impl OutputNode {
|
||||||
pub fn perform_screencopies(
|
pub fn perform_screencopies(
|
||||||
&self,
|
&self,
|
||||||
fb: Option<&dyn GfxFramebuffer>,
|
|
||||||
tex: &Rc<dyn GfxTexture>,
|
tex: &Rc<dyn GfxTexture>,
|
||||||
render_hardware_cursor: bool,
|
render_hardware_cursor: bool,
|
||||||
x_off: i32,
|
x_off: i32,
|
||||||
|
|
@ -93,7 +92,7 @@ impl OutputNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.global
|
self.global
|
||||||
.perform_screencopies(fb, tex, render_hardware_cursor, x_off, y_off, size);
|
.perform_screencopies(tex, render_hardware_cursor, x_off, y_off, size);
|
||||||
for sc in self.screencasts.lock().values() {
|
for sc in self.screencasts.lock().values() {
|
||||||
sc.copy_texture(self, tex, render_hardware_cursor, x_off, y_off, size);
|
sc.copy_texture(self, tex, render_hardware_cursor, x_off, y_off, size);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue