DisplayServer (Linux): improve performance for X11

Try fixing #634
This commit is contained in:
李通洲
2023-11-30 04:26:30 +00:00
parent 67f4b991d7
commit ea3d904bfe
2 changed files with 31 additions and 98 deletions
+23 -51
View File
@@ -1,5 +1,6 @@
#include "displayserver_linux.h"
#include "util/mallocHelper.h"
#include "common/time.h"
#ifdef FF_HAVE_XCB
#include "common/library.h"
@@ -159,11 +160,9 @@ void ffdsConnectXcb(FFDisplayServerResult* result)
typedef struct XcbRandrData
{
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources)
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_reply)
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_modes_iterator)
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_info)
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_info_reply)
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_current)
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_current_reply)
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_current_modes_iterator)
FF_LIBRARY_SYMBOL(xcb_randr_mode_info_next)
FF_LIBRARY_SYMBOL(xcb_randr_get_monitors)
FF_LIBRARY_SYMBOL(xcb_randr_get_monitors_reply)
@@ -189,9 +188,7 @@ typedef struct XcbRandrData
XcbPropertyData propData;
//init per screen
uint32_t defaultRefreshRate;
uint32_t defaultRotation;
xcb_randr_get_screen_resources_reply_t* screenResources;
xcb_randr_get_screen_resources_current_reply_t* screenResources;
} XcbRandrData;
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary)
@@ -202,7 +199,7 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo
data->result,
(uint32_t) modeInfo->width,
(uint32_t) modeInfo->height,
refreshRate == 0 ? data->defaultRefreshRate : refreshRate,
refreshRate,
(uint32_t) modeInfo->width,
(uint32_t) modeInfo->height,
rotation,
@@ -219,7 +216,7 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb
if(data->screenResources == NULL)
return false;
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_modes_iterator(data->screenResources);
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_current_modes_iterator(data->screenResources);
while(modesIterator.rem > 0)
{
@@ -260,7 +257,7 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
data->result,
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
data->defaultRefreshRate,
0,
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
rotation,
@@ -334,10 +331,10 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
data->result,
(uint32_t) monitor->width,
(uint32_t) monitor->height,
data->defaultRefreshRate,
0,
(uint32_t) monitor->width,
(uint32_t) monitor->height,
data->defaultRotation,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
!!monitor->primary,
@@ -370,38 +367,10 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
{
//Init screen info. This is used to get the default refresh rate. If this fails, default refresh rate is simply 0.
xcb_randr_get_screen_info_cookie_t screenInfoCookie = data->ffxcb_randr_get_screen_info(data->connection, screen->root);
xcb_randr_get_screen_info_reply_t* screenInfoReply = data->ffxcb_randr_get_screen_info_reply(data->connection, screenInfoCookie, NULL);
if(screenInfoReply != NULL)
{
data->defaultRefreshRate = screenInfoReply->rate;
switch (screenInfoReply->rotation)
{
case XCB_RANDR_ROTATION_ROTATE_90:
data->defaultRotation = 90;
break;
case XCB_RANDR_ROTATION_ROTATE_180:
data->defaultRotation = 180;
break;
case XCB_RANDR_ROTATION_ROTATE_270:
data->defaultRotation = 270;
break;
default:
data->defaultRotation = 0;
break;
}
free(screenInfoReply);
}
else
{
data->defaultRefreshRate = 0;
data->defaultRotation = 0;
}
//Init screen resources. They are used to iterate over all modes. xcbRandrHandleMode checks for " == NULL", to fail as late as possible.
xcb_randr_get_screen_resources_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources(data->connection, screen->root);
data->screenResources = data->ffxcb_randr_get_screen_resources_reply(data->connection, screenResourcesCookie, NULL);
xcb_randr_get_screen_resources_current_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources_current(data->connection, screen->root);
data->screenResources = data->ffxcb_randr_get_screen_resources_current_reply(data->connection, screenResourcesCookie, NULL);
//With all the initialisation done, start the detection
bool ret = xcbRandrHandleMonitors(data, screen);
@@ -416,10 +385,10 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
data->result,
(uint32_t) screen->width_in_pixels,
(uint32_t) screen->height_in_pixels,
data->defaultRefreshRate,
0,
(uint32_t) screen->width_in_pixels,
(uint32_t) screen->height_in_pixels,
data->defaultRotation,
0,
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
@@ -440,11 +409,9 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_modes_iterator,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_info,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_info_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_modes_iterator,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_mode_info_next,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_reply,)
@@ -464,17 +431,21 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
bool propertyDataInitialized = xcbInitPropertyData(xcbRandr, &data.propData);
data.connection = ffxcb_connect(NULL, NULL);
if(data.connection == NULL)
return;
data.result = result;
xcb_screen_iterator_t iterator = ffxcb_setup_roots_iterator(ffxcb_get_setup(data.connection));
if(iterator.rem > 0 && propertyDataInitialized)
xcbDetectWMfromEWMH(&data.propData, data.connection, iterator.data->root, result);
while(iterator.rem > 0)
{
xcbRandrHandleScreen(&data, iterator.data);
@@ -483,6 +454,7 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
ffxcb_disconnect(data.connection);
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
if(result->wmProtocolName.length == 0)
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
+8 -47
View File
@@ -117,11 +117,9 @@ typedef struct XrandrData
FF_LIBRARY_SYMBOL(XInternAtom)
FF_LIBRARY_SYMBOL(XGetAtomName);
FF_LIBRARY_SYMBOL(XFree);
FF_LIBRARY_SYMBOL(XRRGetScreenInfo)
FF_LIBRARY_SYMBOL(XRRConfigCurrentConfiguration)
FF_LIBRARY_SYMBOL(XRRConfigCurrentRate)
FF_LIBRARY_SYMBOL(XRRGetMonitors)
FF_LIBRARY_SYMBOL(XRRGetScreenResources)
FF_LIBRARY_SYMBOL(XRRGetScreenResourcesCurrent)
FF_LIBRARY_SYMBOL(XRRGetOutputInfo)
FF_LIBRARY_SYMBOL(XRRGetOutputProperty)
FF_LIBRARY_SYMBOL(XRRGetCrtcInfo)
@@ -129,15 +127,12 @@ typedef struct XrandrData
FF_LIBRARY_SYMBOL(XRRFreeOutputInfo)
FF_LIBRARY_SYMBOL(XRRFreeScreenResources)
FF_LIBRARY_SYMBOL(XRRFreeMonitors)
FF_LIBRARY_SYMBOL(XRRFreeScreenConfigInfo)
//Init once
Display* display;
FFDisplayServerResult* result;
//Init per screen
uint32_t defaultRefreshRate;
uint32_t defaultRotation;
XRRScreenResources* screenResources;
} XrandrData;
@@ -151,7 +146,7 @@ static double xrandrHandleMode(XrandrData* data, RRMode mode)
return (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
}
}
return data->defaultRefreshRate;
return 0;
}
static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary)
@@ -246,10 +241,10 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
data->result,
(uint32_t) monitorInfo->width,
(uint32_t) monitorInfo->height,
data->defaultRefreshRate,
0,
(uint32_t) monitorInfo->width,
(uint32_t) monitorInfo->height,
data->defaultRotation,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
!!monitorInfo->primary,
@@ -279,39 +274,8 @@ static bool xrandrHandleMonitors(XrandrData* data, Screen* screen)
static void xrandrHandleScreen(XrandrData* data, Screen* screen)
{
//Init screen configuration. This is used to get the default refresh rate. If this fails, default refresh rate is simply 0.
XRRScreenConfiguration* screenConfiguration = data->ffXRRGetScreenInfo(data->display, RootWindowOfScreen(screen));
if(screenConfiguration != NULL)
{
data->defaultRefreshRate = (uint32_t) data->ffXRRConfigCurrentRate(screenConfiguration);
Rotation rotation = 0;
data->ffXRRConfigCurrentConfiguration(screenConfiguration, &rotation);
switch (rotation)
{
case RR_Rotate_90:
data->defaultRotation = 90;
break;
case RR_Rotate_180:
data->defaultRotation = 180;
break;
case RR_Rotate_270:
data->defaultRotation = 270;
break;
default:
data->defaultRotation = 0;
break;
}
data->ffXRRFreeScreenConfigInfo(screenConfiguration);
}
else
{
data->defaultRefreshRate = 0;
data->defaultRotation = 0;
}
//Init screen resources
data->screenResources = data->ffXRRGetScreenResources(data->display, RootWindowOfScreen(screen));
data->screenResources = data->ffXRRGetScreenResourcesCurrent(data->display, RootWindowOfScreen(screen));
bool ret = xrandrHandleMonitors(data, screen);
@@ -325,10 +289,10 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
data->result,
(uint32_t) WidthOfScreen(screen),
(uint32_t) HeightOfScreen(screen),
data->defaultRefreshRate,
0,
(uint32_t) WidthOfScreen(screen),
(uint32_t) HeightOfScreen(screen),
data->defaultRotation,
0,
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
@@ -348,11 +312,9 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XFree,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenInfo,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentRate,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentConfiguration,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetMonitors,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResources,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResourcesCurrent,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputInfo,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputProperty,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetCrtcInfo,);
@@ -360,7 +322,6 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeOutputInfo,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeScreenResources,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeMonitors,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeScreenConfigInfo,);
X11PropertyData propertyData;
bool propertyDataInitialized = x11InitPropertyData(xrandr, &propertyData);