@ -319,16 +319,6 @@ weston_client_launch(struct weston_compositor *compositor,
return client ;
}
static void
surface_handle_pending_buffer_destroy ( struct wl_listener * listener , void * data )
{
struct weston_surface * surface =
container_of ( listener , struct weston_surface ,
pending . buffer_destroy_listener ) ;
surface - > pending . buffer = NULL ;
}
static void
region_init_infinite ( pixman_region32_t * region )
{
@ -382,6 +372,72 @@ struct weston_frame_callback {
struct wl_list link ;
} ;
static void
surface_state_handle_buffer_destroy ( struct wl_listener * listener , void * data )
{
struct weston_surface_state * state =
container_of ( listener , struct weston_surface_state ,
buffer_destroy_listener ) ;
state - > buffer = NULL ;
}
static void
weston_surface_state_init ( struct weston_surface_state * state )
{
state - > newly_attached = 0 ;
state - > buffer = NULL ;
state - > buffer_destroy_listener . notify =
surface_state_handle_buffer_destroy ;
state - > sx = 0 ;
state - > sy = 0 ;
pixman_region32_init ( & state - > damage ) ;
pixman_region32_init ( & state - > opaque ) ;
region_init_infinite ( & state - > input ) ;
wl_list_init ( & state - > frame_callback_list ) ;
state - > buffer_viewport . buffer . transform = WL_OUTPUT_TRANSFORM_NORMAL ;
state - > buffer_viewport . buffer . scale = 1 ;
state - > buffer_viewport . buffer . src_width = wl_fixed_from_int ( - 1 ) ;
state - > buffer_viewport . surface . width = - 1 ;
state - > buffer_viewport . changed = 0 ;
}
static void
weston_surface_state_fini ( struct weston_surface_state * state )
{
struct weston_frame_callback * cb , * next ;
wl_list_for_each_safe ( cb , next ,
& state - > frame_callback_list , link )
wl_resource_destroy ( cb - > resource ) ;
pixman_region32_fini ( & state - > input ) ;
pixman_region32_fini ( & state - > opaque ) ;
pixman_region32_fini ( & state - > damage ) ;
if ( state - > buffer )
wl_list_remove ( & state - > buffer_destroy_listener . link ) ;
state - > buffer = NULL ;
}
static void
weston_surface_state_set_buffer ( struct weston_surface_state * state ,
struct weston_buffer * buffer )
{
if ( state - > buffer = = buffer )
return ;
if ( state - > buffer )
wl_list_remove ( & state - > buffer_destroy_listener . link ) ;
state - > buffer = buffer ;
if ( state - > buffer )
wl_signal_add ( & state - > buffer - > destroy_signal ,
& state - > buffer_destroy_listener ) ;
}
WL_EXPORT struct weston_surface *
weston_surface_create ( struct weston_compositor * compositor )
{
@ -402,10 +458,10 @@ weston_surface_create(struct weston_compositor *compositor)
surface - > buffer_viewport . buffer . scale = 1 ;
surface - > buffer_viewport . buffer . src_width = wl_fixed_from_int ( - 1 ) ;
surface - > buffer_viewport . surface . width = - 1 ;
surface - > pending . buffer_viewport . changed = 0 ;
surface - > pending . buffer_viewport = surface - > buffer_viewport ;
weston_surface_state_init ( & surface - > pending ) ;
surface - > output = NULL ;
surface - > pending . newly_attached = 0 ;
surface - > viewport_resource = NULL ;
@ -417,13 +473,6 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init ( & surface - > frame_callback_list ) ;
surface - > pending . buffer_destroy_listener . notify =
surface_handle_pending_buffer_destroy ;
pixman_region32_init ( & surface - > pending . damage ) ;
pixman_region32_init ( & surface - > pending . opaque ) ;
region_init_infinite ( & surface - > pending . input ) ;
wl_list_init ( & surface - > pending . frame_callback_list ) ;
wl_list_init ( & surface - > subsurface_list ) ;
wl_list_init ( & surface - > subsurface_list_pending ) ;
@ -1353,9 +1402,7 @@ weston_surface_unmap(struct weston_surface *surface)
static void
weston_surface_reset_pending_buffer ( struct weston_surface * surface )
{
if ( surface - > pending . buffer )
wl_list_remove ( & surface - > pending . buffer_destroy_listener . link ) ;
surface - > pending . buffer = NULL ;
weston_surface_state_set_buffer ( & surface - > pending , NULL ) ;
surface - > pending . sx = 0 ;
surface - > pending . sy = 0 ;
surface - > pending . newly_attached = 0 ;
@ -1404,16 +1451,7 @@ weston_surface_destroy(struct weston_surface *surface)
wl_list_for_each_safe ( ev , nv , & surface - > views , surface_link )
weston_view_destroy ( ev ) ;
wl_list_for_each_safe ( cb , next ,
& surface - > pending . frame_callback_list , link )
wl_resource_destroy ( cb - > resource ) ;
pixman_region32_fini ( & surface - > pending . input ) ;
pixman_region32_fini ( & surface - > pending . opaque ) ;
pixman_region32_fini ( & surface - > pending . damage ) ;
if ( surface - > pending . buffer )
wl_list_remove ( & surface - > pending . buffer_destroy_listener . link ) ;
weston_surface_state_fini ( & surface - > pending ) ;
weston_buffer_reference ( & surface - > buffer_ref , NULL ) ;
@ -1939,17 +1977,11 @@ surface_attach(struct wl_client *client,
/* Attach, attach, without commit in between does not send
* wl_buffer . release . */
if ( surface - > pending . buffer )
wl_list_remove ( & surface - > pending . buffer_destroy_listener . link ) ;
weston_surface_state_set_buffer ( & surface - > pending , buffer ) ;
surface - > pending . sx = sx ;
surface - > pending . sy = sy ;
surface - > pending . buffer = buffer ;
surface - > pending . newly_attached = 1 ;
if ( buffer ) {
wl_signal_add ( & buffer - > destroy_signal ,
& surface - > pending . buffer_destroy_listener ) ;
}
}
static void
@ -2048,7 +2080,8 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface)
}
static void
weston_surface_commit ( struct weston_surface * surface )
weston_surface_commit_state ( struct weston_surface * surface ,
struct weston_surface_state * state )
{
struct weston_view * view ;
pixman_region32_t opaque ;
@ -2056,35 +2089,35 @@ weston_surface_commit(struct weston_surface *surface)
/* wl_surface.set_buffer_transform */
/* wl_surface.set_buffer_scale */
/* wl_viewport.set */
surface - > buffer_viewport = surfac e - > pending . buffer_viewport ;
surface - > buffer_viewport = stat e - > buffer_viewport ;
/* wl_surface.attach */
if ( surface - > pending . newly_attached )
weston_surface_attach ( surface , surface - > pending . buffer ) ;
if ( state - > newly_attached )
weston_surface_attach ( surface , state - > buffer ) ;
weston_surface_state_set_buffer ( state , NULL ) ;
if ( surface - > pending . newly_attached | |
surface - > pending . buffer_viewport . changed ) {
if ( state - > newly_attached | | state - > buffer_viewport . changed ) {
weston_surface_update_size ( surface ) ;
if ( surface - > configure )
surface - > configure ( surface , surface - > pending . sx ,
surface - > pending . sy ) ;
surface - > configure ( surface , state - > sx , state - > sy ) ;
}
weston_surface_reset_pending_buffer ( surface ) ;
state - > sx = 0 ;
state - > sy = 0 ;
state - > newly_attached = 0 ;
state - > buffer_viewport . changed = 0 ;
/* wl_surface.damage */
pixman_region32_union ( & surface - > damage , & surface - > damage ,
& surfac e - > pending . damage ) ;
& stat e - > damage ) ;
pixman_region32_intersect_rect ( & surface - > damage , & surface - > damage ,
0 , 0 , surface - > width , surface - > height ) ;
pixman_region32_clear ( & surface - > pending . damage ) ;
/* wl_surface.set_opaque_region */
pixman_region32_init_rect ( & opaque , 0 , 0 ,
surface - > width ,
surface - > height ) ;
pixman_region32_intersect ( & opaque ,
& opaque , & surface - > pending . opaque ) ;
pixman_region32_init ( & opaque ) ;
pixman_region32_intersect_rect ( & opaque , & state - > opaque ,
0 , 0 , surface - > width , surface - > height ) ;
if ( ! pixman_region32_equal ( & opaque , & surface - > opaque ) ) {
pixman_region32_copy ( & surface - > opaque , & opaque ) ;
@ -2095,17 +2128,19 @@ weston_surface_commit(struct weston_surface *surface)
pixman_region32_fini ( & opaque ) ;
/* wl_surface.set_input_region */
pixman_region32_fini ( & surface - > input ) ;
pixman_region32_init_rect ( & surface - > input , 0 , 0 ,
surface - > width ,
surface - > height ) ;
pixman_region32_intersect ( & surface - > input ,
& surface - > input , & surface - > pending . input ) ;
pixman_region32_intersect_rect ( & surface - > input , & state - > input ,
0 , 0 , surface - > width , surface - > height ) ;
/* wl_surface.frame */
wl_list_insert_list ( & surface - > frame_callback_list ,
& surface - > pending . frame_callback_list ) ;
wl_list_init ( & surface - > pending . frame_callback_list ) ;
& state - > frame_callback_list ) ;
wl_list_init ( & state - > frame_callback_list ) ;
}
static void
weston_surface_commit ( struct weston_surface * surface )
{
weston_surface_commit_state ( surface , & surface - > pending ) ;
weston_surface_commit_subsurface_order ( surface ) ;
@ -2293,73 +2328,15 @@ static void
weston_subsurface_commit_from_cache ( struct weston_subsurface * sub )
{
struct weston_surface * surface = sub - > surface ;
struct weston_view * view ;
pixman_region32_t opaque ;
/* wl_surface.set_buffer_transform */
/* wl_surface.set_buffer_scale */
/* wl_viewport.set */
surface - > buffer_viewport = sub - > cached . buffer_viewport ;
/* wl_surface.attach */
if ( sub - > cached . newly_attached )
weston_surface_attach ( surface , sub - > cached . buffer_ref . buffer ) ;
weston_buffer_reference ( & sub - > cached . buffer_ref , NULL ) ;
if ( sub - > cached . newly_attached | | sub - > cached . buffer_viewport . changed ) {
weston_surface_update_size ( surface ) ;
if ( surface - > configure )
surface - > configure ( surface , sub - > cached . sx ,
sub - > cached . sy ) ;
}
sub - > cached . sx = 0 ;
sub - > cached . sy = 0 ;
sub - > cached . newly_attached = 0 ;
sub - > cached . buffer_viewport . changed = 0 ;
/* wl_surface.damage */
pixman_region32_union ( & surface - > damage , & surface - > damage ,
& sub - > cached . damage ) ;
pixman_region32_intersect_rect ( & surface - > damage , & surface - > damage ,
0 , 0 ,
surface - > width ,
surface - > height ) ;
pixman_region32_clear ( & sub - > cached . damage ) ;
/* wl_surface.set_opaque_region */
pixman_region32_init_rect ( & opaque , 0 , 0 ,
surface - > width ,
surface - > height ) ;
pixman_region32_intersect ( & opaque ,
& opaque , & sub - > cached . opaque ) ;
if ( ! pixman_region32_equal ( & opaque , & surface - > opaque ) ) {
pixman_region32_copy ( & surface - > opaque , & opaque ) ;
wl_list_for_each ( view , & surface - > views , surface_link )
weston_view_geometry_dirty ( view ) ;
}
pixman_region32_fini ( & opaque ) ;
/* wl_surface.set_input_region */
pixman_region32_fini ( & surface - > input ) ;
pixman_region32_init_rect ( & surface - > input , 0 , 0 ,
surface - > width ,
surface - > height ) ;
pixman_region32_intersect ( & surface - > input ,
& surface - > input , & sub - > cached . input ) ;
/* wl_surface.frame */
wl_list_insert_list ( & surface - > frame_callback_list ,
& sub - > cached . frame_callback_list ) ;
wl_list_init ( & sub - > cached . frame_callback_list ) ;
weston_surface_commit_state ( surface , & sub - > cached ) ;
weston_buffer_reference ( & sub - > cached_buffer_ref , NULL ) ;
weston_surface_commit_subsurface_order ( surface ) ;
weston_surface_schedule_repaint ( surface ) ;
sub - > cached . has _data = 0 ;
sub - > has_cached_data = 0 ;
}
static void
@ -2381,7 +2358,9 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
if ( surface - > pending . newly_attached ) {
sub - > cached . newly_attached = 1 ;
weston_buffer_reference ( & sub - > cached . buffer_ref ,
weston_surface_state_set_buffer ( & sub - > cached ,
surface - > pending . buffer ) ;
weston_buffer_reference ( & sub - > cached_buffer_ref ,
surface - > pending . buffer ) ;
}
sub - > cached . sx + = surface - > pending . sx ;
@ -2404,7 +2383,7 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
& surface - > pending . frame_callback_list ) ;
wl_list_init ( & surface - > pending . frame_callback_list ) ;
sub - > cached . has _data = 1 ;
sub - > has_cached _data = 1 ;
}
static int
@ -2433,7 +2412,7 @@ weston_subsurface_commit(struct weston_subsurface *sub)
if ( weston_subsurface_is_synchronized ( sub ) ) {
weston_subsurface_commit_to_cache ( sub ) ;
} else {
if ( sub - > cached . has _data) {
if ( sub - > has_cached _data) {
/* flush accumulated state from cache */
weston_subsurface_commit_to_cache ( sub ) ;
weston_subsurface_commit_from_cache ( sub ) ;
@ -2460,7 +2439,7 @@ weston_subsurface_synchronized_commit(struct weston_subsurface *sub)
* all the way down .
*/
if ( sub - > cached . has _data)
if ( sub - > has_cached _data)
weston_subsurface_commit_from_cache ( sub ) ;
wl_list_for_each ( tmp , & surface - > subsurface_list , parent_link ) {
@ -2665,30 +2644,6 @@ subsurface_set_desync(struct wl_client *client, struct wl_resource *resource)
}
}
static void
weston_subsurface_cache_init ( struct weston_subsurface * sub )
{
pixman_region32_init ( & sub - > cached . damage ) ;
pixman_region32_init ( & sub - > cached . opaque ) ;
pixman_region32_init ( & sub - > cached . input ) ;
wl_list_init ( & sub - > cached . frame_callback_list ) ;
sub - > cached . buffer_ref . buffer = NULL ;
}
static void
weston_subsurface_cache_fini ( struct weston_subsurface * sub )
{
struct weston_frame_callback * cb , * tmp ;
wl_list_for_each_safe ( cb , tmp , & sub - > cached . frame_callback_list , link )
wl_resource_destroy ( cb - > resource ) ;
weston_buffer_reference ( & sub - > cached . buffer_ref , NULL ) ;
pixman_region32_fini ( & sub - > cached . damage ) ;
pixman_region32_fini ( & sub - > cached . opaque ) ;
pixman_region32_fini ( & sub - > cached . input ) ;
}
static void
weston_subsurface_unlink_parent ( struct weston_subsurface * sub )
{
@ -2791,7 +2746,8 @@ weston_subsurface_destroy(struct weston_subsurface *sub)
if ( sub - > parent )
weston_subsurface_unlink_parent ( sub ) ;
weston_subsurface_cache_fini ( sub ) ;
weston_surface_state_fini ( & sub - > cached ) ;
weston_buffer_reference ( & sub - > cached_buffer_ref , NULL ) ;
sub - > surface - > configure = NULL ;
sub - > surface - > configure_private = NULL ;
@ -2840,7 +2796,8 @@ weston_subsurface_create(uint32_t id, struct weston_surface *surface,
sub , subsurface_resource_destroy ) ;
weston_subsurface_link_surface ( sub , surface ) ;
weston_subsurface_link_parent ( sub , parent ) ;
weston_subsurface_cache_init ( sub ) ;
weston_surface_state_init ( & sub - > cached ) ;
sub - > cached_buffer_ref . buffer = NULL ;
sub - > synchronized = 1 ;
return sub ;