@ -58,7 +58,7 @@ static void render_texture(struct wlr_output *wlr_output,
pixman_region32_intersect ( & damage , & damage , output_damage ) ;
pixman_region32_intersect ( & damage , & damage , output_damage ) ;
bool damaged = pixman_region32_not_empty ( & damage ) ;
bool damaged = pixman_region32_not_empty ( & damage ) ;
if ( ! damaged ) {
if ( ! damaged ) {
goto damage_finish;
goto buffer_ damage_finish;
}
}
int nrects ;
int nrects ;
@ -68,7 +68,7 @@ static void render_texture(struct wlr_output *wlr_output,
wlr_render_texture_with_matrix ( renderer , texture , matrix , alpha ) ;
wlr_render_texture_with_matrix ( renderer , texture , matrix , alpha ) ;
}
}
damage_finish:
buffer_ damage_finish:
pixman_region32_fini ( & damage ) ;
pixman_region32_fini ( & damage ) ;
}
}
@ -121,7 +121,7 @@ static void render_decorations(struct roots_output *output,
pixman_region32_intersect ( & damage , & damage , data - > damage ) ;
pixman_region32_intersect ( & damage , & damage , data - > damage ) ;
bool damaged = pixman_region32_not_empty ( & damage ) ;
bool damaged = pixman_region32_not_empty ( & damage ) ;
if ( ! damaged ) {
if ( ! damaged ) {
goto damage_finish;
goto buffer_ damage_finish;
}
}
float matrix [ 9 ] ;
float matrix [ 9 ] ;
@ -137,7 +137,7 @@ static void render_decorations(struct roots_output *output,
wlr_render_quad_with_matrix ( renderer , color , matrix ) ;
wlr_render_quad_with_matrix ( renderer , color , matrix ) ;
}
}
damage_finish:
buffer_ damage_finish:
pixman_region32_fini ( & damage ) ;
pixman_region32_fini ( & damage ) ;
}
}
@ -221,25 +221,26 @@ void output_render(struct roots_output *output) {
}
}
bool needs_frame ;
bool needs_frame ;
pixman_region32_t damage ;
pixman_region32_t buffer_damage ;
pixman_region32_init ( & damage ) ;
pixman_region32_init ( & buffer_damage ) ;
if ( ! wlr_output_damage_attach_render ( output - > damage , & needs_frame , & damage ) ) {
if ( ! wlr_output_damage_attach_render ( output - > damage , & needs_frame ,
& buffer_damage ) ) {
return ;
return ;
}
}
struct render_data data = {
struct render_data data = {
. damage = & damage,
. damage = & buffer_ damage,
. alpha = 1.0 ,
. alpha = 1.0 ,
} ;
} ;
if ( ! needs_frame ) {
if ( ! needs_frame ) {
// Output doesn't need swap and isn't damaged, skip rendering completely
// Output doesn't need swap and isn't damaged, skip rendering completely
goto damage_finish;
goto buffer_ damage_finish;
}
}
wlr_renderer_begin ( renderer , wlr_output - > width , wlr_output - > height ) ;
wlr_renderer_begin ( renderer , wlr_output - > width , wlr_output - > height ) ;
if ( ! pixman_region32_not_empty ( & damage) ) {
if ( ! pixman_region32_not_empty ( & buffer_ damage) ) {
// Output isn't damaged but needs buffer swap
// Output isn't damaged but needs buffer swap
goto renderer_end ;
goto renderer_end ;
}
}
@ -249,15 +250,15 @@ void output_render(struct roots_output *output) {
}
}
int nrects ;
int nrects ;
pixman_box32_t * rects = pixman_region32_rectangles ( & damage, & nrects ) ;
pixman_box32_t * rects = pixman_region32_rectangles ( & buffer_ damage, & nrects ) ;
for ( int i = 0 ; i < nrects ; + + i ) {
for ( int i = 0 ; i < nrects ; + + i ) {
scissor_output ( output - > wlr_output , & rects [ i ] ) ;
scissor_output ( output - > wlr_output , & rects [ i ] ) ;
wlr_renderer_clear ( renderer , clear_color ) ;
wlr_renderer_clear ( renderer , clear_color ) ;
}
}
render_layer ( output , & damage,
render_layer ( output , & buffer_ damage,
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ] ) ;
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ] ) ;
render_layer ( output , & damage,
render_layer ( output , & buffer_ damage,
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM ] ) ;
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM ] ) ;
// If a view is fullscreen on this output, render it
// If a view is fullscreen on this output, render it
@ -285,39 +286,46 @@ void output_render(struct roots_output *output) {
render_view ( output , view , & data ) ;
render_view ( output , view , & data ) ;
}
}
// Render top layer above shell views
// Render top layer above shell views
render_layer ( output , & damage,
render_layer ( output , & buffer_ damage,
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_TOP ] ) ;
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_TOP ] ) ;
}
}
render_drag_icons ( output , & damage, server - > input ) ;
render_drag_icons ( output , & buffer_ damage, server - > input ) ;
render_layer ( output , & damage,
render_layer ( output , & buffer_ damage,
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY ] ) ;
& output - > layers [ ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY ] ) ;
renderer_end :
renderer_end :
wlr_output_render_software_cursors ( wlr_output , & damage) ;
wlr_output_render_software_cursors ( wlr_output , & buffer_ damage) ;
wlr_renderer_scissor ( renderer , NULL ) ;
wlr_renderer_scissor ( renderer , NULL ) ;
wlr_renderer_end ( renderer ) ;
wlr_renderer_end ( renderer ) ;
int width , height ;
int width , height ;
wlr_output_transformed_resolution ( wlr_output , & width , & height ) ;
wlr_output_transformed_resolution ( wlr_output , & width , & height ) ;
pixman_region32_t output_damage ;
pixman_region32_init ( & output_damage ) ;
if ( server - > config - > debug_damage_tracking ) {
if ( server - > config - > debug_damage_tracking ) {
pixman_region32_union_rect ( & damage , & damage , 0 , 0 , width , height ) ;
pixman_region32_union_rect ( & output_damage , & output_damage ,
0 , 0 , width , height ) ;
}
}
enum wl_output_transform transform =
enum wl_output_transform transform =
wlr_output_transform_invert ( wlr_output - > transform ) ;
wlr_output_transform_invert ( wlr_output - > transform ) ;
wlr_region_transform ( & damage , & damage , transform , width , height ) ;
wlr_region_transform ( & output_damage , & output - > damage - > current ,
transform , width , height ) ;
wlr_output_set_damage ( wlr_output , & output_damage ) ;
pixman_region32_fini ( & output_damage ) ;
wlr_output_set_damage ( wlr_output , & damage ) ;
if ( ! wlr_output_commit ( wlr_output ) ) {
if ( ! wlr_output_commit ( wlr_output ) ) {
goto damage_finish ;
goto buffer_ damage_finish;
}
}
output - > last_frame = desktop - > last_frame = now ;
output - > last_frame = desktop - > last_frame = now ;
damage_finish:
buffer_ damage_finish:
pixman_region32_fini ( & damage) ;
pixman_region32_fini ( & buffer_ damage) ;
// Send frame done events to all surfaces
// Send frame done events to all surfaces
output_for_each_surface ( output , surface_send_frame_done_iterator , & now ) ;
output_for_each_surface ( output , surface_send_frame_done_iterator , & now ) ;