mirror of
https://github.com/raysan5/raylib.git
synced 2026-02-07 06:39:17 -05:00
Compare commits
16 Commits
94d8d7133b
...
1fc0b4955f
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fc0b4955f | |||
| eb7f8912f8 | |||
| 8343aed4f6 | |||
| c9f9219fa6 | |||
| 5c680739bd | |||
| 86d9afc10c | |||
| 715e174d13 | |||
| 7262be85fd | |||
| 4da399141a | |||
| d7893141f3 | |||
| 32960af1dc | |||
| d6a897e551 | |||
| 8388160c32 | |||
| 5b182139ae | |||
| de62be0ec5 | |||
| 060bd787b1 |
@ -101,10 +101,37 @@ elseif ("${PLATFORM}" MATCHES "DRM")
|
|||||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread m dl)
|
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread m dl)
|
||||||
|
|
||||||
elseif ("${PLATFORM}" MATCHES "SDL")
|
elseif ("${PLATFORM}" MATCHES "SDL")
|
||||||
find_package(SDL2 REQUIRED)
|
# First, check if SDL is included as a subdirectory
|
||||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
if(TARGET SDL3::SDL3)
|
||||||
set(LIBS_PRIVATE SDL2::SDL2)
|
message(STATUS "Using SDL3 from subdirectory")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||||
|
set(LIBS_PRIVATE SDL3::SDL3)
|
||||||
|
add_compile_definitions(USING_SDL3_PROJECT)
|
||||||
|
elseif(TARGET SDL2::SDL2)
|
||||||
|
message(STATUS "Using SDL2 from subdirectory")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||||
|
set(LIBS_PRIVATE SDL2::SDL2)
|
||||||
|
add_compile_definitions(USING_SDL2_PROJECT)
|
||||||
|
else()
|
||||||
|
# No SDL added via add_subdirectory(), try find_package()
|
||||||
|
message(STATUS "No SDL target from subdirectory, searching via find_package()...")
|
||||||
|
|
||||||
|
# First try SDL3
|
||||||
|
find_package(SDL3 QUIET)
|
||||||
|
if(SDL3_FOUND)
|
||||||
|
message(STATUS "Found SDL3 via find_package()")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||||
|
set(LIBS_PRIVATE SDL3::SDL3)
|
||||||
|
add_compile_definitions(USING_SDL3_PACKAGE)
|
||||||
|
else()
|
||||||
|
# Fallback to SDL2
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
message(STATUS "Found SDL2 via find_package()")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||||
|
set(LIBS_PRIVATE SDL2::SDL2)
|
||||||
|
add_compile_definitions(USING_SDL2_PACKAGE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||||
|
|||||||
807
src/external/rl_gputex.h
vendored
807
src/external/rl_gputex.h
vendored
File diff suppressed because it is too large
Load Diff
@ -1862,8 +1862,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||||||
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
|
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
|
||||||
// to work properly with our implementation (IsKeyDown/IsKeyUp checks)
|
// to work properly with our implementation (IsKeyDown/IsKeyUp checks)
|
||||||
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
|
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
|
||||||
else if(action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
|
else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
|
||||||
else if(action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
else if (action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
||||||
|
|
||||||
// WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys
|
// WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys
|
||||||
if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) ||
|
if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) ||
|
||||||
|
|||||||
@ -52,13 +52,27 @@
|
|||||||
#ifndef SDL_ENABLE_OLD_NAMES
|
#ifndef SDL_ENABLE_OLD_NAMES
|
||||||
#define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily
|
#define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily
|
||||||
#endif
|
#endif
|
||||||
#include "SDL.h" // SDL base library (window/rendered, input, timing... functionality)
|
// SDL base library (window/rendered, input, timing... functionality)
|
||||||
|
#ifdef USING_SDL3_PROJECT
|
||||||
|
#include "SDL3/SDL.h"
|
||||||
|
#elif USING_SDL2_PROJECT
|
||||||
|
#include "SDL2/SDL.h"
|
||||||
|
#else
|
||||||
|
#include "SDL.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
// It seems it does not need to be included to work
|
// It seems it does not need to be included to work
|
||||||
//#include "SDL_opengles2.h"
|
//#include "SDL_opengles2.h"
|
||||||
#else
|
#else
|
||||||
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
// SDL OpenGL functionality (if required, instead of internal renderer)
|
||||||
|
#ifdef USING_SDL3_PROJECT
|
||||||
|
#include "SDL3/SDL_opengl.h"
|
||||||
|
#elif USING_SDL2_PROJECT
|
||||||
|
#include "SDL2/SDL_opengl.h"
|
||||||
|
#else
|
||||||
|
#include "SDL_opengl.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -238,8 +252,7 @@ static const int CursorsLUT[] = {
|
|||||||
//SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h
|
//SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// SDL3 Migration Layer made to avoid 'ifdefs' inside functions when we can.
|
||||||
// SDL3 Migration Layer made to avoid `ifdefs` inside functions when we can.
|
|
||||||
#if defined(PLATFORM_DESKTOP_SDL3)
|
#if defined(PLATFORM_DESKTOP_SDL3)
|
||||||
|
|
||||||
// SDL3 Migration:
|
// SDL3 Migration:
|
||||||
@ -290,13 +303,13 @@ int SDL_GetNumVideoDisplays(void)
|
|||||||
int monitorCount = 0;
|
int monitorCount = 0;
|
||||||
SDL_DisplayID *displays = SDL_GetDisplays(&monitorCount);
|
SDL_DisplayID *displays = SDL_GetDisplays(&monitorCount);
|
||||||
|
|
||||||
// Safe because If `mem` is NULL, SDL_free does nothing
|
// Safe because If 'mem' is NULL, SDL_free does nothing
|
||||||
SDL_free(displays);
|
SDL_free(displays);
|
||||||
|
|
||||||
return monitorCount;
|
return monitorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SLD3 Migration: To emulate SDL2 this function should return `SDL_DISABLE` or `SDL_ENABLE`
|
// SLD3 Migration: To emulate SDL2 this function should return 'SDL_DISABLE' or 'SDL_ENABLE'
|
||||||
// representing the *processing state* of the event before this function makes any changes to it
|
// representing the *processing state* of the event before this function makes any changes to it
|
||||||
Uint8 SDL_EventState(Uint32 type, int state)
|
Uint8 SDL_EventState(Uint32 type, int state)
|
||||||
{
|
{
|
||||||
@ -567,7 +580,7 @@ void SetWindowState(unsigned int flags)
|
|||||||
if (flags & FLAG_WINDOW_UNFOCUSED)
|
if (flags & FLAG_WINDOW_UNFOCUSED)
|
||||||
{
|
{
|
||||||
// NOTE: To be able to implement this part it seems that we should
|
// NOTE: To be able to implement this part it seems that we should
|
||||||
// do it ourselves, via `Windows.h`, `X11/Xlib.h` or even `Cocoa.h`
|
// do it ourselves, via 'windows.h', 'X11/Xlib.h' or even 'Cocoa.h'
|
||||||
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL");
|
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL");
|
||||||
}
|
}
|
||||||
if (flags & FLAG_WINDOW_TOPMOST)
|
if (flags & FLAG_WINDOW_TOPMOST)
|
||||||
@ -1155,13 +1168,13 @@ Image GetClipboardImage(void)
|
|||||||
image = LoadImageFromMemory(imageExtensions[i], fileData, dataSize);
|
image = LoadImageFromMemory(imageExtensions[i], fileData, dataSize);
|
||||||
if (IsImageValid(image))
|
if (IsImageValid(image))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_INFO, "Clipboard image: Got image from clipboard as a `%s` successfully", imageExtensions[i]);
|
TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsImageValid(image)) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data. Error: %s", SDL_GetError());
|
if (!IsImageValid(image)) TRACELOG(LOG_WARNING, "Clipboard: Couldn't get clipboard data. ERROR: %s", SDL_GetError());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|||||||
@ -48,11 +48,11 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************/
|
**********************************************************************************************/
|
||||||
|
|
||||||
#include <fcntl.h> // POSIX file control definitions - open(), creat(), fcntl()
|
#include <fcntl.h> // POSIX file control definitions - open(), creat(), fcntl()
|
||||||
#include <unistd.h> // POSIX standard function definitions - read(), close(), STDIN_FILENO
|
#include <unistd.h> // POSIX standard function definitions - read(), close(), STDIN_FILENO
|
||||||
#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
|
#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
|
||||||
#include <pthread.h> // POSIX threads management (inputs reading)
|
#include <pthread.h> // POSIX threads management (inputs reading)
|
||||||
#include <dirent.h> // POSIX directory browsing
|
#include <dirent.h> // POSIX directory browsing
|
||||||
|
|
||||||
#include <sys/ioctl.h> // Required for: ioctl() - UNIX System call for device-specific input/output operations
|
#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
|
#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
|
||||||
@ -71,6 +71,14 @@
|
|||||||
#include "EGL/egl.h" // Native platform windowing system interface
|
#include "EGL/egl.h" // Native platform windowing system interface
|
||||||
#include "EGL/eglext.h" // EGL extensions
|
#include "EGL/eglext.h" // EGL extensions
|
||||||
|
|
||||||
|
// NOTE: DRM cache enables triple buffered DRM caching
|
||||||
|
#if defined(SUPPORT_DRM_CACHE)
|
||||||
|
#include <poll.h> // Required for: drmHandleEvent() poll
|
||||||
|
#include <errno.h> // Required for: EBUSY, EAGAIN
|
||||||
|
|
||||||
|
#define MAX_DRM_CACHED_BUFFERS 3
|
||||||
|
#endif // SUPPORT_DRM_CACHE
|
||||||
|
|
||||||
#ifndef EGL_OPENGL_ES3_BIT
|
#ifndef EGL_OPENGL_ES3_BIT
|
||||||
#define EGL_OPENGL_ES3_BIT 0x40
|
#define EGL_OPENGL_ES3_BIT 0x40
|
||||||
#endif
|
#endif
|
||||||
@ -78,18 +86,16 @@
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// 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
|
// Actually biggest key is KEY_CNT but we only really map the keys up to KEY_ALS_TOGGLE
|
||||||
// KEY_ALS_TOGGLE
|
|
||||||
#define KEYMAP_SIZE KEY_ALS_TOGGLE
|
#define KEYMAP_SIZE KEY_ALS_TOGGLE
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Display data
|
// Display data
|
||||||
int fd; // File descriptor for /dev/dri/...
|
int fd; // File descriptor for /dev/dri/...
|
||||||
@ -129,6 +135,18 @@ typedef struct {
|
|||||||
int gamepadCount; // The number of gamepads registered
|
int gamepadCount; // The number of gamepads registered
|
||||||
} PlatformData;
|
} 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
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -551,6 +569,212 @@ void DisableCursor(void)
|
|||||||
CORE.Input.Mouse.cursorHidden = true;
|
CORE.Input.Mouse.cursorHidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SUPPORT_DRM_CACHE)
|
||||||
|
|
||||||
|
// 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, "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];
|
||||||
|
|
||||||
|
fbCacheCount--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create or retrieve cached DRM FB for 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new entry if cache not full
|
||||||
|
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 = 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);
|
||||||
|
|
||||||
|
TRACELOG(LOG_INFO, "DISPLAY: DRM: Added new buffer object [%u]" , (uintptr_t)fbId);
|
||||||
|
|
||||||
|
return fbId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renders a blank frame to allocate initial buffers
|
||||||
|
// 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);
|
||||||
|
glFinish(); // Ensure the buffer is processed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize with first buffer only
|
||||||
|
int InitSwapScreenBuffer()
|
||||||
|
{
|
||||||
|
if (!platform.gbmSurface || (platform.fd < 0))
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "DISPLAY: DRM: Swap buffers can not be initialized");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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: DRM: Failed to lock initial swap buffer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create FB for first buffer
|
||||||
|
uint32_t fbId = GetOrCreateFbForBo(bo);
|
||||||
|
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, "DISPLAY: DRM: Failed to initialize CRTC setup. ERROR: %s", strerror(errno));
|
||||||
|
gbm_surface_release_buffer(platform.gbmSurface, bo);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep first buffer locked until flipped
|
||||||
|
platform.prevBO = bo;
|
||||||
|
crtcSet = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 *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 (boToRelease) gbm_surface_release_buffer(platform.gbmSurface, boToRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap implementation with proper caching
|
||||||
|
void SwapScreenBuffer()
|
||||||
|
{
|
||||||
|
if (!crtcSet || !platform.gbmSurface) return;
|
||||||
|
|
||||||
|
static int loopCnt = 0;
|
||||||
|
static int errCnt[5] = {0};
|
||||||
|
loopCnt++;
|
||||||
|
|
||||||
|
// Call this only, if pendingFlip is not set
|
||||||
|
eglSwapBuffers(platform.device, platform.surface);
|
||||||
|
|
||||||
|
// Process pending events non-blocking
|
||||||
|
drmEventContext evctx = {
|
||||||
|
.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);
|
||||||
|
|
||||||
|
// Skip if previous flip pending
|
||||||
|
if (pendingFlip)
|
||||||
|
{
|
||||||
|
errCnt[0]++; // Skip frame: flip pending
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get new 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(nextBO);
|
||||||
|
if (!fbId)
|
||||||
|
{
|
||||||
|
gbm_surface_release_buffer(platform.gbmSurface, nextBO);
|
||||||
|
errCnt[2]++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt page flip
|
||||||
|
// 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 = 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
|
||||||
|
|
||||||
// Swap back buffer with front buffer (screen drawing)
|
// Swap back buffer with front buffer (screen drawing)
|
||||||
void SwapScreenBuffer(void)
|
void SwapScreenBuffer(void)
|
||||||
{
|
{
|
||||||
@ -580,6 +804,7 @@ void SwapScreenBuffer(void)
|
|||||||
|
|
||||||
platform.prevBO = bo;
|
platform.prevBO = bo;
|
||||||
}
|
}
|
||||||
|
#endif // SUPPORT_DRM_CACHE
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition: Misc
|
// Module Functions Definition: Misc
|
||||||
@ -1083,9 +1308,21 @@ int InitPlatform(void)
|
|||||||
CORE.Storage.basePath = GetWorkingDirectory();
|
CORE.Storage.basePath = GetWorkingDirectory();
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(SUPPORT_DRM_CACHE)
|
||||||
|
if (InitSwapScreenBuffer() == 0)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else // !SUPPORT_DRM_CACHE
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close platform
|
// Close platform
|
||||||
|
|||||||
@ -1547,7 +1547,8 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
|||||||
music.looping = true; // Looping enabled by default
|
music.looping = true; // Looping enabled by default
|
||||||
musicLoaded = true;
|
musicLoaded = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
drwav_uninit(ctxWav);
|
drwav_uninit(ctxWav);
|
||||||
RL_FREE(ctxWav);
|
RL_FREE(ctxWav);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -539,7 +539,7 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
|
|||||||
#pragma message ("WARNING: Getting image from the clipboard might not work without SUPPORT_FILEFORMAT_PNG or SUPPORT_FILEFORMAT_JPG")
|
#pragma message ("WARNING: Getting image from the clipboard might not work without SUPPORT_FILEFORMAT_PNG or SUPPORT_FILEFORMAT_JPG")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Not needed because `rtexture.c` will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
|
// Not needed because 'rtexture.c' will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
|
||||||
// #if !defined(STBI_REQUIRED)
|
// #if !defined(STBI_REQUIRED)
|
||||||
// #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
|
// #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
|
||||||
// #endif
|
// #endif
|
||||||
|
|||||||
15
src/rlgl.h
15
src/rlgl.h
@ -710,6 +710,7 @@ RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha,
|
|||||||
RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
|
RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
|
||||||
RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures)
|
RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures)
|
||||||
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
|
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
|
||||||
|
RLAPI void *rlGetProcAddress(const char *procName); // Get OpenGL procedure address
|
||||||
RLAPI int rlGetVersion(void); // Get current OpenGL version
|
RLAPI int rlGetVersion(void); // Get current OpenGL version
|
||||||
RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width
|
RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width
|
||||||
RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
|
RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
|
||||||
@ -1041,10 +1042,15 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
|||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
|
||||||
|
typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc)
|
||||||
|
|
||||||
typedef struct rlglData {
|
typedef struct rlglData {
|
||||||
rlRenderBatch *currentBatch; // Current render batch
|
rlRenderBatch *currentBatch; // Current render batch
|
||||||
rlRenderBatch defaultBatch; // Default internal render batch
|
rlRenderBatch defaultBatch; // Default internal render batch
|
||||||
|
|
||||||
|
rlglLoadProc loader; // OpenGL function loader
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int vertexCounter; // Current active render batch vertex counter (generic, used for all batches)
|
int vertexCounter; // Current active render batch vertex counter (generic, used for all batches)
|
||||||
float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*())
|
float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*())
|
||||||
@ -1114,8 +1120,6 @@ typedef struct rlglData {
|
|||||||
} ExtSupported; // Extensions supported flags
|
} ExtSupported; // Extensions supported flags
|
||||||
} rlglData;
|
} rlglData;
|
||||||
|
|
||||||
typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc)
|
|
||||||
|
|
||||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -2567,6 +2571,8 @@ void rlLoadExtensions(void *loader)
|
|||||||
TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION));
|
TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION));
|
||||||
TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
|
||||||
|
RLGL.loader = (rlglLoadProc)loader;
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
// NOTE: Anisotropy levels capability is an extension
|
// NOTE: Anisotropy levels capability is an extension
|
||||||
#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
|
#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
|
||||||
@ -2625,6 +2631,11 @@ void rlLoadExtensions(void *loader)
|
|||||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get OpenGL procedure address
|
||||||
|
void *rlGetProcAddress(const char *procName) {
|
||||||
|
return RLGL.loader(procName);
|
||||||
|
}
|
||||||
|
|
||||||
// Get current OpenGL version
|
// Get current OpenGL version
|
||||||
int rlGetVersion(void)
|
int rlGetVersion(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4292,7 +4292,7 @@ static Model LoadOBJ(const char *fileName)
|
|||||||
|
|
||||||
if (fileText == NULL)
|
if (fileText == NULL)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_ERROR, "MODEL: [%s] Unable to read obj file", fileName);
|
TRACELOG(LOG_WARNING, "MODEL: [%s] Unable to read obj file", fileName);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4308,7 +4308,7 @@ static Model LoadOBJ(const char *fileName)
|
|||||||
|
|
||||||
if (ret != TINYOBJ_SUCCESS)
|
if (ret != TINYOBJ_SUCCESS)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_ERROR, "MODEL: Unable to read obj data %s", fileName);
|
TRACELOG(LOG_WARNING, "MODEL: Unable to read obj data %s", fileName);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -168,23 +168,14 @@
|
|||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define RL_GPUTEX_MALLOC RL_MALLOC
|
|
||||||
#define RL_GPUTEX_CALLOC RL_CALLOC
|
|
||||||
#define RL_GPUTEX_REALLOC RL_REALLOC
|
|
||||||
#define RL_GPUTEX_FREE RL_FREE
|
|
||||||
#define RL_GPUTEX_WARN(...) TRACELOG(LOG_WARNING, "IMAGE: " __VA_ARGS__)
|
|
||||||
#define RL_GPUTEX_SHOW_WARN_INFO
|
|
||||||
|
|
||||||
// FIXME: probably, we should NOT export public functions from rl_gputex
|
|
||||||
// but this is how it always worked... so let's keep it this way
|
|
||||||
#define RLGPUTEXAPI RLAPI
|
|
||||||
|
|
||||||
|
#define RL_GPUTEX_MALLOC RL_MALLOC
|
||||||
|
#define RL_GPUTEX_FREE RL_FREE
|
||||||
|
#define RL_GPUTEX_LOG(...) TRACELOG(LOG_WARNING, "IMAGE: " __VA_ARGS__)
|
||||||
|
#define RL_GPUTEX_SHOW_LOG_INFO
|
||||||
#define RL_GPUTEX_IMPLEMENTATION
|
#define RL_GPUTEX_IMPLEMENTATION
|
||||||
#include "external/rl_gputex.h" // Required for: rl_load_xxx_from_memory()
|
#include "external/rl_gputex.h" // Required for: rl_load_xxx_from_memory()
|
||||||
// NOTE: Used to read compressed textures data (multiple formats support)
|
// NOTE: Used to read compressed textures data (multiple formats support)
|
||||||
|
|
||||||
#if defined(__GNUC__) // GCC and Clang
|
#if defined(__GNUC__) // GCC and Clang
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user