コード例 #1
0
ファイル: replicatespu_misc.c プロジェクト: alown/chromium
void REPLICATESPU_APIENTRY replicatespu_Finish( void )
{
	unsigned int i;
	GET_THREAD(thread);

	replicatespuFlushAll( (void *) thread );

	for (i = 0; i < CR_MAX_REPLICANTS; i++) {
		int writeback = 1;

		if (!IS_CONNECTED(replicate_spu.rserver[i].conn))
			continue;

		if (replicate_spu.swap) {
			crPackFinishSWAP();
			crPackWritebackSWAP( &writeback );
		}
		else {
			crPackFinish();
			crPackWriteback( &writeback );
		}

		replicatespuFlushOne(thread, i);

		while (writeback)
			crNetRecv();
	}
}
コード例 #2
0
void PACKSPU_APIENTRY packspu_Finish( void )
{
    GET_THREAD(thread);
    GLint writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;

    if (pack_spu.swap)
    {
        crPackFinishSWAP();
    }
    else
    {
        crPackFinish();
    }

    if (packspuSyncOnFlushes())
    {
        if (writeback)
        {
            if (pack_spu.swap)
                crPackWritebackSWAP(&writeback);
            else
                crPackWriteback(&writeback);

            packspuFlush( (void *) thread );

            while (writeback)
                crNetRecv();
        }
    }
}
コード例 #3
0
ファイル: tilesortspu_bcast.c プロジェクト: alown/chromium
/**
 * Implementation of glFinish for tilesorter
 */
void TILESORTSPU_APIENTRY tilesortspu_Finish(void)
{
	GET_THREAD(thread);
	GLint writeback = tilesort_spu.num_servers;
	tilesortspuFlush( thread );
	if (tilesort_spu.swap)
	{
		crPackFinishSWAP( );
	}
	else
	{
		crPackFinish( );
	}
	if (tilesort_spu.syncOnFinish)
	{
		if (tilesort_spu.swap)
		{
			crPackWritebackSWAP( &writeback );
		}
		else
		{
			crPackWriteback( &writeback );
		}
	}
	tilesortspuBroadcastGeom(0);
	tilesortspuShipBuffers();
	if (tilesort_spu.syncOnFinish)
	{
		while(writeback)
		{
			crNetRecv();
		}
	}
}
コード例 #4
0
void PACKSPU_APIENTRY packspu_Flush( void )
{
    GET_THREAD(thread);
    int writeback=1;
    int found=0;

    if (!thread->bInjectThread)
    {
        crPackFlush();
        if (packspuSyncOnFlushes())
        {
            crPackWriteback(&writeback);
            packspuFlush( (void *) thread );
            while (writeback)
                crNetRecv();
        }
    }
    else
    {
        int i;

        crLockMutex(&_PackMutex);

        /*Make sure we process commands in order they should appear, so flush other threads first*/
        for (i=0; i<MAX_THREADS; ++i)
        {
            if (pack_spu.thread[i].inUse
                && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
                && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
            {
                packspuFlush((void *) &pack_spu.thread[i]);

                if (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
                {
                    found=1;
                }

            }
        }

        if (!found)
        {
            /*Thread we're supposed to inject commands for has been detached,
              so there's nothing to sync with and we should just pass commands through our own connection.
             */
            thread->netServer.conn->u32InjectClientID=0;
        }

        packspuFlush((void *) thread);

        crUnlockMutex(&_PackMutex);
    }
}
コード例 #5
0
ファイル: net.c プロジェクト: L3oV1nc3/VMGL
/**
 * Get the next message from the given network connection.  If there isn't
 * one already in the linked list of received messages, call crNetRecv()
 * until we get something.
 *
 * \param message returns pointer to the message
 * \return total length of message (header + payload, in bytes)
 */
unsigned int
crNetGetMessage( CRConnection *conn, CRMessage **message )
{
	/* Keep getting work to do */
	for (;;)
	{
		int len = crNetPeekMessage( conn, message );
		if (len)
			return len;
		crNetRecv();
	}

	/* silence compiler */
	return 0;
}
コード例 #6
0
ファイル: main.c プロジェクト: boompig/chromium
int 
main( int argc, char *argv[] )
{
    char *mothership = NULL;
        
    crNetInit(crutProxyRecv, crutProxyClose);
    
    crutInitProxy(mothership);
  
    for (;;) 
	crNetRecv();	

#ifndef WINDOWS
    return 0;
#endif
}
コード例 #7
0
ファイル: net.c プロジェクト: boompig/chromium
/**
 * Get the next message from the given network connection.  If there isn't
 * one already in the linked list of received messages, call crNetRecv()
 * until we get something.
 *
 * \param message returns pointer to the message
 * \return total length of message (header + payload, in bytes)
 */
unsigned int
crNetGetMessage( CRConnection *conn, CRMessage **message )
{
	/* Keep getting work to do */
	for (;;)
	{
		int len = crNetPeekMessage( conn, message );
		if (len)
			return len;
		crNetRecv();
	}

#if !defined(WINDOWS) && !defined(IRIX) && !defined(IRIX64)
	/* silence compiler */
	return 0;
#endif
}
コード例 #8
0
ファイル: packspu_misc.c プロジェクト: L3oV1nc3/VMGL
GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
{
	static int num_calls = 0;
	int writeback = pack_spu.thread[0].netServer.conn->actual_network;
	GLint return_val = (GLint) 0;
	WindowInfo *WInfo;

	/* WindowCreate is special - just like CreateContext.
	 * GET_THREAD(thread) doesn't work as the thread won't have called
	 * MakeCurrent yet, so we've got to use the first thread's packer
	 * buffer.
	 */

	crPackSetContext( pack_spu.thread[0].packer );

	if (pack_spu.swap)
	{
		crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
	}
	else
	{
		crPackWindowCreate( dpyName, visBits, &return_val, &writeback );
	}
	packspuFlush( &pack_spu.thread[0] );
	if (!(pack_spu.thread[0].netServer.conn->actual_network))
	{
		return num_calls++;
	}
	else
	{
		while (writeback)
			crNetRecv();
		if (pack_spu.swap)
		{
			return_val = (GLint) SWAP32(return_val);
		}
		WInfo = (WindowInfo *) crAlloc(sizeof(WindowInfo));
		WInfo->XWindow = 0;
		WInfo->visual = visBits;
		crHashtableAdd(pack_spu.XWindows,return_val,WInfo);
		return return_val;
	}
}
コード例 #9
0
ファイル: replicatespu_pixel.c プロジェクト: alown/chromium
void REPLICATESPU_APIENTRY
replicatespu_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
												 GLenum format, GLenum type, GLvoid *pixels )
{
	GET_THREAD(thread);
	unsigned int i;
	ContextInfo *ctx = thread->currentContext;
	CRClientState *clientState = &(ctx->State->client);

	replicatespuFlushAll( (void *) thread );

	replicate_spu.ReadPixels++;

	/*
	 * Only send ReadPixels to one server, the first active one we find.
	 */

	for (i = 1; i < CR_MAX_REPLICANTS; i++) {
		/* hijack the current packer context */
		if (IS_CONNECTED(replicate_spu.rserver[i].conn)) {
			int writeback;

			if (replicate_spu.swap)
			{
				crPackReadPixelsSWAP( x, y, width, height, format, type, pixels,
							&(clientState->pack), &writeback );
			}
			else
			{
				crPackReadPixels( x, y, width, height, format, type, pixels,
							&(clientState->pack), &writeback );
			}
			replicatespuFlushOne(thread, i);

			while (replicate_spu.ReadPixels) 
				crNetRecv();

			/* Only need pixels from one server - all done now */
			return;
		}
	}
}
コード例 #10
0
ファイル: server_stream.c プロジェクト: L3oV1nc3/VMGL
/**
 * Check if any of the clients need servicing.
 * If so, service one client and return.
 * Else, just return.
 */
void
glStubServiceClients(void)
{
	RunQueue *q;

	q = getNextClient(GL_FALSE); /* don't block */
	if (q) {
		ClientStatus stat = glStubServiceClient(q);
		if (stat == CLIENT_NEXT && cr_server.run_queue->next) {
			/* advance to next client */
			cr_server.run_queue = cr_server.run_queue->next;
		}
	}
	else {
		/* no clients ready, do a receive and maybe we'll get a new
		 * client message
		 */
		crNetRecv();
	}
}
コード例 #11
0
ファイル: packspu_misc.c プロジェクト: L3oV1nc3/VMGL
void PACKSPU_APIENTRY packspu_Finish( void )
{
	GET_THREAD(thread);
	GLint writeback = pack_spu.thread[0].netServer.conn->actual_network;
	if (pack_spu.swap)
	{
		crPackFinishSWAP(  );
		if (writeback)
			crPackWritebackSWAP( &writeback );
	}
	else
	{
		crPackFinish(  );
		if (writeback)
			crPackWriteback( &writeback );
	}
	packspuFlush( (void *) thread );
	while (writeback)
		crNetRecv();
}
コード例 #12
0
GLboolean PACKSPU_APIENTRY
packspu_AreTexturesResident( GLsizei n, const GLuint * textures,
                                                         GLboolean * residences )
{
    GET_THREAD(thread);
    int writeback = 1;
    GLboolean return_val = GL_TRUE;
    GLsizei i;

    if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
    {
        crError( "packspu_AreTexturesResident doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
    }

    if (pack_spu.swap)
    {
        crPackAreTexturesResidentSWAP( n, textures, residences, &return_val, &writeback );
    }
    else
    {
        crPackAreTexturesResident( n, textures, residences, &return_val, &writeback );
    }
    packspuFlush( (void *) thread );

    while (writeback)
        crNetRecv();

    /* Since the Chromium packer/unpacker can't return both 'residences'
     * and the function's return value, compute the return value here.
     */
    for (i = 0; i < n; i++) {
        if (!residences[i]) {
            return_val = GL_FALSE;
            break;
        }
    }

    return return_val;
}
コード例 #13
0
GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
{
    GET_THREAD(thread);
    static int num_calls = 0;
    int writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
    GLint return_val = (GLint) 0;

    if (!thread) {
        thread = packspuNewThread( crThreadID() );
    }
    CRASSERT(thread);
    CRASSERT(thread->packer);

    crPackSetContext(thread->packer);

    if (pack_spu.swap)
    {
        crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
    }
    else
    {
        crPackWindowCreate( dpyName, visBits, &return_val, &writeback );
    }
    packspuFlush(thread);
    if (!(thread->netServer.conn->actual_network))
    {
        return num_calls++;
    }
    else
    {
        while (writeback)
            crNetRecv();
        if (pack_spu.swap)
        {
            return_val = (GLint) SWAP32(return_val);
        }
        return return_val;
    }
}
コード例 #14
0
void PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
{
    GET_THREAD(thread);
    int writeback = 1;

    if (pack_spu.swap)
    {
        crPackGetPixelMapusvSWAP( map, values, &writeback );
    }
    else
    {
        crPackGetPixelMapusv( map, values, &writeback );
    }

#ifdef CR_ARB_pixel_buffer_object
    if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
    {
        packspuFlush( (void *) thread );
        while (writeback)
            crNetRecv();
    }
}
コード例 #15
0
void PACKSPU_APIENTRY packspu_GetPolygonStipple( GLubyte * mask )
{
    GET_THREAD(thread);
    int writeback = 1;

    if (pack_spu.swap)
    {
        crPackGetPolygonStippleSWAP( mask, &writeback );
    }
    else
    {
        crPackGetPolygonStipple( mask, &writeback );
    }

#ifdef CR_ARB_pixel_buffer_object
    if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
    {
        packspuFlush( (void *) thread );
        while (writeback)
            crNetRecv();
    }
}
コード例 #16
0
/**
 * Callback called by crHashTableWalk() below.
 * Used to create viewer-side windows for all the application windows.
 */
static void
replicatespuReplicateWindow(unsigned long key, void *data1, void *data2)
{
	ThreadInfo *thread = (ThreadInfo *) data2;
	WindowInfo *winInfo = (WindowInfo *) data1;
	GLint window = 0;
	GLint writeback = 1;
	Window root;
	int x, y;
	unsigned int width, height, bw, d;
	GLboolean unviewable = GL_FALSE;
	XWindowAttributes winAtt;

	CRASSERT(NewServerIndex >= 0);

	/* clear this flag, in case it was still set from an old connection */
	winInfo->writeback[NewServerIndex] = 0;

	/**
	 * Get application window's attributes
	 */
	old_xerror_handler = XSetErrorHandler( x11_error_handler );
	XSync(replicate_spu.glx_display, 0);
	XGetGeometry(replicate_spu.glx_display, (Window)winInfo->nativeWindow,
							 &root, &x, &y, &width, &height, &bw, &d );
	XGetWindowAttributes(replicate_spu.glx_display,
											 (Window) winInfo->nativeWindow, &winAtt);
	XSetErrorHandler( old_xerror_handler );
	if (!caught_x11_error) {
		 unviewable = (winAtt.map_state == IsUnviewable);
	}
	caught_x11_error = 0;

	/*
	 * Create the server-side window
	 */
	if (replicate_spu.swap)
		crPackWindowCreateSWAP( replicate_spu.dpyName, winInfo->visBits, &window, &writeback);
	else
		crPackWindowCreate( replicate_spu.dpyName, winInfo->visBits, &window, &writeback);

	replicatespuFlushOne(thread, NewServerIndex);

	/* Get return value */
	while (writeback) {
		crNetRecv();
	}
	if (replicate_spu.swap)
		window = (GLint) SWAP32(window);

	/* save the server-side window ID */
	winInfo->id[NewServerIndex] = window;

	crDebug("Replicate SPU: created server-side window %d", window);

	if (window < 0) {
		crWarning("Replicate SPU: failed to create server-side window");
		return;
	}

	XVncChromiumMonitor(replicate_spu.glx_display,
											window, winInfo->nativeWindow);

	/*
	 * If the app window is not visible, hide the server-side window too.
	 */
	if (unviewable)
	{
		if (replicate_spu.swap)
			crPackWindowShowSWAP( window, GL_FALSE );
		else
			crPackWindowShow( window, GL_FALSE );
		
		replicatespuFlushOne(thread, NewServerIndex);
	}
}
コード例 #17
0
ファイル: server_stream.c プロジェクト: L3oV1nc3/VMGL
/**
 * Find the next client in the run queue that's not blocked and has a
 * waiting message.
 * Check if all clients are blocked (on barriers, semaphores), if so we've
 * deadlocked!
 * If no clients have a waiting message, call crNetRecv to get something
 * if 'block' is true, else return NULL if 'block' if false.
 */
static RunQueue *
getNextClient(GLboolean block)
{
	while (1)
	{
		if (cr_server.run_queue) 
		{
			GLboolean all_blocked = GL_TRUE;
			GLboolean done_something = GL_FALSE;
			RunQueue *start = cr_server.run_queue;

			/* check if this client's connection has gone away */
 			if (!cr_server.run_queue->client->conn
					 || (cr_server.run_queue->client->conn->type == CR_NO_CONNECTION
							 && crNetNumMessages(cr_server.run_queue->client->conn) == 0)) {
 				glStubDeleteClient( cr_server.run_queue->client );
				start = cr_server.run_queue;
			}
 
 			if (cr_server.run_queue == NULL) {
				/* empty queue */
 				return NULL;
			}

			if (glStubClientInBeginEnd(cr_server.run_queue->client)) {
				/* We _must_ service this client and no other.
				 * If we've got a message waiting on this client's connection we'll
				 * service it.  Else, return NULL.
				 */
				if (crNetNumMessages(cr_server.run_queue->client->conn) > 0)
					return cr_server.run_queue;
				else
					return NULL;
			}

			/* loop over entries in run queue, looking for next one that's ready */
			while (!done_something || cr_server.run_queue != start)
			{
				done_something = GL_TRUE;
				if (!cr_server.run_queue->blocked)
				{
					all_blocked = GL_FALSE;
				}
				if (!cr_server.run_queue->blocked
						&& cr_server.run_queue->client->conn
						&& crNetNumMessages(cr_server.run_queue->client->conn) > 0)
				{
					/* OK, this client isn't blocked and has a queued message */
					return cr_server.run_queue;
				}
				cr_server.run_queue = cr_server.run_queue->next;
			}

			if (all_blocked)
			{
				crWarning( "GLStub: DEADLOCK! (numClients=%d, all blocked)",
									 cr_server.numClients );
				if (cr_server.numClients < (int) cr_server.maxBarrierCount) {
					if (cr_server.exitIfNoClients) {
						crWarning("GLStub: exiting.");
						exit(0);
					}
					crWarning("GLStub: Waiting for more clients.");
					while (cr_server.numClients < (int) cr_server.maxBarrierCount) {
						crNetRecv();
					}
				}
			}
		}

		if (!block)
			 return NULL;

		/* no one had any work, get some! */
		crNetRecv();

	} /* while */

	/* UNREACHED */
	/* return NULL; */
}
コード例 #18
0
ファイル: tilesortspu_swap.c プロジェクト: alown/chromium
/**
 * Implementation of SwapBuffers for tilesorter
 *
 * \param window
 * \param flags
 */
void TILESORTSPU_APIENTRY tilesortspu_SwapBuffers( GLint window, GLint flags )
{
	GET_THREAD(thread);
	GLint writeback = tilesort_spu.num_servers;
	WindowInfo *winInfo;
	int serverWindow;

	tilesortspuFlush( thread );

	winInfo = tilesortspuGetWindowInfo(window, 0);
	CRASSERT(winInfo);
	/* NOTE: winInfo->server[n].window should be the same for all n! */
	serverWindow = winInfo->server[0].window;

	/* Here's where we force quad-buffered stereo rendering.
	 * We use an X trick to make the app draw each frame twice.
	 */
	if (winInfo->forceQuadBuffering) {
		if (winInfo->parity == 0) {
			/* we're swapping after drawing an even-numbered frame.
			 * Even frames are for left eye, odd frames are for right eye.
			 * Now, switch draw buffer to the right.
			 */
			/*
			crDebug("Swap: done with left.  Send expose to 0x%x",
							(int) winInfo->xwin);
			*/
			tilesortspu_DrawBuffer(GL_BACK_RIGHT);
			/*
			 * Trigger drawing the right view by sending an expose event to
			 * the app to trick it into redrawing.
			 */
#ifdef WINDOWS
			/** XXX \todo is there a Window equivalent here??? */
#elif defined(Darwin)
			/** XXX \todo is there a Darwin equivalent here??? */
#else
			CRASSERT(winInfo->dpy);
			CRASSERT(winInfo->xwin);
			XClearArea( winInfo->dpy, winInfo->xwin, 0, 0,
				    winInfo->lastWidth, winInfo->lastHeight,
				    True );
			XSync(winInfo->dpy, 0);
#endif
		}
		else
		{
			/*
			crDebug("Swap: done with right, now left");
			*/
			/* We're swapping after drawing an odd frame.
			 * Now, switch draw buffer back to the left.
			 */
			tilesortspu_DrawBuffer(GL_BACK_LEFT);
		}
		/* flip parity bit for next frame */
		winInfo->parity = !winInfo->parity;

		/* only swap prior to even (left) frames */
		if (winInfo->parity)
			return;
	}

	if (tilesort_spu.swap)
		crPackSwapBuffersSWAP( serverWindow, flags );
	else
		crPackSwapBuffers( serverWindow, flags );

	if (tilesort_spu.syncOnSwap)
	{
		if (tilesort_spu.swap)
			crPackWritebackSWAP( &writeback );
		else
			crPackWriteback( &writeback );
	}

	tilesortspuBroadcastGeom(0);
	tilesortspuShipBuffers();

	if (tilesort_spu.syncOnSwap)
	{
		while(writeback)
			crNetRecv();
	}

	/* want to emit a parameteri here */
	if (tilesort_spu.emit_GATHER_POST_SWAPBUFFERS)
	{
		if (tilesort_spu.swap)
			crPackChromiumParameteriCRSWAP(GL_GATHER_POST_SWAPBUFFERS_CR, serverWindow);
		else
			crPackChromiumParameteriCR(GL_GATHER_POST_SWAPBUFFERS_CR, serverWindow);
	}
}
コード例 #19
0
GLint PACKSPU_APIENTRY
packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
{
    GET_THREAD(thread);
    int writeback = 1;
    GLint serverCtx = (GLint) -1;
    int slot;

#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&_PackMutex);
#endif

    if (!thread) {
        thread = packspuNewThread(crThreadID());
    }
    CRASSERT(thread);
    CRASSERT(thread->packer);

    if (shareCtx > 0) {
        /* translate to server ctx id */
        shareCtx -= MAGIC_OFFSET;
        if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
            shareCtx = pack_spu.context[shareCtx].serverCtx;
        }
    }

    crPackSetContext( thread->packer );

    /* Pack the command */
    if (pack_spu.swap)
        crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
    else
        crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );

    /* Flush buffer and get return value */
    packspuFlush(thread);
    if (!(thread->netServer.conn->actual_network))
    {
        /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
         *
         * The hack exists solely to make file networking work for now.  This
         * is totally gross, but since the server expects the numbers to start
         * from 5000, we need to write them out this way.  This would be
         * marginally less gross if the numbers (500 and 5000) were maybe
         * some sort of #define'd constants somewhere so the client and the
         * server could be aware of how each other were numbering things in
         * cases like file networking where they actually
         * care. 
         *
         *  -Humper 
         *
         */
        serverCtx = 5000;
    }
    else {
        while (writeback)
            crNetRecv();

        if (pack_spu.swap) {
            serverCtx = (GLint) SWAP32(serverCtx);
        }
        if (serverCtx < 0) {
#ifdef CHROMIUM_THREADSAFE
            crUnlockMutex(&_PackMutex);
#endif
            crWarning("Failure in packspu_CreateContext");
            return -1;  /* failed */
        }
    }

    /* find an empty context slot */
    for (slot = 0; slot < pack_spu.numContexts; slot++) {
        if (!pack_spu.context[slot].clientState) {
            /* found empty slot */
            break;
        }
    }
    if (slot == pack_spu.numContexts) {
        pack_spu.numContexts++;
    }

    /* Fill in the new context info */
    /* XXX fix-up sharedCtx param here */
    pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
    pack_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE;
    pack_spu.context[slot].serverCtx = serverCtx;

#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&_PackMutex);
#endif

    return MAGIC_OFFSET + slot;
}
コード例 #20
0
ファイル: replicatespu_misc.c プロジェクト: alown/chromium
GLint REPLICATESPU_APIENTRY
replicatespu_WindowCreate( const char *dpyName, GLint visBits )
{
	unsigned int i;
	static GLint freeWinID = 400;
	WindowInfo *winInfo = (WindowInfo *) crCalloc(sizeof(WindowInfo));
	GET_THREAD(thread);

	if (!winInfo)
		return -1;

	if (thread)
		replicatespuFlushAll( (void *) thread );
	else
		thread = replicatespuNewThread( crThreadID() );

	replicatespuFlushAll( (void *) thread );
	crPackSetContext( thread->packer );

#ifdef CHROMIUM_THREADSAFE_notyet
	crLockMutex(&_ReplicateMutex);
#endif

	for (i = 1; i < CR_MAX_REPLICANTS; i++) {
		if (IS_CONNECTED(replicate_spu.rserver[i].conn)) {
			int writeback = 1;
			int return_val = -1;

			if (replicate_spu.swap)
				crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
			else
				crPackWindowCreate( dpyName, visBits, &return_val, &writeback );

			replicatespuFlushOne(thread, i);

			while (writeback)
				crNetRecv();

			if (replicate_spu.swap)
				return_val = (GLint) SWAP32(return_val);

			if (return_val < 0)
				crWarning("Replicate SPU: server %d returned window id -1", i);

			/* XXX temp */
			crDebug("Replicate SPU: Window create, server %d returned %d", i, return_val);
			winInfo->id[i] = return_val;
		}
		else {
			winInfo->id[i] = -1;
		}
	}

	winInfo->visBits = visBits;
	winInfo->width = 0;
	winInfo->height = 0;
	winInfo->nativeWindow = 0;
	winInfo->viewable = GL_FALSE; 

	crHashtableAdd(replicate_spu.windowTable, freeWinID, winInfo);

#ifdef CHROMIUM_THREADSAFE_notyet
	crUnlockMutex(&_ReplicateMutex);
#endif

	return freeWinID++;
}
コード例 #21
0
/**
 * Replicate our contexts on a new server (indicated by NewServerIndex).
 * XXX It may be a problem if we try to attach to a shared context,
 * when that shared context has not yet been created.
 */
static void
replicatespuReplicateContext(void *element, void *arg)
{
	GLint ctx = (GLint) element;
	ThreadInfo *thread = (ThreadInfo *) arg;
	ContextInfo *context = crHashtableSearch(replicate_spu.contextTable, ctx);
	ContextInfo *sharedContext = NULL;
	CRContext *tempState;
	GLint return_val = 0, shareCtx = context->shareCtx, sharedServerCtx = 0;
	int writeback;

	if (!context->State) { /* XXX need this? */
		crWarning("ReplicateSPU: replicating context with no state!");
		return;
	}

	if (shareCtx > 0) {
		sharedContext = (ContextInfo *)
			crHashtableSearch(replicate_spu.contextTable, shareCtx);
		if (sharedContext)
			sharedServerCtx = sharedContext->rserverCtx[NewServerIndex];
	}


	/*
	 * Send CreateContext to new server and get return value
	 */
	if (replicate_spu.swap)
		crPackCreateContextSWAP( replicate_spu.dpyName, context->visBits,
														 sharedServerCtx, &return_val, &writeback);
	else
		crPackCreateContext( replicate_spu.dpyName, context->visBits,
												 sharedServerCtx, &return_val, &writeback);
	replicatespuFlushOne(thread, NewServerIndex);
	writeback = 1;
	while (writeback)
		crNetRecv();
	if (replicate_spu.swap)
		return_val = (GLint) SWAP32(return_val);
	if (return_val <= 0) {
		crWarning("Replicate SPU: CreateContext failed");
		return;
	}

	context->rserverCtx[NewServerIndex] = return_val;

	/*
	 * Create a new CRContext record representing the state of the new
	 * server (all default state).  We'll diff against this to send all the
	 * needed state to the server.
	 * When done, we can dispose of this context.
	 */
	tempState = crStateCreateContext(NULL, context->visBits, NULL);

	/* Bind the remote context. The window's not really significant. */
	{
		int serverWindow;
		if (context->currentWindow)
			serverWindow = context->currentWindow->id[NewServerIndex];
		else
			serverWindow = 0;

		if (replicate_spu.swap)
			crPackMakeCurrentSWAP( serverWindow, 0, return_val );
		else
			crPackMakeCurrent( serverWindow, 0, return_val );
	}

	/* Send state differences, all texture objects and all display lists
	 * to the new server.
	 * XXX We could be more efficient; in the case of a shared context,
	 * we only need to replicate textures and display lists once...
	 */
	crStateDiffContext( tempState, context->State );
	replicatespuReplicateTextures(tempState, context->State);
	replicatespuReplicateLists(tempState, context->displayListManager);
			
	/* XXX this call may not be needed */
	replicatespuFlushOne(thread, NewServerIndex);

	/* Destroy the temporary context, no longer needed */
	crStateDestroyContext( tempState );
}
コード例 #22
0
ファイル: server_main.c プロジェクト: LastRitter/vbox-haiku
int32_t crVBoxServerClientWrite(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t cbBuffer)
{
    CRClient *pClient = NULL;
    int32_t i;
#ifdef VBOXCR_LOGFPS
    uint64_t tstart, tend;
#endif

    /*crDebug("=>crServer: ClientWrite u32ClientID=%d", u32ClientID);*/

    for (i = 0; i < cr_server.numClients; i++)
    {
        if (cr_server.clients[i] && cr_server.clients[i]->conn
            && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
        {
            pClient = cr_server.clients[i];
            break;
        }
    }
    if (!pClient) return VERR_INVALID_PARAMETER;

    if (!pClient->conn->vMajor) return VERR_NOT_SUPPORTED;

#ifdef VBOXCR_LOGFPS
    tstart = RTTimeNanoTS();
#endif

    CRASSERT(pBuffer);

    /* This should never fire unless we start to multithread */
    CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);

    /* Check if there's a blocker in queue and it's not this client */
    if (cr_server.run_queue->client != pClient
        && crServerClientInBeginEnd(cr_server.run_queue->client))
    {
        crDebug("crServer: client %d blocked, allow_redir_ptr = 0", u32ClientID);
        pClient->conn->allow_redir_ptr = 0;
    }
    else
    {
        pClient->conn->allow_redir_ptr = 1;
    }

    pClient->conn->pBuffer = pBuffer;
    pClient->conn->cbBuffer = cbBuffer;

    crNetRecv();
    CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);

    crServerServiceClients();

#if 0
        if (pClient->currentMural) {
            crStateViewport( 0, 0, 500, 500 );
            pClient->currentMural->viewportValidated = GL_FALSE;
            cr_server.head_spu->dispatch_table.Viewport( 0, 0, 500, 500 );
            crStateViewport( 0, 0, 600, 600 );
            pClient->currentMural->viewportValidated = GL_FALSE;
            cr_server.head_spu->dispatch_table.Viewport( 0, 0, 600, 600 );

            crStateMatrixMode(GL_PROJECTION);
            cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
            crServerDispatchLoadIdentity();
            crStateFrustum(-0.6, 0.6, -0.5, 0.5, 1.5, 150.0);
            cr_server.head_spu->dispatch_table.Frustum(-0.6, 0.6, -0.5, 0.5, 1.5, 150.0);
            crServerDispatchLoadIdentity();
            crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);

            crStateMatrixMode(GL_MODELVIEW);
            cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
            crServerDispatchLoadIdentity();
            crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            crServerDispatchLoadIdentity();
        }
#endif

    crStateResetCurrentPointers(&cr_server.current);

    CRASSERT(!pClient->conn->allow_redir_ptr || crNetNumMessages(pClient->conn)==0);

#ifdef VBOXCR_LOGFPS
    tend = RTTimeNanoTS();
    pClient->timeUsed += tend-tstart;
#endif
    /*crDebug("<=crServer: ClientWrite u32ClientID=%d", u32ClientID);*/

    return VINF_SUCCESS;
}
コード例 #23
0
ファイル: replicatespu_context.c プロジェクト: alown/chromium
GLint REPLICATESPU_APIENTRY
replicatespu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
{
	static GLint freeCtxID = MAGIC_OFFSET;
	char headspuname[10];
	ContextInfo *context, *sharedContext = NULL;
	unsigned int i;

	if (shareCtx > 0) {
		sharedContext = (ContextInfo *)
			crHashtableSearch(replicate_spu.contextTable, shareCtx);
	}

	replicatespuFlushAll( &(replicate_spu.thread[0]) );

#ifdef CHROMIUM_THREADSAFE_notyet
	crLockMutex(&_ReplicateMutex);
#endif

	replicatespuStartVnc(dpyName);

	/*
	 * Alloc new ContextInfo object
	 */
	context = (ContextInfo *) crCalloc(sizeof(ContextInfo));
	if (!context) {
		crWarning("Replicate SPU: Out of memory in CreateContext");
		return -1;
	}

	/* Contexts that don't share display lists get their own
	 * display list managers.  Contexts that do, share the
	 * display list managers of the contexts they're sharing
	 * with (man, some grammarian has to go over that and make
	 * it actually sound like English).
	 */
	if (sharedContext) {
		context->displayListManager = sharedContext->displayListManager;
		/* Let the DLM know that a second context is using the
		 * same display list manager, so it can manage when its
		 * resources are released.
		 */
		crDLMUseDLM(context->displayListManager);
	}
	else {
		context->displayListManager = crDLMNewDLM(0, NULL);
		if (!context->displayListManager) {
			crWarning("Replicate SPU: could not initialize display list manager.");
		}
	}

	/* Fill in the new context info */
	if (sharedContext)
		context->State = crStateCreateContext(NULL, visual, sharedContext->State);
	else
		context->State = crStateCreateContext(NULL, visual, NULL);
	context->rserverCtx[0] = 1; /* not really used */
	context->visBits = visual;
	context->currentWindow = 0; /* not bound */
	context->dlmState
		= crDLMNewContext(context->displayListManager);
	context->displayListMode = GL_FALSE; /* not compiling */
	context->displayListIdentifier = 0;
	context->shareCtx = shareCtx;

#if 0
	/* Set the Current pointers now.... */
	crStateSetCurrentPointers( context->State,
														 &(replicate_spu.thread[0].packer->current) );
#endif

	for (i = 1; i < CR_MAX_REPLICANTS; i++) {
		int r_writeback = 1, rserverCtx = -1;
		int sharedServerCtx;

		sharedServerCtx = sharedContext ? sharedContext->rserverCtx[i] : 0;

		if (!IS_CONNECTED(replicate_spu.rserver[i].conn))
			continue;

		if (replicate_spu.swap)
			crPackCreateContextSWAP( dpyName, visual, sharedServerCtx,
															 &rserverCtx, &r_writeback );
		else
			crPackCreateContext( dpyName, visual, sharedServerCtx,
													 &rserverCtx, &r_writeback );

		/* Flush buffer and get return value */
		replicatespuFlushOne( &(replicate_spu.thread[0]), i );

		while (r_writeback)
			crNetRecv();
		if (replicate_spu.swap)
			rserverCtx = (GLint) SWAP32(rserverCtx);

		if (rserverCtx < 0) {
#ifdef CHROMIUM_THREADSAFE_notyet
			crUnlockMutex(&_ReplicateMutex);
#endif
			crWarning("Replicate SPU: CreateContext failed.");
			return -1;  /* failed */
		}

		context->rserverCtx[i] = rserverCtx;
	}


	if (!crStrcmp( headspuname, "nop" ))
		replicate_spu.NOP = 0;
	else
		replicate_spu.NOP = 1;

#ifdef CHROMIUM_THREADSAFE_notyet
	crUnlockMutex(&_ReplicateMutex);
#endif

	crListPushBack(replicate_spu.contextList, (void *)freeCtxID);
	crHashtableAdd(replicate_spu.contextTable, freeCtxID, context);

	return freeCtxID++;
}