| 
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -48,11 +48,11 @@ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			* | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			**********************************************************************************************/ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <fcntl.h>   // POSIX file control definitions - open(), creat(), fcntl() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <unistd.h>  // POSIX standard function definitions - read(), close(), STDIN_FILENO | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <pthread.h> // POSIX threads management (inputs reading) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <dirent.h>  // POSIX directory browsing | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <fcntl.h>          // POSIX file control definitions - open(), creat(), fcntl() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <unistd.h>         // POSIX standard function definitions - read(), close(), STDIN_FILENO | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <termios.h>        // POSIX terminal control definitions - tcgetattr(), tcsetattr() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <pthread.h>        // POSIX threads management (inputs reading) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <dirent.h>         // POSIX directory browsing | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <sys/ioctl.h>      // Required for: ioctl() - UNIX System call for device-specific input/output operations | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <linux/kd.h>       // Linux: KDSKBMODE, K_MEDIUMRAM constants definition | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -71,23 +71,13 @@ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include "EGL/egl.h"        // Native platform windowing system interface | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include "EGL/eglext.h"     // EGL extensions | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// NOTE: DRM cache enables triple buffered DRM caching | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#if defined(SUPPORT_DRM_CACHE) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <poll.h>  // for drmHandleEvent poll | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#include <errno.h> //for EBUSY, EAGAIN | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    #include <poll.h>       // Required for: drmHandleEvent() poll | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    #include <errno.h>      // Required for: EBUSY, EAGAIN | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define MAX_CACHED_BOS 3 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			typedef struct { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    struct gbm_bo *bo; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uint32_t fbId;  // DRM framebuffer ID | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} FramebufferCache; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static FramebufferCache fbCache[MAX_CACHED_BOS] = {0}; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static volatile int fbCacheCount = 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static volatile bool pendingFlip = false; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static bool crtcSet = false; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif //SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    #define MAX_DRM_CACHED_BUFFERS  3 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif // SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#ifndef EGL_OPENGL_ES3_BIT | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    #define EGL_OPENGL_ES3_BIT  0x40 | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -96,18 +86,16 @@ static bool crtcSet = false; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Defines and Macros | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define USE_LAST_TOUCH_DEVICE       // When multiple touchscreens are connected, only use the one with the highest event<N> number | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define USE_LAST_TOUCH_DEVICE           // When multiple touchscreens are connected, only use the one with the highest event<N> number | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define DEFAULT_EVDEV_PATH       "/dev/input/"      // Path to the linux input events | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define DEFAULT_EVDEV_PATH "/dev/input/"    // Path to the linux input events | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// So actually the biggest key is KEY_CNT but we only really map the keys up to | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// KEY_ALS_TOGGLE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Actually biggest key is KEY_CNT but we only really map the keys up to KEY_ALS_TOGGLE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define KEYMAP_SIZE KEY_ALS_TOGGLE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Types and Structures Definition | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			typedef struct { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Display data | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    int fd;                             // File descriptor for /dev/dri/... | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -147,6 +135,18 @@ typedef struct { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    int gamepadCount;                   // The number of gamepads registered | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} PlatformData; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#if defined(SUPPORT_DRM_CACHE) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			typedef struct { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    struct gbm_bo *bo;      // Graphics buffer object | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uint32_t fbId;          // DRM framebuffer ID | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} FramebufferCache; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static FramebufferCache fbCache[MAX_DRM_CACHED_BUFFERS] = { 0 }; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static volatile int fbCacheCount = 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static volatile bool pendingFlip = false; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static bool crtcSet = false; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif // SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Global Variables Definition | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -570,18 +570,23 @@ void DisableCursor(void) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#if defined(SUPPORT_DRM_CACHE) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//callback to destroy cached framebuffer, set by gbm_bo_set_user_data() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void DestroyFrameBufferCallback(struct gbm_bo *bo, void *data) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Destroy cached framebuffer callback, set by gbm_bo_set_user_data() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void DestroyFrameBufferCallback(struct gbm_bo *bo, void *data) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uint32_t fbId = (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)fbId); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    for (int i = 0; i < fbCacheCount; i++) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        if (fbCache[i].bo == bo) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            TRACELOG(LOG_INFO, "DISPLAY: DRM: Framebuffer removed [%u]", (uintptr_t)fbId); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            drmModeRmFB(platform.fd, fbCache[i].fbId); // Release DRM FB | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            // Shift remaining entries | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            for (int j = i; j < fbCacheCount - 1; j++) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                fbCache[j] = fbCache[j + 1]; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            for (int j = i; j < fbCacheCount - 1; j++) fbCache[j] = fbCache[j + 1]; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            fbCacheCount--; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            break; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        } | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -589,56 +594,53 @@ static void DestroyFrameBufferCallback(struct gbm_bo *bo, void *data) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Create or retrieve cached DRM FB for BO | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static uint32_t GetOrCreateFbForBo(struct gbm_bo *bo) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static uint32_t GetOrCreateFbForBo(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].fbId; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    for (int i = 0; i < fbCacheCount; i++) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        if (fbCache[i].bo == bo) return fbCache[i].fbId; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Create new entry if cache not full | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (fbCacheCount >= MAX_CACHED_BOS) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //FB cache full! | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (fbCacheCount >= MAX_DRM_CACHED_BUFFERS) return 0; // FB cache full | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    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 fbId; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (drmModeAddFB(platform.fd, width, height, 24, 32, stride, handle, &fbId)) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //rmModeAddFB failed | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uint32_t fbId = 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (drmModeAddFB(platform.fd, width, height, 24, 32, stride, handle, &fbId)) return 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Store in cache | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    fbCache[fbCacheCount] = (FramebufferCache){ .bo = bo, .fbId = fbId }; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    fbCacheCount++; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Set destroy callback to auto-cleanup | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    gbm_bo_set_user_data(bo, (void*)(uintptr_t)fbId, DestroyFrameBufferCallback); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    gbm_bo_set_user_data(bo, (void *)(uintptr_t)fbId, DestroyFrameBufferCallback); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    TRACELOG(LOG_INFO, "DISPLAY: DRM: Added new buffer object [%u]" , (uintptr_t)fbId); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    TRACELOG(LOG_INFO, "DRM: added new bo %u" , (uintptr_t)fbId); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return fbId; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Renders a blank frame to allocate initial buffers | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			void RenderBlankFrame() { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// TODO: WARNING: Platform layers do not include OpenGL code! | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			void RenderBlankFrame() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glClearColor(0, 0, 0, 1); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glClear(GL_COLOR_BUFFER_BIT); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    eglSwapBuffers(platform.device, platform.surface); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Ensure the buffer is processed | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glFinish(); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glFinish(); // Ensure the buffer is processed | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Initialize with first buffer only | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			int InitSwapScreenBuffer() { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!platform.gbmSurface || platform.fd < 0) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_ERROR, "DRM not initialized"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			int InitSwapScreenBuffer() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!platform.gbmSurface || (platform.fd < 0)) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_ERROR, "DISPLAY: DRM: Swap buffers can not be initialized"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return -1; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -647,23 +649,24 @@ int InitSwapScreenBuffer() { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Get first buffer | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    struct gbm_bo *bo = gbm_surface_lock_front_buffer(platform.gbmSurface); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!bo) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_ERROR, "Failed to lock initial buffer"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!bo) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_ERROR, "DISPLAY: DRM: Failed to lock initial swap buffer"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return -1; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Create FB for first buffer | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uint32_t fbId = GetOrCreateFbForBo(bo); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!fbId) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!fbId) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        gbm_surface_release_buffer(platform.gbmSurface, bo); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return -1; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Initial CRTC setup | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fbId, | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                       0, 0, &platform.connector->connector_id, 1, | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                       &platform.connector->modes[platform.modeIndex])) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_ERROR, "Initial CRTC setup failed: %s", strerror(errno)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fbId, 0, 0, &platform.connector->connector_id, 1, &platform.connector->modes[platform.modeIndex])) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_ERROR, "DISPLAY: DRM: Failed to initialize CRTC setup. ERROR: %s", strerror(errno)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        gbm_surface_release_buffer(platform.gbmSurface, bo); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return -1; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -671,32 +674,38 @@ int InitSwapScreenBuffer() { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // 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 PageFlipHandler(int fd, unsigned int frame,  | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                              unsigned int sec, unsigned int usec,  | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                              void *data) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    (void)fd; (void)frame; (void)sec; (void)usec; // Unused | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Static page flip handler | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// NOTE: Called once the drmModePageFlip() finished from the drmHandleEvent() context | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void PageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Unused inputs | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    (void)fd; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    (void)frame; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    (void)sec; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    (void)usec; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    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. | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    struct gbm_bo *boToRelease = (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); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (boToRelease) gbm_surface_release_buffer(platform.gbmSurface, boToRelease); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Swap implementation with proper caching | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			void SwapScreenBuffer() { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			void SwapScreenBuffer() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!crtcSet || !platform.gbmSurface) return; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    static int loopCnt = 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    loopCnt++; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    static int errCnt[5] = {0}; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    k">if (!crtcSet || !platform.gbmSurface) return; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    n">loopCnt++; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    //call this only, if pendingFlip is not set | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Call this only, if pendingFlip is not set | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    eglSwapBuffers(platform.device, platform.surface); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Process pending events non-blocking | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -704,76 +713,68 @@ void SwapScreenBuffer() { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        .version = DRM_EVENT_CONTEXT_VERSION, | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        .page_flip_handler = PageFlipHandler | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    }; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    struct pollfd pfd = { .fd = platform.fd, .events = POLLIN }; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    //polling for event for 0ms | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    while (poll(&pfd, 1, 0) > 0) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        drmHandleEvent(platform.fd, &evctx); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Polling for event for 0ms | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    while (poll(&pfd, 1, 0) > 0) drmHandleEvent(platform.fd, &evctx); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Skip if previous flip pending | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (pendingFlip) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //Skip frame: flip pending | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        errCnt[0]++; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (pendingFlip) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        errCnt[0]++; // Skip frame: flip pending | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        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 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    struct gbm_bo *nextBO = gbm_surface_lock_front_buffer(platform.gbmSurface); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!nextBO) // Failed to lock front buffer | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        errCnt[1]++; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Get FB ID (creates new one if needed) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uint32_t fbId = GetOrCreateFbForBo(next_bo); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!fbId) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        gbm_surface_release_buffer(platform.gbmSurface, next_bo); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uint32_t fbId = GetOrCreateFbForBo(nextBO); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (!fbId) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        gbm_surface_release_buffer(platform.gbmSurface, nextBO); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        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, fbId, | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                       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); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // NOTE: 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, fbId, DRM_MODE_PAGE_FLIP_EVENT, platform.prevBO)) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        if (errno == EBUSY) errCnt[3]++; // Display busy - skip flip | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        else errCnt[4]++; // Page flip failed | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        gbm_surface_release_buffer(platform.gbmSurface, nextBO); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Success: update state | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    pendingFlip = true; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    platform.prevBO = next_bo; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    //successful usage, do benchmarking | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    //in every 10 sec, at 60FPS 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; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    platform.prevBO = nextBO; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			/* | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Some benchmarking code | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (loopCnt >= 600) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_INFO, "DRM: Error counters: %d, %d, %d, %d, %d, %d", errCnt[0], errCnt[1], errCnt[2], errCnt[3], errCnt[4], loopCnt); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        for (int i = 0; i < 5; i++) errCnt[i] = 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        loopCnt = 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			*/ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#else //SUPPORT_DRM_CACHE is not defined | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#else // !SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Swap back buffer with front buffer (screen drawing) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			void SwapScreenBuffer(void) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -803,7 +804,8 @@ void SwapScreenBuffer(void) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    platform.prevBO = bo; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif //SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif // SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Module Functions Definition: Misc | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -1307,17 +1309,20 @@ int InitPlatform(void) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    //---------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#if defined(SUPPORT_DRM_CACHE) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if(InitSwapScreenBuffer() == 0) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif//SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (InitSwapScreenBuffer() == 0) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#if defined(SUPPORT_DRM_CACHE) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } else { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    else | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized failed"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return -1; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif //SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#else // !SUPPORT_DRM_CACHE | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return 0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Close platform | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
				
				 | 
			
			 | 
			
			
 |