render: split rendering into two phases
In the first phase we collect a list of simple operations (copying textures and filling rectangles.) In the second phase we send this list to the graphics API to be executed. As part of this, we also remove the use of scissors.
This commit is contained in:
parent
a2a04512ed
commit
5e8a6eb86f
27 changed files with 732 additions and 384 deletions
|
|
@ -147,7 +147,7 @@ impl JayScreencast {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn copy_texture(&self, on: &OutputNode, texture: &Texture) {
|
||||
pub fn copy_texture(&self, on: &OutputNode, texture: &Rc<Texture>) {
|
||||
if !self.running.get() {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ impl WlOutputGlobal {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn perform_screencopies(&self, fb: &Framebuffer, tex: &Texture) {
|
||||
pub fn perform_screencopies(&self, fb: &Framebuffer, tex: &Rc<Texture>) {
|
||||
if self.pending_captures.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,10 @@ use {
|
|||
leaks::Tracker,
|
||||
object::Object,
|
||||
rect::{Rect, Region},
|
||||
render::Renderer,
|
||||
render::{
|
||||
gfx_api::{BufferPoint, BufferPoints},
|
||||
Renderer,
|
||||
},
|
||||
tree::{
|
||||
FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, NodeVisitorBase, OutputNode,
|
||||
ToplevelNode,
|
||||
|
|
@ -101,20 +104,6 @@ impl Transform {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct BufferPoint {
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct BufferPoints {
|
||||
top_right: BufferPoint,
|
||||
top_left: BufferPoint,
|
||||
bottom_right: BufferPoint,
|
||||
bottom_left: BufferPoint,
|
||||
}
|
||||
|
||||
impl Transform {
|
||||
fn apply_inv_sized(self, x1: f32, y1: f32, width: f32, height: f32) -> BufferPoints {
|
||||
let x2 = x1 + width;
|
||||
|
|
@ -237,7 +226,7 @@ pub struct WlSurface {
|
|||
input_region: Cell<Option<Rc<Region>>>,
|
||||
opaque_region: Cell<Option<Rc<Region>>>,
|
||||
buffer_points: RefCell<BufferPoints>,
|
||||
pub buffer_points_norm: RefCell<[f32; 8]>,
|
||||
pub buffer_points_norm: RefCell<BufferPoints>,
|
||||
buffer_transform: Cell<Transform>,
|
||||
buffer_scale: Cell<i32>,
|
||||
src_rect: Cell<Option<[Fixed; 4]>>,
|
||||
|
|
@ -817,35 +806,12 @@ impl WlSurface {
|
|||
.buffer_transform
|
||||
.get()
|
||||
.apply_inv_sized(0.0, 0.0, 1.0, 1.0);
|
||||
let points = &*buffer_points;
|
||||
*buffer_points_norm = [
|
||||
points.top_right.x,
|
||||
points.top_right.y,
|
||||
points.top_left.x,
|
||||
points.top_left.y,
|
||||
points.bottom_right.x,
|
||||
points.bottom_right.y,
|
||||
points.bottom_left.x,
|
||||
points.bottom_left.y,
|
||||
];
|
||||
*buffer_points_norm = *buffer_points;
|
||||
} else {
|
||||
let width = buffer.rect.width() as f32;
|
||||
let height = buffer.rect.height() as f32;
|
||||
let points = &*buffer_points;
|
||||
*buffer_points_norm = [
|
||||
points.top_right.x / width,
|
||||
points.top_right.y / height,
|
||||
points.top_left.x / width,
|
||||
points.top_left.y / height,
|
||||
points.bottom_right.x / width,
|
||||
points.bottom_right.y / height,
|
||||
points.bottom_left.x / width,
|
||||
points.bottom_left.y / height,
|
||||
];
|
||||
for &v in buffer_points_norm.iter() {
|
||||
if v > 1.0 {
|
||||
return Err(WlSurfaceError::ViewportOutsideBuffer);
|
||||
}
|
||||
*buffer_points_norm = buffer_points
|
||||
.norm(buffer.rect.width() as f32, buffer.rect.height() as f32);
|
||||
if !buffer_points_norm.is_leq_1() {
|
||||
return Err(WlSurfaceError::ViewportOutsideBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1134,8 +1100,15 @@ impl Node for WlSurface {
|
|||
}
|
||||
}
|
||||
|
||||
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_surface(self, x, y);
|
||||
fn node_render(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
x: i32,
|
||||
y: i32,
|
||||
max_width: i32,
|
||||
max_height: i32,
|
||||
) {
|
||||
renderer.render_surface(self, x, y, max_width, max_height);
|
||||
}
|
||||
|
||||
fn node_client(&self) -> Option<Rc<Client>> {
|
||||
|
|
|
|||
|
|
@ -76,16 +76,28 @@ impl Cursor for CursorSurface {
|
|||
let (hot_x, hot_y) = (Fixed::from_int(hot_x), Fixed::from_int(hot_y));
|
||||
let x = ((x - hot_x).to_f64() * scale).round() as _;
|
||||
let y = ((y - hot_y).to_f64() * scale).round() as _;
|
||||
renderer.render_surface_scaled(&self.surface, x, y, None);
|
||||
renderer.render_surface_scaled(&self.surface, x, y, None, i32::MAX, i32::MAX);
|
||||
} else {
|
||||
renderer.render_surface(&self.surface, x_int - hot_x, y_int - hot_y);
|
||||
renderer.render_surface(
|
||||
&self.surface,
|
||||
x_int - hot_x,
|
||||
y_int - hot_y,
|
||||
i32::MAX,
|
||||
i32::MAX,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_hardware_cursor(&self, renderer: &mut Renderer) {
|
||||
let extents = self.surface.extents.get();
|
||||
renderer.render_surface(&self.surface, -extents.x1(), -extents.y1());
|
||||
renderer.render_surface(
|
||||
&self.surface,
|
||||
-extents.x1(),
|
||||
-extents.y1(),
|
||||
i32::MAX,
|
||||
i32::MAX,
|
||||
);
|
||||
|
||||
struct FrameRequests;
|
||||
impl NodeVisitorBase for FrameRequests {
|
||||
|
|
|
|||
|
|
@ -334,8 +334,15 @@ impl Node for Xwindow {
|
|||
FindTreeResult::Other
|
||||
}
|
||||
|
||||
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_surface(&self.x.surface, x, y)
|
||||
fn node_render(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
x: i32,
|
||||
y: i32,
|
||||
max_width: i32,
|
||||
max_height: i32,
|
||||
) {
|
||||
renderer.render_surface(&self.x.surface, x, y, max_width, max_height)
|
||||
}
|
||||
|
||||
fn node_client(&self) -> Option<Rc<Client>> {
|
||||
|
|
|
|||
|
|
@ -308,8 +308,15 @@ impl Node for XdgPopup {
|
|||
self.xdg.find_tree_at(x, y, tree)
|
||||
}
|
||||
|
||||
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_xdg_surface(&self.xdg, x, y)
|
||||
fn node_render(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
x: i32,
|
||||
y: i32,
|
||||
max_width: i32,
|
||||
max_height: i32,
|
||||
) {
|
||||
renderer.render_xdg_surface(&self.xdg, x, y, max_width, max_height)
|
||||
}
|
||||
|
||||
fn node_client(&self) -> Option<Rc<Client>> {
|
||||
|
|
|
|||
|
|
@ -425,8 +425,15 @@ impl Node for XdgToplevel {
|
|||
self.xdg.find_tree_at(x, y, tree)
|
||||
}
|
||||
|
||||
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_xdg_surface(&self.xdg, x, y)
|
||||
fn node_render(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
x: i32,
|
||||
y: i32,
|
||||
max_width: i32,
|
||||
max_height: i32,
|
||||
) {
|
||||
renderer.render_xdg_surface(&self.xdg, x, y, max_width, max_height)
|
||||
}
|
||||
|
||||
fn node_client(&self) -> Option<Rc<Client>> {
|
||||
|
|
|
|||
|
|
@ -394,7 +394,14 @@ impl Node for ZwlrLayerSurfaceV1 {
|
|||
self.surface.find_tree_at_(x, y, tree)
|
||||
}
|
||||
|
||||
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
fn node_render(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
x: i32,
|
||||
y: i32,
|
||||
_max_width: i32,
|
||||
_max_height: i32,
|
||||
) {
|
||||
renderer.render_layer_surface(self, x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue