@ -104,13 +104,8 @@ enum buffer_type { 
			
		
	
		
			
				
					struct  rpir_surface  {  
			
		
	
		
			
				
						struct  weston_surface  * surface ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* If link is empty, the surface is guaranteed to not be on screen,
   
			
		
	
		
			
				
						 *  i . e .  updates  removing  Elements  have  completed .   
			
		
	
		
			
				
						 */   
			
		
	
		
			
				
						struct  wl_list  link ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						DISPMANX_ELEMENT_HANDLE_T  handle ;   
			
		
	
		
			
				
						int  layer ;   
			
		
	
		
			
				
						struct  wl_list  views ;   
			
		
	
		
			
				
						int  visible_views ;   
			
		
	
		
			
				
						int  need_swap ;   
			
		
	
		
			
				
						int  single_buffer ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -127,6 +122,20 @@ struct rpir_surface { 
			
		
	
		
			
				
						enum  buffer_type  buffer_type ;   
			
		
	
		
			
				
					} ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					struct  rpir_view  {  
			
		
	
		
			
				
						struct  rpir_surface  * surface ;   
			
		
	
		
			
				
						struct  wl_list  surface_link ;   
			
		
	
		
			
				
						struct  weston_view  * view ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* If link is empty, the view is guaranteed to not be on screen,
   
			
		
	
		
			
				
						 *  i . e .  updates  removing  Elements  have  completed .   
			
		
	
		
			
				
						 */   
			
		
	
		
			
				
						struct  wl_list  link ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						DISPMANX_ELEMENT_HANDLE_T  handle ;   
			
		
	
		
			
				
						int  layer ;   
			
		
	
		
			
				
					} ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					struct  rpir_output  {  
			
		
	
		
			
				
						DISPMANX_DISPLAY_HANDLE_T  display ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -134,10 +143,10 @@ struct rpir_output { 
			
		
	
		
			
				
						struct  weston_matrix  matrix ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* all Elements currently on screen */   
			
		
	
		
			
				
						struct  wl_list  surface _list;  /* struct rpir_surface::link */   
			
		
	
		
			
				
						struct  wl_list  view _list;  /* struct rpir_surface::link */   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* Elements just removed, waiting for update completion */   
			
		
	
		
			
				
						struct  wl_list  surface _cleanup_list;  /* struct rpir_surface::link */   
			
		
	
		
			
				
						struct  wl_list  view _cleanup_list;  /* struct rpir_surface::link */   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  rpi_resource  capture_buffer ;   
			
		
	
		
			
				
						uint8_t  * capture_data ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -164,6 +173,12 @@ to_rpir_surface(struct weston_surface *surface) 
			
		
	
		
			
				
						return  surface - > renderer_state ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  inline  struct  rpir_view  *  
			
		
	
		
			
				
					to_rpir_view ( struct  weston_view  * view )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						return  view - > renderer_state ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  inline  struct  rpir_output  *  
			
		
	
		
			
				
					to_rpir_output ( struct  weston_output  * output )  
			
		
	
		
			
				
					{  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -356,9 +371,8 @@ rpir_surface_create(struct rpi_renderer *renderer) 
			
		
	
		
			
				
						if  ( ! surface )   
			
		
	
		
			
				
							return  NULL ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_init ( & surface - > link ) ;   
			
		
	
		
			
				
						surface - > visible_views  =  0 ;   
			
		
	
		
			
				
						surface - > single_buffer  =  renderer - > single_buffer ;   
			
		
	
		
			
				
						surface - > handle  =  DISPMANX_NO_HANDLE ;   
			
		
	
		
			
				
						rpi_resource_init ( & surface - > resources [ 0 ] ) ;   
			
		
	
		
			
				
						rpi_resource_init ( & surface - > resources [ 1 ] ) ;   
			
		
	
		
			
				
						surface - > front  =  & surface - > resources [ 0 ] ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -376,15 +390,18 @@ rpir_surface_create(struct rpi_renderer *renderer) 
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					rpir_surface_destroy ( struct  rpir_surface  * surface )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( surface - > handle  ! =  DISPMANX_NO_HANDLE )   
			
		
	
		
			
				
						if  ( surface - > visible_views )   
			
		
	
		
			
				
							weston_log ( " ERROR rpi: destroying on-screen element \n " ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						assert ( wl_list_empty ( & surface - > views ) ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( surface - > surface )   
			
		
	
		
			
				
							surface - > surface - > renderer_state  =  NULL ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						pixman_region32_fini ( & surface - > prev_damage ) ;   
			
		
	
		
			
				
						rpi_resource_release ( & surface - > resources [ 0 ] ) ;   
			
		
	
		
			
				
						rpi_resource_release ( & surface - > resources [ 1 ] ) ;   
			
		
	
		
			
				
						DBG ( " rpir_surface %p destroyed (%u) \n " ,  surface ,  surface - > handle ) ;   
			
		
	
		
			
				
						DBG ( " rpir_surface %p destroyed (%u) \n " ,  surface ,  surface - > visible_views ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( surface - > egl_back  ! =  NULL )  {   
			
		
	
		
			
				
							weston_buffer_reference ( & surface - > egl_back - > buffer_ref ,  NULL ) ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -436,6 +453,46 @@ rpir_surface_damage(struct rpir_surface *surface, struct weston_buffer *buffer, 
			
		
	
		
			
				
						return  ret ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  struct  rpir_view  *  
			
		
	
		
			
				
					rpir_view_create ( struct  rpir_surface  * surface )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  rpir_view  * view ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						view  =  calloc ( 1 ,  sizeof  * view ) ;   
			
		
	
		
			
				
						if  ( ! view )   
			
		
	
		
			
				
							return  NULL ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						view - > surface  =  surface ;   
			
		
	
		
			
				
						wl_list_insert ( & surface - > views ,  & view - > surface_link ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_init ( & view - > link ) ;   
			
		
	
		
			
				
						view - > handle  =  DISPMANX_NO_HANDLE ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  view ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					rpir_view_destroy ( struct  rpir_view  * view )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( view - > handle  ! =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
							view - > surface - > visible_views - - ;   
			
		
	
		
			
				
							weston_log ( " ERROR rpi: destroying on-screen element \n " ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( view - > view )   
			
		
	
		
			
				
							view - > view - > renderer_state  =  NULL ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_remove ( & view - > surface_link ) ;   
			
		
	
		
			
				
						if  ( wl_list_empty ( & view - > surface - > views )  & &  view - > surface - > surface  = =  NULL )   
			
		
	
		
			
				
							rpir_surface_destroy ( view - > surface ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						DBG ( " rpir_view %p destroyed (%d) \n " ,  view ,  view - > handle ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						free ( view ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					matrix_type_str ( struct  weston_matrix  * matrix ,  char  * buf ,  int  len )  
			
		
	
		
			
				
					{  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -495,13 +552,13 @@ warn_bad_matrix(struct weston_matrix *total, struct weston_matrix *output, 
			
		
	
		
			
				
					/*#define SURFACE_TRANSFORM */  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  int  
			
		
	
		
			
				
					rpir_surface_compute_rects ( struct  rpir_surface  * surface  ,  
			
		
	
		
			
				
								    VC_RECT_T  * src_rect ,  VC_RECT_T  * dst_rect ,   
			
		
	
		
			
				
								    VC_IMAGE_TRANSFORM_T  * flipmask )   
			
		
	
		
			
				
					rpir_view_compute_rects ( struct  rpir_view  * view  ,  
			
		
	
		
			
				
								VC_RECT_T  * src_rect ,  VC_RECT_T  * dst_rect ,   
			
		
	
		
			
				
								VC_IMAGE_TRANSFORM_T  * flipmask )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  weston_output  * output_base  =  surface - > surface - > output ;   
			
		
	
		
			
				
						struct  weston_output  * output_base  =  view - > view - > surface - > output ;   
			
		
	
		
			
				
						struct  rpir_output  * output  =  to_rpir_output ( output_base ) ;   
			
		
	
		
			
				
						struct  weston_matrix  matrix  =  surface - > surface - > transform . matrix ;   
			
		
	
		
			
				
						struct  weston_matrix  matrix  =  view - > view - > transform . matrix ;   
			
		
	
		
			
				
						VC_IMAGE_TRANSFORM_T  flipt  =  0 ;   
			
		
	
		
			
				
						int  src_x ,  src_y ;   
			
		
	
		
			
				
						int  dst_x ,  dst_y ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -523,14 +580,15 @@ rpir_surface_compute_rects(struct rpir_surface *surface, 
			
		
	
		
			
				
						src_x  =  0  < <  16 ;   
			
		
	
		
			
				
						src_y  =  0  < <  16 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( surface - > buffer_type  = =  BUFFER_TYPE_EGL )  {   
			
		
	
		
			
				
							struct  weston_buffer  * buffer  =  surface - > egl_front - > buffer_ref . buffer ;   
			
		
	
		
			
				
						if  ( view - > surface - > buffer_type  = =  BUFFER_TYPE_EGL )  {   
			
		
	
		
			
				
							struct  weston_buffer  * buffer  =   
			
		
	
		
			
				
								view - > surface - > egl_front - > buffer_ref . buffer ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							src_width  =  buffer - > width  < <  16 ;   
			
		
	
		
			
				
							src_height  =  buffer - > height  < <  16 ;   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							src_width  =  surface - > front - > width  < <  16 ;   
			
		
	
		
			
				
							src_height  =  surface - > front - > height  < <  16 ;   
			
		
	
		
			
				
							src_width  =  view - > surface - > front - > width  < <  16 ;   
			
		
	
		
			
				
							src_height  =  view - > surface - > front - > height  < <  16 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						weston_matrix_multiply ( & matrix ,  & output - > matrix ) ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -541,7 +599,7 @@ rpir_surface_compute_rects(struct rpir_surface *surface, 
			
		
	
		
			
				
						if  ( matrix . type  > =  WESTON_MATRIX_TRANSFORM_ROTATE )  {   
			
		
	
		
			
				
					# endif  
			
		
	
		
			
				
							warn_bad_matrix ( & matrix ,  & output - > matrix ,   
			
		
	
		
			
				
									& surface - > surface - > transform . matrix ) ;   
			
		
	
		
			
				
									& view - > view - > transform . matrix ) ;   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							if  ( matrix . type  &  WESTON_MATRIX_TRANSFORM_ROTATE )  {   
			
		
	
		
			
				
								if  ( fabsf ( matrix . d [ 0 ] )  <  1e-4 f  & &   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -552,13 +610,13 @@ rpir_surface_compute_rects(struct rpir_surface *surface, 
			
		
	
		
			
				
									/* no transpose */   
			
		
	
		
			
				
								}  else  {   
			
		
	
		
			
				
									warn_bad_matrix ( & matrix ,  & output - > matrix ,   
			
		
	
		
			
				
										& surface - > surface - > transform . matrix ) ;   
			
		
	
		
			
				
										& view - > view - > transform . matrix ) ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						p2 . f [ 0 ]  =  surface - > surface - > geometry . width ;   
			
		
	
		
			
				
						p2 . f [ 1 ]  =  surface - > surface - > geometry . height ;   
			
		
	
		
			
				
						p2 . f [ 0 ]  =  view - > view - > geometry . width ;   
			
		
	
		
			
				
						p2 . f [ 1 ]  =  view - > view - > geometry . height ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* transform top-left and bot-right corner into screen coordinates */   
			
		
	
		
			
				
						weston_matrix_transform ( & matrix ,  & p1 ) ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -680,9 +738,9 @@ rpir_surface_compute_rects(struct rpir_surface *surface, 
			
		
	
		
			
				
						src_width  =  int_max ( src_width ,  0 ) ;   
			
		
	
		
			
				
						src_height  =  int_max ( src_height ,  0 ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						DBG ( " rpir_surface  %p %dx%d: p1 %f, %f; p2 %f, %f \n " ,  surface ,   
			
		
	
		
			
				
						    surface - > surface - > geometry . width ,   
			
		
	
		
			
				
						    surface - > surface - > geometry . height ,   
			
		
	
		
			
				
						DBG ( " rpir_view  %p %dx%d: p1 %f, %f; p2 %f, %f \n " ,  view ,   
			
		
	
		
			
				
						    view - > view - > geometry . width ,   
			
		
	
		
			
				
						    view - > view - > geometry . height ,   
			
		
	
		
			
				
						    p1 . f [ 0 ] ,  p1 . f [ 1 ] ,  p2 . f [ 0 ] ,  p2 . f [ 1 ] ) ;   
			
		
	
		
			
				
						DBG ( " src rect %d;%d, %d;%d, %d;%dx%d;%d \n " ,   
			
		
	
		
			
				
						    src_x  > >  16 ,  src_x  &  0xffff ,   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -706,7 +764,7 @@ rpir_surface_compute_rects(struct rpir_surface *surface, 
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* EGL buffers will be upside-down related to what DispmanX expects */   
			
		
	
		
			
				
						if  ( surface - > buffer_type  = =  BUFFER_TYPE_EGL )   
			
		
	
		
			
				
						if  ( view - > surface - > buffer_type  = =  BUFFER_TYPE_EGL )   
			
		
	
		
			
				
							flipt  ^ =  TRANSFORM_VFLIP ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						vc_dispmanx_rect_set ( src_rect ,  src_x ,  src_y ,  src_width ,  src_height ) ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -760,8 +818,8 @@ rpir_surface_get_resource(struct rpir_surface *surface) 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  int  
			
		
	
		
			
				
					rpir_surface_dmx_add ( struct  rpir_surface  * surface  ,  struct  rpir_output  * output ,  
			
		
	
		
			
				
							     DISPMANX_UPDATE_HANDLE_T  update ,  int  layer )   
			
		
	
		
			
				
					rpir_view_dmx_add ( struct  rpir_view  * view  ,  struct  rpir_output  * output ,  
			
		
	
		
			
				
							  DISPMANX_UPDATE_HANDLE_T  update ,  int  layer )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						/* Do not use DISPMANX_FLAGS_ALPHA_PREMULT here.
   
			
		
	
		
			
				
						 *  If  you  define  PREMULT  and  ALPHA_MIX ,  the  hardware  will  not   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -771,7 +829,7 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output, 
			
		
	
		
			
				
						VC_DISPMANX_ALPHA_T  alphasetup  =  {   
			
		
	
		
			
				
							DISPMANX_FLAGS_ALPHA_FROM_SOURCE  |   
			
		
	
		
			
				
							DISPMANX_FLAGS_ALPHA_MIX ,   
			
		
	
		
			
				
							float2uint8 ( surface - > surface - > alpha ) ,  /* opacity 0-255 */   
			
		
	
		
			
				
							float2uint8 ( view - > view - > alpha ) ,  /* opacity 0-255 */   
			
		
	
		
			
				
							0  /* mask resource handle */   
			
		
	
		
			
				
						} ;   
			
		
	
		
			
				
						VC_RECT_T  dst_rect ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -780,18 +838,17 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output, 
			
		
	
		
			
				
						int  ret ;   
			
		
	
		
			
				
						DISPMANX_RESOURCE_HANDLE_T  resource_handle ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						resource_handle  =  rpir_surface_get_resource ( surface ) ;   
			
		
	
		
			
				
						resource_handle  =  rpir_surface_get_resource ( view - > surface ) ;   
			
		
	
		
			
				
						if  ( resource_handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
							weston_log ( " %s: no buffer yet, aborting \n " ,  __func__ ) ;   
			
		
	
		
			
				
							return  0 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						ret  =  rpir_surface_compute_rects ( surface ,  & src_rect ,  & dst_rect ,   
			
		
	
		
			
				
										 & flipmask ) ;   
			
		
	
		
			
				
						ret  =  rpir_view_compute_rects ( view ,  & src_rect ,  & dst_rect ,  & flipmask ) ;   
			
		
	
		
			
				
						if  ( ret  <  0 )   
			
		
	
		
			
				
							return  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						surface - > handle  =  vc_dispmanx_element_add (   
			
		
	
		
			
				
						view - > handle  =  vc_dispmanx_element_add (   
			
		
	
		
			
				
							update ,   
			
		
	
		
			
				
							output - > display ,   
			
		
	
		
			
				
							layer ,   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -802,37 +859,42 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output, 
			
		
	
		
			
				
							& alphasetup ,   
			
		
	
		
			
				
							NULL  /* clamp */ ,   
			
		
	
		
			
				
							vc_image2dispmanx_transform ( flipmask ) ) ;   
			
		
	
		
			
				
						DBG ( " rpir_surface %p add %u, alpha %f resource %d \n " ,  surface ,   
			
		
	
		
			
				
						    surface - > handle ,  surface - > surface - > alpha ,  resource_handle ) ;   
			
		
	
		
			
				
						DBG ( " rpir_surface %p add %u, alpha %f resource %d \n " ,  view ,   
			
		
	
		
			
				
						    view - > handle ,  view - > view - > alpha ,  resource_handle ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( view - > handle  = =  DISPMANX_NO_HANDLE )   
			
		
	
		
			
				
							return  - 1 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						view - > surface - > visible_views + + ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  1 ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					rpir_surface_dmx_swap ( struct  rpir_surface  * surface  ,  
			
		
	
		
			
				
							       DISPMANX_UPDATE_HANDLE_T  update )   
			
		
	
		
			
				
					rpir_view_dmx_swap ( struct  rpir_view  * view  ,  
			
		
	
		
			
				
							   DISPMANX_UPDATE_HANDLE_T  update )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						VC_RECT_T  rect ;   
			
		
	
		
			
				
						pixman_box32_t  * r ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* XXX: skip, iff resource was not reallocated, and single-buffering */   
			
		
	
		
			
				
						vc_dispmanx_element_change_source ( update ,  surface - > handle ,   
			
		
	
		
			
				
										  surface - > front - > handle ) ;   
			
		
	
		
			
				
						vc_dispmanx_element_change_source ( update ,  view - > handle ,   
			
		
	
		
			
				
										  view - > surface - > front - > handle ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* This is current damage now, after rpir_surface_damage() */   
			
		
	
		
			
				
						r  =  pixman_region32_extents ( & surface - > prev_damage ) ;   
			
		
	
		
			
				
						r  =  pixman_region32_extents ( & view - > surface - > prev_damage ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						vc_dispmanx_rect_set ( & rect ,  r - > x1 ,  r - > y1 ,   
			
		
	
		
			
				
								     r - > x2  -  r - > x1 ,  r - > y2  -  r - > y1 ) ;   
			
		
	
		
			
				
						vc_dispmanx_element_modified ( update ,  surface - > handle ,  & rect ) ;   
			
		
	
		
			
				
						DBG ( " rpir_surface  %p swap \n " ,  surface ) ;   
			
		
	
		
			
				
						vc_dispmanx_element_modified ( update ,  view - > handle ,  & rect ) ;   
			
		
	
		
			
				
						DBG ( " rpir_view  %p swap \n " ,  view ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  int  
			
		
	
		
			
				
					rpir_surface_dmx_move ( struct  rpir_surface  * surface  ,  
			
		
	
		
			
				
							       DISPMANX_UPDATE_HANDLE_T  update ,  int  layer )   
			
		
	
		
			
				
					rpir_view_dmx_move ( struct  rpir_view  * view  ,  
			
		
	
		
			
				
							   DISPMANX_UPDATE_HANDLE_T  update ,  int  layer )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						uint8_t  alpha  =  float2uint8 ( surface - > surface - > alpha ) ;   
			
		
	
		
			
				
						uint8_t  alpha  =  float2uint8 ( view - > view - > alpha ) ;   
			
		
	
		
			
				
						VC_RECT_T  dst_rect ;   
			
		
	
		
			
				
						VC_RECT_T  src_rect ;   
			
		
	
		
			
				
						VC_IMAGE_TRANSFORM_T  flipmask ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -840,28 +902,27 @@ rpir_surface_dmx_move(struct rpir_surface *surface, 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* XXX: return early, if all attributes stay the same */   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( surface - > buffer_type  = =  BUFFER_TYPE_EGL )  {   
			
		
	
		
			
				
						if  ( view - > surface - > buffer_type  = =  BUFFER_TYPE_EGL )  {   
			
		
	
		
			
				
							DISPMANX_RESOURCE_HANDLE_T  resource_handle ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							resource_handle  =  rpir_surface_get_resource ( surface ) ;   
			
		
	
		
			
				
							resource_handle  =  rpir_surface_get_resource ( view - > surface ) ;   
			
		
	
		
			
				
							if  ( resource_handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
								weston_log ( " %s: no buffer yet, aborting \n " ,  __func__ ) ;   
			
		
	
		
			
				
								return  0 ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							vc_dispmanx_element_change_source ( update ,   
			
		
	
		
			
				
											  surface - > handle ,   
			
		
	
		
			
				
											  view - > handle ,   
			
		
	
		
			
				
											  resource_handle ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						ret  =  rpir_surface_compute_rects ( surface ,  & src_rect ,  & dst_rect ,   
			
		
	
		
			
				
										 & flipmask ) ;   
			
		
	
		
			
				
						ret  =  rpir_view_compute_rects ( view ,  & src_rect ,  & dst_rect ,  & flipmask ) ;   
			
		
	
		
			
				
						if  ( ret  <  0 )   
			
		
	
		
			
				
							return  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						ret  =  vc_dispmanx_element_change_attributes (   
			
		
	
		
			
				
							update ,   
			
		
	
		
			
				
							surface - > handle ,   
			
		
	
		
			
				
							view - > handle ,   
			
		
	
		
			
				
							ELEMENT_CHANGE_LAYER  |   
			
		
	
		
			
				
								ELEMENT_CHANGE_OPACITY  |   
			
		
	
		
			
				
								ELEMENT_CHANGE_TRANSFORM  |   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -875,7 +936,7 @@ rpir_surface_dmx_move(struct rpir_surface *surface, 
			
		
	
		
			
				
							/* This really is DISPMANX_TRANSFORM_T, no matter
   
			
		
	
		
			
				
							 *  what  the  header  says .  */   
			
		
	
		
			
				
							vc_image2dispmanx_transform ( flipmask ) ) ;   
			
		
	
		
			
				
						DBG ( " rpir_surface  %p move \n " ,  surface ) ;   
			
		
	
		
			
				
						DBG ( " rpir_view  %p move \n " ,  view ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( ret )   
			
		
	
		
			
				
							return  - 1 ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -884,15 +945,16 @@ rpir_surface_dmx_move(struct rpir_surface *surface, 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					rpir_surface_dmx_remove ( struct  rpir_surface  * surface  ,  
			
		
	
		
			
				
								 DISPMANX_UPDATE_HANDLE_T  update )   
			
		
	
		
			
				
					rpir_view_dmx_remove ( struct  rpir_view  * view  ,  
			
		
	
		
			
				
							      DISPMANX_UPDATE_HANDLE_T  update )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						if  ( surface - > handle  = =  DISPMANX_NO_HANDLE )   
			
		
	
		
			
				
						if  ( view - > handle  = =  DISPMANX_NO_HANDLE )   
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						vc_dispmanx_element_remove ( update ,  surface - > handle ) ;   
			
		
	
		
			
				
						DBG ( " rpir_surface %p remove %u \n " ,  surface ,  surface - > handle ) ;   
			
		
	
		
			
				
						surface - > handle  =  DISPMANX_NO_HANDLE ;   
			
		
	
		
			
				
						vc_dispmanx_element_remove ( update ,  view - > handle ) ;   
			
		
	
		
			
				
						DBG ( " rpir_view %p remove %u \n " ,  view ,  view - > handle ) ;   
			
		
	
		
			
				
						view - > handle  =  DISPMANX_NO_HANDLE ;   
			
		
	
		
			
				
						view - > surface - > visible_views - - ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -900,23 +962,31 @@ rpir_surface_swap_pointers(struct rpir_surface *surface) 
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  rpi_resource  * tmp ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						tmp  =  surface - > front ;   
			
		
	
		
			
				
						surface - > front  =  surface - > back ;   
			
		
	
		
			
				
						surface - > back  =  tmp ;   
			
		
	
		
			
				
						surface - > need_swap  =  0 ;   
			
		
	
		
			
				
						if  ( surface - > buffer_type  = =  BUFFER_TYPE_EGL )  {   
			
		
	
		
			
				
							if  ( surface - > egl_back  ! =  NULL )  {   
			
		
	
		
			
				
								assert ( surface - > egl_old_front  = =  NULL ) ;   
			
		
	
		
			
				
								surface - > egl_old_front  =  surface - > egl_front ;   
			
		
	
		
			
				
								surface - > egl_front  =  surface - > egl_back ;   
			
		
	
		
			
				
								surface - > egl_back  =  NULL ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							tmp  =  surface - > front ;   
			
		
	
		
			
				
							surface - > front  =  surface - > back ;   
			
		
	
		
			
				
							surface - > back  =  tmp ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						DBG ( " new back %p, new front %p \n " ,  surface - > back ,  surface - > front ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  int  
			
		
	
		
			
				
					is_surface_not_visible ( struct  weston_surface  * surface )  
			
		
	
		
			
				
					is_view_not_visible ( struct  weston_view  * view  )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						/* Return true, if surface is guaranteed to be totally obscured. */   
			
		
	
		
			
				
						int  ret ;   
			
		
	
		
			
				
						pixman_region32_t  unocc ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						pixman_region32_init ( & unocc ) ;   
			
		
	
		
			
				
						pixman_region32_subtract ( & unocc ,  & surface - > transform . boundingbox ,   
			
		
	
		
			
				
									 & surface - > clip ) ;   
			
		
	
		
			
				
						pixman_region32_subtract ( & unocc ,  & view - > transform . boundingbox ,   
			
		
	
		
			
				
									 & view - > clip ) ;   
			
		
	
		
			
				
						ret  =  ! pixman_region32_not_empty ( & unocc ) ;   
			
		
	
		
			
				
						pixman_region32_fini ( & unocc ) ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -924,81 +994,55 @@ is_surface_not_visible(struct weston_surface *surface) 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					rpir_surface_update ( struct  rpir_surface  * surface  ,  struct  rpir_output  * output ,  
			
		
	
		
			
				
							     DISPMANX_UPDATE_HANDLE_T  update ,  int  layer )   
			
		
	
		
			
				
					rpir_view_update ( struct  rpir_view  * view  ,  struct  rpir_output  * output ,  
			
		
	
		
			
				
							 DISPMANX_UPDATE_HANDLE_T  update ,  int  layer )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						int  need_swap  =  surface - > need_swap ;   
			
		
	
		
			
				
						int  ret ;   
			
		
	
		
			
				
						int  obscured ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( surface - > buffer_type  = =  BUFFER_TYPE_EGL )  {   
			
		
	
		
			
				
							if  ( surface - > egl_back  ! =  NULL )  {   
			
		
	
		
			
				
								assert ( surface - > egl_old_front  = =  NULL ) ;   
			
		
	
		
			
				
								surface - > egl_old_front  =  surface - > egl_front ;   
			
		
	
		
			
				
								surface - > egl_front  =  surface - > egl_back ;   
			
		
	
		
			
				
								surface - > egl_back  =  NULL ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
							if  ( surface - > egl_front - > buffer_ref . buffer  = =  NULL )  {   
			
		
	
		
			
				
								weston_log ( " warning: client unreffed current front buffer \n " ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
								if  ( surface - > handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
									wl_list_init ( & surface - > link ) ;   
			
		
	
		
			
				
								}  else  {   
			
		
	
		
			
				
									rpir_surface_dmx_remove ( surface ,  update ) ;   
			
		
	
		
			
				
									wl_list_insert ( & output - > surface_cleanup_list ,   
			
		
	
		
			
				
											   & surface - > link ) ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								goto  out ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							if  ( need_swap )   
			
		
	
		
			
				
								rpir_surface_swap_pointers ( surface ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						obscured  =  is_surface_not_visible ( surface - > surface  ) ;   
			
		
	
		
			
				
						obscured  =  is_view_not_visible ( view - > view ) ;   
			
		
	
		
			
				
						if  ( obscured )  {   
			
		
	
		
			
				
							DBG ( " rpir_surface  %p totally obscured. \n " ,  surface ) ;   
			
		
	
		
			
				
							DBG ( " rpir_view %p totally obscured. \n " ,  view ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
							if  ( surface - > handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
								wl_list_init ( & surface - > link ) ;   
			
		
	
		
			
				
							wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
							if  ( view - > handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
								wl_list_init ( & view - > link ) ;   
			
		
	
		
			
				
							}  else  {   
			
		
	
		
			
				
								rpir_surface_dmx_remove ( surface  ,  update ) ;   
			
		
	
		
			
				
								wl_list_insert ( & output - > surface _cleanup_list,   
			
		
	
		
			
				
									       & surface - > link ) ;   
			
		
	
		
			
				
								rpir_view_dmx_remove ( view ,  update ) ;   
			
		
	
		
			
				
								wl_list_insert ( & output - > view_cleanup_list ,   
			
		
	
		
			
				
									       & view - > link ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							goto  out ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( surface - > handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
							ret  =  rpir_surface_dmx_add ( surface  ,  output ,  update ,  layer ) ;   
			
		
	
		
			
				
						if  ( view - > handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
							ret  =  rpir_view_dmx_add ( view ,  output ,  update ,  layer ) ;   
			
		
	
		
			
				
							if  ( ret  = =  0 )  {   
			
		
	
		
			
				
								wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
								wl_list_init ( & surface - > link ) ;   
			
		
	
		
			
				
								wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
								wl_list_init ( & view - > link ) ;   
			
		
	
		
			
				
							}  else  if  ( ret  <  0 )  {   
			
		
	
		
			
				
								weston_log ( " ERROR rpir_surface _dmx_add() failed. \n " ) ;   
			
		
	
		
			
				
								weston_log ( " ERROR rpir_view_dmx_add() failed. \n " ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							if  ( need_swap )   
			
		
	
		
			
				
								rpir_surface_dmx_swap ( surface  ,  update ) ;   
			
		
	
		
			
				
							if  ( view - > surface - > need_swap )   
			
		
	
		
			
				
								rpir_view_dmx_swap ( view  ,  update ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							ret  =  rpir_surface_dmx_move ( surface  ,  update ,  layer ) ;   
			
		
	
		
			
				
							ret  =  rpir_view_dmx_move ( view  ,  update ,  layer ) ;   
			
		
	
		
			
				
							if  ( ret  = =  0 )  {   
			
		
	
		
			
				
								rpir_surface_dmx_remove ( surface  ,  update ) ;   
			
		
	
		
			
				
								rpir_view_dmx_remove ( view  ,  update ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
								wl_list_insert ( & output - > surface _cleanup_list,   
			
		
	
		
			
				
									       & surface - > link ) ;   
			
		
	
		
			
				
								wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
								wl_list_insert ( & output - > view _cleanup_list,   
			
		
	
		
			
				
									       & view - > link ) ;   
			
		
	
		
			
				
							}  else  if  ( ret  <  0 )  {   
			
		
	
		
			
				
								weston_log ( " ERROR rpir_surface _dmx_move() failed. \n " ) ;   
			
		
	
		
			
				
								weston_log ( " ERROR rpir_view _dmx_move() failed. \n " ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					out :  
			
		
	
		
			
				
						surface - > layer  =  layer ;   
			
		
	
		
			
				
						view - > layer  =  layer ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  int  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1105,15 +1149,15 @@ static void 
			
		
	
		
			
				
					rpir_output_dmx_remove_all ( struct  rpir_output  * output ,  
			
		
	
		
			
				
								   DISPMANX_UPDATE_HANDLE_T  update )   
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  rpir_surface  * surface  ;   
			
		
	
		
			
				
						struct  rpir_view  * view  ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						while  ( ! wl_list_empty ( & output - > surface _list) )  {   
			
		
	
		
			
				
							surface =  container_of ( output - > surface _list. next ,   
			
		
	
		
			
				
									        struct  rpir_surface  ,  link ) ;   
			
		
	
		
			
				
							rpir_surface_dmx_remove ( surface  ,  update ) ;   
			
		
	
		
			
				
						while  ( ! wl_list_empty ( & output - > view _list) )  {   
			
		
	
		
			
				
							view =  container_of ( output - > view _list. next ,   
			
		
	
		
			
				
									    struct  rpir_view  ,  link ) ;   
			
		
	
		
			
				
							rpir_view_dmx_remove ( view  ,  update ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
							wl_list_insert ( & output - > surface_cleanup_list ,  & surface - > link ) ;   
			
		
	
		
			
				
							wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
							wl_list_insert ( & output - > view_cleanup_list ,  & view - > link ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1186,8 +1230,8 @@ rpi_renderer_repaint_output(struct weston_output *base, 
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  weston_compositor  * compositor  =  base - > compositor ;   
			
		
	
		
			
				
						struct  rpir_output  * output  =  to_rpir_output ( base ) ;   
			
		
	
		
			
				
						struct  weston_surface  * ws  ;   
			
		
	
		
			
				
						struct  rpir_surface  * surface  ;   
			
		
	
		
			
				
						struct  weston_view  * wv  ;   
			
		
	
		
			
				
						struct  rpir_view  * view  ;   
			
		
	
		
			
				
						struct  wl_list  done_list ;   
			
		
	
		
			
				
						int  layer  =  1 ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1199,27 +1243,59 @@ rpi_renderer_repaint_output(struct weston_output *base, 
			
		
	
		
			
				
						free ( output - > capture_data ) ;   
			
		
	
		
			
				
						output - > capture_data  =  NULL ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* Swap resources on surfaces as needed */   
			
		
	
		
			
				
						wl_list_for_each_reverse ( wv ,  & compositor - > view_list ,  link )   
			
		
	
		
			
				
							wv - > surface - > touched  =  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_for_each_reverse ( wv ,  & compositor - > view_list ,  link )  {   
			
		
	
		
			
				
							view  =  to_rpir_view ( wv ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( ! wv - > surface - > touched )  {   
			
		
	
		
			
				
								wv - > surface - > touched  =  1 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								if  ( view - > surface - > need_swap )   
			
		
	
		
			
				
									rpir_surface_swap_pointers ( view - > surface ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( view - > surface - > egl_front - > buffer_ref . buffer  = =  NULL )  {   
			
		
	
		
			
				
								weston_log ( " warning: client unreffed current front buffer \n " ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
								if  ( view - > handle  = =  DISPMANX_NO_HANDLE )  {   
			
		
	
		
			
				
									wl_list_init ( & view - > link ) ;   
			
		
	
		
			
				
								}  else  {   
			
		
	
		
			
				
									rpir_view_dmx_remove ( view ,  output - > update ) ;   
			
		
	
		
			
				
									wl_list_insert ( & output - > view_cleanup_list ,   
			
		
	
		
			
				
										       & view - > link ) ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* update all renderable surfaces */   
			
		
	
		
			
				
						wl_list_init ( & done_list ) ;   
			
		
	
		
			
				
						wl_list_for_each_reverse ( ws ,  & compositor - > surface_list ,  link )  {   
			
		
	
		
			
				
							if  ( ws - > plane  ! =  & compositor - > primary_plane )   
			
		
	
		
			
				
						wl_list_for_each_reverse ( wv  ,  & compositor - > view _list,  link )  {   
			
		
	
		
			
				
							if  ( wv  - > plane  ! =  & compositor - > primary_plane )   
			
		
	
		
			
				
								continue ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							surface  =  to_rpir_surface ( ws ) ;   
			
		
	
		
			
				
							assert ( ! wl_list_empty ( & surface - > link )  | |   
			
		
	
		
			
				
							       surface - > handle  = =  DISPMANX_NO_HANDLE ) ;   
			
		
	
		
			
				
							view  =  to_rpir_view ( wv ) ;   
			
		
	
		
			
				
							assert ( ! wl_list_empty ( & view - > link )  | |   
			
		
	
		
			
				
							       view - > handle  = =  DISPMANX_NO_HANDLE ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
							wl_list_insert ( & done_list ,  & surface - > link ) ;   
			
		
	
		
			
				
							rpir_surface_update ( surface ,  output ,  output - > update ,  layer + + ) ;   
			
		
	
		
			
				
							wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
							wl_list_insert ( & done_list ,  & view - > link ) ;   
			
		
	
		
			
				
							rpir_view_update ( view  ,  output ,  output - > update ,  layer + + ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* Mark all surfaces as swapped */   
			
		
	
		
			
				
						wl_list_for_each_reverse ( wv ,  & compositor - > view_list ,  link )   
			
		
	
		
			
				
							to_rpir_surface ( wv - > surface ) - > need_swap  =  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* Remove all surfaces that are still on screen, but were
   
			
		
	
		
			
				
						 *  not  rendered  this  time .   
			
		
	
		
			
				
						 */   
			
		
	
		
			
				
						rpir_output_dmx_remove_all ( output ,  output - > update ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_insert_list ( & output - > surface_list ,  & done_list ) ;   
			
		
	
		
			
				
						wl_list_insert_list ( & output - > view _list,  & done_list ) ;   
			
		
	
		
			
				
						output - > update  =  DISPMANX_NO_HANDLE ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* The frame_signal is emitted in rpi_renderer_finish_frame(),
   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1263,7 +1339,7 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer) 
			
		
	
		
			
				
								/* XXX: need to check if in middle of update */   
			
		
	
		
			
				
								rpi_resource_release ( surface - > back ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( surface - > handle  = =  DISPMANX_NO_HANDLE )   
			
		
	
		
			
				
							if  ( ! surface - > visible_views )   
			
		
	
		
			
				
								/* XXX: cannot do this, if middle of an update */   
			
		
	
		
			
				
								rpi_resource_release ( surface - > front ) ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1336,6 +1412,23 @@ rpi_renderer_create_surface(struct weston_surface *base) 
			
		
	
		
			
				
						return  0 ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  int  
			
		
	
		
			
				
					rpi_renderer_create_view ( struct  weston_view  * base )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  rpir_surface  * surface  =  to_rpir_surface ( base - > surface ) ;   
			
		
	
		
			
				
						struct  rpir_view  * view ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						assert ( base - > renderer_state  = =  NULL ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						view  =  rpir_view_create ( surface ) ;   
			
		
	
		
			
				
						if  ( ! view )   
			
		
	
		
			
				
							return  - 1 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						view - > view  =  base ;   
			
		
	
		
			
				
						base - > renderer_state  =  view ;   
			
		
	
		
			
				
						return  0 ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					rpi_renderer_surface_set_color ( struct  weston_surface  * base ,  
			
		
	
		
			
				
								       float  red ,  float  green ,  float  blue ,  float  alpha )   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1390,13 +1483,27 @@ rpi_renderer_destroy_surface(struct weston_surface *base) 
			
		
	
		
			
				
						surface - > surface  =  NULL ;   
			
		
	
		
			
				
						base - > renderer_state  =  NULL ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* If guaranteed to not be on screen, just detroy it. */   
			
		
	
		
			
				
						if  ( wl_list_empty ( & surface - > link ) )   
			
		
	
		
			
				
						if  ( wl_list_empty ( & surface - > views ) )   
			
		
	
		
			
				
							rpir_surface_destroy ( surface ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* Otherwise, the surface is either on screen and needs
   
			
		
	
		
			
				
					static  void  
			
		
	
		
			
				
					rpi_renderer_destroy_view ( struct  weston_view  * base )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  rpir_view  * view  =  to_rpir_view ( base ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						assert ( view ) ;   
			
		
	
		
			
				
						assert ( view - > view  = =  base ) ;   
			
		
	
		
			
				
						if  ( ! view )   
			
		
	
		
			
				
							return ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* If guaranteed to not be on screen, just detroy it. */   
			
		
	
		
			
				
						if  ( wl_list_empty ( & view - > link ) )   
			
		
	
		
			
				
							rpir_view_destroy ( view ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/* Otherwise, the view is either on screen and needs
   
			
		
	
		
			
				
						 *  to  be  removed  by  a  repaint  update ,  or  it  is  in  the   
			
		
	
		
			
				
						 *  surface_cleanup_list ,  and  will  be  destroyed  by   
			
		
	
		
			
				
						 *  view _cleanup_list,  and  will  be  destroyed  by   
			
		
	
		
			
				
						 *  rpi_renderer_finish_frame ( ) .   
			
		
	
		
			
				
						 */   
			
		
	
		
			
				
					}  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1440,8 +1547,10 @@ rpi_renderer_create(struct weston_compositor *compositor, 
			
		
	
		
			
				
						renderer - > base . flush_damage  =  rpi_renderer_flush_damage ;   
			
		
	
		
			
				
						renderer - > base . attach  =  rpi_renderer_attach ;   
			
		
	
		
			
				
						renderer - > base . create_surface  =  rpi_renderer_create_surface ;   
			
		
	
		
			
				
						renderer - > base . create_view  =  rpi_renderer_create_view ;   
			
		
	
		
			
				
						renderer - > base . surface_set_color  =  rpi_renderer_surface_set_color ;   
			
		
	
		
			
				
						renderer - > base . destroy_surface  =  rpi_renderer_destroy_surface ;   
			
		
	
		
			
				
						renderer - > base . destroy_view  =  rpi_renderer_destroy_view ;   
			
		
	
		
			
				
						renderer - > base . destroy  =  rpi_renderer_destroy ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# ifdef ENABLE_EGL  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1504,8 +1613,8 @@ rpi_renderer_output_create(struct weston_output *base, 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						output - > display  =  display ;   
			
		
	
		
			
				
						output - > update  =  DISPMANX_NO_HANDLE ;   
			
		
	
		
			
				
						wl_list_init ( & output - > surface _list) ;   
			
		
	
		
			
				
						wl_list_init ( & output - > surface _cleanup_list) ;   
			
		
	
		
			
				
						wl_list_init ( & output - > view _list) ;   
			
		
	
		
			
				
						wl_list_init ( & output - > view _cleanup_list) ;   
			
		
	
		
			
				
						rpi_resource_init ( & output - > capture_buffer ) ;   
			
		
	
		
			
				
						base - > renderer_state  =  output ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1516,7 +1625,7 @@ WL_EXPORT void 
			
		
	
		
			
				
					rpi_renderer_output_destroy ( struct  weston_output  * base )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  rpir_output  * output  =  to_rpir_output ( base ) ;   
			
		
	
		
			
				
						struct  rpir_surface  * surface  ;   
			
		
	
		
			
				
						struct  rpir_view  * view  ;   
			
		
	
		
			
				
						DISPMANX_UPDATE_HANDLE_T  update ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						rpi_resource_release ( & output - > capture_buffer ) ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1527,12 +1636,10 @@ rpi_renderer_output_destroy(struct weston_output *base) 
			
		
	
		
			
				
						rpir_output_dmx_remove_all ( output ,  update ) ;   
			
		
	
		
			
				
						vc_dispmanx_update_submit_sync ( update ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						while  ( ! wl_list_empty ( & output - > surface_cleanup_list ) )  {   
			
		
	
		
			
				
							surface  =  container_of ( output - > surface_cleanup_list . next ,   
			
		
	
		
			
				
									       struct  rpir_surface ,  link ) ;   
			
		
	
		
			
				
							if  ( surface - > surface )   
			
		
	
		
			
				
								surface - > surface - > renderer_state  =  NULL ;   
			
		
	
		
			
				
							rpir_surface_destroy ( surface ) ;   
			
		
	
		
			
				
						while  ( ! wl_list_empty ( & output - > view_cleanup_list ) )  {   
			
		
	
		
			
				
							view  =  container_of ( output - > view_cleanup_list . next ,   
			
		
	
		
			
				
									    struct  rpir_view ,  link ) ;   
			
		
	
		
			
				
							rpir_view_destroy ( view ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						free ( output ) ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1553,41 +1660,41 @@ rpi_renderer_finish_frame(struct weston_output *base) 
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						struct  rpir_output  * output  =  to_rpir_output ( base ) ;   
			
		
	
		
			
				
						struct  weston_compositor  * compositor  =  base - > compositor ;   
			
		
	
		
			
				
						struct  weston_surface  * ws  ;   
			
		
	
		
			
				
						struct  rpir_surface  * surface  ;   
			
		
	
		
			
				
						struct  weston_view  * wv  ;   
			
		
	
		
			
				
						struct  rpir_view  * view  ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						while  ( ! wl_list_empty ( & output - > surface _cleanup_list) )  {   
			
		
	
		
			
				
							surface =  container_of ( output - > surface _cleanup_list. next ,   
			
		
	
		
			
				
									        struct  rpir_surface  ,  link ) ;   
			
		
	
		
			
				
						while  ( ! wl_list_empty ( & output - > view _cleanup_list) )  {   
			
		
	
		
			
				
							view =  container_of ( output - > view _cleanup_list. next ,   
			
		
	
		
			
				
									    struct  rpir_view  ,  link ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( surface - > surface )  {   
			
		
	
		
			
				
								/* The weston_surface  still exists, but is
   
			
		
	
		
			
				
							if  ( view - > view )  {   
			
		
	
		
			
				
								/* The weston_view  still exists, but is
   
			
		
	
		
			
				
								 *  temporarily  not  visible ,  and  hence  its  Element   
			
		
	
		
			
				
								 *  was  removed .  The  current  front  buffer  contents   
			
		
	
		
			
				
								 *  must  be  preserved .   
			
		
	
		
			
				
								 */   
			
		
	
		
			
				
								if  ( ! surface - > single_buffer )   
			
		
	
		
			
				
									rpi_resource_release ( surface - > back ) ;   
			
		
	
		
			
				
								if  ( ! view - > surface - > visible_views )   
			
		
	
		
			
				
									rpi_resource_release ( view - > surface - > back ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								wl_list_remove ( & surface - > link ) ;   
			
		
	
		
			
				
								wl_list_init ( & surface - > link ) ;   
			
		
	
		
			
				
								wl_list_remove ( & view - > link ) ;   
			
		
	
		
			
				
								wl_list_init ( & view - > link ) ;   
			
		
	
		
			
				
							}  else  {   
			
		
	
		
			
				
								rpir_surface_destroy ( surface  ) ;   
			
		
	
		
			
				
								rpir_view_destroy ( view  ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_list_for_each ( ws  ,  & compositor - > surface _list,  link )  {   
			
		
	
		
			
				
							surface  =  to_rpir_surface ( ws ) ;   
			
		
	
		
			
				
						wl_list_for_each ( wv  ,  & compositor - > view _list,  link )  {   
			
		
	
		
			
				
							view  =  to_rpir_view ( wv ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( surface - > buffer_type  ! =  BUFFER_TYPE_EGL )   
			
		
	
		
			
				
							if  ( view - > surface - > buffer_type  ! =  BUFFER_TYPE_EGL )   
			
		
	
		
			
				
								continue ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if ( surface - > egl_old_front  = =  NULL )   
			
		
	
		
			
				
							if   ( view - > surface - > egl_old_front  = =  NULL )   
			
		
	
		
			
				
								continue ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							weston_buffer_reference ( & surface - > egl_old_front - > buffer_ref ,  NULL ) ;   
			
		
	
		
			
				
							free ( surface - > egl_old_front ) ;   
			
		
	
		
			
				
							surface - > egl_old_front  =  NULL ;   
			
		
	
		
			
				
							weston_buffer_reference ( & view - > surface - > egl_old_front - > buffer_ref ,  NULL ) ;   
			
		
	
		
			
				
							free ( view - > surface - > egl_old_front ) ;   
			
		
	
		
			
				
							view - > surface - > egl_old_front  =  NULL ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wl_signal_emit ( & base - > frame_signal ,  base ) ;