示例#1
0
文件: renderspu.c 项目: apaka/vbox
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);
    }
}
示例#2
0
/**
 * 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 );
}
示例#4
0
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);
    }


}
示例#5
0
文件: crutapi.c 项目: alown/chromium
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 );
    }
}
示例#6
0
/*
 * 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);
	}
}
示例#7
0
/*
 * 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;
}
示例#8
0
文件: net.c 项目: L3oV1nc3/VMGL
/**
 * 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 );
}
示例#9
0
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 );
}
示例#10
0
/*
 * 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);
}
示例#11
0
/**
 * 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);
}
示例#12
0
/**
 * 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);
	}
}
示例#13
0
/*
 * 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
}