/* * This is called from either the Pack SPU and the packer library whenever * we need to send a data buffer to the server. */ void packspuFlush(void *arg ) { ThreadInfo *thread = (ThreadInfo *) arg; ContextInfo *ctx; unsigned int len; CRMessageOpcodes *hdr; CRPackBuffer *buf; /* we should _always_ pass a valid <arg> value */ CRASSERT(thread); ctx = thread->currentContext; buf = &(thread->buffer); CRASSERT(buf); /* We're done packing into the current buffer, unbind it */ crPackReleaseBuffer( thread->packer ); /* printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n", __FUNCTION__, (void*) thread, (int) thread->id, thread->packer, (int) t2->id, t2->packer, buf->pack, thread->packer->buffer.pack); */ if ( buf->opcode_current == buf->opcode_start ) { /* printf("%s early return\n", __FUNCTION__); */ /* XXX these calls seem to help, but might be appropriate */ crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); return; } hdr = __prependHeader( buf, &len, 0 ); CRASSERT( thread->netServer.conn ); if ( buf->holds_BeginEnd ) crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len ); else crNetSend( thread->netServer.conn, &(buf->pack), hdr, len ); buf->pack = crNetAlloc( thread->netServer.conn ); /* The network may have found a new mtu */ buf->mtu = thread->netServer.conn->mtu; crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); (void) arg; }
/** * Send the current tilesort tile info to all the servers. */ void tilesortspuSendTileInfoToServers( WindowInfo *winInfo ) { GET_THREAD(thread); int i; /* release geometry buffer */ crPackReleaseBuffer( thread->packer ); /* loop over servers */ for (i = 0; i < tilesort_spu.num_servers; i++) { ServerWindowInfo *servWinInfo = winInfo->server + i; int tileInfo[4 + 4 * CR_MAX_EXTENTS], arraySize; int j; /* build tileInfo array */ tileInfo[0] = i; tileInfo[1] = winInfo->muralWidth; tileInfo[2] = winInfo->muralHeight; tileInfo[3] = servWinInfo->num_extents; for (j = 0; j < servWinInfo->num_extents; j++) { int w = servWinInfo->extents[j].x2 - servWinInfo->extents[j].x1; int h = servWinInfo->extents[j].y2 - servWinInfo->extents[j].y1; tileInfo[4 + j * 4 + 0] = servWinInfo->extents[j].x1; tileInfo[4 + j * 4 + 1] = servWinInfo->extents[j].y1; tileInfo[4 + j * 4 + 2] = w; tileInfo[4 + j * 4 + 3] = h; } arraySize = 4 + 4 * servWinInfo->num_extents; /* pack/send to server[i] */ crPackSetBuffer( thread->packer, &(thread->buffer[i]) ); if (tilesort_spu.swap) crPackChromiumParametervCRSWAP(GL_TILE_INFO_CR, GL_INT, arraySize, tileInfo); else crPackChromiumParametervCR(GL_TILE_INFO_CR, GL_INT, arraySize, tileInfo); /* release server buffer */ crPackReleaseBuffer( thread->packer ); } /* Restore default buffer */ crPackSetBuffer( thread->packer, &(thread->geometry_buffer) ); }
void REPLICATESPU_APIENTRY replicatespu_End( void ) { GET_THREAD(thread); CRPackBuffer *buf = &thread->BeginEndBuffer; if ( thread->server.conn->Barf && (thread->BeginEndMode == GL_LINES || thread->BeginEndMode == GL_TRIANGLES || thread->BeginEndMode == GL_QUADS || thread->BeginEndMode == GL_POLYGON ) ) { CRASSERT(buf->pack); crPackReleaseBuffer( thread->packer ); crPackSetBuffer( thread->packer, &thread->normBuffer ); if ( !crPackCanHoldBuffer( buf ) ) replicatespuFlush( (void *) thread ); crPackAppendBuffer( buf ); crNetFree( thread->server.conn, buf->pack ); buf->pack = NULL; } if (thread->currentContext->displayListMode != GL_FALSE) { crDLMCompileEnd(); } if (replicate_spu.swap) { crPackEndSWAP(); } else { crPackEnd(); } }
/* This is useful for debugging packer problems */ void crPackSetBufferDEBUG( const char *file, int line, CRPackContext *pc, CRPackBuffer *buffer) { crPackSetBuffer( pc, buffer ); /* record debugging info */ pc->file = crStrdup(file); pc->line = line; }
/* * Allocate a new ThreadInfo structure, setup a connection to the * server, allocate/init a packer context, bind this ThreadInfo to * the calling thread with crSetTSD(). * We'll always call this function at least once even if we're not * using threads. */ ThreadInfo *replicatespuNewThread( CRthread id ) { ThreadInfo *thread; #ifdef CHROMIUM_THREADSAFE_notyet crLockMutex(&_ReplicateMutex); #else CRASSERT(replicate_spu.numThreads == 0); #endif CRASSERT(replicate_spu.numThreads < MAX_THREADS); thread = &(replicate_spu.thread[replicate_spu.numThreads]); thread->id = id; thread->currentContext = NULL; /* connect to the server */ thread->server.name = crStrdup( replicate_spu.name ); thread->server.buffer_size = replicate_spu.buffer_size; if (replicate_spu.numThreads == 0) { replicatespuConnectToServer( &(thread->server) ); CRASSERT(thread->server.conn); replicate_spu.swap = thread->server.conn->swap; } else { /* a new pthread */ replicatespuFlushAll( &(replicate_spu.thread[0]) ); crNetNewClient( replicate_spu.thread[0].server.conn, &(thread->server)); CRASSERT(thread->server.conn); } /* packer setup */ CRASSERT(thread->packer == NULL); thread->packer = crPackNewContext( replicate_spu.swap ); CRASSERT(thread->packer); crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->server.conn), thread->server.conn->buffer_size, thread->server.conn->mtu ); thread->buffer.canBarf = thread->server.conn->Barf ? GL_TRUE : GL_FALSE; crPackSetBuffer( thread->packer, &thread->buffer ); crPackFlushFunc( thread->packer, replicatespuFlush ); crPackFlushArg( thread->packer, (void *) thread ); crPackSendHugeFunc( thread->packer, replicatespuHuge ); crPackSetContext( thread->packer ); #ifdef CHROMIUM_THREADSAFE_notyet crSetTSD(&_ReplicateTSD, thread); #endif replicate_spu.numThreads++; #ifdef CHROMIUM_THREADSAFE_notyet crUnlockMutex(&_ReplicateMutex); #endif return thread; }
/* * This is called from either replicatespuFlushAll or the packer library * whenever we need to send a data buffer to the servers. */ void replicatespuFlush(void *arg ) { ThreadInfo *thread = (ThreadInfo *) arg; unsigned int len; CRMessageOpcodes *hdr; CRPackBuffer *buf; unsigned int i; /* we should _always_ pass a valid <arg> value */ CRASSERT(thread); buf = &(thread->buffer); CRASSERT(buf); CRASSERT(buf->pack); crPackReleaseBuffer( thread->packer ); if ( buf->opcode_current == buf->opcode_start ) { /* XXX these calls seem to help, but might be appropriate */ crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); return; } hdr = __prependHeader( buf, &len, 0 ); /* Now send it to all our replicants */ for (i = 1; i < CR_MAX_REPLICANTS; i++) { if (IS_CONNECTED(replicate_spu.rserver[i].conn)) { crNetSend( replicate_spu.rserver[i].conn, NULL, hdr, len ); } } /* The network may have found a new mtu */ buf->mtu = thread->server.conn->mtu; crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); }
/** * Flush buffered commands, sending them to just one server */ void replicatespuFlushOne(ThreadInfo *thread, int server) { unsigned int len; CRMessageOpcodes *hdr; CRPackBuffer *buf; CRConnection *conn; CRASSERT(server >= 0); CRASSERT(server < CR_MAX_REPLICANTS); CRASSERT(thread); buf = &(thread->buffer); CRASSERT(buf); CRASSERT(buf->pack); crPackReleaseBuffer( thread->packer ); if ( buf->opcode_current == buf->opcode_start ) { /* XXX these calls seem to help, but might be appropriate */ crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); return; } hdr = __prependHeader( buf, &len, 0 ); conn = replicate_spu.rserver[server].conn; CRASSERT(conn); if (conn->type != CR_NO_CONNECTION) { crNetSend( conn, NULL, hdr, len ); } /* The network may have found a new mtu */ buf->mtu = thread->server.conn->mtu; crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); }
static void DoVertex( void ) { GET_THREAD(thread); CRPackBuffer *buf = &thread->BeginEndBuffer; CRPackBuffer *gbuf = &thread->normBuffer; int num_data; int num_opcode; /*crDebug( "really doing Vertex" );*/ crPackReleaseBuffer( thread->packer ); num_data = buf->data_current - buf->data_start; num_opcode = buf->opcode_start - buf->opcode_current; crPackSetBuffer( thread->packer, gbuf ); if ( !crPackCanHoldBuffer( buf ) ) /* doesn't hold, first flush gbuf*/ replicatespuFlush( (void *) thread ); crPackAppendBuffer( buf ); crPackReleaseBuffer( thread->packer ); crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); }
void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void) { crLockMutex(&_PackMutex); { int i; GET_THREAD(thread); CRASSERT(!thread); CRASSERT((pack_spu.numThreads>0) && (pack_spu.numThreads<MAX_THREADS)); for (i=0; i<MAX_THREADS; ++i) { if (!pack_spu.thread[i].inUse) { thread = &pack_spu.thread[i]; break; } } CRASSERT(thread); thread->inUse = GL_TRUE; thread->id = crThreadID(); thread->currentContext = NULL; thread->bInjectThread = GL_TRUE; thread->netServer.name = crStrdup(pack_spu.name); thread->netServer.buffer_size = 64 * 1024; crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer)); CRASSERT(thread->netServer.conn); CRASSERT(thread->packer == NULL); thread->packer = crPackNewContext( pack_spu.swap ); CRASSERT(thread->packer); crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn), thread->netServer.conn->buffer_size, thread->netServer.conn->mtu); thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE; crPackSetBuffer( thread->packer, &thread->buffer ); crPackFlushFunc( thread->packer, packspuFlush ); crPackFlushArg( thread->packer, (void *) thread ); crPackSendHugeFunc( thread->packer, packspuHuge ); crPackSetContext( thread->packer ); crSetTSD(&_PackTSD, thread); pack_spu.numThreads++; } crUnlockMutex(&_PackMutex); }
/* * Get an empty packing buffer from the buffer pool, or allocate a new one. * Then tell the packer to use it. */ void hiddenlineProvidePackBuffer(void) { void *buf; GET_CONTEXT(context); CRASSERT(context); buf = crBufferPoolPop( context->bufpool, hiddenline_spu.buffer_size ); if (!buf) { buf = crAlloc( hiddenline_spu.buffer_size ); } crPackInitBuffer( &(context->pack_buffer), buf, hiddenline_spu.buffer_size, hiddenline_spu.buffer_size ); crPackSetBuffer( context->packer, &(context->pack_buffer) ); }
/** * Examine the server tile boundaries to compute the overall max * viewport dims. Then send those dims to the servers. * * XXX \todo This isn't used!?! */ void tilesortspuComputeMaxViewport(WindowInfo *winInfo) { ThreadInfo *thread0 = &(tilesort_spu.thread[0]); GLint totalDims[2]; int i; /* release geometry buffer, if it's bound */ crPackReleaseBuffer( thread0->packer ); /* * It's hard to say what the max viewport size should be. * We've changed this computation a few times now. * For now, we set it to twice the mural size, or at least 4K. * One problem is that the mural size can change dynamically... */ totalDims[0] = 2 * winInfo->muralWidth; totalDims[1] = 2 * winInfo->muralHeight; if (totalDims[0] < 4096) totalDims[0] = 4096; if (totalDims[1] < 4096) totalDims[1] = 4096; tilesort_spu.limits.maxViewportDims[0] = totalDims[0]; tilesort_spu.limits.maxViewportDims[1] = totalDims[1]; /* * Once we've computed the maximum viewport size, we send * a message to each server with its new viewport parameters. */ for (i = 0; i < tilesort_spu.num_servers; i++) { crPackSetBuffer( thread0->packer, &(thread0->buffer[i]) ); if (tilesort_spu.swap) crPackChromiumParametervCRSWAP(GL_SET_MAX_VIEWPORT_CR, GL_INT, 2, totalDims); else crPackChromiumParametervCR(GL_SET_MAX_VIEWPORT_CR, GL_INT, 2, totalDims); /* release server buffer */ crPackReleaseBuffer( thread0->packer ); /* Flush buffer (send to server) */ tilesortspuSendServerBuffer( i ); } }
void REPLICATESPU_APIENTRY replicatespu_Begin( GLenum mode ) { GET_THREAD(thread); CRPackBuffer *buf = &thread->BeginEndBuffer; CRASSERT( mode >= GL_POINTS && mode <= GL_POLYGON ); if (thread->currentContext->displayListMode != GL_FALSE) { crDLMCompileBegin(mode); } if (replicate_spu.swap) { crPackBeginSWAP( mode ); } else { crPackBegin( mode ); } if ( thread->server.conn->Barf ) { thread->BeginEndMode = mode; thread->BeginEndState = -1; if ( mode == GL_LINES || mode == GL_TRIANGLES || mode == GL_QUADS || mode == GL_POLYGON ) { CRASSERT(!buf->pack); crPackReleaseBuffer( thread->packer ); buf->pack = crNetAlloc( thread->server.conn ); crPackInitBuffer( buf, buf->pack, thread->server.conn->buffer_size, thread->server.conn->mtu ); buf->holds_BeginEnd = 1; buf->in_BeginEnd = 1; crPackSetBuffer( thread->packer, buf ); thread->BeginEndState = 0; } } }
GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi) { GLint con = 0; int i; GET_THREAD(thread); CRASSERT(!thread); crLockMutex(&_PackMutex); { CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI() || (pack_spu.numThreads>0)); CRASSERT(pack_spu.numThreads<MAX_THREADS); for (i=0; i<MAX_THREADS; ++i) { if (!pack_spu.thread[i].inUse) { thread = &pack_spu.thread[i]; break; } } CRASSERT(thread); thread->inUse = GL_TRUE; if (!CRPACKSPU_IS_WDDM_CRHGSMI()) thread->id = crThreadID(); else thread->id = THREAD_OFFSET_MAGIC + i; thread->currentContext = NULL; thread->bInjectThread = GL_TRUE; thread->netServer.name = crStrdup(pack_spu.name); thread->netServer.buffer_size = 64 * 1024; packspuConnectToServer(&(thread->netServer) #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , pHgsmi #endif ); CRASSERT(thread->netServer.conn); CRASSERT(thread->packer == NULL); thread->packer = crPackNewContext( pack_spu.swap ); CRASSERT(thread->packer); crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn), thread->netServer.conn->buffer_size, thread->netServer.conn->mtu); thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE; crPackSetBuffer( thread->packer, &thread->buffer ); crPackFlushFunc( thread->packer, packspuFlush ); crPackFlushArg( thread->packer, (void *) thread ); crPackSendHugeFunc( thread->packer, packspuHuge ); crPackSetContext( thread->packer ); crSetTSD(&_PackTSD, thread); pack_spu.numThreads++; } crUnlockMutex(&_PackMutex); if (CRPACKSPU_IS_WDDM_CRHGSMI()) { CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread) && GET_THREAD_VAL_ID(thread->id) == thread); con = thread->id; } return con; }
/** * Implementation of glClean for tilesorter * \param mask */ void TILESORTSPU_APIENTRY tilesortspu_Clear( GLbitfield mask ) { GET_THREAD(thread); GLenum dlMode = thread->currentContext->displayListMode; WindowInfo *winInfo = thread->currentContext->currentWindow; /* This is a good place to check for new tiling geometry when * the DMX window is changed. */ #ifdef USE_DMX if (tilesort_spu.trackWindowPosition && !dlMode) { if (winInfo->isDMXWindow && winInfo->xwin) { if (tilesortspuUpdateWindowInfo(winInfo)) { tilesortspuGetNewTiling(winInfo); } } } if (winInfo->newBackendWindows) { tilesortspuGetNewTiling(winInfo); } #endif if (dlMode != GL_FALSE) { /* just creating and/or compiling display lists */ if (tilesort_spu.lazySendDLists) crDLMCompileClear(mask); else if (tilesort_spu.swap) crPackClearSWAP(mask); else crPackClear(mask); return; } if (winInfo->passiveStereo) { /* only send Clear to left/right servers */ int i; tilesortspuFlush( thread ); crPackReleaseBuffer( thread->packer ); /* Send glClear command to those servers designated as left/right * which match the current glDrawBuffer setting (stereo). */ for (i = 0; i < tilesort_spu.num_servers; i++) { const ServerWindowInfo *servWinInfo = winInfo->server + i; if (servWinInfo->eyeFlags & thread->currentContext->stereoDestFlags) { crPackSetBuffer( thread->packer, &(thread->buffer[i]) ); if (tilesort_spu.swap) crPackClearSWAP(mask); else crPackClear(mask); crPackReleaseBuffer( thread->packer ); tilesortspuSendServerBuffer( i ); } } /* Restore the default pack buffer */ crPackSetBuffer( thread->packer, &(thread->geometry_buffer) ); } else { /* not doing stereo, truly broadcast glClear */ tilesortspuFlush( thread ); if (tilesort_spu.swap) crPackClearSWAP( mask ); else crPackClear( mask ); tilesortspuBroadcastGeom(GL_TRUE); } }
/* * Allocate a new ThreadInfo structure, setup a connection to the * server, allocate/init a packer context, bind this ThreadInfo to * the calling thread with crSetTSD(). * We'll always call this function at least once even if we're not * using threads. */ ThreadInfo *packspuNewThread( unsigned long id ) { ThreadInfo *thread=NULL; int i; #ifdef CHROMIUM_THREADSAFE crLockMutex(&_PackMutex); #else CRASSERT(pack_spu.numThreads == 0); #endif CRASSERT(pack_spu.numThreads < MAX_THREADS); for (i=0; i<MAX_THREADS; ++i) { if (!pack_spu.thread[i].inUse) { thread = &pack_spu.thread[i]; break; } } CRASSERT(thread); thread->inUse = GL_TRUE; thread->id = id; thread->currentContext = NULL; thread->bInjectThread = GL_FALSE; /* connect to the server */ thread->netServer.name = crStrdup( pack_spu.name ); thread->netServer.buffer_size = pack_spu.buffer_size; if (pack_spu.numThreads == 0) { packspuConnectToServer( &(thread->netServer) ); if (!thread->netServer.conn) { return NULL; } pack_spu.swap = thread->netServer.conn->swap; } else { /* a new pthread */ crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer)); CRASSERT(thread->netServer.conn); } /* packer setup */ CRASSERT(thread->packer == NULL); thread->packer = crPackNewContext( pack_spu.swap ); CRASSERT(thread->packer); crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn), thread->netServer.conn->buffer_size, thread->netServer.conn->mtu ); thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE; crPackSetBuffer( thread->packer, &thread->buffer ); crPackFlushFunc( thread->packer, packspuFlush ); crPackFlushArg( thread->packer, (void *) thread ); crPackSendHugeFunc( thread->packer, packspuHuge ); crPackSetContext( thread->packer ); #ifdef CHROMIUM_THREADSAFE crSetTSD(&_PackTSD, thread); #endif pack_spu.numThreads++; #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_PackMutex); #endif return thread; }
/* * This is called from either the Pack SPU and the packer library whenever * we need to send a data buffer to the server. */ void packspuFlush(void *arg ) { ThreadInfo *thread = (ThreadInfo *) arg; ContextInfo *ctx; unsigned int len; CRMessageOpcodes *hdr; CRPackBuffer *buf; /* we should _always_ pass a valid <arg> value */ CRASSERT(thread && thread->inUse); #ifdef CHROMIUM_THREADSAFE CR_LOCK_PACKER_CONTEXT(thread->packer); #endif ctx = thread->currentContext; buf = &(thread->buffer); CRASSERT(buf); if (ctx && ctx->fCheckZerroVertAttr) crStateCurrentRecoverNew(ctx->clientState, &thread->packer->current); /* We're done packing into the current buffer, unbind it */ crPackReleaseBuffer( thread->packer ); /* printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n", __FUNCTION__, (void*) thread, (int) thread->id, thread->packer, (int) t2->id, t2->packer, buf->pack, thread->packer->buffer.pack); */ if ( buf->opcode_current == buf->opcode_start ) { /* printf("%s early return\n", __FUNCTION__); */ /* XXX these calls seem to help, but might be appropriate */ crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); #ifdef CHROMIUM_THREADSAFE CR_UNLOCK_PACKER_CONTEXT(thread->packer); #endif return; } hdr = __prependHeader( buf, &len, 0 ); CRASSERT( thread->netServer.conn ); if ( buf->holds_BeginEnd ) { /*crDebug("crNetBarf %d, (%d)", len, buf->size);*/ crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len ); } else { /*crDebug("crNetSend %d, (%d)", len, buf->size);*/ crNetSend( thread->netServer.conn, &(buf->pack), hdr, len ); } buf->pack = crNetAlloc( thread->netServer.conn ); /* The network may have found a new mtu */ buf->mtu = thread->netServer.conn->mtu; crPackSetBuffer( thread->packer, buf ); crPackResetPointers(thread->packer); #ifdef CHROMIUM_THREADSAFE CR_UNLOCK_PACKER_CONTEXT(thread->packer); #endif }