/** * 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 crPackSetBuffer( CRPackContext *pc, CRPackBuffer *buffer ) { CRASSERT( pc ); CRASSERT( buffer ); if (pc->currentBuffer == buffer) return; /* re-bind is no-op */ if (pc->currentBuffer) { /* Another buffer currently bound to this packer (shouldn't normally occur) * Release it. Fixes Ensight issue. */ crPackReleaseBuffer(pc); } CRASSERT( pc->currentBuffer == NULL); /* release if NULL? */ CRASSERT( buffer->context == NULL ); /* bind context to buffer */ pc->currentBuffer = buffer; buffer->context = pc; /* update the context's packing fields with those from the buffer */ pc->buffer = *buffer; /* struct copy */ }
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(); } }
/** * 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 ); } }
/* * 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; }
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); }
/* * This is called by the packer when the packer's buffer is full and * it needs to be emptied. * This function is registered as a callback with crPackFlushFunc(). */ void hiddenlineFlush( void *arg ) { GET_CONTEXT(context); CRPackBuffer *buf; CRASSERT(context); buf = &(context->pack_buffer); /* release previous buffer if any */ crPackReleaseBuffer( context->packer ); hiddenlineRecord( buf->pack, buf->data_start, buf->opcode_start, buf->opcode_start - buf->opcode_current , 1 ); hiddenlineProvidePackBuffer(); (void) arg; }
/* * 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); }
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; } } }
/** * 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); } }
/* * 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 }