static bool crDLMLoadListInstance(PSSMHANDLE pSSM, DLMListInfo *pListInfo, SPUDispatchTable *dispatchTable) { uint32_t cbInstance = 0; DLMInstanceList *pInstance; int32_t rc; /* Get Display List item size. */ rc = SSMR3GetU32(pSSM, &cbInstance); if (RT_SUCCESS(rc)) { /* Allocate memory for the item, initialize it and put into the list. */ pInstance = crCalloc(cbInstance); if (pInstance) { crMemset(pInstance, 0, cbInstance); rc = SSMR3GetMem(pSSM, pInstance, cbInstance); AssertRCReturn(rc, rc); if (RT_SUCCESS(rc)) { pInstance->execute = crDLMGetExecuteRoutine(pInstance->iVBoxOpCode); if (pInstance->execute) { pInstance->execute(pInstance, dispatchTable); pInstance->next = NULL; pInstance->stateNext = NULL; pInstance->cbInstance = cbInstance; pListInfo->numInstances++; if (!pListInfo->first) pListInfo->first = pInstance; if (pListInfo->last) pListInfo->last->next = pInstance; pListInfo->last = pInstance; return true; } else crError("Restoring Display Lists: unknown list item (opcode=%u).", pInstance->iVBoxOpCode); } else crError("Restoring Display Lists: can't read list element size."); } else crError("Restoring Display Lists: not enough memory, aborting."); } else crError("Restoring Display Lists: saved state file might be corrupted."); return false; }
void vboxCrFpsInit(PVBOXCRFPS pFps, uint32_t cPeriods) { crMemset(pFps, 0, sizeof (*pFps)); pFps->mcPeriods = cPeriods; pFps->mpaPeriods = crCalloc(sizeof (pFps->mpaPeriods[0]) * cPeriods); pFps->mpaBytes = crCalloc(sizeof (pFps->mpaBytes[0]) * cPeriods); pFps->mpaBytesSent = crCalloc(sizeof (pFps->mpaBytesSent[0]) * cPeriods); pFps->mpaCalls = crCalloc(sizeof (pFps->mpaCalls[0]) * cPeriods); pFps->mpaOps = crCalloc(sizeof (pFps->mpaOps[0]) * cPeriods); pFps->mpaTimes = crCalloc(sizeof (pFps->mpaTimes[0]) * cPeriods); }
/** * Return a free port number for the mothership to use, or -1 if we * can't find one. */ static int GenerateMothershipPort(void) { const int MAX_PORT = 10100; unsigned short port; /* generate initial port number randomly */ crRandAutoSeed(); port = (unsigned short) crRandInt(10001, MAX_PORT); #ifdef WINDOWS /* XXX should implement a free port check here */ return port; #else /* * See if this port number really is free, try another if needed. */ { struct sockaddr_in servaddr; int so_reuseaddr = 1; int sock, k; /* create socket */ sock = socket(AF_INET, SOCK_STREAM, 0); CRASSERT(sock > 2); /* deallocate socket/port when we exit */ k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &so_reuseaddr, sizeof(so_reuseaddr)); CRASSERT(k == 0); /* initialize the servaddr struct */ crMemset(&servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); while (port < MAX_PORT) { /* Bind to the given port number, return -1 if we fail */ servaddr.sin_port = htons((unsigned short) port); k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)); if (k) { /* failed to create port. try next one. */ port++; } else { /* free the socket/port now so mothership can make it */ close(sock); return port; } } } #endif /* WINDOWS */ return -1; }
GLboolean renderspuWindowInit( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id ) { crMemset(window, 0, sizeof (*window)); RTCritSectInit(&window->CompositorLock); window->fCompositorPresentEmpty = GL_FALSE; window->pCompositor = NULL; window->BltInfo.Base.id = id; window->x = render_spu.defaultX; window->y = render_spu.defaultY; window->BltInfo.width = render_spu.defaultWidth; window->BltInfo.height = render_spu.defaultHeight; /* Set window->title, replacing %i with the window ID number */ { const char *s = crStrstr(render_spu.window_title, "%i"); if (s) { int i, j, k; window->title = crAlloc(crStrlen(render_spu.window_title) + 10); for (i = 0; render_spu.window_title[i] != '%'; i++) window->title[i] = render_spu.window_title[i]; k = sprintf(window->title + i, "%d", window->BltInfo.Base.id); CRASSERT(k < 10); i++; /* skip the 'i' after the '%' */ j = i + k; for (; (window->title[j] = s[i]) != 0; i++, j++) ; } else { window->title = crStrdup(render_spu.window_title); } } window->BltInfo.Base.visualBits = visual->visAttribs; /* crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id); */ /* Have GLX/WGL/AGL create the window */ if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window )) { crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" ); return GL_FALSE; } window->visible = !!showIt; CRASSERT(window->visual == visual); return GL_TRUE; }
/** * This is called when we exit. * We call all the SPU's cleanup functions. */ static void stubSPUTearDownLocked(void) { crDebug("stubSPUTearDownLocked"); #ifdef WINDOWS # ifndef CR_NEWWINTRACK stubUninstallWindowMessageHook(); # endif #endif #ifdef CR_NEWWINTRACK ASMAtomicWriteBool(&stub.bShutdownSyncThread, true); #endif //delete all created contexts stubMakeCurrent( NULL, NULL); /* the lock order is windowTable->contextTable (see wglMakeCurrent_prox, glXMakeCurrent) * this is why we need to take a windowTable lock since we will later do stub.windowTable access & locking */ crHashtableLock(stub.windowTable); crHashtableWalk(stub.contextTable, hsWalkStubDestroyContexts, NULL); crHashtableUnlock(stub.windowTable); /* shutdown, now trap any calls to a NULL dispatcher */ crSPUCopyDispatchTable(&glim, &stubNULLDispatch); crSPUUnloadChain(stub.spu); stub.spu = NULL; #ifndef Linux crUnloadOpenGL(); #endif #ifndef WINDOWS crNetTearDown(); #endif #ifdef GLX if (stub.xshmSI.shmid>=0) { shmctl(stub.xshmSI.shmid, IPC_RMID, 0); shmdt(stub.xshmSI.shmaddr); } crFreeHashtable(stub.pGLXPixmapsHash, crFree); #endif crFreeHashtable(stub.windowTable, crFree); crFreeHashtable(stub.contextTable, NULL); crMemset(&stub, 0, sizeof(stub)); }
static void setDefaults(void) { if (!cr_server.tcpip_port) cr_server.tcpip_port = DEFAULT_SERVER_PORT; cr_server.run_queue = NULL; cr_server.optimizeBucket = 1; cr_server.useL2 = 0; cr_server.maxBarrierCount = 0; cr_server.ignore_papi = 0; cr_server.only_swap_once = 0; cr_server.overlapBlending = 0; cr_server.debug_barriers = 0; cr_server.sharedDisplayLists = 0; cr_server.sharedTextureObjects = 0; cr_server.sharedPrograms = 0; cr_server.sharedWindows = 0; cr_server.useDMX = 0; cr_server.vpProjectionMatrixParameter = -1; cr_server.vpProjectionMatrixVariable = NULL; cr_server.currentProgram = 0; cr_server.num_overlap_intens = 0; cr_server.overlap_intens = 0; crMemset(&cr_server.MainContextInfo, 0, sizeof (cr_server.MainContextInfo)); crMatrixInit(&cr_server.viewMatrix[0]); crMatrixInit(&cr_server.viewMatrix[1]); crMatrixInit(&cr_server.projectionMatrix[0]); crMatrixInit(&cr_server.projectionMatrix[1]); cr_server.currentEye = -1; cr_server.uniqueWindows = 0; cr_server.screenCount = 0; cr_server.fPresentMode = CR_SERVER_REDIR_F_NONE; cr_server.fPresentModeDefault = cr_server.fPresentMode; cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM; cr_server.bUsePBOForReadback = GL_FALSE; cr_server.bUseOutputRedirect = GL_FALSE; cr_server.bWindowsInitiallyHidden = GL_FALSE; memset(cr_server.NotifyEventMap, 0, sizeof (cr_server.NotifyEventMap)); cr_server.cDisableEvent = 0; cr_server.pfnNotifyEventCB = NULL; }
static void setDefaults(void) { if (!cr_server.tcpip_port) cr_server.tcpip_port = DEFAULT_SERVER_PORT; cr_server.run_queue = NULL; cr_server.optimizeBucket = 1; cr_server.useL2 = 0; cr_server.maxBarrierCount = 0; cr_server.ignore_papi = 0; cr_server.only_swap_once = 0; cr_server.overlapBlending = 0; cr_server.debug_barriers = 0; cr_server.sharedDisplayLists = 0; cr_server.sharedTextureObjects = 0; cr_server.sharedPrograms = 0; cr_server.sharedWindows = 0; cr_server.useDMX = 0; cr_server.vpProjectionMatrixParameter = -1; cr_server.vpProjectionMatrixVariable = NULL; cr_server.currentProgram = 0; cr_server.num_overlap_intens = 0; cr_server.overlap_intens = 0; crMemset(&cr_server.MainContextInfo, 0, sizeof (cr_server.MainContextInfo)); crMatrixInit(&cr_server.viewMatrix[0]); crMatrixInit(&cr_server.viewMatrix[1]); crMatrixInit(&cr_server.projectionMatrix[0]); crMatrixInit(&cr_server.projectionMatrix[1]); cr_server.currentEye = -1; cr_server.uniqueWindows = 0; cr_server.screenCount = 0; cr_server.bForceOffscreenRendering = CR_SERVER_REDIR_NONE; cr_server.bOffscreenRenderingDefault = cr_server.bForceOffscreenRendering; cr_server.bUsePBOForReadback = GL_FALSE; cr_server.bUseOutputRedirect = GL_FALSE; }
DECLEXPORT(HGLRC) WINAPI VBoxCreateContext( HDC hdc, struct VBOXUHGSMI *pHgsmi ) { char *dpyName; ContextInfo *context; CR_DDI_PROLOGUE(); stubInit(); CRASSERT(stub.contextTable); dpyName = crCalloc(MAX_DPY_NAME); if (dpyName) { crMemset(dpyName, 0, MAX_DPY_NAME); sprintf(dpyName, "%p", hdc); } #ifndef VBOX_CROGL_USE_VBITS_SUPERSET if (stub.haveNativeOpenGL) desiredVisual |= ComputeVisBits( hdc ); #endif context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0 #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , pHgsmi #else , NULL #endif ); /* Not needed any more. */ crFree(dpyName); if (!context) return 0; return (HGLRC) context->id; }
static bool crDLMLoadList(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable) { uint32_t cElements = 0; uint32_t idList = 0; uint32_t i; int32_t rc; /* Restore Display List length. */ rc = SSMR3GetU32(pSSM, &cElements); if (RT_SUCCESS(rc)) { /* Restore Display List ID. */ rc = SSMR3GetU32(pSSM, &idList); if (RT_SUCCESS(rc)) { /* Initialize new list data and start recording it. */ DLMListInfo *pListInfo; pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo)); if (pListInfo) { GLuint hwid; crMemset(pListInfo, 0, sizeof(DLMListInfo)); hwid = dispatchTable->GenLists(1); if (hwid > 0) { bool fSuccess = true; CRDLMContextState *pDLMContextState; pListInfo->numInstances = 0; pListInfo->stateFirst = pListInfo->stateLast = NULL; pListInfo->hwid = hwid; dispatchTable->NewList(hwid, GL_COMPILE); /* Fake list state in order to prevent expando SPU from double caching. */ pDLMContextState = crDLMGetCurrentState(); pDLMContextState->currentListMode = GL_FALSE; crDebug("Restoring Display Lists:\t%u elements to restore.", cElements); /* Iterate over list instances. */ for (i = 0; i < cElements; i++) { fSuccess = crDLMLoadListInstance(pSSM, pListInfo, dispatchTable); if (!fSuccess) break; } dispatchTable->EndList(); if (fSuccess) { /* Add list to cache. */ crHashtableReplace(dlm->displayLists, idList, pListInfo, NULL); return true; } else crError("Restoring Display Lists: some elements could not be restored."); } else crError("Restoring Display Lists: can't allocate hwid for list %u.", idList); crFree(pListInfo); } else crError("Restoring Display Lists: can't allocate memory."); } else crError("Restoring Display Lists: can't get list ID."); } else crError("Restoring Display Lists: can't get number of elements in list."); return false; }
static void stubSPUSafeTearDown(void) { #ifdef CHROMIUM_THREADSAFE CRmutex *mutex; #endif if (!stub_initialized) return; stub_initialized = 0; #ifdef CHROMIUM_THREADSAFE mutex = &stub.mutex; crLockMutex(mutex); #endif crDebug("stubSPUSafeTearDown"); #ifdef WINDOWS # ifndef CR_NEWWINTRACK stubUninstallWindowMessageHook(); # endif #endif #if defined(CR_NEWWINTRACK) crUnlockMutex(mutex); # if defined(WINDOWS) if (RTThreadGetState(stub.hSyncThread)!=RTTHREADSTATE_TERMINATED) { HANDLE hNative; DWORD ec=0; hNative = OpenThread(SYNCHRONIZE|THREAD_QUERY_INFORMATION|THREAD_TERMINATE, false, RTThreadGetNative(stub.hSyncThread)); if (!hNative) { crWarning("Failed to get handle for sync thread(%#x)", GetLastError()); } else { crDebug("Got handle %p for thread %#x", hNative, RTThreadGetNative(stub.hSyncThread)); } ASMAtomicWriteBool(&stub.bShutdownSyncThread, true); if (PostThreadMessage(RTThreadGetNative(stub.hSyncThread), WM_QUIT, 0, 0)) { RTThreadWait(stub.hSyncThread, 1000, NULL); /*Same issue as on linux, RTThreadWait exits before system thread is terminated, which leads * to issues as our dll goes to be unloaded. *@todo *We usually call this function from DllMain which seems to be holding some lock and thus we have to * kill thread via TerminateThread. */ if (WaitForSingleObject(hNative, 100)==WAIT_TIMEOUT) { crDebug("Wait failed, terminating"); if (!TerminateThread(hNative, 1)) { crDebug("TerminateThread failed"); } } if (GetExitCodeThread(hNative, &ec)) { crDebug("Thread %p exited with ec=%i", hNative, ec); } else { crDebug("GetExitCodeThread failed(%#x)", GetLastError()); } } else { crDebug("Sync thread killed before DLL_PROCESS_DETACH"); } if (hNative) { CloseHandle(hNative); } } #else if (stub.hSyncThread!=NIL_RTTHREAD) { ASMAtomicWriteBool(&stub.bShutdownSyncThread, true); { /*RTThreadWait might return too early, which cause our code being unloaded while RT thread wrapper is still running*/ int rc = pthread_join(RTThreadGetNative(stub.hSyncThread), NULL); if (!rc) { crDebug("pthread_join failed %i", rc); } } } #endif crLockMutex(mutex); #endif #ifndef WINDOWS crNetTearDown(); #endif #ifdef CHROMIUM_THREADSAFE crUnlockMutex(mutex); crFreeMutex(mutex); #endif crMemset(&stub, 0, sizeof(stub)); }
/* The function that actually connects. This should only be called by clients * Servers have another way to set up the socket. */ static int crSDPDoConnect( CRConnection *conn ) { int err; struct sockaddr_in servaddr; struct hostent *hp; int i; conn->sdp_socket = socket( AF_INET_SDP, SOCK_STREAM, 0 ); if ( conn->sdp_socket < 0 ) { int err = crSDPErrno( ); crWarning( "socket error: %s", crSDPErrorString( err ) ); cr_sdp.conns[conn->index] = NULL; /* remove from table */ return 0; } /* Set up the socket the way *we* want. */ spankSocket( conn->sdp_socket ); /* Standard Berkeley sockets mumbo jumbo */ hp = gethostbyname( conn->hostname ); if ( !hp ) { crWarning( "Unknown host: \"%s\"", conn->hostname ); cr_sdp.conns[conn->index] = NULL; /* remove from table */ return 0; } crMemset( &servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_port = htons( (short) conn->port ); crMemcpy( (char *) &servaddr.sin_addr, hp->h_addr, sizeof(servaddr.sin_addr) ); if (conn->broker) { CRConnection *mother; char response[8096]; int remote_endianness; mother = __copy_of_crMothershipConnect( ); if (!__copy_of_crMothershipSendString( mother, response, "connectrequest sdp %s %d %d", conn->hostname, conn->port, conn->endianness) ) { crError( "Mothership didn't like my connect request" ); } __copy_of_crMothershipDisconnect( mother ); sscanf( response, "%u %d", &(conn->id), &(remote_endianness) ); if (conn->endianness != remote_endianness) { conn->swap = 1; } } for (i=1;i;) { #ifdef RECV_BAIL_OUT err = sizeof(unsigned int); if ( getsockopt( conn->sdp_socket, SOL_SOCKET, SO_RCVBUF, (char *) &conn->krecv_buf_size, &err ) ) { conn->krecv_buf_size = 0; } #endif if ( !connect( conn->sdp_socket, (struct sockaddr *) &servaddr, sizeof(servaddr) ) ) return 1; err = crSDPErrno( ); if ( err == EADDRINUSE || err == ECONNREFUSED ) crWarning( "Couldn't connect to %s:%d, %s", conn->hostname, conn->port, crSDPErrorString( err ) ); else if ( err == EINTR ) { crWarning( "connection to %s:%d " "interruped, trying again", conn->hostname, conn->port ); continue; } else crWarning( "Couldn't connect to %s:%d, %s", conn->hostname, conn->port, crSDPErrorString( err ) ); i=0; } cr_sdp.conns[conn->index] = NULL; /* remove from table */ return 0; }
/** * Generate host and guest IDs, setup IDs mapping between host and guest. */ GLuint DLM_APIENTRY crDLMGenLists(GLsizei range, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); GLuint idHostRangeStart = 0; GLuint idGuestRangeStart = 0; crDebug("DLM: GenLists(%d) (DLM=%p).", range, listState ? listState->dlm : 0); if (listState) { idHostRangeStart = dispatchTable->GenLists(range); if (idHostRangeStart > 0) { idGuestRangeStart = crHashtableAllocKeys(listState->dlm->displayLists, range); if (idGuestRangeStart > 0) { GLuint i; bool fSuccess = true; /* Now have successfully generated IDs range for host and guest. Let's make IDs association. */ for (i = 0; i < (GLuint)range; i++) { DLMListInfo *pListInfo; pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo)); if (pListInfo) { crMemset(pListInfo, 0, sizeof(DLMListInfo)); pListInfo->hwid = idHostRangeStart + i; /* Insert pre-initialized list data which contains IDs mapping into the hash. */ crHashtableReplace(listState->dlm->displayLists, idGuestRangeStart + i, pListInfo, NULL); } else { fSuccess = false; break; } } /* All structures allocated and initialized successfully. */ if (fSuccess) return idGuestRangeStart; /* Rollback some data was not allocated. */ crDLMDeleteLists(idGuestRangeStart, range, NULL /* we do DeleteLists() later in this routine */ ); } else crDebug("DLM: Can't allocate Display List IDs range for the guest."); dispatchTable->DeleteLists(idHostRangeStart, range); } else crDebug("DLM: Can't allocate Display List IDs range on the host side."); } else crDebug("DLM: GenLists(%u) called with no current state.", range); /* Can't reserve IDs range. */ return 0; }