metal: wait for rendering to complete before committing buffers
This commit is contained in:
parent
93bfb9c0b4
commit
0dc5d9adb8
5 changed files with 881 additions and 681 deletions
185
src/gfx_api.rs
185
src/gfx_api.rs
|
|
@ -288,7 +288,7 @@ impl dyn GfxFramebuffer {
|
|||
}
|
||||
|
||||
pub fn logical_size(&self, transform: Transform) -> (i32, i32) {
|
||||
transform.maybe_swap(self.physical_size())
|
||||
logical_size(self.physical_size(), transform)
|
||||
}
|
||||
|
||||
pub fn renderer_base<'a>(
|
||||
|
|
@ -297,16 +297,7 @@ impl dyn GfxFramebuffer {
|
|||
scale: Scale,
|
||||
transform: Transform,
|
||||
) -> RendererBase<'a> {
|
||||
let (width, height) = self.logical_size(transform);
|
||||
RendererBase {
|
||||
ops,
|
||||
scaled: scale != 1,
|
||||
scale,
|
||||
scalef: scale.to_f64(),
|
||||
transform,
|
||||
fb_width: width as _,
|
||||
fb_height: height as _,
|
||||
}
|
||||
renderer_base(self.physical_size(), ops, scale, transform)
|
||||
}
|
||||
|
||||
pub fn copy_texture(
|
||||
|
|
@ -362,69 +353,19 @@ impl dyn GfxFramebuffer {
|
|||
transform: Transform,
|
||||
visualizer: Option<&DamageVisualizer>,
|
||||
) -> GfxRenderPass {
|
||||
let mut ops = vec![];
|
||||
let mut renderer = Renderer {
|
||||
base: self.renderer_base(&mut ops, scale, transform),
|
||||
create_render_pass(
|
||||
self.physical_size(),
|
||||
node,
|
||||
state,
|
||||
cursor_rect,
|
||||
result,
|
||||
logical_extents: node.node_absolute_position().at_point(0, 0),
|
||||
pixel_extents: {
|
||||
let (width, height) = self.logical_size(transform);
|
||||
Rect::new(0, 0, width, height).unwrap()
|
||||
},
|
||||
};
|
||||
node.node_render(&mut renderer, 0, 0, None);
|
||||
if let Some(rect) = cursor_rect {
|
||||
let seats = state.globals.lock_seats();
|
||||
for seat in seats.values() {
|
||||
let (x, y) = seat.pointer_cursor().position_int();
|
||||
if let Some(im) = seat.input_method() {
|
||||
for (_, popup) in &im.popups {
|
||||
if popup.surface.node_visible() {
|
||||
let pos = popup.surface.buffer_abs_pos.get();
|
||||
let extents = popup.surface.extents.get().move_(pos.x1(), pos.y1());
|
||||
if extents.intersects(&rect) {
|
||||
let (x, y) = rect.translate(pos.x1(), pos.y1());
|
||||
renderer.render_surface(&popup.surface, x, y, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(drag) = seat.toplevel_drag() {
|
||||
drag.render(&mut renderer, &rect, x, y);
|
||||
}
|
||||
if let Some(dnd_icon) = seat.dnd_icon() {
|
||||
dnd_icon.render(&mut renderer, &rect, x, y);
|
||||
}
|
||||
if render_cursor {
|
||||
let cursor_user_group = seat.cursor_group();
|
||||
if render_hardware_cursor || !cursor_user_group.hardware_cursor() {
|
||||
if let Some(cursor_user) = cursor_user_group.active() {
|
||||
if let Some(cursor) = cursor_user.get() {
|
||||
cursor.tick();
|
||||
let (mut x, mut y) = cursor_user.position();
|
||||
x -= Fixed::from_int(rect.x1());
|
||||
y -= Fixed::from_int(rect.y1());
|
||||
cursor.render(&mut renderer, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(visualizer) = visualizer {
|
||||
if let Some(cursor_rect) = cursor_rect {
|
||||
visualizer.render(&cursor_rect, &mut renderer.base);
|
||||
}
|
||||
}
|
||||
let c = match black_background {
|
||||
true => Color::SOLID_BLACK,
|
||||
false => state.theme.colors.background.get(),
|
||||
};
|
||||
GfxRenderPass {
|
||||
ops,
|
||||
clear: Some(c),
|
||||
}
|
||||
scale,
|
||||
render_cursor,
|
||||
render_hardware_cursor,
|
||||
black_background,
|
||||
transform,
|
||||
visualizer,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn perform_render_pass(&self, pass: &GfxRenderPass) -> Result<Option<SyncFile>, GfxError> {
|
||||
|
|
@ -691,3 +632,103 @@ impl Drop for PendingShmUpload {
|
|||
self.cancel.cancel(self.id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_render_pass(
|
||||
physical_size: (i32, i32),
|
||||
node: &dyn Node,
|
||||
state: &State,
|
||||
cursor_rect: Option<Rect>,
|
||||
result: Option<&mut RenderResult>,
|
||||
scale: Scale,
|
||||
render_cursor: bool,
|
||||
render_hardware_cursor: bool,
|
||||
black_background: bool,
|
||||
transform: Transform,
|
||||
visualizer: Option<&DamageVisualizer>,
|
||||
) -> GfxRenderPass {
|
||||
let mut ops = vec![];
|
||||
let mut renderer = Renderer {
|
||||
base: renderer_base(physical_size, &mut ops, scale, transform),
|
||||
state,
|
||||
result,
|
||||
logical_extents: node.node_absolute_position().at_point(0, 0),
|
||||
pixel_extents: {
|
||||
let (width, height) = logical_size(physical_size, transform);
|
||||
Rect::new(0, 0, width, height).unwrap()
|
||||
},
|
||||
};
|
||||
node.node_render(&mut renderer, 0, 0, None);
|
||||
if let Some(rect) = cursor_rect {
|
||||
let seats = state.globals.lock_seats();
|
||||
for seat in seats.values() {
|
||||
let (x, y) = seat.pointer_cursor().position_int();
|
||||
if let Some(im) = seat.input_method() {
|
||||
for (_, popup) in &im.popups {
|
||||
if popup.surface.node_visible() {
|
||||
let pos = popup.surface.buffer_abs_pos.get();
|
||||
let extents = popup.surface.extents.get().move_(pos.x1(), pos.y1());
|
||||
if extents.intersects(&rect) {
|
||||
let (x, y) = rect.translate(pos.x1(), pos.y1());
|
||||
renderer.render_surface(&popup.surface, x, y, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(drag) = seat.toplevel_drag() {
|
||||
drag.render(&mut renderer, &rect, x, y);
|
||||
}
|
||||
if let Some(dnd_icon) = seat.dnd_icon() {
|
||||
dnd_icon.render(&mut renderer, &rect, x, y);
|
||||
}
|
||||
if render_cursor {
|
||||
let cursor_user_group = seat.cursor_group();
|
||||
if render_hardware_cursor || !cursor_user_group.hardware_cursor() {
|
||||
if let Some(cursor_user) = cursor_user_group.active() {
|
||||
if let Some(cursor) = cursor_user.get() {
|
||||
cursor.tick();
|
||||
let (mut x, mut y) = cursor_user.position();
|
||||
x -= Fixed::from_int(rect.x1());
|
||||
y -= Fixed::from_int(rect.y1());
|
||||
cursor.render(&mut renderer, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(visualizer) = visualizer {
|
||||
if let Some(cursor_rect) = cursor_rect {
|
||||
visualizer.render(&cursor_rect, &mut renderer.base);
|
||||
}
|
||||
}
|
||||
let c = match black_background {
|
||||
true => Color::SOLID_BLACK,
|
||||
false => state.theme.colors.background.get(),
|
||||
};
|
||||
GfxRenderPass {
|
||||
ops,
|
||||
clear: Some(c),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn renderer_base<'a>(
|
||||
physical_size: (i32, i32),
|
||||
ops: &'a mut Vec<GfxApiOpt>,
|
||||
scale: Scale,
|
||||
transform: Transform,
|
||||
) -> RendererBase<'a> {
|
||||
let (width, height) = logical_size(physical_size, transform);
|
||||
RendererBase {
|
||||
ops,
|
||||
scaled: scale != 1,
|
||||
scale,
|
||||
scalef: scale.to_f64(),
|
||||
transform,
|
||||
fb_width: width as _,
|
||||
fb_height: height as _,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn logical_size(physical_size: (i32, i32), transform: Transform) -> (i32, i32) {
|
||||
transform.maybe_swap(physical_size)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue