1 #include <X11/Xlib.h>
2
3 #include <thread>
4 #include <mutex>
5 #include <vector>
6 #include <cstring>
7 #if defined(__linux__)
8 #include <sys/capability.h>
9 #endif
10
11 #include <unistd.h>
12
13 #include "main.hpp"
14 #include "steamcompmgr.hpp"
15 #include "drm.hpp"
16 #include "rendervulkan.hpp"
17 #include "sdlwindow.hpp"
18 #include "wlserver.hpp"
19
20 int ac;
21 char **av;
22
23 int g_nNestedWidth = 1280;
24 int g_nNestedHeight = 720;
25 int g_nNestedRefresh = 0;
26 int g_nNestedUnfocusedRefresh = 0;
27
28 uint32_t g_nOutputWidth = 1280;
29 uint32_t g_nOutputHeight = 720;
30 int g_nOutputRefresh = 60;
31
32 bool g_bFullscreen = false;
33
34 bool g_bIsNested = false;
35
36 bool g_bFilterGameWindow = true;
37
38 bool g_bBorderlessOutputWindow = false;
39
40 bool g_bTakeScreenshot = false;
41
42 bool g_bNiceCap = false;
43 int g_nOldNice = 0;
44 int g_nNewNice = 0;
45
46 uint32_t g_nSubCommandArg = 0;
47
BIsNested()48 int BIsNested()
49 {
50 return g_bIsNested == true;
51 }
52
main(int argc,char ** argv)53 int main(int argc, char **argv)
54 {
55 // Grab the starting position of a potential command that follows "--" in argv
56 // Do it before getopt can reorder anything, for use later
57 for ( int i = 0; i < argc; i++ )
58 {
59 if ( strcmp( "--", argv[ i ] ) == 0 && i + 1 < argc )
60 {
61 g_nSubCommandArg = i + 1;
62 break;
63 }
64 }
65
66 int o;
67 ac = argc;
68 av = argv;
69
70 bool bSleepAtStartup = false;
71
72 while ((o = getopt (argc, argv, ":R:T:w:h:W:H:r:o:NFSvVecsdlnbf")) != -1)
73 {
74 switch (o) {
75 case 'w':
76 g_nNestedWidth = atoi( optarg );
77 break;
78 case 'h':
79 g_nNestedHeight = atoi( optarg );
80 break;
81 case 'W':
82 g_nOutputWidth = atoi( optarg );
83 break;
84 case 'H':
85 g_nOutputHeight = atoi( optarg );
86 break;
87 case 'r':
88 g_nNestedRefresh = atoi( optarg );
89 break;
90 case 'o':
91 g_nNestedUnfocusedRefresh = atoi( optarg );
92 break;
93 case 's':
94 bSleepAtStartup = true;
95 break;
96 case 'l':
97 g_bUseLayers = true;
98 break;
99 case 'd':
100 g_bDebugLayers = true;
101 break;
102 case 'n':
103 g_bFilterGameWindow = false;
104 break;
105 case 'b':
106 g_bBorderlessOutputWindow = true;
107 break;
108 case 'f':
109 g_bFullscreen = true;
110 break;
111 default:
112 break;
113 }
114 }
115
116 // If we're going to execute something monolithic, might as well set this since it'll extend to our clients
117 if ( g_nSubCommandArg != 0 )
118 {
119 const char *pchR600Debug = getenv( "R600_DEBUG" );
120
121 if ( pchR600Debug == nullptr )
122 {
123 setenv( "R600_DEBUG", "nodcc", 1 );
124 }
125 else if ( strstr( pchR600Debug, "nodcc" ) == nullptr )
126 {
127 std::string strPreviousR600Debug = pchR600Debug;
128 strPreviousR600Debug.append( ",nodcc" );
129 setenv( "R600_DEBUG", strPreviousR600Debug.c_str(), 1 );
130 }
131 }
132
133 #if defined(__linux__)
134 cap_t caps;
135 caps = cap_get_proc();
136 cap_flag_value_t nicecapvalue = CAP_CLEAR;
137
138 if ( caps != nullptr )
139 {
140 cap_get_flag( caps, CAP_SYS_NICE, CAP_EFFECTIVE, &nicecapvalue );
141
142 if ( nicecapvalue == CAP_SET )
143 {
144 g_bNiceCap = true;
145
146 errno = 0;
147 int nOldNice = nice( 0 );
148 if ( nOldNice != -1 && errno == 0 )
149 {
150 g_nOldNice = nOldNice;
151 }
152
153 errno = 0;
154 int nNewNice = nice( -20 );
155 if ( nNewNice != -1 && errno == 0 )
156 {
157 g_nNewNice = nNewNice;
158 }
159 }
160 }
161
162 if ( g_bNiceCap == false )
163 {
164 fprintf( stderr, "No CAP_SYS_NICE, falling back to regular-priority compute and threads.\nPerformance will be affected.\n" );
165 }
166 #endif
167
168 if ( bSleepAtStartup == true )
169 {
170 sleep( 2 );
171 }
172
173 XInitThreads();
174
175 if ( getenv("DISPLAY") != NULL )
176 {
177 g_bIsNested = true;
178 }
179
180 wlserver_init(argc, argv, g_bIsNested == true );
181
182 if ( initOutput() != 0 )
183 {
184 fprintf( stderr, "Failed to initialize output\n" );
185 return 1;
186 }
187
188 wlserver_run();
189 }
190
steamCompMgrThreadRun(void)191 void steamCompMgrThreadRun(void)
192 {
193 steamcompmgr_main( ac, av );
194 }
195
startSteamCompMgr(void)196 void startSteamCompMgr(void)
197 {
198 std::thread steamCompMgrThread( steamCompMgrThreadRun );
199 steamCompMgrThread.detach();
200
201 return;
202 }
203
initOutput(void)204 int initOutput(void)
205 {
206 if ( g_bIsNested == true )
207 {
208 return sdlwindow_init() == false;
209 }
210 else
211 {
212 return init_drm( &g_DRM, nullptr, nullptr, 0 );
213 }
214 }
215
wayland_commit(struct wlr_surface * surf,struct wlr_buffer * buf)216 void wayland_commit(struct wlr_surface *surf, struct wlr_buffer *buf)
217 {
218 {
219 std::lock_guard<std::mutex> lock( wayland_commit_lock );
220
221 ResListEntry_t newEntry = {
222 .surf = surf,
223 .buf = buf,
224 };
225 wayland_commit_queue.push_back( newEntry );
226 }
227
228 nudge_steamcompmgr();
229 }
230