render: use explicit sync for framebuffers
This commit is contained in:
parent
1bc344dcc2
commit
386ee5120f
15 changed files with 235 additions and 64 deletions
|
|
@ -9,7 +9,7 @@ use {
|
||||||
},
|
},
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
create_render_pass, AcquireSync, BufferResv, GfxApiOpt, GfxRenderPass, GfxTexture,
|
create_render_pass, AcquireSync, BufferResv, GfxApiOpt, GfxRenderPass, GfxTexture,
|
||||||
SyncFile,
|
ReleaseSync, SyncFile,
|
||||||
},
|
},
|
||||||
theme::Color,
|
theme::Color,
|
||||||
time::Time,
|
time::Time,
|
||||||
|
|
@ -43,7 +43,8 @@ pub struct DirectScanoutCache {
|
||||||
pub struct DirectScanoutData {
|
pub struct DirectScanoutData {
|
||||||
tex: Rc<dyn GfxTexture>,
|
tex: Rc<dyn GfxTexture>,
|
||||||
acquire_sync: AcquireSync,
|
acquire_sync: AcquireSync,
|
||||||
_resv: Option<Rc<dyn BufferResv>>,
|
release_sync: ReleaseSync,
|
||||||
|
resv: Option<Rc<dyn BufferResv>>,
|
||||||
fb: Rc<DrmFramebuffer>,
|
fb: Rc<DrmFramebuffer>,
|
||||||
dma_buf_id: DmaBufId,
|
dma_buf_id: DmaBufId,
|
||||||
position: DirectScanoutPosition,
|
position: DirectScanoutPosition,
|
||||||
|
|
@ -618,7 +619,8 @@ impl MetalConnector {
|
||||||
return buffer.fb.as_ref().map(|fb| DirectScanoutData {
|
return buffer.fb.as_ref().map(|fb| DirectScanoutData {
|
||||||
tex: buffer.tex.upgrade().unwrap(),
|
tex: buffer.tex.upgrade().unwrap(),
|
||||||
acquire_sync: ct.acquire_sync.clone(),
|
acquire_sync: ct.acquire_sync.clone(),
|
||||||
_resv: ct.buffer_resv.clone(),
|
release_sync: ct.release_sync,
|
||||||
|
resv: ct.buffer_resv.clone(),
|
||||||
fb: fb.clone(),
|
fb: fb.clone(),
|
||||||
dma_buf_id: dmabuf.id,
|
dma_buf_id: dmabuf.id,
|
||||||
position,
|
position,
|
||||||
|
|
@ -643,7 +645,8 @@ impl MetalConnector {
|
||||||
Ok(fb) => Some(DirectScanoutData {
|
Ok(fb) => Some(DirectScanoutData {
|
||||||
tex: ct.tex.clone(),
|
tex: ct.tex.clone(),
|
||||||
acquire_sync: ct.acquire_sync.clone(),
|
acquire_sync: ct.acquire_sync.clone(),
|
||||||
_resv: ct.buffer_resv.clone(),
|
release_sync: ct.release_sync,
|
||||||
|
resv: ct.buffer_resv.clone(),
|
||||||
fb: Rc::new(fb),
|
fb: Rc::new(fb),
|
||||||
dma_buf_id: dmabuf.id,
|
dma_buf_id: dmabuf.id,
|
||||||
position,
|
position,
|
||||||
|
|
@ -708,7 +711,7 @@ impl MetalConnector {
|
||||||
None => {
|
None => {
|
||||||
let sf = buffer
|
let sf = buffer
|
||||||
.render_fb()
|
.render_fb()
|
||||||
.perform_render_pass(pass)
|
.perform_render_pass(AcquireSync::Unnecessary, ReleaseSync::Explicit, pass)
|
||||||
.map_err(MetalError::RenderFrame)?;
|
.map_err(MetalError::RenderFrame)?;
|
||||||
sync_file = buffer.copy_to_dev(sf)?;
|
sync_file = buffer.copy_to_dev(sf)?;
|
||||||
fb = buffer.drm.clone();
|
fb = buffer.drm.clone();
|
||||||
|
|
@ -748,11 +751,23 @@ impl MetalConnector {
|
||||||
let render_hardware_cursor = self.cursor_enabled.get();
|
let render_hardware_cursor = self.cursor_enabled.get();
|
||||||
match &fb.direct_scanout_data {
|
match &fb.direct_scanout_data {
|
||||||
None => {
|
None => {
|
||||||
output.perform_screencopies(&fb.tex, render_hardware_cursor, 0, 0, None);
|
output.perform_screencopies(
|
||||||
|
&fb.tex,
|
||||||
|
None,
|
||||||
|
&AcquireSync::Unnecessary,
|
||||||
|
ReleaseSync::None,
|
||||||
|
render_hardware_cursor,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Some(dsd) => {
|
Some(dsd) => {
|
||||||
output.perform_screencopies(
|
output.perform_screencopies(
|
||||||
&dsd.tex,
|
&dsd.tex,
|
||||||
|
dsd.resv.as_ref(),
|
||||||
|
&dsd.acquire_sync,
|
||||||
|
dsd.release_sync,
|
||||||
render_hardware_cursor,
|
render_hardware_cursor,
|
||||||
dsd.position.crtc_x,
|
dsd.position.crtc_x,
|
||||||
dsd.position.crtc_y,
|
dsd.position.crtc_y,
|
||||||
|
|
|
||||||
|
|
@ -2474,7 +2474,9 @@ impl MetalBackend {
|
||||||
Ok(fb) => fb,
|
Ok(fb) => fb,
|
||||||
Err(e) => return Err(MetalError::ImportFb(e)),
|
Err(e) => return Err(MetalError::ImportFb(e)),
|
||||||
};
|
};
|
||||||
dev_fb.clear().map_err(MetalError::Clear)?;
|
dev_fb
|
||||||
|
.clear(AcquireSync::Unnecessary, ReleaseSync::None)
|
||||||
|
.map_err(MetalError::Clear)?;
|
||||||
let (dev_tex, render_tex, render_fb, render_bo) = if dev.id == render_ctx.dev_id {
|
let (dev_tex, render_tex, render_fb, render_bo) = if dev.id == render_ctx.dev_id {
|
||||||
let render_tex = match dev_img.to_texture() {
|
let render_tex = match dev_img.to_texture() {
|
||||||
Ok(fb) => fb,
|
Ok(fb) => fb,
|
||||||
|
|
@ -2526,7 +2528,9 @@ impl MetalBackend {
|
||||||
Ok(fb) => fb,
|
Ok(fb) => fb,
|
||||||
Err(e) => return Err(MetalError::ImportFb(e)),
|
Err(e) => return Err(MetalError::ImportFb(e)),
|
||||||
};
|
};
|
||||||
render_fb.clear().map_err(MetalError::Clear)?;
|
render_fb
|
||||||
|
.clear(AcquireSync::Unnecessary, ReleaseSync::None)
|
||||||
|
.map_err(MetalError::Clear)?;
|
||||||
let render_tex = match render_img.to_texture() {
|
let render_tex = match render_img.to_texture() {
|
||||||
Ok(fb) => fb,
|
Ok(fb) => fb,
|
||||||
Err(e) => return Err(MetalError::ImportTexture(e)),
|
Err(e) => return Err(MetalError::ImportTexture(e)),
|
||||||
|
|
@ -2797,9 +2801,17 @@ impl RenderBuffer {
|
||||||
let Some(tex) = &self.dev_tex else {
|
let Some(tex) = &self.dev_tex else {
|
||||||
return Ok(sync_file);
|
return Ok(sync_file);
|
||||||
};
|
};
|
||||||
let acquire_point = AcquireSync::from_sync_file(sync_file);
|
|
||||||
self.dev_fb
|
self.dev_fb
|
||||||
.copy_texture(tex, acquire_point, ReleaseSync::Implicit, 0, 0)
|
.copy_texture(
|
||||||
|
AcquireSync::Unnecessary,
|
||||||
|
ReleaseSync::Explicit,
|
||||||
|
tex,
|
||||||
|
None,
|
||||||
|
AcquireSync::from_sync_file(sync_file),
|
||||||
|
ReleaseSync::None,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
.map_err(MetalError::CopyToOutput)
|
.map_err(MetalError::CopyToOutput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use {
|
||||||
},
|
},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
format::XRGB8888,
|
format::XRGB8888,
|
||||||
gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture},
|
gfx_api::{AcquireSync, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync},
|
||||||
ifs::wl_output::OutputId,
|
ifs::wl_output::OutputId,
|
||||||
state::State,
|
state::State,
|
||||||
utils::{
|
utils::{
|
||||||
|
|
@ -750,9 +750,14 @@ impl XBackend {
|
||||||
image.last_serial.set(serial);
|
image.last_serial.set(serial);
|
||||||
|
|
||||||
if let Some(node) = self.state.root.outputs.get(&output.id) {
|
if let Some(node) = self.state.root.outputs.get(&output.id) {
|
||||||
let res = self
|
let res = self.state.present_output(
|
||||||
.state
|
&node,
|
||||||
.present_output(&node, &image.fb.get(), &image.tex.get(), true);
|
&image.fb.get(),
|
||||||
|
AcquireSync::Implicit,
|
||||||
|
ReleaseSync::Implicit,
|
||||||
|
&image.tex.get(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
log::error!("Could not render screen: {}", ErrorFmt(e));
|
log::error!("Could not render screen: {}", ErrorFmt(e));
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use {
|
||||||
backend::HardwareCursorUpdate,
|
backend::HardwareCursorUpdate,
|
||||||
cursor::{Cursor, KnownCursor, DEFAULT_CURSOR_SIZE},
|
cursor::{Cursor, KnownCursor, DEFAULT_CURSOR_SIZE},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
|
gfx_api::{AcquireSync, ReleaseSync},
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
state::State,
|
state::State,
|
||||||
|
|
@ -497,8 +498,14 @@ impl CursorUser {
|
||||||
}
|
}
|
||||||
if render {
|
if render {
|
||||||
let buffer = hc.get_buffer();
|
let buffer = hc.get_buffer();
|
||||||
let res =
|
let res = buffer.render_hardware_cursor(
|
||||||
buffer.render_hardware_cursor(cursor.deref(), &self.group.state, scale, transform);
|
AcquireSync::Unnecessary,
|
||||||
|
ReleaseSync::Explicit,
|
||||||
|
cursor.deref(),
|
||||||
|
&self.group.state,
|
||||||
|
scale,
|
||||||
|
transform,
|
||||||
|
);
|
||||||
match res {
|
match res {
|
||||||
Ok(sync_file) => {
|
Ok(sync_file) => {
|
||||||
hc.set_sync_file(sync_file);
|
hc.set_sync_file(sync_file);
|
||||||
|
|
|
||||||
|
|
@ -208,13 +208,13 @@ pub enum AcquireSync {
|
||||||
impl AcquireSync {
|
impl AcquireSync {
|
||||||
pub fn from_sync_file(sync_file: Option<SyncFile>) -> Self {
|
pub fn from_sync_file(sync_file: Option<SyncFile>) -> Self {
|
||||||
match sync_file {
|
match sync_file {
|
||||||
None => Self::Implicit,
|
None => Self::Unnecessary,
|
||||||
Some(sync_file) => Self::SyncFile { sync_file },
|
Some(sync_file) => Self::SyncFile { sync_file },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
pub enum ReleaseSync {
|
pub enum ReleaseSync {
|
||||||
None,
|
None,
|
||||||
Implicit,
|
Implicit,
|
||||||
|
|
@ -260,6 +260,8 @@ pub trait GfxFramebuffer: Debug {
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
ops: &[GfxApiOpt],
|
ops: &[GfxApiOpt],
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
) -> Result<Option<SyncFile>, GfxError>;
|
) -> Result<Option<SyncFile>, GfxError>;
|
||||||
|
|
@ -279,12 +281,24 @@ pub trait GfxFramebuffer: Debug {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl dyn GfxFramebuffer {
|
impl dyn GfxFramebuffer {
|
||||||
pub fn clear(&self) -> Result<Option<SyncFile>, GfxError> {
|
pub fn clear(
|
||||||
self.clear_with(0.0, 0.0, 0.0, 0.0)
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
|
self.clear_with(acquire_sync, release_sync, 0.0, 0.0, 0.0, 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_with(&self, r: f32, g: f32, b: f32, a: f32) -> Result<Option<SyncFile>, GfxError> {
|
pub fn clear_with(
|
||||||
self.render(&[], Some(&Color { r, g, b, a }))
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
|
r: f32,
|
||||||
|
g: f32,
|
||||||
|
b: f32,
|
||||||
|
a: f32,
|
||||||
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
|
self.render(acquire_sync, release_sync, &[], Some(&Color { r, g, b, a }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn logical_size(&self, transform: Transform) -> (i32, i32) {
|
pub fn logical_size(&self, transform: Transform) -> (i32, i32) {
|
||||||
|
|
@ -302,7 +316,10 @@ impl dyn GfxFramebuffer {
|
||||||
|
|
||||||
pub fn copy_texture(
|
pub fn copy_texture(
|
||||||
&self,
|
&self,
|
||||||
|
fb_acquire_sync: AcquireSync,
|
||||||
|
fb_release_sync: ReleaseSync,
|
||||||
texture: &Rc<dyn GfxTexture>,
|
texture: &Rc<dyn GfxTexture>,
|
||||||
|
resv: Option<&Rc<dyn BufferResv>>,
|
||||||
acquire_sync: AcquireSync,
|
acquire_sync: AcquireSync,
|
||||||
release_sync: ReleaseSync,
|
release_sync: ReleaseSync,
|
||||||
x: i32,
|
x: i32,
|
||||||
|
|
@ -320,16 +337,18 @@ impl dyn GfxFramebuffer {
|
||||||
None,
|
None,
|
||||||
scale,
|
scale,
|
||||||
None,
|
None,
|
||||||
None,
|
resv.cloned(),
|
||||||
acquire_sync,
|
acquire_sync,
|
||||||
release_sync,
|
release_sync,
|
||||||
);
|
);
|
||||||
let clear = self.format().has_alpha.then_some(&Color::TRANSPARENT);
|
let clear = self.format().has_alpha.then_some(&Color::TRANSPARENT);
|
||||||
self.render(&ops, clear)
|
self.render(fb_acquire_sync, fb_release_sync, &ops, clear)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_custom(
|
pub fn render_custom(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
scale: Scale,
|
scale: Scale,
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
f: &mut dyn FnMut(&mut RendererBase),
|
f: &mut dyn FnMut(&mut RendererBase),
|
||||||
|
|
@ -337,7 +356,7 @@ impl dyn GfxFramebuffer {
|
||||||
let mut ops = vec![];
|
let mut ops = vec![];
|
||||||
let mut renderer = self.renderer_base(&mut ops, scale, Transform::None);
|
let mut renderer = self.renderer_base(&mut ops, scale, Transform::None);
|
||||||
f(&mut renderer);
|
f(&mut renderer);
|
||||||
self.render(&ops, clear)
|
self.render(acquire_sync, release_sync, &ops, clear)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_render_pass(
|
pub fn create_render_pass(
|
||||||
|
|
@ -366,12 +385,19 @@ impl dyn GfxFramebuffer {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_render_pass(&self, pass: &GfxRenderPass) -> Result<Option<SyncFile>, GfxError> {
|
pub fn perform_render_pass(
|
||||||
self.render(&pass.ops, pass.clear.as_ref())
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
|
pass: &GfxRenderPass,
|
||||||
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
|
self.render(acquire_sync, release_sync, &pass.ops, pass.clear.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_output(
|
pub fn render_output(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
node: &OutputNode,
|
node: &OutputNode,
|
||||||
state: &State,
|
state: &State,
|
||||||
cursor_rect: Option<Rect>,
|
cursor_rect: Option<Rect>,
|
||||||
|
|
@ -379,6 +405,8 @@ impl dyn GfxFramebuffer {
|
||||||
render_hardware_cursor: bool,
|
render_hardware_cursor: bool,
|
||||||
) -> Result<Option<SyncFile>, GfxError> {
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
self.render_node(
|
self.render_node(
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
node,
|
node,
|
||||||
state,
|
state,
|
||||||
cursor_rect,
|
cursor_rect,
|
||||||
|
|
@ -392,6 +420,8 @@ impl dyn GfxFramebuffer {
|
||||||
|
|
||||||
pub fn render_node(
|
pub fn render_node(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
node: &dyn Node,
|
node: &dyn Node,
|
||||||
state: &State,
|
state: &State,
|
||||||
cursor_rect: Option<Rect>,
|
cursor_rect: Option<Rect>,
|
||||||
|
|
@ -412,11 +442,13 @@ impl dyn GfxFramebuffer {
|
||||||
transform,
|
transform,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
self.perform_render_pass(&pass)
|
self.perform_render_pass(acquire_sync, release_sync, &pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_hardware_cursor(
|
pub fn render_hardware_cursor(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
cursor: &dyn Cursor,
|
cursor: &dyn Cursor,
|
||||||
state: &State,
|
state: &State,
|
||||||
scale: Scale,
|
scale: Scale,
|
||||||
|
|
@ -433,7 +465,7 @@ impl dyn GfxFramebuffer {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
cursor.render_hardware_cursor(&mut renderer);
|
cursor.render_hardware_cursor(&mut renderer);
|
||||||
self.render(&ops, Some(&Color::TRANSPARENT))
|
self.render(acquire_sync, release_sync, &ops, Some(&Color::TRANSPARENT))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ use {
|
||||||
ReleaseSync, SyncFile,
|
ReleaseSync, SyncFile,
|
||||||
},
|
},
|
||||||
gfx_apis::gl::{
|
gfx_apis::gl::{
|
||||||
|
egl::image::EglImage,
|
||||||
gl::texture::image_target,
|
gl::texture::image_target,
|
||||||
renderer::{
|
renderer::{
|
||||||
context::{GlRenderContext, TexCopyType, TexSourceType},
|
context::{GlRenderContext, TexCopyType, TexSourceType},
|
||||||
|
|
@ -328,7 +329,7 @@ fn render_texture(ctx: &GlRenderContext, tex: &CopyTexture) {
|
||||||
assert!(rc_eq(&ctx.ctx, &texture.ctx.ctx));
|
assert!(rc_eq(&ctx.ctx, &texture.ctx.ctx));
|
||||||
let gles = ctx.ctx.dpy.gles;
|
let gles = ctx.ctx.dpy.gles;
|
||||||
unsafe {
|
unsafe {
|
||||||
handle_explicit_sync(ctx, texture, &tex.acquire_sync);
|
handle_explicit_sync(ctx, texture.gl.img.as_ref(), &tex.acquire_sync);
|
||||||
|
|
||||||
(gles.glActiveTexture)(GL_TEXTURE0);
|
(gles.glActiveTexture)(GL_TEXTURE0);
|
||||||
|
|
||||||
|
|
@ -395,7 +396,7 @@ fn render_texture(ctx: &GlRenderContext, tex: &CopyTexture) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_explicit_sync(ctx: &GlRenderContext, texture: &Texture, sync: &AcquireSync) {
|
fn handle_explicit_sync(ctx: &GlRenderContext, img: Option<&Rc<EglImage>>, sync: &AcquireSync) {
|
||||||
let sync_file = match sync {
|
let sync_file = match sync {
|
||||||
AcquireSync::None | AcquireSync::Implicit | AcquireSync::Unnecessary => return,
|
AcquireSync::None | AcquireSync::Implicit | AcquireSync::Unnecessary => return,
|
||||||
AcquireSync::SyncFile { sync_file } => sync_file,
|
AcquireSync::SyncFile { sync_file } => sync_file,
|
||||||
|
|
@ -417,7 +418,7 @@ fn handle_explicit_sync(ctx: &GlRenderContext, texture: &Texture, sync: &Acquire
|
||||||
};
|
};
|
||||||
sync.wait();
|
sync.wait();
|
||||||
} else {
|
} else {
|
||||||
if let Some(img) = &texture.gl.img {
|
if let Some(img) = img {
|
||||||
if let Err(e) = img.dmabuf.import_sync_file(DMA_BUF_SYNC_READ, &sync_file) {
|
if let Err(e) = img.dmabuf.import_sync_file(DMA_BUF_SYNC_READ, &sync_file) {
|
||||||
log::error!("Could not import sync file into dmabuf: {}", ErrorFmt(e));
|
log::error!("Could not import sync file into dmabuf: {}", ErrorFmt(e));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
format::Format,
|
format::Format,
|
||||||
gfx_api::{GfxApiOpt, GfxError, GfxFramebuffer, SyncFile},
|
gfx_api::{AcquireSync, GfxApiOpt, GfxError, GfxFramebuffer, ReleaseSync, SyncFile},
|
||||||
gfx_apis::gl::{
|
gfx_apis::gl::{
|
||||||
gl::{
|
gl::{
|
||||||
frame_buffer::GlFrameBuffer,
|
frame_buffer::GlFrameBuffer,
|
||||||
sys::{GL_COLOR_BUFFER_BIT, GL_FRAMEBUFFER},
|
sys::{GL_COLOR_BUFFER_BIT, GL_FRAMEBUFFER},
|
||||||
},
|
},
|
||||||
|
handle_explicit_sync,
|
||||||
renderer::context::GlRenderContext,
|
renderer::context::GlRenderContext,
|
||||||
run_ops,
|
run_ops,
|
||||||
sys::{GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
|
sys::{GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
|
||||||
|
|
@ -69,11 +70,13 @@ impl Framebuffer {
|
||||||
|
|
||||||
pub fn render(
|
pub fn render(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
ops: &[GfxApiOpt],
|
ops: &[GfxApiOpt],
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
) -> Result<Option<SyncFile>, RenderError> {
|
) -> Result<Option<SyncFile>, RenderError> {
|
||||||
let gles = self.ctx.ctx.dpy.gles;
|
let gles = self.ctx.ctx.dpy.gles;
|
||||||
self.ctx.ctx.with_current(|| {
|
self.ctx.ctx.with_current(|| {
|
||||||
|
handle_explicit_sync(&self.ctx, self.gl.rb._img.as_ref(), &acquire_sync);
|
||||||
unsafe {
|
unsafe {
|
||||||
(gles.glBindFramebuffer)(GL_FRAMEBUFFER, self.gl.fbo);
|
(gles.glBindFramebuffer)(GL_FRAMEBUFFER, self.gl.fbo);
|
||||||
(gles.glViewport)(0, 0, self.gl.width, self.gl.height);
|
(gles.glViewport)(0, 0, self.gl.width, self.gl.height);
|
||||||
|
|
@ -101,10 +104,12 @@ impl GfxFramebuffer for Framebuffer {
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
_release_sync: ReleaseSync,
|
||||||
ops: &[GfxApiOpt],
|
ops: &[GfxApiOpt],
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
) -> Result<Option<SyncFile>, GfxError> {
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
self.render(ops, clear).map_err(|e| e.into())
|
self.render(acquire_sync, ops, clear).map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_to_shm(
|
fn copy_to_shm(
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ use {
|
||||||
clientmem::ClientMemOffset,
|
clientmem::ClientMemOffset,
|
||||||
format::Format,
|
format::Format,
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AsyncShmGfxTexture, AsyncShmGfxTextureCallback, AsyncShmGfxTextureUploadCancellable,
|
AcquireSync, AsyncShmGfxTexture, AsyncShmGfxTextureCallback,
|
||||||
GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, PendingShmUpload,
|
AsyncShmGfxTextureUploadCancellable, GfxApiOpt, GfxError, GfxFramebuffer, GfxImage,
|
||||||
ShmGfxTexture, SyncFile,
|
GfxTexture, PendingShmUpload, ReleaseSync, ShmGfxTexture, SyncFile,
|
||||||
},
|
},
|
||||||
gfx_apis::vulkan::{
|
gfx_apis::vulkan::{
|
||||||
allocator::VulkanAllocation, device::VulkanDevice, format::VulkanModifierLimits,
|
allocator::VulkanAllocation, device::VulkanDevice, format::VulkanModifierLimits,
|
||||||
|
|
@ -465,11 +465,13 @@ impl GfxFramebuffer for VulkanImage {
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
ops: &[GfxApiOpt],
|
ops: &[GfxApiOpt],
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
) -> Result<Option<SyncFile>, GfxError> {
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
self.renderer
|
self.renderer
|
||||||
.execute(self, ops, clear)
|
.execute(self, acquire_sync, release_sync, ops, clear)
|
||||||
.map_err(|e| e.into())
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -643,7 +643,11 @@ impl VulkanRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_wait_semaphores(&self, fb: &VulkanImage) -> Result<(), VulkanError> {
|
fn create_wait_semaphores(
|
||||||
|
&self,
|
||||||
|
fb: &VulkanImage,
|
||||||
|
fb_acquire_sync: &AcquireSync,
|
||||||
|
) -> Result<(), VulkanError> {
|
||||||
zone!("create_wait_semaphores");
|
zone!("create_wait_semaphores");
|
||||||
let mut memory = self.memory.borrow_mut();
|
let mut memory = self.memory.borrow_mut();
|
||||||
let memory = &mut *memory;
|
let memory = &mut *memory;
|
||||||
|
|
@ -699,13 +703,13 @@ impl VulkanRenderer {
|
||||||
&mut memory.wait_semaphore_infos,
|
&mut memory.wait_semaphore_infos,
|
||||||
&mut memory.wait_semaphores,
|
&mut memory.wait_semaphores,
|
||||||
fb,
|
fb,
|
||||||
&AcquireSync::Implicit,
|
fb_acquire_sync,
|
||||||
DMA_BUF_SYNC_WRITE,
|
DMA_BUF_SYNC_WRITE,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_release_semaphore(&self, fb: &VulkanImage) {
|
fn import_release_semaphore(&self, fb: &VulkanImage, fb_release_sync: ReleaseSync) {
|
||||||
zone!("import_release_semaphore");
|
zone!("import_release_semaphore");
|
||||||
let memory = &mut *self.memory.borrow_mut();
|
let memory = &mut *self.memory.borrow_mut();
|
||||||
let sync_file = match memory.release_sync_file.as_ref() {
|
let sync_file = match memory.release_sync_file.as_ref() {
|
||||||
|
|
@ -736,7 +740,7 @@ impl VulkanRenderer {
|
||||||
DMA_BUF_SYNC_READ,
|
DMA_BUF_SYNC_READ,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
import(fb, ReleaseSync::Implicit, None, DMA_BUF_SYNC_WRITE);
|
import(fb, fb_release_sync, None, DMA_BUF_SYNC_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn submit(&self, buf: CommandBuffer) -> Result<(), VulkanError> {
|
fn submit(&self, buf: CommandBuffer) -> Result<(), VulkanError> {
|
||||||
|
|
@ -838,7 +842,10 @@ impl VulkanRenderer {
|
||||||
)?;
|
)?;
|
||||||
(&*tmp_tex as &dyn GfxFramebuffer)
|
(&*tmp_tex as &dyn GfxFramebuffer)
|
||||||
.copy_texture(
|
.copy_texture(
|
||||||
|
AcquireSync::None,
|
||||||
|
ReleaseSync::None,
|
||||||
&(tex.clone() as _),
|
&(tex.clone() as _),
|
||||||
|
None,
|
||||||
AcquireSync::None,
|
AcquireSync::None,
|
||||||
ReleaseSync::None,
|
ReleaseSync::None,
|
||||||
x,
|
x,
|
||||||
|
|
@ -992,11 +999,13 @@ impl VulkanRenderer {
|
||||||
pub fn execute(
|
pub fn execute(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
fb: &VulkanImage,
|
fb: &VulkanImage,
|
||||||
|
fb_acquire_sync: AcquireSync,
|
||||||
|
fb_release_sync: ReleaseSync,
|
||||||
opts: &[GfxApiOpt],
|
opts: &[GfxApiOpt],
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
) -> Result<Option<SyncFile>, VulkanError> {
|
) -> Result<Option<SyncFile>, VulkanError> {
|
||||||
zone!("execute");
|
zone!("execute");
|
||||||
let res = self.try_execute(fb, opts, clear);
|
let res = self.try_execute(fb, fb_acquire_sync, fb_release_sync, opts, clear);
|
||||||
let sync_file = {
|
let sync_file = {
|
||||||
let mut memory = self.memory.borrow_mut();
|
let mut memory = self.memory.borrow_mut();
|
||||||
memory.textures.clear();
|
memory.textures.clear();
|
||||||
|
|
@ -1032,6 +1041,8 @@ impl VulkanRenderer {
|
||||||
fn try_execute(
|
fn try_execute(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
fb: &VulkanImage,
|
fb: &VulkanImage,
|
||||||
|
fb_acquire_sync: AcquireSync,
|
||||||
|
fb_release_sync: ReleaseSync,
|
||||||
opts: &[GfxApiOpt],
|
opts: &[GfxApiOpt],
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
) -> Result<(), VulkanError> {
|
) -> Result<(), VulkanError> {
|
||||||
|
|
@ -1047,9 +1058,9 @@ impl VulkanRenderer {
|
||||||
self.copy_bridge_to_dmabuf(buf.buffer, fb);
|
self.copy_bridge_to_dmabuf(buf.buffer, fb);
|
||||||
self.final_barriers(buf.buffer, fb);
|
self.final_barriers(buf.buffer, fb);
|
||||||
self.end_command_buffer(buf.buffer)?;
|
self.end_command_buffer(buf.buffer)?;
|
||||||
self.create_wait_semaphores(fb)?;
|
self.create_wait_semaphores(fb, &fb_acquire_sync)?;
|
||||||
self.submit(buf.buffer)?;
|
self.submit(buf.buffer)?;
|
||||||
self.import_release_semaphore(fb);
|
self.import_release_semaphore(fb, fb_release_sync);
|
||||||
self.store_layouts(fb);
|
self.store_layouts(fb);
|
||||||
self.create_pending_frame(buf);
|
self.create_pending_frame(buf);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ use {
|
||||||
allocator::{AllocatorError, BufferObject, BO_USE_LINEAR, BO_USE_RENDERING},
|
allocator::{AllocatorError, BufferObject, BO_USE_LINEAR, BO_USE_RENDERING},
|
||||||
client::{Client, ClientError},
|
client::{Client, ClientError},
|
||||||
format::XRGB8888,
|
format::XRGB8888,
|
||||||
gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture},
|
gfx_api::{
|
||||||
|
AcquireSync, BufferResv, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync,
|
||||||
|
},
|
||||||
ifs::{jay_output::JayOutput, jay_toplevel::JayToplevel, wl_buffer::WlBufferStorage},
|
ifs::{jay_output::JayOutput, jay_toplevel::JayToplevel, wl_buffer::WlBufferStorage},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
|
|
@ -189,6 +191,8 @@ impl JayScreencast {
|
||||||
for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() {
|
for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() {
|
||||||
if buffer.free {
|
if buffer.free {
|
||||||
let res = buffer.fb.render_node(
|
let res = buffer.fb.render_node(
|
||||||
|
AcquireSync::Implicit,
|
||||||
|
ReleaseSync::Implicit,
|
||||||
tl.tl_as_node(),
|
tl.tl_as_node(),
|
||||||
&self.client.state,
|
&self.client.state,
|
||||||
Some(tl.node_absolute_position()),
|
Some(tl.node_absolute_position()),
|
||||||
|
|
@ -298,6 +302,9 @@ impl JayScreencast {
|
||||||
&self,
|
&self,
|
||||||
on: &OutputNode,
|
on: &OutputNode,
|
||||||
texture: &Rc<dyn GfxTexture>,
|
texture: &Rc<dyn GfxTexture>,
|
||||||
|
resv: Option<&Rc<dyn BufferResv>>,
|
||||||
|
acquire_sync: &AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
render_hardware_cursors: bool,
|
render_hardware_cursors: bool,
|
||||||
x_off: i32,
|
x_off: i32,
|
||||||
y_off: i32,
|
y_off: i32,
|
||||||
|
|
@ -320,7 +327,12 @@ impl JayScreencast {
|
||||||
if buffer.free {
|
if buffer.free {
|
||||||
let res = self.client.state.perform_screencopy(
|
let res = self.client.state.perform_screencopy(
|
||||||
texture,
|
texture,
|
||||||
|
resv,
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
&buffer.fb,
|
&buffer.fb,
|
||||||
|
AcquireSync::Implicit,
|
||||||
|
ReleaseSync::Implicit,
|
||||||
on.global.pos.get(),
|
on.global.pos.get(),
|
||||||
render_hardware_cursors,
|
render_hardware_cursors,
|
||||||
x_off,
|
x_off,
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@ use {
|
||||||
cpu_worker::CpuWorker,
|
cpu_worker::CpuWorker,
|
||||||
format::{Format, ARGB8888, XRGB8888},
|
format::{Format, ARGB8888, XRGB8888},
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AsyncShmGfxTexture, AsyncShmGfxTextureCallback, CopyTexture, FillRect, FramebufferRect,
|
AcquireSync, AsyncShmGfxTexture, AsyncShmGfxTextureCallback, CopyTexture, FillRect,
|
||||||
GfxApiOpt, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxTexture,
|
FramebufferRect, GfxApiOpt, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage,
|
||||||
GfxWriteModifier, PendingShmUpload, ResetStatus, ShmGfxTexture, SyncFile,
|
GfxTexture, GfxWriteModifier, PendingShmUpload, ReleaseSync, ResetStatus,
|
||||||
|
ShmGfxTexture, SyncFile,
|
||||||
},
|
},
|
||||||
rect::{Rect, Region},
|
rect::{Rect, Region},
|
||||||
theme::Color,
|
theme::Color,
|
||||||
|
|
@ -413,6 +414,8 @@ impl GfxFramebuffer for TestGfxFb {
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
|
_acquire_sync: AcquireSync,
|
||||||
|
_release_sync: ReleaseSync,
|
||||||
ops: &[GfxApiOpt],
|
ops: &[GfxApiOpt],
|
||||||
clear: Option<&Color>,
|
clear: Option<&Color>,
|
||||||
) -> Result<Option<SyncFile>, GfxError> {
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
|
|
|
||||||
|
|
@ -635,13 +635,17 @@ impl WindowData {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = buf
|
let res = buf.fb.render_custom(
|
||||||
.fb
|
AcquireSync::Implicit,
|
||||||
.render_custom(self.scale.get(), Some(&Color::from_gray(0)), &mut |r| {
|
ReleaseSync::Implicit,
|
||||||
|
self.scale.get(),
|
||||||
|
Some(&Color::from_gray(0)),
|
||||||
|
&mut |r| {
|
||||||
if let Some(content) = self.content.get() {
|
if let Some(content) = self.content.get() {
|
||||||
content.render_at(r, 0.0, 0.0)
|
content.render_at(r, 0.0, 0.0)
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
log::error!("Could not render frame: {}", ErrorFmt(e));
|
log::error!("Could not render frame: {}", ErrorFmt(e));
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
allocator::{AllocatorError, BufferObject, BufferUsage, BO_USE_RENDERING},
|
allocator::{AllocatorError, BufferObject, BufferUsage, BO_USE_RENDERING},
|
||||||
format::XRGB8888,
|
format::XRGB8888,
|
||||||
gfx_api::{needs_render_usage, GfxError},
|
gfx_api::{needs_render_usage, AcquireSync, GfxError, ReleaseSync},
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
state::State,
|
state::State,
|
||||||
video::drm::DrmError,
|
video::drm::DrmError,
|
||||||
|
|
@ -77,6 +77,8 @@ pub fn take_screenshot(
|
||||||
)?;
|
)?;
|
||||||
let fb = ctx.clone().dmabuf_fb(bo.dmabuf())?;
|
let fb = ctx.clone().dmabuf_fb(bo.dmabuf())?;
|
||||||
fb.render_node(
|
fb.render_node(
|
||||||
|
AcquireSync::Unnecessary,
|
||||||
|
ReleaseSync::Implicit,
|
||||||
state.root.deref(),
|
state.root.deref(),
|
||||||
state,
|
state,
|
||||||
Some(state.root.extents.get()),
|
Some(state.root.extents.get()),
|
||||||
|
|
|
||||||
43
src/state.rs
43
src/state.rs
|
|
@ -27,8 +27,8 @@ use {
|
||||||
forker::ForkerProxy,
|
forker::ForkerProxy,
|
||||||
format::Format,
|
format::Format,
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AcquireSync, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync, SampleRect,
|
AcquireSync, BufferResv, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync,
|
||||||
SyncFile,
|
SampleRect, SyncFile,
|
||||||
},
|
},
|
||||||
gfx_apis::create_gfx_context,
|
gfx_apis::create_gfx_context,
|
||||||
globals::{Globals, GlobalsError, RemovableWaylandGlobal, WaylandGlobal},
|
globals::{Globals, GlobalsError, RemovableWaylandGlobal, WaylandGlobal},
|
||||||
|
|
@ -900,10 +900,14 @@ impl State {
|
||||||
&self,
|
&self,
|
||||||
output: &OutputNode,
|
output: &OutputNode,
|
||||||
fb: &Rc<dyn GfxFramebuffer>,
|
fb: &Rc<dyn GfxFramebuffer>,
|
||||||
|
acquire_sync: AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
tex: &Rc<dyn GfxTexture>,
|
tex: &Rc<dyn GfxTexture>,
|
||||||
render_hw_cursor: bool,
|
render_hw_cursor: bool,
|
||||||
) -> Result<Option<SyncFile>, GfxError> {
|
) -> Result<Option<SyncFile>, GfxError> {
|
||||||
let sync_file = fb.render_output(
|
let sync_file = fb.render_output(
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
output,
|
output,
|
||||||
self,
|
self,
|
||||||
Some(output.global.pos.get()),
|
Some(output.global.pos.get()),
|
||||||
|
|
@ -911,14 +915,28 @@ impl State {
|
||||||
render_hw_cursor,
|
render_hw_cursor,
|
||||||
)?;
|
)?;
|
||||||
output.latched();
|
output.latched();
|
||||||
output.perform_screencopies(tex, !render_hw_cursor, 0, 0, None);
|
output.perform_screencopies(
|
||||||
|
tex,
|
||||||
|
None,
|
||||||
|
&AcquireSync::Unnecessary,
|
||||||
|
ReleaseSync::None,
|
||||||
|
!render_hw_cursor,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
);
|
||||||
Ok(sync_file)
|
Ok(sync_file)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_screencopy(
|
pub fn perform_screencopy(
|
||||||
&self,
|
&self,
|
||||||
src: &Rc<dyn GfxTexture>,
|
src: &Rc<dyn GfxTexture>,
|
||||||
|
resv: Option<&Rc<dyn BufferResv>>,
|
||||||
|
acquire_sync: &AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
target: &Rc<dyn GfxFramebuffer>,
|
target: &Rc<dyn GfxFramebuffer>,
|
||||||
|
target_acquire_sync: AcquireSync,
|
||||||
|
target_release_sync: ReleaseSync,
|
||||||
position: Rect,
|
position: Rect,
|
||||||
render_hardware_cursors: bool,
|
render_hardware_cursors: bool,
|
||||||
x_off: i32,
|
x_off: i32,
|
||||||
|
|
@ -947,9 +965,9 @@ impl State {
|
||||||
size,
|
size,
|
||||||
Scale::from_int(1),
|
Scale::from_int(1),
|
||||||
None,
|
None,
|
||||||
None,
|
resv.cloned(),
|
||||||
AcquireSync::None,
|
acquire_sync.clone(),
|
||||||
ReleaseSync::Implicit,
|
release_sync,
|
||||||
);
|
);
|
||||||
if render_hardware_cursors {
|
if render_hardware_cursors {
|
||||||
if let Some(cursor_user_group) = self.cursor_user_group_hardware_cursor.get() {
|
if let Some(cursor_user_group) = self.cursor_user_group_hardware_cursor.get() {
|
||||||
|
|
@ -963,7 +981,12 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target.render(&ops, Some(&Color::SOLID_BLACK))
|
target.render(
|
||||||
|
target_acquire_sync,
|
||||||
|
target_release_sync,
|
||||||
|
&ops,
|
||||||
|
Some(&Color::SOLID_BLACK),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn have_hardware_cursor(&self) -> bool {
|
fn have_hardware_cursor(&self) -> bool {
|
||||||
|
|
@ -980,6 +1003,7 @@ impl State {
|
||||||
pub fn perform_shm_screencopy(
|
pub fn perform_shm_screencopy(
|
||||||
&self,
|
&self,
|
||||||
src: &Rc<dyn GfxTexture>,
|
src: &Rc<dyn GfxTexture>,
|
||||||
|
acquire_sync: &AcquireSync,
|
||||||
position: Rect,
|
position: Rect,
|
||||||
x_off: i32,
|
x_off: i32,
|
||||||
y_off: i32,
|
y_off: i32,
|
||||||
|
|
@ -1011,7 +1035,12 @@ impl State {
|
||||||
.map_err(ShmScreencopyError::CreateTemporaryFb)?;
|
.map_err(ShmScreencopyError::CreateTemporaryFb)?;
|
||||||
self.perform_screencopy(
|
self.perform_screencopy(
|
||||||
src,
|
src,
|
||||||
|
None,
|
||||||
|
acquire_sync,
|
||||||
|
ReleaseSync::None,
|
||||||
&fb,
|
&fb,
|
||||||
|
AcquireSync::Unnecessary,
|
||||||
|
ReleaseSync::None,
|
||||||
position,
|
position,
|
||||||
true,
|
true,
|
||||||
x_off - capture.rect.x1(),
|
x_off - capture.rect.x1(),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use {
|
||||||
client::ClientId,
|
client::ClientId,
|
||||||
cursor::KnownCursor,
|
cursor::KnownCursor,
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
gfx_api::GfxTexture,
|
gfx_api::{AcquireSync, BufferResv, GfxTexture, ReleaseSync},
|
||||||
ifs::{
|
ifs::{
|
||||||
jay_output::JayOutput,
|
jay_output::JayOutput,
|
||||||
jay_screencast::JayScreencast,
|
jay_screencast::JayScreencast,
|
||||||
|
|
@ -186,6 +186,9 @@ impl OutputNode {
|
||||||
pub fn perform_screencopies(
|
pub fn perform_screencopies(
|
||||||
&self,
|
&self,
|
||||||
tex: &Rc<dyn GfxTexture>,
|
tex: &Rc<dyn GfxTexture>,
|
||||||
|
resv: Option<&Rc<dyn BufferResv>>,
|
||||||
|
acquire_sync: &AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
render_hardware_cursor: bool,
|
render_hardware_cursor: bool,
|
||||||
x_off: i32,
|
x_off: i32,
|
||||||
y_off: i32,
|
y_off: i32,
|
||||||
|
|
@ -196,15 +199,37 @@ impl OutputNode {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.perform_wlr_screencopies(tex, render_hardware_cursor, x_off, y_off, size);
|
self.perform_wlr_screencopies(
|
||||||
|
tex,
|
||||||
|
resv,
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
|
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,
|
||||||
|
resv,
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
|
render_hardware_cursor,
|
||||||
|
x_off,
|
||||||
|
y_off,
|
||||||
|
size,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_wlr_screencopies(
|
pub fn perform_wlr_screencopies(
|
||||||
&self,
|
&self,
|
||||||
tex: &Rc<dyn GfxTexture>,
|
tex: &Rc<dyn GfxTexture>,
|
||||||
|
resv: Option<&Rc<dyn BufferResv>>,
|
||||||
|
acquire_sync: &AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
render_hardware_cursors: bool,
|
render_hardware_cursors: bool,
|
||||||
x_off: i32,
|
x_off: i32,
|
||||||
y_off: i32,
|
y_off: i32,
|
||||||
|
|
@ -232,6 +257,7 @@ impl OutputNode {
|
||||||
WlBufferStorage::Shm { mem, stride } => {
|
WlBufferStorage::Shm { mem, stride } => {
|
||||||
let res = self.state.perform_shm_screencopy(
|
let res = self.state.perform_shm_screencopy(
|
||||||
tex,
|
tex,
|
||||||
|
acquire_sync,
|
||||||
self.global.pos.get(),
|
self.global.pos.get(),
|
||||||
x_off,
|
x_off,
|
||||||
y_off,
|
y_off,
|
||||||
|
|
@ -259,7 +285,12 @@ impl OutputNode {
|
||||||
};
|
};
|
||||||
let res = self.state.perform_screencopy(
|
let res = self.state.perform_screencopy(
|
||||||
tex,
|
tex,
|
||||||
|
resv,
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
&fb,
|
&fb,
|
||||||
|
AcquireSync::Implicit,
|
||||||
|
ReleaseSync::Implicit,
|
||||||
self.global.pos.get(),
|
self.global.pos.get(),
|
||||||
render_hardware_cursors,
|
render_hardware_cursors,
|
||||||
x_off - capture.rect.x1(),
|
x_off - capture.rect.x1(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue