static void set_type( void *spu, const char *response ) { (void) spu; if(crStrcmp( response, "alpha") == 0){ binaryswap_spu.alpha_composite = 1; binaryswap_spu.depth_composite = 0; } else if(crStrcmp( response, "depth") == 0){ binaryswap_spu.depth_composite = 1; binaryswap_spu.alpha_composite = 0; } else{ crError( "Bad composite type specified for the binaryswap SPU?" ); } }
DECLEXPORT(GLint) STATE_APIENTRY crStateGetUniformLocation(GLuint program, const char * name) { #ifdef IN_GUEST CRGLSLProgram *pProgram = crStateGetProgramObj(program); GLint result=-1; GLuint i; if (!pProgram) { crWarning("Unknown program %d", program); return -1; } if (!pProgram->bUniformsSynced) { crWarning("crStateGetUniformLocation called for uncached uniforms"); return -1; } for (i=0; i<pProgram->cUniforms; ++i) { if (!crStrcmp(name, pProgram->pUniforms[i].name)) { result = pProgram->pUniforms[i].location; break; } } return result; #else crWarning("crStateGetUniformLocation called on host side!!"); return -1; #endif }
static void set_ztype(ZpixSPU * zpix_spu, const char *response) { if (crStrcmp(response, "None") == 0) zpix_spu->ztype = GL_NONE; else if (crStrcmp(response, "Zlib") == 0) zpix_spu->ztype = GL_ZLIB_COMPRESSION_CR; else if (crStrcmp(response, "RLE") == 0) zpix_spu->ztype = GL_RLE_COMPRESSION_CR; else if (crStrcmp(response, "PLE") == 0) zpix_spu->ztype = GL_PLE_COMPRESSION_CR; else { crWarning("Bad value (%s) for ZPix compression ", response); zpix_spu->ztype = GL_ZLIB_COMPRESSION_CR; } crDebug("Zpix SPU config: ztype = %d", zpix_spu->ztype); }
SPU * crSPULoad( SPU *child, int id, char *name, char *dir, void *server ) { SPU *the_spu; char *path; CRASSERT( name != NULL ); the_spu = (SPU*)crAlloc( sizeof( *the_spu ) ); the_spu->id = id; the_spu->privatePtr = NULL; path = __findDLL( name, dir ); the_spu->dll = crDLLOpen( path, 0/*resolveGlobal*/ ); the_spu->entry_point = (SPULoadFunction) crDLLGetNoError( the_spu->dll, SPU_ENTRY_POINT_NAME ); if (!the_spu->entry_point) { crError( "Couldn't load the SPU entry point \"%s\" from SPU \"%s\"!", SPU_ENTRY_POINT_NAME, name ); } /* This basicall calls the SPU's SPULoad() function */ if (!the_spu->entry_point( &(the_spu->name), &(the_spu->super_name), &(the_spu->init), &(the_spu->self), &(the_spu->cleanup), &(the_spu->options), &(the_spu->spu_flags)) ) { crError( "I found the SPU \"%s\", but loading it failed!", name ); } if (crStrcmp(the_spu->name,"error")) { /* the default super/base class for an SPU is the error SPU */ if (the_spu->super_name == NULL) { the_spu->super_name = "error"; } the_spu->superSPU = crSPULoad( child, id, the_spu->super_name, dir, server ); } else { the_spu->superSPU = NULL; } crDebug("Initializing %s SPU", name); the_spu->function_table = the_spu->init( id, child, the_spu, 0, 1 ); __buildDispatch( the_spu ); /*crDebug( "initializing dispatch table %p (for SPU %s)", (void*)&(the_spu->dispatch_table), name );*/ crSPUInitDispatchTable( &(the_spu->dispatch_table) ); /*crDebug( "Done initializing the dispatch table for SPU %s, calling the self function", name );*/ the_spu->dispatch_table.server = server; the_spu->self( &(the_spu->dispatch_table) ); /*crDebug( "Done with the self function" );*/ return the_spu; }
int main( int argc, char *argv[] ) { int i; char *mothership = NULL; #ifdef DARWIN #elif !defined(WINDOWS) Display *disp = NULL; #endif for (i = 1 ; i < argc ; i++) { if (!crStrcmp( argv[i], "-mothership" )) { if (i == argc - 1) { crError( "-mothership requires an argument" ); } mothership = argv[i+1]; i++; } } crDebug("This the CRUT server"); crutInitServer(mothership, argc, argv); if (crut_server.callbacks.mouse) glutMouseFunc(handleMouse); if (crut_server.callbacks.keyboard) glutKeyboardFunc(handleKeyboard); if (crut_server.callbacks.motion) glutMotionFunc(handleMotion); if (crut_server.callbacks.passivemotion) glutPassiveMotionFunc(handlePassiveMotion); if (crut_server.callbacks.visibility) glutVisibilityFunc(handleVisibility); if (crut_server.callbacks.reshape) glutReshapeFunc(handleReshape); /* Need to 'release' the current drawable so render SPU can make current to it*/ #ifdef DARWIN #elif !defined(WINDOWS) disp = glXGetCurrentDisplay(); glXMakeCurrent(disp, None, NULL); #endif glutMainLoop(); return 0; }
static void set_spec(void *foo, const char *response) { if (saveframe_spu.spec && (!crStrcmp(response, "frame%d.ppm"))) return; /* Specified basename and only default spec. */ if (saveframe_spu.spec) crFree(saveframe_spu.spec); saveframe_spu.spec = crStrdup(response); }
/* Intersect two strings on a word-by-word basis (separated by spaces). * We typically use this to intersect OpenGL extension strings. * Example: if s1 = "apple banana plum pear" * and s2 = "plum banana orange" * then return "banana plum" (or "plum banana"). */ char *crStrIntersect( const char *s1, const char *s2 ) { int len1, len2; int resultLen; char *result; char **exten1, **exten2; int i, j; if (!s1 || !s2) { /* null strings, no intersection */ return NULL; } len1 = crStrlen(s1); len2 = crStrlen(s2); /* allocate storage for result (a conservative estimate) */ resultLen = ((len1 > len2) ? len1 : len2) + 2; result = (char *) crAlloc(resultLen); if (!result) { return NULL; } result[0] = 0; /* split s1 and s2 at space chars */ exten1 = crStrSplit(s1, " "); exten2 = crStrSplit(s2, " "); for (i = 0; exten1[i]; i++) { for (j = 0; exten2[j]; j++) { if (crStrcmp(exten1[i], exten2[j]) == 0) { /* found an intersection, append to result */ crStrcat(result, exten1[i]); crStrcat(result, " "); break; } } } /* free split strings */ crFreeStrings( exten1 ); crFreeStrings( exten2 ); /*CRASSERT(crStrlen(result) < resultLen);*/ /* all done! */ return result; }
/** * Helper routine used by both crNetConnectToServer() and crNetAcceptClient(). * Call the protocol-specific Init() and Connection() functions. * */ static void InitConnection(CRConnection *conn, const char *protocol, unsigned int mtu) { if (!crStrcmp(protocol, "devnull")) { crDevnullInit(cr_net.recv_list, cr_net.close_list, mtu); crDevnullConnection(conn); } else if (!crStrcmp(protocol, "file")) { cr_net.use_file++; crFileInit(cr_net.recv_list, cr_net.close_list, mtu); crFileConnection(conn); } else if (!crStrcmp(protocol, "swapfile")) { /* file with byte-swapping */ cr_net.use_file++; crFileInit(cr_net.recv_list, cr_net.close_list, mtu); crFileConnection(conn); conn->swap = 1; } else if (!crStrcmp(protocol, "tcpip")) { cr_net.use_tcpip++; crTCPIPInit(cr_net.recv_list, cr_net.close_list, mtu); crTCPIPConnection(conn); } else if (!crStrcmp(protocol, "udptcpip")) { cr_net.use_udp++; crUDPTCPIPInit(cr_net.recv_list, cr_net.close_list, mtu); crUDPTCPIPConnection(conn); } else { crError("Unknown protocol: \"%s\"", protocol); } }
DECLEXPORT(void) STATE_APIENTRY crStateBindAttribLocation(GLuint program, GLuint index, const char * name) { CRGLSLProgram *pProgram = crStateGetProgramObj(program); GLuint i; CRGLSLAttrib *pAttribs; if (!pProgram) { crWarning("Unknown program %d", program); return; } if (index>=CR_MAX_VERTEX_ATTRIBS) { crWarning("crStateBindAttribLocation: Index too big %d", index); return; } for (i=0; i<pProgram->currentState.cAttribs; ++i) { if (!crStrcmp(pProgram->currentState.pAttribs[i].name, name)) { crFree(pProgram->currentState.pAttribs[i].name); pProgram->currentState.pAttribs[i].name = crStrdup(name); return; } } pAttribs = (CRGLSLAttrib*) crAlloc((pProgram->currentState.cAttribs+1)*sizeof(CRGLSLAttrib)); if (!pAttribs) { crWarning("crStateBindAttribLocation: Out of memory!"); return; } if (pProgram->currentState.cAttribs) { crMemcpy(&pAttribs[0], &pProgram->currentState.pAttribs[0], pProgram->currentState.cAttribs*sizeof(CRGLSLAttrib)); } pAttribs[pProgram->currentState.cAttribs].index = index; pAttribs[pProgram->currentState.cAttribs].name = crStrdup(name); pProgram->currentState.cAttribs++; if (pProgram->currentState.pAttribs) crFree(pProgram->currentState.pAttribs); pProgram->currentState.pAttribs = pAttribs; }
static void set_display_string( RenderSPU *render_spu, const char *response ) { if (!crStrcmp(response, "DEFAULT")) { const char *display = crGetenv("DISPLAY"); if (display) crStrncpy(render_spu->display_string, display, sizeof(render_spu->display_string)); else crStrcpy(render_spu->display_string, ""); /* empty string */ } else { crStrncpy(render_spu->display_string, response, sizeof(render_spu->display_string)); } }
int main(int argc, char *argv[]) { SPU *spu; SPUOptions *opt; int pythonMode = 0; int i = 1; while (i < argc) { if (crStrcmp(argv[i], "--pythonmode") == 0) { pythonMode = 1; } else { const char *spuName = argv[i]; int i; /* loop to walk up the inheritance tree */ for (i = 0; ; i++) { spu = SPULoadLite( NULL, 1, spuName, NULL, NULL ); if (i == 0) { print_spu_header( spu, pythonMode ); } for ( opt = &spu->options[0] ; opt->option ; opt++ ) print_option( opt, pythonMode ); if (spu && spu->super_name) { /* traverse up to parent SPU class to get its options */ spuName = spu->super_name; } else { break; } } print_spu_footer( spu, pythonMode ); /* How to unload the spu??? */ } i++; } return 0; }
/* * Find a VisualInfo which matches the given display name and attribute * bitmask, or return a pointer to a new visual. */ VisualInfo * renderspuFindVisual(const char *displayName, GLbitfield visAttribs) { int i; if (!displayName) displayName = ""; /* first, try to find a match */ #if defined(WINDOWS) || defined(DARWIN) for (i = 0; i < render_spu.numVisuals; i++) { if (visAttribs == render_spu.visuals[i].visAttribs) { return &(render_spu.visuals[i]); } } #elif defined(GLX) for (i = 0; i < render_spu.numVisuals; i++) { if (crStrcmp(displayName, render_spu.visuals[i].displayName) == 0 && visAttribs == render_spu.visuals[i].visAttribs) { return &(render_spu.visuals[i]); } } #endif if (render_spu.numVisuals >= MAX_VISUALS) { crWarning("Render SPU: Couldn't create a visual, too many visuals already"); return NULL; } /* create a new visual */ i = render_spu.numVisuals; render_spu.visuals[i].displayName = crStrdup(displayName); render_spu.visuals[i].visAttribs = visAttribs; if (renderspu_SystemInitVisual(&(render_spu.visuals[i]))) { render_spu.numVisuals++; return &(render_spu.visuals[i]); } else { crWarning("Render SPU: Couldn't get a visual, renderspu_SystemInitVisual failed"); return NULL; } }
/** * Find the index of the given enum value in the SPUOption's list of * possible enum values. * Return the enum index, or -1 if not found. */ int crSPUGetEnumIndex( const SPUOptions *options, const char *optName, const char *value ) { const SPUOptions *opt; const int valueLen = crStrlen(value); /* first, find the right option */ for (opt = options; opt->option; opt++) { if (crStrcmp(opt->option, optName) == 0) { char **values; int i; CRASSERT(opt->type == CR_ENUM); /* break into array of strings */ /* min string should be of form "'enum1', 'enum2', 'enum3', etc" */ values = crStrSplit(opt->min, ","); /* search the array */ for (i = 0; values[i]; i++) { /* find leading quote */ const char *e = crStrchr(values[i], '\''); CRASSERT(e); if (e) { /* test for match */ if (crStrncmp(value, e + 1, valueLen) == 0 && e[valueLen + 1] == '\'') { crFreeStrings(values); return i; } } } /* enum value not found! */ crFreeStrings(values); return -1; } } return -1; }
void CRUT_APIENTRY crutGetWindowParams( CRUTAPI *crut_api) { char response[8096]; if (!crut_api->mothershipConn) crError("Checking for Window Params but no connection!"); crMothershipGetCRUTServerParam( crut_api->mothershipConn, response, "window_geometry" ); crDebug("CRUTserver window geometry is %s", response); if (response[0] == '[') sscanf( response, "[ %i, %i, %i, %i ]", &crut_api->winX, &crut_api->winY, &crut_api->winWidth, &crut_api->winHeight ); else if (crStrchr(response, ',')) sscanf( response, "%i, %i, %i, %i", &crut_api->winX, &crut_api->winY, &crut_api->winWidth, &crut_api->winHeight ); else sscanf( response, "%i %i %i %i", &crut_api->winX, &crut_api->winY, &crut_api->winWidth, &crut_api->winHeight ); crDebug("CRUTserver window geometry is %s", response); crMothershipGetCRUTServerParam( crut_api->mothershipConn, response, "composite_mode" ); crut_api->compositeAlpha = crStrstr(response, "alpha") ? 1 : 0; crut_api->compositeDepth = crStrcmp(response, "depth") ? 1 : 0; }
/** * Do CRServer initializations. After this, we can begin servicing clients. */ void crServerInit(int argc, char *argv[]) { int i; char *mothership = NULL; CRMuralInfo *defaultMural; for (i = 1 ; i < argc ; i++) { if (!crStrcmp( argv[i], "-mothership" )) { if (i == argc - 1) { crError( "-mothership requires an argument" ); } mothership = argv[i+1]; i++; } else if (!crStrcmp( argv[i], "-port" )) { /* This is the port on which we'll accept client connections */ if (i == argc - 1) { crError( "-port requires an argument" ); } cr_server.tcpip_port = crStrToInt(argv[i+1]); i++; } else if (!crStrcmp( argv[i], "-vncmode" )) { cr_server.vncMode = 1; } else if (!crStrcmp( argv[i], "-help" )) { crPrintHelp(); exit(0); } } signal( SIGTERM, crServerCleanup ); signal( SIGINT, crServerCleanup ); #ifndef WINDOWS signal( SIGPIPE, SIG_IGN ); #endif #if DEBUG_FP_EXCEPTIONS { fpu_control_t mask; _FPU_GETCW(mask); mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM); _FPU_SETCW(mask); } #endif cr_server.firstCallCreateContext = GL_TRUE; cr_server.firstCallMakeCurrent = GL_TRUE; /* * Create default mural info and hash table. */ cr_server.muralTable = crAllocHashtable(); defaultMural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo)); crHashtableAdd(cr_server.muralTable, 0, defaultMural); cr_server.programTable = crAllocHashtable(); crNetInit(crServerRecv, crServerClose); crStateInit(); crServerGatherConfiguration(mothership); crStateLimitsInit( &(cr_server.limits) ); /* * Default context */ cr_server.contextTable = crAllocHashtable(); cr_server.DummyContext = crStateCreateContext( &cr_server.limits, CR_RGB_BIT | CR_DEPTH_BIT, NULL ); cr_server.curClient->currentCtx = cr_server.DummyContext; crServerInitDispatch(); crStateDiffAPI( &(cr_server.head_spu->dispatch_table) ); crUnpackSetReturnPointer( &(cr_server.return_ptr) ); crUnpackSetWritebackPointer( &(cr_server.writeback_ptr) ); cr_server.barriers = crAllocHashtable(); cr_server.semaphores = crAllocHashtable(); }
/** * Do one-time initializations for the faker. * Returns TRUE on success, FALSE otherwise. */ static bool stubInitLocked(void) { /* Here is where we contact the mothership to find out what we're supposed * to be doing. Networking code in a DLL initializer. I sure hope this * works :) * * HOW can I pass the mothership address to this if I already know it? */ CRConnection *conn = NULL; char response[1024]; char **spuchain; int num_spus; int *spu_ids; char **spu_names; const char *app_id; int i; int disable_sync = 0; stubInitVars(); crGetProcName(response, 1024); crDebug("Stub launched for %s", response); #if defined(CR_NEWWINTRACK) && !defined(WINDOWS) /*@todo when vm boots with compiz turned on, new code causes hang in xcb_wait_for_reply in the sync thread * as at the start compiz runs our code under XGrabServer. */ if (!crStrcmp(response, "compiz") || !crStrcmp(response, "compiz_real") || !crStrcmp(response, "compiz.real") || !crStrcmp(response, "compiz-bin")) { disable_sync = 1; } #elif defined(WINDOWS) && defined(VBOX_WITH_WDDM) && defined(VBOX_WDDM_MINIPORT_WITH_VISIBLE_RECTS) if (GetModuleHandle(VBOX_MODNAME_DISPD3D)) { disable_sync = 1; crDebug("running with " VBOX_MODNAME_DISPD3D); stub.trackWindowVisibleRgn = 0; stub.bRunningUnderWDDM = true; } #endif /* @todo check if it'd be of any use on other than guests, no use for windows */ app_id = crGetenv( "CR_APPLICATION_ID_NUMBER" ); crNetInit( NULL, NULL ); #ifndef WINDOWS { CRNetServer ns; ns.name = "vboxhgcm://host:0"; ns.buffer_size = 1024; crNetServerConnect(&ns #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , NULL #endif ); if (!ns.conn) { crWarning("Failed to connect to host. Make sure 3D acceleration is enabled for this VM."); return false; } else { crNetFreeConnection(ns.conn); } #if 0 && defined(CR_NEWWINTRACK) { Status st = XInitThreads(); if (st==0) { crWarning("XInitThreads returned %i", (int)st); } } #endif } #endif strcpy(response, "2 0 feedback 1 pack"); spuchain = crStrSplit( response, " " ); num_spus = crStrToInt( spuchain[0] ); spu_ids = (int *) crAlloc( num_spus * sizeof( *spu_ids ) ); spu_names = (char **) crAlloc( num_spus * sizeof( *spu_names ) ); for (i = 0 ; i < num_spus ; i++) { spu_ids[i] = crStrToInt( spuchain[2*i+1] ); spu_names[i] = crStrdup( spuchain[2*i+2] ); crDebug( "SPU %d/%d: (%d) \"%s\"", i+1, num_spus, spu_ids[i], spu_names[i] ); } stubSetDefaultConfigurationOptions(); stub.spu = crSPULoadChain( num_spus, spu_ids, spu_names, stub.spu_dir, NULL ); crFree( spuchain ); crFree( spu_ids ); for (i = 0; i < num_spus; ++i) crFree(spu_names[i]); crFree( spu_names ); // spu chain load failed somewhere if (!stub.spu) { return false; } crSPUInitDispatchTable( &glim ); /* This is unlikely to change -- We still want to initialize our dispatch * table with the functions of the first SPU in the chain. */ stubInitSPUDispatch( stub.spu ); /* we need to plug one special stub function into the dispatch table */ glim.GetChromiumParametervCR = stub_GetChromiumParametervCR; #if !defined(VBOX_NO_NATIVEGL) /* Load pointers to native OpenGL functions into stub.nativeDispatch */ stubInitNativeDispatch(); #endif /*crDebug("stub init"); raise(SIGINT);*/ #ifdef WINDOWS # ifndef CR_NEWWINTRACK stubInstallWindowMessageHook(); # endif #endif #ifdef CR_NEWWINTRACK { int rc; RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE); if (!disable_sync) { crDebug("Starting sync thread"); rc = RTThreadCreate(&stub.hSyncThread, stubSyncThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Sync"); if (RT_FAILURE(rc)) { crError("Failed to start sync thread! (%x)", rc); } RTThreadUserWait(stub.hSyncThread, 60 * 1000); RTThreadUserReset(stub.hSyncThread); crDebug("Going on"); } } #endif #ifdef GLX stub.xshmSI.shmid = -1; stub.bShmInitFailed = GL_FALSE; stub.pGLXPixmapsHash = crAllocHashtable(); stub.bXExtensionsChecked = GL_FALSE; stub.bHaveXComposite = GL_FALSE; stub.bHaveXFixes = GL_FALSE; #endif return true; }
/** * This function is called by MakeCurrent() and determines whether or * not a new rendering context should be bound to Chromium or the native * OpenGL. * \return GL_FALSE if native OpenGL should be used, or GL_TRUE if Chromium * should be used. */ static GLboolean stubCheckUseChromium( WindowInfo *window ) { int x, y; unsigned int w, h; /* If the provided window is CHROMIUM, we're clearly intended * to create a CHROMIUM context. */ if (window->type == CHROMIUM) return GL_TRUE; if (stub.ignoreFreeglutMenus) { const char *glutMenuTitle = "freeglut menu"; char title[1000]; GetWindowTitle(window, title); if (crStrcmp(title, glutMenuTitle) == 0) { crDebug("GL faker: Ignoring freeglut menu window"); return GL_FALSE; } } /* If the user's specified a window count for Chromium, see if * this window satisfies that criterium. */ stub.matchChromiumWindowCounter++; if (stub.matchChromiumWindowCount > 0) { if (stub.matchChromiumWindowCounter != stub.matchChromiumWindowCount) { crDebug("Using native GL, app window doesn't meet match_window_count"); return GL_FALSE; } } /* If the user's specified a window list to ignore, see if this * window satisfies that criterium. */ if (stub.matchChromiumWindowID) { GLuint i; for (i = 0; i <= stub.numIgnoreWindowID; i++) { if (stub.matchChromiumWindowID[i] == stub.matchChromiumWindowCounter) { crDebug("Ignore window ID %d, using native GL", stub.matchChromiumWindowID[i]); return GL_FALSE; } } } /* If the user's specified a minimum window size for Chromium, see if * this window satisfies that criterium. */ if (stub.minChromiumWindowWidth > 0 && stub.minChromiumWindowHeight > 0) { stubGetWindowGeometry( window, &x, &y, &w, &h ); if (w >= stub.minChromiumWindowWidth && h >= stub.minChromiumWindowHeight) { /* Check for maximum sized window now too */ if (stub.maxChromiumWindowWidth && stub.maxChromiumWindowHeight) { if (w < stub.maxChromiumWindowWidth && h < stub.maxChromiumWindowHeight) return GL_TRUE; else return GL_FALSE; } return GL_TRUE; } crDebug("Using native GL, app window doesn't meet minimum_window_size"); return GL_FALSE; } else if (stub.matchWindowTitle) { /* If the user's specified a window title for Chromium, see if this * window satisfies that criterium. */ GLboolean wildcard = GL_FALSE; char title[1000]; char *titlePattern; int len; /* check for leading '*' wildcard */ if (stub.matchWindowTitle[0] == '*') { titlePattern = crStrdup( stub.matchWindowTitle + 1 ); wildcard = GL_TRUE; } else { titlePattern = crStrdup( stub.matchWindowTitle ); } /* check for trailing '*' wildcard */ len = crStrlen(titlePattern); if (len > 0 && titlePattern[len - 1] == '*') { titlePattern[len - 1] = '\0'; /* terminate here */ wildcard = GL_TRUE; } GetWindowTitle( window, title ); if (title[0]) { if (wildcard) { if (crStrstr(title, titlePattern)) { crFree(titlePattern); return GL_TRUE; } } else if (crStrcmp(title, titlePattern) == 0) { crFree(titlePattern); return GL_TRUE; } } crFree(titlePattern); crDebug("Using native GL, app window title doesn't match match_window_title string (\"%s\" != \"%s\")", title, stub.matchWindowTitle); return GL_FALSE; } /* Window title and size don't matter */ CRASSERT(stub.minChromiumWindowWidth == 0); CRASSERT(stub.minChromiumWindowHeight == 0); CRASSERT(stub.matchWindowTitle == NULL); /* User hasn't specified a width/height or window title. * We'll use chromium for this window (and context) if no other is. */ return GL_TRUE; /* use Chromium! */ }
static void vboxPatchMesaExport(const char* psFuncName, const void *pStart, const void *pEnd) { Dl_info dlip; DRI_ELFSYM* sym=0; int rv; void *alPatch; void *pMesaEntry; char patch[FAKEDRI_JMP64_PATCH_SIZE]; void *shift; int ignore_size=false; #ifndef VBOX_NO_MESA_PATCH_REPORTS crDebug("\nvboxPatchMesaExport: %s", psFuncName); #endif pMesaEntry = dlsym(RTLD_DEFAULT, psFuncName); if (!pMesaEntry) { crDebug("%s not defined in current scope, are we being loaded by mesa's libGL.so?", psFuncName); return; } rv = dladdr1(pMesaEntry, &dlip, (void**)&sym, RTLD_DL_SYMENT); if (!rv || !sym) { crError("Failed to get size for %p(%s)", pMesaEntry, psFuncName); return; } #if VBOX_OGL_GLX_USE_CSTUBS { Dl_info dlip1; DRI_ELFSYM* sym1=0; int rv; rv = dladdr1(pStart, &dlip1, (void**)&sym1, RTLD_DL_SYMENT); if (!rv || !sym1) { crError("Failed to get size for vbox %p", pStart); return; } pEnd = pStart + sym1->st_size; # ifndef VBOX_NO_MESA_PATCH_REPORTS crDebug("VBox Entry: %p, start: %p(%s:%s), size: %li", pStart, dlip1.dli_saddr, dlip1.dli_fname, dlip1.dli_sname, sym1->st_size); # endif } #endif #ifndef VBOX_NO_MESA_PATCH_REPORTS crDebug("Mesa Entry: %p, start: %p(%s:%s), size: %li", pMesaEntry, dlip.dli_saddr, dlip.dli_fname, dlip.dli_sname, sym->st_size); crDebug("VBox code: start: %p, end %p, size: %li", pStart, pEnd, pEnd-pStart); #endif #ifndef VBOX_OGL_GLX_USE_CSTUBS if (sym->st_size<(pEnd-pStart)) #endif { #ifdef RT_ARCH_AMD64 int64_t offset; #endif /* Try to insert 5 bytes jmp/jmpq to our stub code */ if (sym->st_size<5) { /*@todo we don't really know the size of targeted static function, but it's long enough in practice. We will also patch same place twice, but it's ok.*/ if (!crStrcmp(psFuncName, "glXDestroyContext") || !crStrcmp(psFuncName, "glXFreeContextEXT")) { if (((unsigned char*)dlip.dli_saddr)[0]==0xEB) { /*it's a rel8 jmp, so we're going to patch the place it targets instead of jmp itself*/ dlip.dli_saddr = (void*) ((intptr_t)dlip.dli_saddr + ((char*)dlip.dli_saddr)[1] + 2); ignore_size = true; } else { crError("Can't patch size is too small.(%s)", psFuncName); return; } } else if (!crStrcmp(psFuncName, "glXCreateGLXPixmapMESA")) { /*@todo it's just a return 0, which we're fine with for now*/ return; } else { crError("Can't patch size is too small.(%s)", psFuncName); return; } } shift = (void*)((intptr_t)pStart-((intptr_t)dlip.dli_saddr+5)); #ifdef RT_ARCH_AMD64 offset = (intptr_t)shift; if (offset>INT32_MAX || offset<INT32_MIN) { /*try to insert 64bit abs jmp*/ if (sym->st_size>=FAKEDRI_JMP64_PATCH_SIZE || ignore_size) { # ifndef VBOX_NO_MESA_PATCH_REPORTS crDebug("Inserting movq/jmp instead"); # endif /*add 64bit abs jmp*/ patch[0] = 0x49; /*movq %r11,imm64*/ patch[1] = 0xBB; crMemcpy(&patch[2], &pStart, 8); patch[10] = 0x41; /*jmp *%r11*/ patch[11] = 0xFF; patch[12] = 0xE3; pStart = &patch[0]; pEnd = &patch[FAKEDRI_JMP64_PATCH_SIZE]; } else { FAKEDRI_PatchNode *pNode; # ifndef VBOX_NO_MESA_PATCH_REPORTS crDebug("Can't patch offset is too big. Pushing for 2nd pass(%s)", psFuncName); # endif /*Add patch node to repatch with chain jmps in 2nd pass*/ pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode)); if (!pNode) { crError("Not enough memory."); return; } pNode->psFuncName = psFuncName; pNode->pDstStart = dlip.dli_saddr; pNode->pDstEnd = dlip.dli_saddr+sym->st_size; pNode->pSrcStart = pStart; pNode->pSrcEnd = pEnd; pNode->pNext = g_pRepatchList; g_pRepatchList = pNode; return; } } else #endif { #ifndef VBOX_NO_MESA_PATCH_REPORTS crDebug("Inserting jmp[q] with shift %p instead", shift); #endif patch[0] = 0xE9; crMemcpy(&patch[1], &shift, 4); pStart = &patch[0]; pEnd = &patch[5]; } } vboxApplyPatch(psFuncName, dlip.dli_saddr, pStart, pEnd-pStart); #ifdef RT_ARCH_AMD64 /*Add rest of mesa function body to free list*/ if (sym->st_size-(pEnd-pStart)>=FAKEDRI_JMP64_PATCH_SIZE) { FAKEDRI_PatchNode *pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode)); if (pNode) { pNode->psFuncName = psFuncName; pNode->pDstStart = dlip.dli_saddr+(pEnd-pStart); pNode->pDstEnd = dlip.dli_saddr+sym->st_size; pNode->pSrcStart = dlip.dli_saddr; pNode->pSrcEnd = NULL; pNode->pNext = g_pFreeList; g_pFreeList = pNode; # ifndef VBOX_NO_MESA_PATCH_REPORTS crDebug("Added free node %s, func start=%p, free start=%p, size=%#lx", psFuncName, pNode->pSrcStart, pNode->pDstStart, pNode->pDstEnd-pNode->pDstStart); # endif } } #endif }
/** * Get the tile information (count, extents, etc) from the servers * and build our corresponding data structures. * This is called once during SPU initialization. * Input: conn - mothership connection */ void tilesortspuGetTilingFromServers(CRConnection *conn, WindowInfo *winInfo) { ThreadInfo *thread0 = &(tilesort_spu.thread[0]); char response[8096]; char **serverchain, **serverlist; int num_servers; int i; crDebug("Getting tile information from servers."); /* The response to this tells us how many servers and where they are * * For example: 2 tcpip://foo tcpip://bar */ crMothershipGetServers(conn, response); serverchain = crStrSplitn(response, " ", 1); num_servers = crStrToInt(serverchain[0]); CRASSERT(num_servers == tilesort_spu.num_servers); serverlist = crStrSplit(serverchain[1], ","); tilesort_spu.thread[0].netServer = (CRNetServer *) crCalloc(num_servers * sizeof(CRNetServer)); tilesort_spu.thread[0].buffer = (CRPackBuffer *) crCalloc(num_servers * sizeof(CRPackBuffer)); /** XXX: \todo there is lots of overlap between these cases. merge! */ if (tilesort_spu.localTileSpec) { char **displaylist, **displaychain; double *corners; int num_displays, idx; double world_bbox[4]; /* * Here we has tiles specified relative to the origin of * whichever display they happen to land in. First, gather * the list of displays, then get the tiles that belong on it */ crMothershipGetDisplays(conn, response); displaychain = crStrSplitn(response, " ", 1); displaylist = crStrSplit(displaychain[1], ","); num_displays = crStrToInt(displaychain[0]); corners = (double *) crAlloc(num_displays * 8 * sizeof(double)); tilesort_spu.displays = (WarpDisplayInfo *) crAlloc(num_displays * sizeof(WarpDisplayInfo)); idx = 0; for (i = 0; i < num_displays; i++) { float pnt[2], warped[2]; sscanf(displaylist[i], "%d %d %d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", &tilesort_spu.displays[i].id, &tilesort_spu.displays[i].width, &tilesort_spu.displays[i].height, &tilesort_spu.displays[i].correct[0], &tilesort_spu.displays[i].correct[1], &tilesort_spu.displays[i].correct[2], &tilesort_spu.displays[i].correct[3], &tilesort_spu.displays[i].correct[4], &tilesort_spu.displays[i].correct[5], &tilesort_spu.displays[i].correct[6], &tilesort_spu.displays[i].correct[7], &tilesort_spu.displays[i].correct[8], &tilesort_spu.displays[i].correct_inv[0], &tilesort_spu.displays[i].correct_inv[1], &tilesort_spu.displays[i].correct_inv[2], &tilesort_spu.displays[i].correct_inv[3], &tilesort_spu.displays[i].correct_inv[4], &tilesort_spu.displays[i].correct_inv[5], &tilesort_spu.displays[i].correct_inv[6], &tilesort_spu.displays[i].correct_inv[7], &tilesort_spu.displays[i].correct_inv[8]); pnt[0] = -1; pnt[1] = -1; crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped); corners[idx] = warped[0]; corners[idx + 1] = warped[1]; idx += 2; pnt[0] = -1; pnt[1] = 1; crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped); corners[idx] = warped[0]; corners[idx + 1] = warped[1]; idx += 2; pnt[0] = 1; pnt[1] = 1; crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped); corners[idx] = warped[0]; corners[idx + 1] = warped[1]; idx += 2; pnt[0] = 1; pnt[1] = -1; crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped); corners[idx] = warped[0]; corners[idx + 1] = warped[1]; idx += 2; } crHullInteriorBox(corners, idx / 2, world_bbox); crFree(corners); /* dummy values in case i forget to override them later */ winInfo->muralWidth = tilesort_spu.displays[0].width; winInfo->muralHeight = tilesort_spu.displays[0].height; winInfo->passiveStereo = GL_FALSE; /* may be set true below */ for (i = 0; i < num_servers; i++) { char server_url[1024]; ServerWindowInfo *servWinInfo = winInfo->server + i; char **tilechain, **tilelist; int tile; double cent[2], Sx, Sy; sscanf(serverlist[i], "%s", server_url); crDebug("Server %d: %s", i + 1, server_url); thread0->netServer[i].name = crStrdup(server_url); thread0->netServer[i].buffer_size = tilesort_spu.buffer_size; /* response is just like regular GetTiles, but each tile * is preceeded by a display id */ if (!crMothershipGetDisplayTiles(conn, response, i)) { crError("No tile information for server %d! I can't continue!", i); } tilechain = crStrSplitn(response, " ", 1); servWinInfo->num_extents = crStrToInt(tilechain[0]); tilelist = crStrSplit(tilechain[1], ","); servWinInfo->eyeFlags = EYE_LEFT | EYE_RIGHT; if (crMothershipGetServerParamFromSPU( conn, i, "stereo_view", response)) { if (crStrcmp(response, "left") == 0) { servWinInfo->eyeFlags = EYE_LEFT; winInfo->passiveStereo = GL_TRUE; } else if (crStrcmp(response, "right") == 0) { servWinInfo->eyeFlags = EYE_RIGHT; winInfo->passiveStereo = GL_TRUE; } } Sx = 2.0 / (world_bbox[2] - world_bbox[0]); Sy = 2.0 / (world_bbox[3] - world_bbox[1]); cent[0] = (world_bbox[0] + world_bbox[2]) / (2.); cent[1] = (world_bbox[1] + world_bbox[3]) / (2.); for (tile = 0; tile < servWinInfo->num_extents; tile++) { int id, x, y, w, h, a; float disp_w, disp_h, warped[2], *align; sscanf(tilelist[tile], "%d %d %d %d %d", &id, &x, &y, &w, &h); /* this is the local coordinate tiling */ servWinInfo->display_ndx[tile] = -1; for (a = 0; a < num_displays; a++) { if (tilesort_spu.displays[a].id == id) servWinInfo->display_ndx[tile] = a; } if (servWinInfo->display_ndx[tile] == -1) crError("Invalid Display ID %d", id); servWinInfo->extents[tile].x1 = x; servWinInfo->extents[tile].y1 = y; servWinInfo->extents[tile].x2 = x + w; servWinInfo->extents[tile].y2 = y + h; /* warp the tile to mural space */ disp_w = (float) tilesort_spu.displays[servWinInfo->display_ndx[tile]].width; disp_h = (float) tilesort_spu.displays[servWinInfo->display_ndx[tile]].height; servWinInfo->world_extents[tile][0] = (float) x / disp_w; servWinInfo->world_extents[tile][1] = (float) y / disp_h; servWinInfo->world_extents[tile][2] = (float) x / disp_w; servWinInfo->world_extents[tile][3] = (float) (y + h) / disp_h; servWinInfo->world_extents[tile][4] = (float) (x + w) / disp_w; servWinInfo->world_extents[tile][5] = (float) (y + h) / disp_h; servWinInfo->world_extents[tile][6] = (float) (x + w) / disp_w; servWinInfo->world_extents[tile][7] = (float) y / disp_h; for (a = 0; a < 8; a++) servWinInfo->world_extents[tile][a] = (float)2.0 * servWinInfo->world_extents[tile][a] - (float)1.0; align = tilesort_spu.displays[servWinInfo->display_ndx[tile]].correct_inv; for (a = 0; a < 4; a++) { crWarpPoint(align, servWinInfo->world_extents[tile] + 2 * a, warped); warped[0] = (warped[0] - (float)cent[0]) * (float) Sx; warped[1] = (warped[1] - (float)cent[1]) * (float) Sy; crDebug("%f %f warps to %f %f", servWinInfo->world_extents[tile][2 * a], servWinInfo->world_extents[tile][2 * a + 1], warped[0], warped[1]); servWinInfo->world_extents[tile][2 * a] = warped[0]; servWinInfo->world_extents[tile][2 * a + 1] = warped[1]; } /** XXX: \todo check that the tile fits w/i the display it is on */ } crFreeStrings(tilechain); crFreeStrings(tilelist); } crFreeStrings(displaychain); crFreeStrings(displaylist); /* can't do any fancy bucketing with this */ tilesort_spu.defaultBucketMode = WARPED_GRID; } else { /* * Get the list of tiles from all servers. * And compute mural size. */ winInfo->muralWidth = 0; winInfo->muralHeight = 0; for (i = 0; i < num_servers; i++) { char server_url[1024]; ServerWindowInfo *servWinInfo = winInfo->server + i; char **tilechain, **tilelist; int tile; sscanf(serverlist[i], "%s", server_url); crDebug("Server %d: %s", i + 1, server_url); thread0->netServer[i].name = crStrdup(server_url); thread0->netServer[i].buffer_size = tilesort_spu.buffer_size; if (!crMothershipGetTiles(conn, response, i)) { crError("No tile information for server %d! I can't continue!", i); } tilechain = crStrSplitn(response, " ", 1); servWinInfo->num_extents = crStrToInt(tilechain[0]); tilelist = crStrSplit(tilechain[1], ","); for (tile = 0; tile < servWinInfo->num_extents; tile++) { int x, y, w, h; sscanf(tilelist[tile], "%d %d %d %d", &x, &y, &w, &h); servWinInfo->extents[tile].x1 = x; servWinInfo->extents[tile].y1 = y; servWinInfo->extents[tile].x2 = x + w; servWinInfo->extents[tile].y2 = y + h; /* update mural size */ if (servWinInfo->extents[tile].x2 > (int) winInfo->muralWidth) { winInfo->muralWidth = servWinInfo->extents[tile].x2; } if (servWinInfo->extents[tile].y2 > (int) winInfo->muralHeight) { winInfo->muralHeight = servWinInfo->extents[tile].y2; } } crFreeStrings(tilechain); crFreeStrings(tilelist); /* Determine if the server should receieve left, right or both eye * views when running in passive stereo mode. */ servWinInfo->eyeFlags = EYE_LEFT | EYE_RIGHT; if (crMothershipGetServerParamFromSPU( conn, i, "stereo_view", response)) { if (crStrcmp(response, "left") == 0) { servWinInfo->eyeFlags = EYE_LEFT; winInfo->passiveStereo = GL_TRUE; } else if (crStrcmp(response, "right") == 0) { servWinInfo->eyeFlags = EYE_RIGHT; winInfo->passiveStereo = GL_TRUE; } } /* get view matrices from the server */ if (crMothershipGetServerParamFromSPU( conn, i, "view_matrix", response)) { crMatrixInitFromString(&servWinInfo->viewMatrix[0], response); if (!crMatrixIsIdentity(&servWinInfo->viewMatrix[0])) winInfo->matrixSource = MATRIX_SOURCE_SERVERS; } if (crMothershipGetServerParamFromSPU( conn, i, "right_view_matrix", response)) { crMatrixInitFromString(&servWinInfo->viewMatrix[1], response); if (!crMatrixIsIdentity(&servWinInfo->viewMatrix[1])) winInfo->matrixSource = MATRIX_SOURCE_SERVERS; } /* crMatrixPrint("Left view", &servWinInfo->viewMatrix[0]); crMatrixPrint("Right view", &servWinInfo->viewMatrix[1]); */ /* Also get overriding projection matrix. * Note that this matrix is only relevant to FRUSTUM bucketing. */ if (crMothershipGetServerParamFromSPU( conn, i, "projection_matrix", response)) { /** XXX \todo projection_matrix is obsolete, keep for a while though */ crMatrixInitFromString(&servWinInfo->projectionMatrix[0], response); if (!crMatrixIsIdentity(&servWinInfo->projectionMatrix[0])) winInfo->matrixSource = MATRIX_SOURCE_SERVERS; } if (crMothershipGetServerParamFromSPU( conn, i, "right_projection_matrix", response)) { crMatrixInitFromString(&servWinInfo->projectionMatrix[1], response); if (!crMatrixIsIdentity(&servWinInfo->projectionMatrix[1])) winInfo->matrixSource = MATRIX_SOURCE_SERVERS; } /* crMatrixPrint("Left proj", &servWinInfo->projectionMatrix[0]); crMatrixPrint("Right proj", &servWinInfo->projectionMatrix[1]); */ } } crFreeStrings(serverchain); crFreeStrings(serverlist); tilesortspuBucketingInit( winInfo ); }
/** * Establish a connection with a server. * \param server the server to connect to, in the form * "protocol://servername:port" where the port specifier * is optional and if the protocol is missing it is assumed * to be "tcpip". * \param default_port the port to connect to, if port not specified in the * server URL string. * \param mtu desired maximum transmission unit size (in bytes) * \param broker either 1 or 0 to indicate if connection is brokered through * the mothership */ CRConnection * crNetConnectToServer( const char *server, unsigned short default_port, int mtu, int broker #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , struct VBOXUHGSMI *pHgsmi #endif ) { char hostname[4096], protocol[4096]; unsigned short port; CRConnection *conn; crDebug( "In crNetConnectToServer( \"%s\", port=%d, mtu=%d, broker=%d )", server, default_port, mtu, broker ); CRASSERT( cr_net.initialized ); if (mtu < CR_MINIMUM_MTU) { crError( "You tried to connect to server \"%s\" with an mtu of %d, " "but the minimum MTU is %d", server, mtu, CR_MINIMUM_MTU ); } /* Tear the URL apart into relevant portions. */ if ( !crParseURL( server, protocol, hostname, &port, default_port ) ) { crError( "Malformed URL: \"%s\"", server ); } /* If the host name is "localhost" replace it with the _real_ name * of the localhost. If we don't do this, there seems to be * confusion in the mothership as to whether or not "localhost" and * "foo.bar.com" are the same machine. */ if (crStrcmp(hostname, "localhost") == 0) { int rv = crGetHostname(hostname, 4096); CRASSERT(rv == 0); (void) rv; } /* XXX why is this here??? I think it could be moved into the * crTeacConnection() function with no problem. I.e. change the * connection's port, teac_rank and tcscomm_rank there. (BrianP) */ if ( !crStrcmp( protocol, "quadrics" ) || !crStrcmp( protocol, "quadrics-tcscomm" ) ) { /* For Quadrics protocols, treat "port" as "rank" */ if ( port > CR_QUADRICS_HIGHEST_RANK ) { crWarning( "Invalid crserver rank, %d, defaulting to %d\n", port, CR_QUADRICS_LOWEST_RANK ); port = CR_QUADRICS_LOWEST_RANK; } } crDebug( "Connecting to %s on port %d, with protocol %s", hostname, port, protocol ); #ifdef SDP_SUPPORT /* This makes me ill, but we need to "fix" the hostname for sdp. MCH */ if (!crStrcmp(protocol, "sdp")) { char* temp; temp = strtok(hostname, "."); crStrcat(temp, crGetSDPHostnameSuffix()); crStrcpy(hostname, temp); crDebug("SDP rename hostname: %s", hostname); } #endif conn = (CRConnection *) crCalloc( sizeof(*conn) ); if (!conn) return NULL; /* init the non-zero fields */ conn->type = CR_NO_CONNECTION; /* we don't know yet */ conn->recv_credits = CR_INITIAL_RECV_CREDITS; conn->hostname = crStrdup( hostname ); conn->port = port; conn->mtu = mtu; conn->buffer_size = mtu; conn->broker = broker; conn->endianness = crDetermineEndianness(); /* XXX why are these here??? Move them into the crTeacConnection() * and crTcscommConnection() functions. */ conn->teac_id = -1; conn->teac_rank = port; conn->tcscomm_id = -1; conn->tcscomm_rank = port; crInitMessageList(&conn->messageList); /* now, just dispatch to the appropriate protocol's initialization functions. */ InitConnection(conn, protocol, mtu #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , pHgsmi #endif ); if (!crNetConnect( conn )) { crDebug("crNetConnectToServer() failed, freeing the connection"); #ifdef CHROMIUM_THREADSAFE crFreeMutex( &conn->messageList.lock ); #endif conn->Disconnect(conn); crFree( conn ); return NULL; } crDebug( "Done connecting to %s (swapping=%d)", server, conn->swap ); return conn; }
GLint REPLICATESPU_APIENTRY replicatespu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx ) { static GLint freeCtxID = MAGIC_OFFSET; char headspuname[10]; ContextInfo *context, *sharedContext = NULL; unsigned int i; if (shareCtx > 0) { sharedContext = (ContextInfo *) crHashtableSearch(replicate_spu.contextTable, shareCtx); } replicatespuFlushAll( &(replicate_spu.thread[0]) ); #ifdef CHROMIUM_THREADSAFE_notyet crLockMutex(&_ReplicateMutex); #endif replicatespuStartVnc(dpyName); /* * Alloc new ContextInfo object */ context = (ContextInfo *) crCalloc(sizeof(ContextInfo)); if (!context) { crWarning("Replicate SPU: Out of memory in CreateContext"); return -1; } /* Contexts that don't share display lists get their own * display list managers. Contexts that do, share the * display list managers of the contexts they're sharing * with (man, some grammarian has to go over that and make * it actually sound like English). */ if (sharedContext) { context->displayListManager = sharedContext->displayListManager; /* Let the DLM know that a second context is using the * same display list manager, so it can manage when its * resources are released. */ crDLMUseDLM(context->displayListManager); } else { context->displayListManager = crDLMNewDLM(0, NULL); if (!context->displayListManager) { crWarning("Replicate SPU: could not initialize display list manager."); } } /* Fill in the new context info */ if (sharedContext) context->State = crStateCreateContext(NULL, visual, sharedContext->State); else context->State = crStateCreateContext(NULL, visual, NULL); context->rserverCtx[0] = 1; /* not really used */ context->visBits = visual; context->currentWindow = 0; /* not bound */ context->dlmState = crDLMNewContext(context->displayListManager); context->displayListMode = GL_FALSE; /* not compiling */ context->displayListIdentifier = 0; context->shareCtx = shareCtx; #if 0 /* Set the Current pointers now.... */ crStateSetCurrentPointers( context->State, &(replicate_spu.thread[0].packer->current) ); #endif for (i = 1; i < CR_MAX_REPLICANTS; i++) { int r_writeback = 1, rserverCtx = -1; int sharedServerCtx; sharedServerCtx = sharedContext ? sharedContext->rserverCtx[i] : 0; if (!IS_CONNECTED(replicate_spu.rserver[i].conn)) continue; if (replicate_spu.swap) crPackCreateContextSWAP( dpyName, visual, sharedServerCtx, &rserverCtx, &r_writeback ); else crPackCreateContext( dpyName, visual, sharedServerCtx, &rserverCtx, &r_writeback ); /* Flush buffer and get return value */ replicatespuFlushOne( &(replicate_spu.thread[0]), i ); while (r_writeback) crNetRecv(); if (replicate_spu.swap) rserverCtx = (GLint) SWAP32(rserverCtx); if (rserverCtx < 0) { #ifdef CHROMIUM_THREADSAFE_notyet crUnlockMutex(&_ReplicateMutex); #endif crWarning("Replicate SPU: CreateContext failed."); return -1; /* failed */ } context->rserverCtx[i] = rserverCtx; } if (!crStrcmp( headspuname, "nop" )) replicate_spu.NOP = 0; else replicate_spu.NOP = 1; #ifdef CHROMIUM_THREADSAFE_notyet crUnlockMutex(&_ReplicateMutex); #endif crListPushBack(replicate_spu.contextList, (void *)freeCtxID); crHashtableAdd(replicate_spu.contextTable, freeCtxID, context); return freeCtxID++; }
int main(int argc, char *argv[]) { int menu1, menu2, menu3; if (argc < 5) { crError( "Usage: %s -rank <ID NUMBER> -size <SIZE> [-swap]", argv[0] ); } for (i = 1 ; i < argc ; i++) { if (!crStrcmp( argv[i], "-rank" )) { if (i == argc - 1) { crError( "-rank requires an argument" ); } rank = crStrToInt( argv[i+1] ); i++; } else if (!crStrcmp( argv[i], "-size" )) { if (i == argc - 1) { crError( "-size requires an argument" ); } size = crStrToInt( argv[i+1] ); i++; } else if (!crStrcmp( argv[i], "-swap" )) { swapFlag = 1; } else if (!crStrcmp( argv[i], "-clear" )) { clearFlag = 1; } } if (rank == -1) { crError( "Rank not specified" ); } if (size == -1) { crError( "Size not specified" ); } if (rank >= size || rank < 0) { crError( "Bogus rank: %d (size = %d)", rank, size ); } crDebug("initializing"); ctx = crutCreateContext(visual); window = crutCreateWindow(visual); crutDisplayFunc(DisplayRings); crutMouseFunc(mouse); crutKeyboardFunc(keyboard); crutMotionFunc(motion); menu1 = crutCreateMenu(changeRank); crutAddMenuEntry("Rank++", 1); crutAddMenuEntry("Rank--", 2); menu2 = crutCreateMenu(changeSize); crutAddMenuEntry("Size++", 1); crutAddMenuEntry("Size--", 2); menu3 = crutCreateMenu(changeSides); crutAddMenuEntry("Sides++", 1); crutAddMenuEntry("Sides--", 2); crutCreateMenu(menu_func); crutAddSubMenu("Change Rank", menu1); crutAddSubMenu("Change Size", menu2); crutAddSubMenu("Change Vertices", menu3); crutAttachMenu(CRUT_RIGHT_BUTTON); /* crutPassiveMotionFunc(passive_motion); */ crutInitClient(); #define LOAD( x ) x##_ptr = (x##Proc) crGetProcAddress( #x ) LOAD( crCreateContext ); LOAD( crMakeCurrent ); LOAD( crSwapBuffers ); LOAD( glChromiumParametervCR ); LOAD( glBarrierCreateCR ); LOAD( glBarrierExecCR ); crMakeCurrent_ptr(window, ctx); /* It's OK for everyone to create this, as long as all the "size"s match */ glBarrierCreateCR_ptr( MASTER_BARRIER, size ); theta = (float)(360.0 / (float) size); glEnable( GL_DEPTH_TEST ); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_AMBIENT, gray); glLightfv(GL_LIGHT0, GL_DIFFUSE, gray); glLightfv(GL_LIGHT0, GL_SPECULAR, white); glLightfv(GL_LIGHT0, GL_POSITION, pos); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10.0); glEnable(GL_NORMALIZE); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glFrustum( -1.0, 1.0, -1.0, 1.0, 7.0, 13.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0, 0.0, -10.0 ); glClearColor(0.0, 0.0, 0.0, 1.0); crutMainLoop(); /* ARGH -- need to trick out the compiler this sucks. */ if (argv[0] == NULL) { return 0; } return 0; }
/** * Helper routine used by both crNetConnectToServer() and crNetAcceptClient(). * Call the protocol-specific Init() and Connection() functions. * */ static void InitConnection(CRConnection *conn, const char *protocol, unsigned int mtu #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , struct VBOXUHGSMI *pHgsmi #endif ) { if (!crStrcmp(protocol, "devnull")) { crDevnullInit(cr_net.recv_list, cr_net.close_list, mtu); crDevnullConnection(conn); } else if (!crStrcmp(protocol, "file")) { cr_net.use_file++; crFileInit(cr_net.recv_list, cr_net.close_list, mtu); crFileConnection(conn); } else if (!crStrcmp(protocol, "swapfile")) { /* file with byte-swapping */ cr_net.use_file++; crFileInit(cr_net.recv_list, cr_net.close_list, mtu); crFileConnection(conn); conn->swap = 1; } else if (!crStrcmp(protocol, "tcpip")) { cr_net.use_tcpip++; crTCPIPInit(cr_net.recv_list, cr_net.close_list, mtu); crTCPIPConnection(conn); } else if (!crStrcmp(protocol, "udptcpip")) { cr_net.use_udp++; crUDPTCPIPInit(cr_net.recv_list, cr_net.close_list, mtu); crUDPTCPIPConnection(conn); } #ifdef VBOX_WITH_HGCM else if (!crStrcmp(protocol, "vboxhgcm")) { cr_net.use_hgcm++; crVBoxHGCMInit(cr_net.recv_list, cr_net.close_list, mtu); crVBoxHGCMConnection(conn #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , pHgsmi #endif ); } #endif #ifdef GM_SUPPORT else if (!crStrcmp(protocol, "gm")) { cr_net.use_gm++; crGmInit(cr_net.recv_list, cr_net.close_list, mtu); crGmConnection(conn); } #endif #ifdef TEAC_SUPPORT else if (!crStrcmp(protocol, "quadrics")) { cr_net.use_teac++; crTeacInit(cr_net.recv_list, cr_net.close_list, mtu); crTeacConnection(conn); } #endif #ifdef TCSCOMM_SUPPORT else if (!crStrcmp(protocol, "quadrics-tcscomm")) { cr_net.use_tcscomm++; crTcscommInit(cr_net.recv_list, cr_net.close_list, mtu); crTcscommConnection(conn); } #endif #ifdef SDP_SUPPORT else if (!crStrcmp(protocol, "sdp")) { cr_net.use_sdp++; crSDPInit(cr_net.recv_list, cr_net.close_list, mtu); crSDPConnection(conn); } #endif #ifdef IB_SUPPORT else if (!crStrcmp(protocol, "ib")) { cr_net.use_ib++; crDebug("Calling crIBInit()"); crIBInit(cr_net.recv_list, cr_net.close_list, mtu); crIBConnection(conn); crDebug("Done Calling crIBInit()"); } #endif #ifdef HP_MULTICAST_SUPPORT else if (!crStrcmp(protocol, "hpmc")) { cr_net.use_hpmc++; crHPMCInit(cr_net.recv_list, cr_net.close_list, mtu); crHPMCConnection(conn); } #endif else { crError("Unknown protocol: \"%s\"", protocol); } }
void crServerGatherConfiguration(char *mothership) { CRMuralInfo *defaultMural; CRConnection *conn; char response[8096]; char **spuchain; int num_spus; int *spu_ids; char **spu_names; char *spu_dir = NULL; int i; /* Quadrics defaults */ int my_rank = 0; int low_context = CR_QUADRICS_DEFAULT_LOW_CONTEXT; int high_context = CR_QUADRICS_DEFAULT_HIGH_CONTEXT; char *low_node = "none"; char *high_node = "none"; unsigned char key[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; char hostname[1024]; char **clientchain, **clientlist; defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0); CRASSERT(defaultMural); setDefaults(); if (mothership) { crSetenv("CRMOTHERSHIP", mothership); } conn = crMothershipConnect(); if (!conn) { crError("Couldn't connect to the mothership, I have no idea what to do!"); } /* * Get my hostname */ if (crGetHostname(hostname, sizeof(hostname))) { crError("CRServer: Couldn't get my own hostname?"); } /* Identify ourselves to the mothership */ if (cr_server.vncMode) { /* we're running inside a vnc viewer */ if (!crMothershipSendString( conn, response, "vncserver %s", hostname )) crError( "Bad Mothership response: %s", response ); } else { crMothershipIdentifyServer(conn, response); } crDebug("CRServer: my SPU chain: %s", response); /* response will describe the SPU chain. * Example "2 5 wet 6 render" */ spuchain = crStrSplit(response, " "); num_spus = crStrToInt(spuchain[0]); spu_ids = (int *) crAlloc(num_spus * sizeof(*spu_ids)); spu_names = (char **) crAlloc((num_spus + 1) * sizeof(*spu_names)); for (i = 0; i < num_spus; i++) { spu_ids[i] = crStrToInt(spuchain[2 * i + 1]); spu_names[i] = crStrdup(spuchain[2 * i + 2]); crDebug("SPU %d/%d: (%d) \"%s\"", i + 1, num_spus, spu_ids[i], spu_names[i]); } spu_names[i] = NULL; /* * Gather configuration options. * NOTE: when you add new options, be sure to update the * mothership/tools/crtypes.py file's NetworkNode class's notion of * config options. * XXX Use the SPU option parser code here someday. */ if (crMothershipGetServerParam( conn, response, "spu_dir" ) && crStrlen(response) > 0) { spu_dir = crStrdup(response); } /* Quadrics networking stuff */ if (crMothershipGetRank(conn, response)) { my_rank = crStrToInt(response); } crNetSetRank(my_rank); if (crMothershipGetParam(conn, "low_context", response)) { low_context = crStrToInt(response); } if (crMothershipGetParam(conn, "high_context", response)) { high_context = crStrToInt(response); } crNetSetContextRange(low_context, high_context); if (crMothershipGetParam(conn, "low_node", response)) { low_node = crStrdup(response); } if (crMothershipGetParam(conn, "high_node", response)) { high_node = crStrdup(response); } crNetSetNodeRange(low_node, high_node); if (low_node) crFree(low_node); if (high_node) crFree(high_node); if (crMothershipGetParam(conn, "comm_key", response)) { unsigned int a; char **words, *found; /* remove the silly []'s */ while ((found = crStrchr(response, '[')) != NULL) *found = ' '; while ((found = crStrchr(response, ']')) != NULL) *found = ' '; words = crStrSplit(response, ","); a = 0; while (words[a] != NULL && a < sizeof(key)) { key[a]= crStrToInt(words[a]); a++; } crFreeStrings(words); } crNetSetKey(key,sizeof(key)); if (crMothershipGetServerParam(conn, response, "port")) { cr_server.tcpip_port = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "optimize_bucket")) { cr_server.optimizeBucket = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "local_tile_spec")) { cr_server.localTileSpec = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "lightning2")) { cr_server.useL2 = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "ignore_papi")) { cr_server.ignore_papi = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "overlap_blending")) { if (!crStrcmp(response, "blend")) cr_server.overlapBlending = 1; else if (!crStrcmp(response, "knockout")) cr_server.overlapBlending = 2; } if (crMothershipGetServerParam(conn, response, "overlap_levels")) { int a; char **levels, *found; /* remove the []'s */ while ((found = crStrchr(response, '['))) *found = ' '; while ((found = crStrchr(response, ']'))) *found = ' '; levels = crStrSplit(response, ","); a = 0; while (levels[a] != NULL) { crDebug("%d: %s", a, levels[a]); cr_server.num_overlap_intens++; a++; } cr_server.overlap_intens = (float *)crAlloc(cr_server.num_overlap_intens*sizeof(float)); for (a=0; a<cr_server.num_overlap_intens; a++) cr_server.overlap_intens[a] = crStrToFloat(levels[a]); crFreeStrings(levels); } if (crMothershipGetServerParam(conn, response, "only_swap_once")) { cr_server.only_swap_once = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "debug_barriers")) { cr_server.debug_barriers = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "shared_display_lists")) { cr_server.sharedDisplayLists = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "shared_texture_objects")) { cr_server.sharedTextureObjects = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "shared_programs")) { cr_server.sharedPrograms = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "shared_windows")) { cr_server.sharedWindows = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "unique_window_ids")) { cr_server.uniqueWindows = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "use_dmx")) { cr_server.useDMX = crStrToInt(response); } if (crMothershipGetServerParam(conn, response, "vertprog_projection_param")) { if (crIsDigit(response[0])) { cr_server.vpProjectionMatrixParameter = crStrToInt(response); } else { cr_server.vpProjectionMatrixVariable = crStrdup(response); } } if (crMothershipGetServerParam(conn, response, "stereo_view")) { if (crStrcmp(response, "left") == 0) cr_server.stereoView = 0x1; else if (crStrcmp(response, "right") == 0) cr_server.stereoView = 0x2; else if (crStrcmp(response, "both") == 0) cr_server.stereoView = 0x3; else cr_server.stereoView = 0x3; } if (crMothershipGetServerParam(conn, response, "view_matrix")) { crMatrixInitFromString(&cr_server.viewMatrix[0], response); cr_server.viewOverride = GL_TRUE; } if (crMothershipGetServerParam(conn, response, "right_view_matrix")) { crMatrixInitFromString(&cr_server.viewMatrix[1], response); cr_server.viewOverride = GL_TRUE; } if (crMothershipGetServerParam(conn, response, "projection_matrix")) { crMatrixInitFromString(&cr_server.projectionMatrix[0], response); cr_server.projectionOverride = GL_TRUE; } if (crMothershipGetServerParam(conn, response, "right_projection_matrix")) { crMatrixInitFromString(&cr_server.projectionMatrix[1], response); cr_server.projectionOverride = GL_TRUE; } if (crMothershipGetServerParam(conn, response, "exit_if_no_clients")) { cr_server.exitIfNoClients = crStrToInt(response); } crDebug("CRServer: my port number is %d", cr_server.tcpip_port); /* * Load the SPUs */ cr_server.head_spu = crSPULoadChain(num_spus, spu_ids, spu_names, spu_dir, &cr_server); /* Need to do this as early as possible */ /* XXX DMX get window size instead? */ cr_server.head_spu->dispatch_table.GetIntegerv(GL_VIEWPORT, (GLint *) defaultMural->underlyingDisplay); crFree(spu_ids); crFreeStrings(spu_names); crFreeStrings(spuchain); if (spu_dir) crFree(spu_dir); cr_server.mtu = crMothershipGetMTU( conn ); /* * Get a list of all the clients talking to me. */ if (cr_server.vncMode) { /* we're inside a vnc viewer */ if (!crMothershipSendString( conn, response, "getvncclient %s", hostname )) crError( "Bad Mothership response: %s", response ); } else { crMothershipGetClients(conn, response); } crDebug("CRServer: my clients: %s", response); /* * 'response' will now contain a number indicating the number of clients * of this server, followed by a comma-separated list of protocol/SPU ID * pairs. * Example: "3 tcpip 1,gm 2,via 10" */ clientchain = crStrSplitn(response, " ", 1); cr_server.numClients = crStrToInt(clientchain[0]); if (cr_server.numClients == 0) { crError("I have no clients! What's a poor server to do?"); } clientlist = crStrSplit(clientchain[1], ","); /* * Connect to initial set of clients. * Call crNetAcceptClient() for each client. * Also, look for a client that's _not_ using the file: protocol. */ for (i = 0; i < cr_server.numClients; i++) { CRClient *newClient = (CRClient *) crCalloc(sizeof(CRClient)); sscanf(clientlist[i], "%s %d", cr_server.protocol, &(newClient->spu_id)); newClient->conn = crNetAcceptClient(cr_server.protocol, NULL, cr_server.tcpip_port, cr_server.mtu, 1); newClient->currentCtx = cr_server.DummyContext; crServerAddToRunQueue(newClient); cr_server.clients[i] = newClient; } /* set default client and mural */ if (cr_server.numClients > 0) { cr_server.curClient = cr_server.clients[0]; cr_server.curClient->currentMural = defaultMural; cr_server.client_spu_id =cr_server.clients[0]->spu_id; } crFreeStrings(clientchain); crFreeStrings(clientlist); /* Ask the mothership for the tile info */ crServerGetTileInfoFromMothership(conn, defaultMural); if (cr_server.vncMode) { /* In vnc mode, we reset the mothership configuration so that it can be * used by subsequent OpenGL apps without having to spawn a new mothership * on a new port. */ crDebug("CRServer: Resetting mothership to initial state"); crMothershipReset(conn); } crMothershipDisconnect(conn); }
int main(int argc, char *argv[]) { const int port = 10000; CRConnection *conn[MAX_SERVERS]; const char *servers[MAX_SERVERS]; int numServers = 0; int bufferSize = 10000; int numBuffers = 10; int autoMode = 0; int size; int i, j; if (argc < 2) { PrintHelp(); return 0; } for (i = 1; i < argc; i++) { if (!crStrcmp(argv[i], "-a")) { autoMode = 1; } else if (!crStrcmp(argv[i], "-b") && (i + 1 < argc)) { bufferSize = crStrToInt(argv[i + 1]); i++; } else if (!crStrcmp(argv[i], "-h")) { PrintHelp(); return 0; } else if (!crStrcmp(argv[i], "-m") && (i + 1 < argc)) { MTU = crStrToInt(argv[i + 1]); i++; } else if (!crStrcmp(argv[i], "-n") && (i + 1 < argc)) { numBuffers = crStrToInt(argv[i + 1]); i++; } else if ((argv[i][0] != '-') && (numServers < MAX_SERVERS)) { servers[numServers] = argv[i]; numServers++; } } if (numServers == 0) { printf("npclient error: need to specify at least one server\n"); return 1; } if (autoMode) printf("npclient: MTU=%d (automatic buffer sizing)\n", MTU); else printf("npclient: MTU=%d bufferSize=%d numBuffers=%d\n", MTU, bufferSize, numBuffers); MyTimer = crTimerNewTimer(); crNetInit( ReceiveFunc, CloseFunc ); printf("npclient: Connecting to servers\n"); for (i = 0; i < numServers; i++) { conn[i] = crNetConnectToServer(servers[i], (unsigned short) port, MTU, 0); if (conn[i]) { printf("npclient: Connection to %s OK.\n", servers[i]); } else { printf("npclient: Connection to %s failed!\n", servers[i]); exit(1); } } printf("npclient: Testing...\n"); if (autoMode) { bufferSize = 10000; for (size = 0; size < 5; size++) { double t0, t1, dt, rate; double bytes; int buffers; bytes = 0.0; buffers = 0; crStartTimer(MyTimer); t0 = crTimerTime(MyTimer); do { for (j = 0; j < numServers; j++) { SendOpcodes(conn[j], bufferSize, 0); } bytes += (double) bufferSize; buffers++; t1 = crTimerTime(MyTimer); } while (t1 - t0 < 5.0); crStopTimer(MyTimer); dt = t1 - t0; rate = (double) bytes / dt / 1000000.0; printf("npclient: %8.3f MB/s (%d bytes / buffer, %d buffers, %d servers)\n", rate, bufferSize, buffers, numServers); if (rate < 0.0) { char *t = 0; *t = 0; CRASSERT(rate >= 0.0); } bufferSize *= 10; } } else { double t0, t1, dt, rate; double bytes; crStartTimer(MyTimer); t0 = crTimerTime(MyTimer); bytes = 0.0; for (i = 0; i < numBuffers; i++) { for (j = 0; j < numServers; j++) { SendOpcodes(conn[j], bufferSize, 0); } bytes += (double) bufferSize; } t1 = crTimerTime(MyTimer); dt = t1 - t0; rate = (double) bytes / dt / 1000000.0; printf("npclient: %8.3f MB/s (%d bytes / buffer, %d buffers, %d servers)\n", rate, bufferSize, numBuffers, numServers); } /* Send exit message to servers */ for (j = 0; j < numServers; j++) { SendOpcodes(conn[j], 100, 1); } for (j = 0; j < numServers; j++) { crNetDisconnect(conn[j]); } printf("npclient: done!\n"); return 0; }