static void DoSync(void) { CRMessage *in, out; out.header.type = CR_MESSAGE_OOB; if (render_spu.is_swap_master) { int a; for (a = 0; a < render_spu.num_swap_clients; a++) { crNetGetMessage( render_spu.swap_conns[a], &in ); crNetFree( render_spu.swap_conns[a], in); } for (a = 0; a < render_spu.num_swap_clients; a++) crNetSend( render_spu.swap_conns[a], NULL, &out, sizeof(CRMessage)); } else { crNetSend( render_spu.swap_conns[0], NULL, &out, sizeof(CRMessage)); crNetGetMessage( render_spu.swap_conns[0], &in ); crNetFree( render_spu.swap_conns[0], in); } }
/** * Send a huge buffer to one server, or all if server==-1. */ void replicatespuHugeOne(CROpcode opcode, void *buf, int server) { unsigned int len; unsigned char *src; CRMessageOpcodes *msg; int i; /* packet length is indicated by the variable length field, and includes an additional word for the opcode (with alignment) and a header */ len = ((unsigned int *) buf)[-1]; if (replicate_spu.swap) { /* It's already been swapped, swap it back. */ len = SWAP32(len); } len += 4 + sizeof(CRMessageOpcodes); /* write the opcode in just before the length */ ((unsigned char *) buf)[-5] = (unsigned char) opcode; /* fix up the pointer to the packet to include the length & opcode & header */ src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes); msg = (CRMessageOpcodes *) src; if (replicate_spu.swap) { msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES); msg->numOpcodes = SWAP32(1); } else { msg->header.type = CR_MESSAGE_OPCODES; msg->numOpcodes = 1; } if (server >= 0) { /* send to just one */ if (IS_CONNECTED(replicate_spu.rserver[server].conn)) { crNetSend( replicate_spu.rserver[server].conn, NULL, src, len ); } } else { /* send to all */ for (i = 1; i < CR_MAX_REPLICANTS; i++) { if (IS_CONNECTED(replicate_spu.rserver[i].conn)) { crNetSend( replicate_spu.rserver[i].conn, NULL, src, len ); } } } }
/** * XXX NOTE: there's a lot of duplicate code here common to the * pack, tilesort and replicate SPUs. Try to simplify someday! */ void packspuHuge( CROpcode opcode, void *buf ) { GET_THREAD(thread); unsigned int len; unsigned char *src; CRMessageOpcodes *msg; CRASSERT(thread); /* packet length is indicated by the variable length field, and includes an additional word for the opcode (with alignment) and a header */ len = ((unsigned int *) buf)[-1]; len += 4 + sizeof(CRMessageOpcodes); /* write the opcode in just before the length */ ((unsigned char *) buf)[-5] = (unsigned char) opcode; /* fix up the pointer to the packet to include the length & opcode & header */ src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes); msg = (CRMessageOpcodes *) src; msg->header.type = CR_MESSAGE_OPCODES; msg->numOpcodes = 1; CRASSERT( thread->netServer.conn ); crNetSend( thread->netServer.conn, NULL, src, len ); }
void PACKSPU_APIENTRY packspu_ChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values) { CRMessage msg; int len; GET_THREAD(thread); switch(target) { case GL_GATHER_PACK_CR: /* flush the current pack buffer */ packspuFlush( (void *) thread ); /* the connection is thread->server.conn */ msg.header.type = CR_MESSAGE_GATHER; msg.gather.offset = 69; len = sizeof(CRMessageGather); crNetSend(thread->netServer.conn, NULL, &msg, len); break; default: if (pack_spu.swap) crPackChromiumParametervCRSWAP(target, type, count, values); else crPackChromiumParametervCR(target, type, count, values); } }
void crutSendEvent( CRUTAPI *crut_api, void *msg, int size ) { int i; for (i=0; i<crut_api->numclients; ++i) { crNetSend( crut_api->crutclients[i].send_conn, NULL, msg, size ); } }
/* * Send a Chromium opcode buffer across the given net connection. * size - size of opcode buffer in bytes. * exitFlag - if true, send 'exit' code to server. */ static void SendOpcodes(CRConnection *conn, int size, int exitFlag) { char *buffer, *firstCode; CRMessageOpcodes *msg; if (size <= MTU) { buffer = crNetAlloc(conn); msg = (CRMessageOpcodes *) buffer; msg->header.type = CR_MESSAGE_OPCODES; msg->numOpcodes = size; firstCode = buffer + sizeof(CRMessageOpcodes); if (exitFlag) *firstCode = 42; else *firstCode = 99; crNetSend(conn, NULL, buffer, MTU); crNetFree(conn, buffer); } else { /* send "huge" buffer */ const int totalSize = size + 8 + sizeof(CRMessageOpcodes); unsigned int *uiptr; buffer = crAlloc(totalSize); msg = (CRMessageOpcodes *) buffer; msg->header.type = CR_MESSAGE_OPCODES; msg->numOpcodes = 1; uiptr = (unsigned int *) (buffer + sizeof(CRMessageOpcodes) + 4); uiptr[0] = size; firstCode = buffer + sizeof(CRMessageOpcodes); if (exitFlag) *firstCode = 42; else *firstCode = 99; crNetSend(conn, NULL, buffer, size); crFree(buffer); } }
/* * 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 a message to the receiver that another connection is needed. * We send a CR_MESSAGE_NEWCLIENT packet, then call crNetServerConnect. */ void crNetNewClient( CRConnection *conn, CRNetServer *ns ) { unsigned int len = sizeof(CRMessageNewClient); CRMessageNewClient msg; CRASSERT( conn ); if (conn->swap) msg.header.type = (CRMessageType) SWAP32(CR_MESSAGE_NEWCLIENT); else msg.header.type = CR_MESSAGE_NEWCLIENT; crNetSend( conn, NULL, &msg, len ); crNetServerConnect( ns ); }
void SERVER_DISPATCH_APIENTRY crServerDispatchReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { /* Note: this local var overrides the global var in cr_unpack.h */ const unsigned char *cr_unpackData = crUnpackGetDataPointer(); CRMessageReadPixels *rp; const GLint stride = READ_DATA( 24, GLint ); const GLint alignment = READ_DATA( 28, GLint ); const GLint skipRows = READ_DATA( 32, GLint ); const GLint skipPixels = READ_DATA( 36, GLint ); const GLint bytes_per_row = READ_DATA( 40, GLint ); const GLint rowLength = READ_DATA( 44, GLint ); const int msg_len = sizeof(*rp) + bytes_per_row * height; CRASSERT(bytes_per_row > 0); rp = (CRMessageReadPixels *) crAlloc( msg_len ); /* Note: the ReadPixels data gets densely packed into the buffer * (no skip pixels, skip rows, etc. It's up to the receiver (pack spu, * tilesort spu, etc) to apply the real PixelStore packing parameters. */ cr_server.head_spu->dispatch_table.ReadPixels( x, y, width, height, format, type, rp + 1); rp->header.type = CR_MESSAGE_READ_PIXELS; rp->width = width; rp->height = height; rp->bytes_per_row = bytes_per_row; rp->stride = stride; rp->format = format; rp->type = type; rp->alignment = alignment; rp->skipRows = skipRows; rp->skipPixels = skipPixels; rp->rowLength = rowLength; /* <pixels> points to the 8-byte network pointer */ crMemcpy( &rp->pixels, pixels, sizeof(rp->pixels) ); crNetSend( cr_server.curClient->conn, NULL, rp, msg_len ); crFree( rp ); }
/* * 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); }
/** * This is the guts of the binaryswap operation. Here, we call glReadPixels * to read a region of the color and depth buffers from the parent (render * SPU) window. We then begin the process of composition using binary swap. * Each node does a glReadPixels and sends its swap region to its swap * partner. Once we receive our partner's frame region, we use draw pixels to * composite against our frame. This repeats for all swap partners. Once we * have all of the regions composited against the one we are responsible for, * we issue another read and send our region to final display by glDrawPixels * (and some other GL functions) on the child/downstream SPU to send our region * to the final display node. * Input: window - the window we're processing * startx, starty - glReadPixels start coordinates * endx, endy - glReadPixels ending coordinates */ static void CompositeNode(WindowInfo * window, int startx, int starty, int endx, int endy) { int i = 0; int read_start_x = 0, read_start_y = 0; int read_width = 0, read_height = 0; CRMessage *incoming_msg = NULL; GLubyte *incoming_color = NULL; GLuint *incoming_depth = NULL; BinarySwapMsg *render_info = NULL; int draw_x = 0, draw_y = 0; int draw_width = 0, draw_height = 0; float other_depth = 0.0; int recalc_end_x = 0, recalc_end_y = 0; int recalc_start_x = 0, recalc_start_y = 0; int recalc_temp; CRASSERT(window->width > 0); CRASSERT(window->height > 0); /* figure out our portion for each stage */ for (i = 0; i < binaryswap_spu.stages; i++) { BinarySwapMsg *msg = (BinarySwapMsg *) window->msgBuffer; /* set up message header */ msg->start_x = window->read_x[i]; msg->start_y = window->read_y[i]; msg->width = window->read_width[i]; msg->height = window->read_height[i]; msg->depth = binaryswap_spu.depth; if (startx < window->read_x[i]) msg->clipped_x = window->read_x[i]; else msg->clipped_x = startx; if (starty < window->read_y[i]) msg->clipped_y = window->read_y[i]; else msg->clipped_y = starty; if (endx > (window->read_x[i] + window->read_width[i])) msg->clipped_width = (window->read_x[i] + window->read_width[i]) - msg->clipped_x; else msg->clipped_width = endx - msg->clipped_x; if (endy > (window->read_y[i] + window->read_height[i])) msg->clipped_height = (window->read_y[i] + window->read_height[i]) - msg->clipped_y; else msg->clipped_height = endy - msg->clipped_y; if (msg->clipped_width < 0) msg->clipped_width = 0; if (msg->clipped_height < 0) msg->clipped_height = 0; read_start_x = msg->clipped_x; read_start_y = msg->clipped_y; read_width = msg->clipped_width; read_height = msg->clipped_height; /* read our portion for this pass */ /* figure out which mode to use, depth or alpha */ if (binaryswap_spu.alpha_composite) { if (read_width > 0 && read_height > 0) binaryswap_spu.super.ReadPixels(read_start_x, read_start_y, read_width, read_height, GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte *) window->msgBuffer + binaryswap_spu.offset); if (binaryswap_spu.highlow[i]) { /* lower of pair => recv,send */ crNetGetMessage(binaryswap_spu.peer_recv[i], &incoming_msg); crNetSend(binaryswap_spu.peer_send[i], NULL, window->msgBuffer, (read_width * read_height * 4) + binaryswap_spu.offset); } else { /* higher of pair => send,recv */ crNetSend(binaryswap_spu.peer_send[i], NULL, window->msgBuffer, (read_width * read_height * 4) + binaryswap_spu.offset); crNetGetMessage(binaryswap_spu.peer_recv[i], &incoming_msg); } if (binaryswap_spu.mtu > binaryswap_spu.peer_send[i]->mtu) binaryswap_spu.mtu = binaryswap_spu.peer_send[i]->mtu; /* get render info from other node */ render_info = (BinarySwapMsg *) incoming_msg; draw_x = render_info->clipped_x; draw_y = render_info->clipped_y; draw_width = render_info->clipped_width; draw_height = render_info->clipped_height; other_depth = render_info->depth; if (draw_width > 0 && draw_height > 0) { /* get incoming fb */ incoming_color = (GLubyte *) ((GLubyte *) incoming_msg + binaryswap_spu.offset); /* figure out blend function based on z */ binaryswap_spu.super.Enable(GL_BLEND); /* Other image is on top of ours! */ if (binaryswap_spu.depth > other_depth) { /* over operator */ binaryswap_spu.super.BlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); binaryswap_spu.super.WindowPos2iARB(draw_x, draw_y); binaryswap_spu.super.DrawPixels(draw_width, draw_height, GL_RGBA, GL_UNSIGNED_BYTE, incoming_color); } /* other image is under ours */ else if(binaryswap_spu.depth < other_depth) { /* under operator */ binaryswap_spu.super.BlendFuncSeparateEXT(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ONE, GL_ONE); binaryswap_spu.super.WindowPos2iARB(draw_x, draw_y); binaryswap_spu.super.DrawPixels(draw_width, draw_height, GL_RGBA, GL_UNSIGNED_BYTE, incoming_color); } else { if(binaryswap_spu.highlow[i]) { /* over operator */ binaryswap_spu.super.BlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); binaryswap_spu.super.WindowPos2iARB(draw_x, draw_y); binaryswap_spu.super.DrawPixels(draw_width, draw_height, GL_RGBA, GL_UNSIGNED_BYTE, incoming_color); } else { /* under operator */ binaryswap_spu.super.BlendFuncSeparateEXT(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ONE, GL_ONE); binaryswap_spu.super.WindowPos2iARB(draw_x, draw_y); binaryswap_spu.super.DrawPixels(draw_width, draw_height, GL_RGBA, GL_UNSIGNED_BYTE, incoming_color); } } if (binaryswap_spu.depth > other_depth) { binaryswap_spu.depth = other_depth; } } } else { /* depth composite */ if (read_width > 0 && read_height > 0) { GLubyte *colors = (GLubyte *) window->msgBuffer + binaryswap_spu.offset; GLuint *depths = (GLuint *) ((GLubyte *) window->msgBuffer + /* base address */ (read_width * read_height * 3) + /* color information */ binaryswap_spu.offset); /* message header */ binaryswap_spu.super.ReadPixels(read_start_x, read_start_y, read_width, read_height, GL_RGB, GL_UNSIGNED_BYTE, colors); binaryswap_spu.super.ReadPixels(read_start_x, read_start_y, read_width, read_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, depths); } if (binaryswap_spu.highlow[i]) { /* lower of pair => recv,send */ crNetGetMessage(binaryswap_spu.peer_recv[i], &incoming_msg); crNetSend(binaryswap_spu.peer_send[i], NULL, window->msgBuffer, read_width * read_height * (3 + 4) + binaryswap_spu.offset); } else { /* higher of pair => send,recv */ crNetSend(binaryswap_spu.peer_send[i], NULL, window->msgBuffer, read_width * read_height * (3 + 4) + binaryswap_spu.offset); crNetGetMessage(binaryswap_spu.peer_recv[i], &incoming_msg); } if (binaryswap_spu.mtu > binaryswap_spu.peer_send[i]->mtu) binaryswap_spu.mtu = binaryswap_spu.peer_send[i]->mtu; /* get render info from other node */ render_info = (BinarySwapMsg *) incoming_msg; draw_x = render_info->clipped_x; draw_y = render_info->clipped_y; draw_width = render_info->clipped_width; draw_height = render_info->clipped_height; if (draw_width > 0 && draw_height > 0) { /* get incoming fb */ incoming_color = (GLubyte *) ((GLubyte *) incoming_msg + binaryswap_spu.offset); incoming_depth = (GLuint *) (incoming_color + draw_width * draw_height * 3); binaryswap_spu.super.WindowPos2iARB(draw_x, draw_y); /* Draw the depth image into the depth buffer, setting the stencil * to one wherever we pass the Z test, clearinging to zero where * we fail. */ binaryswap_spu.super.ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); binaryswap_spu.super.StencilOp(GL_KEEP, GL_ZERO, GL_REPLACE); binaryswap_spu.super.StencilFunc(GL_ALWAYS, 1, ~0); binaryswap_spu.super.Enable(GL_STENCIL_TEST); binaryswap_spu.super.Enable(GL_DEPTH_TEST); binaryswap_spu.super.DepthFunc(GL_LEQUAL); binaryswap_spu.super.DrawPixels(draw_width, draw_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, incoming_depth); /* Now draw the RGBA image, only where the stencil is one, reset * stencil to zero as we go * (to avoid calling glClear(STENCIL_BUFFER_BIT)). */ binaryswap_spu.super.Disable(GL_DEPTH_TEST); binaryswap_spu.super.StencilOp(GL_ZERO, GL_ZERO, GL_ZERO); binaryswap_spu.super.StencilFunc(GL_EQUAL, 1, ~0); binaryswap_spu.super.ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); binaryswap_spu.super.DrawPixels(draw_width, draw_height, GL_RGB, GL_UNSIGNED_BYTE, incoming_color); binaryswap_spu.super.Disable(GL_STENCIL_TEST); } } /* make sure everything got drawn for next pass */ binaryswap_spu.super.Flush(); /* find optimal starting point for readback based on this node's region and the partner's region */ recalc_start_x = render_info->start_x; if (startx < render_info->clipped_x) { recalc_temp = startx; } else { recalc_temp = render_info->clipped_x; if (render_info->clipped_width > 0 && render_info->clipped_height > 0) startx = recalc_temp; } if (recalc_temp > recalc_start_x) { recalc_start_x = recalc_temp; } recalc_start_y = render_info->start_y; if (starty < render_info->clipped_y) { recalc_temp = starty; } else { recalc_temp = render_info->clipped_y; if (render_info->clipped_width > 0 && render_info->clipped_height > 0) starty = recalc_temp; } if (recalc_temp > recalc_start_y) { recalc_start_y = recalc_temp; } /* find optimal ending point for readback based on * this node's region and the partner's region */ recalc_end_x = render_info->start_x + render_info->width; if (endx > (render_info->clipped_x + render_info->clipped_width)) { recalc_temp = endx; } else { recalc_temp = (render_info->clipped_x + render_info->clipped_width); if (render_info->clipped_width > 0 && render_info->clipped_height > 0) endx = recalc_temp; } if (recalc_end_x > recalc_temp) { recalc_end_x = recalc_temp; } recalc_end_y = render_info->start_y + render_info->height; if (endy > (render_info->clipped_y + render_info->clipped_height)) { recalc_temp = endy; } else { recalc_temp = (render_info->clipped_y + render_info->clipped_height); if (render_info->clipped_width > 0 && render_info->clipped_height > 0) endy = recalc_temp; } if (recalc_end_y > recalc_temp) { recalc_end_y = recalc_temp; } /* clean up the memory allocated for the recv */ crNetFree(binaryswap_spu.peer_recv[i], incoming_msg); } draw_x = recalc_start_x; draw_y = recalc_start_y; draw_width = recalc_end_x - recalc_start_x; draw_height = recalc_end_y - recalc_start_y; if (draw_width > 0 && draw_height > 0) { /* send our final portion off to child */ binaryswap_spu.super.ReadPixels(draw_x, draw_y, draw_width, draw_height, GL_RGB, GL_UNSIGNED_BYTE, window->msgBuffer + binaryswap_spu.offset); /* * Set the downstream viewport. If we don't do this, and the * downstream window is resized, the glRasterPos command doesn't * seem to be reliable. This is a problem both with Mesa and the * NVIDIA drivers. Technically, this may not be a driver bug at * all since we're doing funny stuff. Anyway, this fixes the problem. * Note that the width and height are arbitrary since we only care * about getting the origin right. glDrawPixels, glClear, etc don't * care what the viewport size is. (BrianP) */ CRASSERT(window->width > 0); CRASSERT(window->height > 0); /* Begin critical region */ binaryswap_spu.child.SemaphorePCR(MUTEX_SEMAPHORE); /* Update child window position, in case we're using the windowtracker * and VNC SPUs. */ { GLint pos[2]; binaryswap_spu.child.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, window->childWindow, GL_INT, 2, pos); if (pos[0] != window->child_xpos || pos[1] != window->child_ypos) { binaryswap_spu.child.WindowPosition(window->childWindow, pos[0], pos[1]); window->child_xpos = pos[0]; window->child_ypos = pos[1]; } } binaryswap_spu.child.WindowPos2iARB(draw_x, draw_y); binaryswap_spu.child.DrawPixels(draw_width, draw_height, GL_RGB, GL_UNSIGNED_BYTE, window->msgBuffer + binaryswap_spu.offset); /* end critical region */ binaryswap_spu.child.SemaphoreVCR(MUTEX_SEMAPHORE); } }
/* * 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 }