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