VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c@ 59198

Last change on this file since 59198 was 59198, checked in by vboxsync, 9 years ago

SharedOpenGL: bugref:6538: require OpenGL 2.1

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.1 KB
Line 
1 /* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include <string.h>
8#include "cr_mem.h"
9#include "cr_environment.h"
10#include "cr_string.h"
11#include "cr_error.h"
12#include "cr_glstate.h"
13#include "server.h"
14
15#ifdef WINDOWS
16#pragma warning( disable: 4706 )
17#endif
18
19static void
20setDefaults(void)
21{
22 if (!cr_server.tcpip_port)
23 cr_server.tcpip_port = DEFAULT_SERVER_PORT;
24 cr_server.run_queue = NULL;
25 cr_server.optimizeBucket = 1;
26 cr_server.useL2 = 0;
27 cr_server.maxBarrierCount = 0;
28 cr_server.ignore_papi = 0;
29 cr_server.only_swap_once = 0;
30 cr_server.overlapBlending = 0;
31 cr_server.debug_barriers = 0;
32 cr_server.sharedDisplayLists = 0;
33 cr_server.sharedTextureObjects = 0;
34 cr_server.sharedPrograms = 0;
35 cr_server.sharedWindows = 0;
36 cr_server.useDMX = 0;
37 cr_server.vpProjectionMatrixParameter = -1;
38 cr_server.vpProjectionMatrixVariable = NULL;
39 cr_server.currentProgram = 0;
40
41 cr_server.num_overlap_intens = 0;
42 cr_server.overlap_intens = 0;
43 crMemset(&cr_server.MainContextInfo, 0, sizeof (cr_server.MainContextInfo));
44
45 crMatrixInit(&cr_server.viewMatrix[0]);
46 crMatrixInit(&cr_server.viewMatrix[1]);
47 crMatrixInit(&cr_server.projectionMatrix[0]);
48 crMatrixInit(&cr_server.projectionMatrix[1]);
49 cr_server.currentEye = -1;
50
51 cr_server.uniqueWindows = 0;
52
53 cr_server.screenCount = 0;
54 cr_server.bUsePBOForReadback = GL_FALSE;
55 cr_server.bWindowsInitiallyHidden = GL_FALSE;
56
57 cr_server.pfnNotifyEventCB = NULL;
58}
59
60/* Check if host reports minimal OpenGL capabilities.
61 *
62 * Require OpenGL 2.1 or later.
63 *
64 * For example, on Windows host this may happen if host has no graphics
65 * card drivers installed or drivers were not properly signed or VBox
66 * is running via remote desktop session etc. Currently, we take care
67 * about Windows host only when specific RENDERER and VERSION strings
68 * returned in this case. Later this check should be expanded to the
69 * rest of hosts. */
70static bool crServerHasInsufficientCaps()
71{
72 const char *pszRealVersion;
73 int rc;
74 uint32_t u32VerMajor = 0;
75 uint32_t u32VerMinor = 0;
76 char *pszNext = NULL;
77
78 if (!cr_server.head_spu)
79 return true;
80
81 pszRealVersion = (const char *)cr_server.head_spu->dispatch_table.GetString(GL_REAL_VERSION);
82 if (!pszRealVersion)
83 return true; /* No version == insufficient. */
84
85 rc = RTStrToUInt32Ex(pszRealVersion, &pszNext, 10, &u32VerMajor);
86 if ( RT_SUCCESS(rc)
87 && *pszNext == '.')
88 RTStrToUInt32Ex(pszNext + 1, NULL, 10, &u32VerMinor);
89
90 crInfo("Host supports version %d.%d [%s]", u32VerMajor, u32VerMinor, pszRealVersion);
91
92 if ( u32VerMajor > 2
93 || (u32VerMajor == 2 && u32VerMinor >= 1))
94 return false; /* >= 2.1, i.e. good enough. */
95
96 return true; /* Insufficient. */
97}
98
99void crServerSetVBoxConfiguration()
100{
101 CRMuralInfo *defaultMural;
102 char response[8096];
103
104 char **spuchain;
105 int num_spus;
106 int *spu_ids;
107 char **spu_names;
108 char *spu_dir = NULL;
109 int i;
110 /* Quadrics defaults */
111 int my_rank = 0;
112 int low_context = CR_QUADRICS_DEFAULT_LOW_CONTEXT;
113 int high_context = CR_QUADRICS_DEFAULT_HIGH_CONTEXT;
114 unsigned char key[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
115 char hostname[1024];
116 char **clientchain, **clientlist;
117 GLint dims[4];
118 const char * env;
119
120 defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
121 CRASSERT(defaultMural);
122
123 setDefaults();
124
125 /*
126 * Get my hostname
127 */
128 if (crGetHostname(hostname, sizeof(hostname)))
129 {
130 crError("CRServer: Couldn't get my own hostname?");
131 }
132
133#ifdef VBOX_WITH_CR_DISPLAY_LISTS
134 strcpy(response, "1 0 expando");
135#else
136 strcpy(response, "1 0 render");
137#endif
138 crDebug("CRServer: my SPU chain: %s", response);
139
140 /* response will describe the SPU chain.
141 * Example "2 5 wet 6 render"
142 */
143 spuchain = crStrSplit(response, " ");
144 num_spus = crStrToInt(spuchain[0]);
145 spu_ids = (int *) crAlloc(num_spus * sizeof(*spu_ids));
146 spu_names = (char **) crAlloc((num_spus + 1) * sizeof(*spu_names));
147 for (i = 0; i < num_spus; i++)
148 {
149 spu_ids[i] = crStrToInt(spuchain[2 * i + 1]);
150 spu_names[i] = crStrdup(spuchain[2 * i + 2]);
151 crDebug("SPU %d/%d: (%d) \"%s\"", i + 1, num_spus, spu_ids[i],
152 spu_names[i]);
153 }
154 spu_names[i] = NULL;
155
156 crNetSetRank(0);
157 crNetSetContextRange(32, 35);
158 crNetSetNodeRange("iam0", "iamvis20");
159 crNetSetKey(key,sizeof(key));
160 crNetSetKey(key,sizeof(key));
161 cr_server.tcpip_port = 7000;
162
163 crDebug("CRServer: my port number is %d", cr_server.tcpip_port);
164
165 /*
166 * Load the SPUs
167 */
168 cr_server.head_spu =
169 crSPULoadChain(num_spus, spu_ids, spu_names, spu_dir, &cr_server);
170
171 env = crGetenv( "CR_SERVER_DEFAULT_VISUAL_BITS" );
172 if (env != NULL && env[0] != '\0')
173 {
174 unsigned int bits = (unsigned int)crStrParseI32(env, 0);
175 if (bits <= CR_ALL_BITS)
176 cr_server.fVisualBitsDefault = bits;
177 else
178 crWarning("invalid bits option %c", bits);
179 }
180 else
181 cr_server.fVisualBitsDefault = CR_RGB_BIT | CR_ALPHA_BIT | CR_DOUBLE_BIT;
182
183 env = crGetenv("CR_SERVER_CAPS");
184 if (env && env[0] != '\0')
185 {
186 cr_server.u32Caps = crStrParseI32(env, 0);
187 cr_server.u32Caps &= CR_VBOX_CAPS_ALL;
188 }
189 else
190 {
191 cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT
192 | CR_VBOX_CAP_CMDVBVA
193 | CR_VBOX_CAP_CMDBLOCKS
194 | CR_VBOX_CAP_GETATTRIBSLOCATIONS
195 | CR_VBOX_CAP_CMDBLOCKS_FLUSH
196 ;
197 }
198
199 if (crServerHasInsufficientCaps())
200 {
201 crDebug("Cfg: report minimal OpenGL capabilities");
202 cr_server.u32Caps |= CR_VBOX_CAP_HOST_CAPS_NOT_SUFFICIENT;
203 }
204
205 crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)",
206 cr_server.u32Caps,
207 cr_server.fVisualBitsDefault);
208
209 /* Need to do this as early as possible */
210
211 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]);
212 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, 0, GL_INT, 2, &dims[2]);
213
214 defaultMural->gX = dims[0];
215 defaultMural->gY = dims[1];
216 defaultMural->width = dims[2];
217 defaultMural->height = dims[3];
218
219 crFree(spu_ids);
220 crFreeStrings(spu_names);
221 crFreeStrings(spuchain);
222 if (spu_dir)
223 crFree(spu_dir);
224
225 cr_server.mtu = 1024 * 30;
226
227 /*
228 * Get a list of all the clients talking to me.
229 */
230 if (cr_server.vncMode) {
231 /* we're inside a vnc viewer */
232 /*if (!crMothershipSendString( conn, response, "getvncclient %s", hostname ))
233 crError( "Bad Mothership response: %s", response );*/
234 }
235 else {
236 //crMothershipGetClients(conn, response);
237 strcpy(response, "1 tcpip 1");
238 }
239
240 crDebug("CRServer: my clients: %s", response);
241
242 /*
243 * 'response' will now contain a number indicating the number of clients
244 * of this server, followed by a comma-separated list of protocol/SPU ID
245 * pairs.
246 * Example: "3 tcpip 1,gm 2,via 10"
247 */
248 clientchain = crStrSplitn(response, " ", 1);
249 cr_server.numClients = crStrToInt(clientchain[0]);
250 if (cr_server.numClients == 0)
251 {
252 crError("I have no clients! What's a poor server to do?");
253 }
254 clientlist = crStrSplit(clientchain[1], ",");
255
256 /*
257 * Connect to initial set of clients.
258 * Call crNetAcceptClient() for each client.
259 * Also, look for a client that's _not_ using the file: protocol.
260 */
261 for (i = 0; i < cr_server.numClients; i++)
262 {
263 CRClient *newClient = (CRClient *) crCalloc(sizeof(CRClient));
264#ifdef VBOX
265 sscanf(clientlist[i], "%1023s %d", cr_server.protocol, &(newClient->spu_id));
266#else
267 sscanf(clientlist[i], "%s %d", cr_server.protocol, &(newClient->spu_id));
268#endif
269 newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
270 cr_server.tcpip_port,
271 cr_server.mtu, 0);
272 newClient->currentCtxInfo = &cr_server.MainContextInfo;
273 crServerAddToRunQueue(newClient);
274
275 cr_server.clients[i] = newClient;
276 }
277
278 /* set default client and mural */
279 if (cr_server.numClients > 0) {
280 cr_server.curClient = cr_server.clients[0];
281 cr_server.curClient->currentMural = defaultMural;
282 cr_server.client_spu_id =cr_server.clients[0]->spu_id;
283 }
284
285 crFreeStrings(clientchain);
286 crFreeStrings(clientlist);
287
288 /* Ask the mothership for the tile info */
289 //crServerGetTileInfoFromMothership(conn, defaultMural);
290
291 if (cr_server.vncMode) {
292 /* In vnc mode, we reset the mothership configuration so that it can be
293 * used by subsequent OpenGL apps without having to spawn a new mothership
294 * on a new port.
295 */
296 crDebug("CRServer: Resetting mothership to initial state");
297 //crMothershipReset(conn);
298 }
299
300 //crMothershipDisconnect(conn);
301}
302
303void crServerSetVBoxConfigurationHGCM()
304{
305 CRMuralInfo *defaultMural;
306
307#ifdef VBOX_WITH_CR_DISPLAY_LISTS
308 int spu_ids[1] = {0};
309 char *spu_names[1] = {"expando"};
310#else
311 int spu_ids[1] = {0};
312 char *spu_names[1] = {"render"};
313#endif
314 char *spu_dir = NULL;
315 int i;
316 GLint dims[4];
317 const char * env;
318
319 defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
320 CRASSERT(defaultMural);
321
322 //@todo should be moved to addclient so we have a chain for each client
323
324 setDefaults();
325
326 /* Load the SPUs */
327 cr_server.head_spu = crSPULoadChain(1, spu_ids, spu_names, spu_dir, &cr_server);
328
329 if (!cr_server.head_spu)
330 return;
331
332
333 env = crGetenv( "CR_SERVER_DEFAULT_VISUAL_BITS" );
334 if (env != NULL && env[0] != '\0')
335 {
336 unsigned int bits = (unsigned int)crStrParseI32(env, 0);
337 if (bits <= CR_ALL_BITS)
338 cr_server.fVisualBitsDefault = bits;
339 else
340 crWarning("invalid bits option %c", bits);
341 }
342 else
343 cr_server.fVisualBitsDefault = CR_RGB_BIT | CR_ALPHA_BIT | CR_DOUBLE_BIT;
344
345
346 env = crGetenv("CR_SERVER_CAPS");
347 if (env && env[0] != '\0')
348 {
349 cr_server.u32Caps = crStrParseI32(env, 0);
350 cr_server.u32Caps &= CR_VBOX_CAPS_ALL;
351 }
352 else
353 {
354 cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT
355 | CR_VBOX_CAP_CMDVBVA
356 | CR_VBOX_CAP_CMDBLOCKS
357 | CR_VBOX_CAP_GETATTRIBSLOCATIONS
358 | CR_VBOX_CAP_CMDBLOCKS_FLUSH
359 ;
360 }
361
362 if (crServerHasInsufficientCaps())
363 {
364 crDebug("Cfg: report minimal OpenGL capabilities");
365 cr_server.u32Caps |= CR_VBOX_CAP_HOST_CAPS_NOT_SUFFICIENT;
366 }
367
368 crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)",
369 cr_server.u32Caps,
370 cr_server.fVisualBitsDefault);
371
372 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]);
373 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, 0, GL_INT, 2, &dims[2]);
374
375 defaultMural->gX = dims[0];
376 defaultMural->gY = dims[1];
377 defaultMural->width = dims[2];
378 defaultMural->height = dims[3];
379
380 cr_server.mtu = 1024 * 250;
381
382 cr_server.numClients = 0;
383 strcpy(cr_server.protocol, "vboxhgcm");
384
385 for (i = 0; i < cr_server.numClients; i++)
386 {
387 CRClient *newClient = (CRClient *) crCalloc(sizeof(CRClient));
388 newClient->spu_id = 0;
389 newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
390 cr_server.tcpip_port,
391 cr_server.mtu, 0);
392 newClient->currentCtxInfo = &cr_server.MainContextInfo;
393 crServerAddToRunQueue(newClient);
394
395 cr_server.clients[i] = newClient;
396 }
397
398 /* set default client and mural */
399 if (cr_server.numClients > 0) {
400 cr_server.curClient = cr_server.clients[0];
401 cr_server.curClient->currentMural = defaultMural;
402 cr_server.client_spu_id =cr_server.clients[0]->spu_id;
403 }
404}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette