@ -71,6 +71,21 @@  
			
		 
		
	
		
			
			 
			 
			
			 
			
			# include  "EGL/egl.h"        // Native platform windowing system interface  
			
		 
		
	
		
			
			 
			 
			
			 
			
			# include  "EGL/eglext.h"     // EGL extensions  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			# include  <poll.h>  // for drmHandleEvent poll  
			
		 
		
	
		
			
			 
			 
			
			 
			
			# include  <errno.h> //for EBUSY, EAGAIN  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			# define MAX_CACHED_BOS 3  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			typedef  struct  {  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    struct  gbm_bo  * bo ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  fb_id ;   / /  DRM  framebuffer  ID   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  FramebufferCache ;  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			static  FramebufferCache  fbCache [ MAX_CACHED_BOS ] ;  
			
		 
		
	
		
			
			 
			 
			
			 
			
			static  volatile  int  fbCacheCount  =  0 ;  
			
		 
		
	
		
			
			 
			 
			
			 
			
			static  volatile  bool  pendingFlip  =  false ;  
			
		 
		
	
		
			
			 
			 
			
			 
			
			static  bool  crtcSet  =  false ;  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			# ifndef EGL_OPENGL_ES3_BIT  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    # define EGL_OPENGL_ES3_BIT  0x40   
			
		 
		
	
		
			
			 
			 
			
			 
			
			# endif  
			
		 
		
	
	
		
			
				
				
					
						 
					 
				
				
					
						 
					 
				
				
				 
			
			 
			
			@ -217,6 +232,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = {  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Module  Internal  Functions  Declaration  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
			
		 
		
	
		
			
			 
			 
			
			 
			
			int  InitSwapScreenBuffer ( void ) ;  
			
		 
		
	
		
			
			 
			 
			
			 
			
			int  InitPlatform ( void ) ;           / /  Initialize  platform  ( graphics ,  inputs  and  more )  
			
		 
		
	
		
			
			 
			 
			
			 
			
			void  ClosePlatform ( void ) ;         / /  Close  platform  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
	
		
			
				
				
					
						 
					 
				
				
					
						 
					 
				
				
				 
			
			 
			
			@ -551,34 +567,207 @@ void DisableCursor(void)  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    CORE . Input . Mouse . cursorHidden  =  true ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Swap  back  buffer  with  front  buffer  ( screen  drawing )  
			
		 
		
	
		
			
			 
			 
			
			 
			
			void  SwapScreenBuffer ( void )  
			
		 
		
	
		
			
			 
			 
			
			 
			
			{  
			
		 
		
	
		
			
			 
			 
			
			 
			
			static  void  drm_fb_destroy_callback ( struct  gbm_bo  * bo ,  void  * data )  {  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  fb_id  =  ( uintptr_t ) data ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Remove  from  cache   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    for  ( int  i  =  0 ;  i  <  fbCacheCount ;  i + + )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        if  ( fbCache [ i ] . bo  = =  bo )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            TRACELOG ( LOG_INFO ,  " DRM: fb removed %u " ,  ( uintptr_t ) fb_id ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            drmModeRmFB ( platform . fd ,  fbCache [ i ] . fb_id ) ;  / /  Release  DRM  FB   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            / /  Shift  remaining  entries   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            for  ( int  j  =  i ;  j  <  fbCacheCount  -  1 ;  j + + )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			                fbCache [ j ]  =  fbCache [ j  +  1 ] ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            fbCacheCount - - ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            break ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Create  or  retrieve  cached  DRM  FB  for  BO  
			
		 
		
	
		
			
			 
			 
			
			 
			
			static  uint32_t  get_or_create_fb_for_bo ( struct  gbm_bo  * bo )  {  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Try  to  find  existing  cache  entry   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    for  ( int  i  =  0 ;  i  <  fbCacheCount ;  i + + )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        if  ( fbCache [ i ] . bo  = =  bo )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            return  fbCache [ i ] . fb_id ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Create  new  entry  if  cache  not  full   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( fbCacheCount  > =  MAX_CACHED_BOS )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / FB  cache  full !   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  handle  =  gbm_bo_get_handle ( bo ) . u32 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  stride  =  gbm_bo_get_stride ( bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  width  =  gbm_bo_get_width ( bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  height  =  gbm_bo_get_height ( bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  fb_id ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( drmModeAddFB ( platform . fd ,  width ,  height ,  24 ,  32 ,  stride ,  handle ,  & fb_id ) )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / rmModeAddFB  failed   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Store  in  cache   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    fbCache [ fbCacheCount ]  =  ( FramebufferCache ) {  . bo  =  bo ,  . fb_id  =  fb_id  } ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    fbCacheCount + + ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Set  destroy  callback  to  auto - cleanup   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    gbm_bo_set_user_data ( bo ,  ( void * ) ( uintptr_t ) fb_id ,  drm_fb_destroy_callback ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    TRACELOG ( LOG_INFO ,  " DRM: added new bo %u "  ,  ( uintptr_t ) fb_id ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    return  fb_id ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Renders  a  blank  frame  to  allocate  initial  buffers  
			
		 
		
	
		
			
			 
			 
			
			 
			
			void  RenderBlankFrame ( )  {  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    glClearColor ( 0 ,  0 ,  0 ,  1 ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    glClear ( GL_COLOR_BUFFER_BIT ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    eglSwapBuffers ( platform . device ,  platform . surface ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			      
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Ensure  the  buffer  is  processed   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    glFinish ( ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Initialize  with  first  buffer  only  
			
		 
		
	
		
			
			 
			 
			
			 
			
			int  InitSwapScreenBuffer ( )  {  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! platform . gbmSurface  | |  platform . fd  <  0 )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        TRACELOG ( LOG_ERROR ,  " DRM not initialized " ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  - 1 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! platform . gbmSurface  | |  ( - 1  = =  platform . fd )  | |  ! platform . connector  | |  ! platform . crtc )  TRACELOG ( LOG_ERROR ,  " DISPLAY: DRM initialization failed to swap " ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Render  a  blank  frame  to  allocate  buffers   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    RenderBlankFrame ( ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Get  first  buffer   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    struct  gbm_bo  * bo  =  gbm_surface_lock_front_buffer ( platform . gbmSurface ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! bo )  TRACELOG ( LOG_ERROR ,  " DISPLAY: Failed GBM to lock front buffer " ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! bo )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        TRACELOG ( LOG_ERROR ,  " Failed to lock initial buffer " ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  - 1 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  fb  =  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    int  result  =  drmModeAddFB ( platform . fd ,  platform . connector - > modes [ platform . modeIndex ] . hdisplay ,  platform . connector - > modes [ platform . modeIndex ] . vdisplay ,  24 ,  32 ,  gbm_bo_get_stride ( bo ) ,  gbm_bo_get_handle ( bo ) . u32 ,  & fb ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( result  ! =  0 )  TRACELOG ( LOG_ERROR ,  " DISPLAY: drmModeAddFB() failed with result: %d " ,  result ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Create  FB  for  first  buffer   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  fb_id  =  get_or_create_fb_for_bo ( bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! fb_id )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        gbm_surface_release_buffer ( platform . gbmSurface ,  bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  - 1 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    result  =  drmModeSetCrtc ( platform . fd ,  platform . crtc - > crtc_id ,  fb ,  0 ,  0 ,  & platform . connector - > connector_id ,  1 ,  & platform . connector - > modes [ platform . modeIndex ] ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( result  ! =  0 )  TRACELOG ( LOG_ERROR ,  " DISPLAY: drmModeSetCrtc() failed with result: %d " ,  result ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Initial  CRTC  setup   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( drmModeSetCrtc ( platform . fd ,  platform . crtc - > crtc_id ,  fb_id ,   
			
		 
		
	
		
			
			 
			 
			
			 
			
			                       0 ,  0 ,  & platform . connector - > connector_id ,  1 ,   
			
		 
		
	
		
			
			 
			 
			
			 
			
			                       & platform . connector - > modes [ platform . modeIndex ] ) )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        TRACELOG ( LOG_ERROR ,  " Initial CRTC setup failed: %s " ,  strerror ( errno ) ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        gbm_surface_release_buffer ( platform . gbmSurface ,  bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  - 1 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( platform . prevFB )   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        result  =  drmModeRmFB ( platform . fd ,  platform . prevFB ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        if  ( result  ! =  0 )  TRACELOG ( LOG_ERROR ,  " DISPLAY: drmModeRmFB() failed with result: %d " ,  result ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Keep  first  buffer  locked  until  flipped   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    platform . prevBO  =  bo ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    crtcSet  =  true ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    return  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Static  page  flip  handler   
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  this  will  be  called  once  the  drmModePageFlip ( )  finished  from  the  drmHandleEvent ( platform . fd ,  & evctx ) ;  context  
			
		 
		
	
		
			
			 
			 
			
			 
			
			static  void  page_flip_handler ( int  fd ,  unsigned  int  frame ,   
			
		 
		
	
		
			
			 
			 
			
			 
			
			                              unsigned  int  sec ,  unsigned  int  usec ,    
			
		 
		
	
		
			
			 
			 
			
			 
			
			                              void  * data )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    ( void ) fd ;  ( void ) frame ;  ( void ) sec ;  ( void ) usec ;  / /  Unused   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    pendingFlip  =  false ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    struct  gbm_bo  * bo_to_release  =  ( struct  gbm_bo  * ) data ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / / Buffers  are  released  after  the  flip  completes  ( via  page_flip_handler ) ,  ensuring  they ' re  no  longer  in  use .   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Prevents  the  GPU  from  writing  to  a  buffer  being  scanned  out   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( bo_to_release )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        gbm_surface_release_buffer ( platform . gbmSurface ,  bo_to_release ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    platform . prevFB  =  fb ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Swap  implementation  with  proper  caching  
			
		 
		
	
		
			
			 
			 
			
			 
			
			void  SwapScreenBuffer ( )  {  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    static  int  loopCnt  =  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    loopCnt + + ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    static  int  errCnt [ 5 ]  =  { 0 } ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! crtcSet  | |  ! platform . gbmSurface )  return ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( platform . prevBO )  gbm_surface_release_buffer ( platform . gbmSurface ,  platform . prevBO ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / / call  this  only ,  if  pendingFlip  is  not  set   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    eglSwapBuffers ( platform . device ,  platform . surface ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    platform . prevBO  =  bo ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Process  pending  events  non - blocking   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    drmEventContext  evctx  =  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        . version  =  DRM_EVENT_CONTEXT_VERSION ,   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        . page_flip_handler  =  page_flip_handler   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    } ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			      
			
		 
		
	
		
			
			 
			 
			
			 
			
			    struct  pollfd  pfd  =  {  . fd  =  platform . fd ,  . events  =  POLLIN  } ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / / polling  for  event  for  0 ms   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    while  ( poll ( & pfd ,  1 ,  0 )  >  0 )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        drmHandleEvent ( platform . fd ,  & evctx ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Skip  if  previous  flip  pending   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( pendingFlip )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / Skip  frame :  flip  pending   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        errCnt [ 0 ] + + ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }    
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Get  new  front  buffer   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    struct  gbm_bo  * next_bo  =  gbm_surface_lock_front_buffer ( platform . gbmSurface ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! next_bo )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / Failed  to  lock  front  buffer   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        errCnt [ 1 ] + + ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Get  FB  ID  ( creates  new  one  if  needed )   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    uint32_t  fb_id  =  get_or_create_fb_for_bo ( next_bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( ! fb_id )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        gbm_surface_release_buffer ( platform . gbmSurface ,  next_bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        errCnt [ 2 ] + + ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Attempt  page  flip   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    /* rmModePageFlip() schedules a buffer-flip for the next vblank and then   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *    notifies  us  about  it .  It  takes  a  CRTC - id ,  fb - id  and  an  arbitrary   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *    data - pointer  and  then  schedules  the  page - flip .  This  is  fully  asynchronous  and   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *  When  the  page - flip  happens ,  the  DRM - fd  will  become  readable  and  we  can  call   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *  drmHandleEvent ( ) .  This  will  read  all  vblank / page - flip  events  and  call  our   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *  modeset_page_flip_event ( )  callback  with  the  data - pointer  that  we  passed  to   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *  drmModePageFlip ( ) .  We  simply  call  modeset_draw_dev ( )  then  so  the  next  frame   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *  is  rendered . .   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        *    returns  immediately .    
			
		 
		
	
		
			
			 
			 
			
			 
			
			    */   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if  ( drmModePageFlip ( platform . fd ,  platform . crtc - > crtc_id ,  fb_id ,   
			
		 
		
	
		
			
			 
			 
			
			 
			
			                       DRM_MODE_PAGE_FLIP_EVENT ,  platform . prevBO ) )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        if  ( errno  = =  EBUSY )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            / / Display  busy  -  skip  flip   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            errCnt [ 3 ] + + ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        }  else  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            / / Page  flip  failed   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            errCnt [ 4 ] + + ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        gbm_surface_release_buffer ( platform . gbmSurface ,  next_bo ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / /  Success :  update  state   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    pendingFlip  =  true ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			      
			
		 
		
	
		
			
			 
			 
			
			 
			
			    platform . prevBO  =  next_bo ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / / successful  usage ,  do  benchmarking   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / / in  every  10  sec ,  at  60F PS  60 * 10  - >  600    
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if ( loopCnt  > =  600 )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        TRACELOG ( LOG_INFO ,  " DRM err counters: %d, %d, %d, %d, %d, %d " , errCnt [ 0 ] , errCnt [ 1 ] , errCnt [ 2 ] , errCnt [ 3 ] , errCnt [ 4 ] ,  loopCnt ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / reinit  the  errors   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        for ( int  i = 0 ; i < 5 ; i + + )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			            errCnt [ i ]  =  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        loopCnt  =  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
			
		 
		
	
	
		
			
				
				
					
						 
					 
				
				
					
						 
					 
				
				
				 
			
			 
			
			@ -910,7 +1099,8 @@ int InitPlatform(void)  
			
		 
		
	
		
			
			 
			 
			
			 
			
			        EGL_BLUE_SIZE ,  8 ,            / /  BLUE  color  bit  depth  ( alternative :  5 )   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        EGL_ALPHA_SIZE ,  8 ,         / /  ALPHA  bit  depth  ( required  for  transparent  framebuffer )   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / EGL_TRANSPARENT_TYPE ,  EGL_NONE ,  / /  Request  transparent  framebuffer  ( EGL_TRANSPARENT_RGB  does  not  work  on  RPI )   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        EGL_DEPTH_SIZE ,  24 ,          / /  Depth  buffer  size  ( Required  to  use  Depth  testing ! )   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / ToDo :  verify  this .  In  5.5  it  is  16 ,  in  master  it  was  24   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        EGL_DEPTH_SIZE ,  16 ,          / /  Depth  buffer  size  ( Required  to  use  Depth  testing ! )   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        / / EGL_STENCIL_SIZE ,  8 ,       / /  Stencil  buffer  size   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        EGL_SAMPLE_BUFFERS ,  sampleBuffer ,  / /  Activate  MSAA   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        EGL_SAMPLES ,  samples ,        / /  4 x  Antialiasing  if  activated  ( Free  on  MALI  GPUs )   
			
		 
		
	
	
		
			
				
				
					
						 
					 
				
				
					
						 
					 
				
				
				 
			
			 
			
			@ -1083,9 +1273,14 @@ int InitPlatform(void)  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    CORE . Storage . basePath  =  GetWorkingDirectory ( ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    TRACELOG ( LOG_INFO ,  " PLATFORM: DRM: Initialized successfully " ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    if ( InitSwapScreenBuffer ( )  = =  0 )  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        TRACELOG ( LOG_INFO ,  " PLATFORM: DRM: Initialized successfully " ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }  else  {   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        TRACELOG ( LOG_INFO ,  " PLATFORM: DRM: Initialized failed " ) ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			        return  - 1 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			    }   
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			    return  0 ;   
			
		 
		
	
		
			
			 
			 
			
			 
			
			}  
			
		 
		
	
		
			
			 
			 
			
			 
			
			
  
			
		 
		
	
		
			
			 
			 
			
			 
			
			/ /  Close  platform