Example #1
0
/**
 * Process incoming/pending message for the given client (queue entry).
 * \return CLIENT_GONE if this client has gone away/exited,
 *         CLIENT_NEXT if we can advance to the next client
 *         CLIENT_MORE if we have to process more messages for this client. 
 */
static ClientStatus
crServerServiceClient(const RunQueue *qEntry)
{
	CRMessage *msg;
	CRConnection *conn;

	/* set current client pointer */
	cr_server.curClient = qEntry->client;

	conn = cr_server.run_queue->client->conn;

	/* service current client as long as we can */
	while (conn && conn->type != CR_NO_CONNECTION &&
				 crNetNumMessages(conn) > 0) {
		unsigned int len;

		/*
		crDebug("%d messages on %p",
						crNetNumMessages(conn), (void *) conn);
		*/

		/* Don't use GetMessage, because we want to do our own crNetRecv() calls
		 * here ourself.
		 * Note that crNetPeekMessage() DOES remove the message from the queue
		 * if there is one.
		 */
		len = crNetPeekMessage( conn, &msg );
		CRASSERT(len > 0);
		if (msg->header.type != CR_MESSAGE_OPCODES) {
			crError( "SPU %d sent me CRAP (type=0x%x)",
							 cr_server.curClient->spu_id, msg->header.type );
		}

		/* Do the context switch here.  No sense in switching before we
		 * really have any work to process.  This is a no-op if we're
		 * not really switching contexts.
		 *
		 * XXX This isn't entirely sound.  The crStateMakeCurrent() call
		 * will compute the state difference and dispatch it using
		 * the head SPU's dispatch table.
		 *
		 * This is a problem if this is the first buffer coming in,
		 * and the head SPU hasn't had a chance to do a MakeCurrent()
		 * yet (likely because the MakeCurrent() command is in the
		 * buffer itself).
		 *
		 * At best, in this case, the functions are no-ops, and
		 * are essentially ignored by the SPU.  In the typical
		 * case, things aren't too bad; if the SPU just calls
		 * crState*() functions to update local state, everything
		 * will work just fine.
		 *
		 * In the worst (but unusual) case where a nontrivial
		 * SPU is at the head of a crserver's SPU chain (say,
		 * in a multiple-tiered "tilesort" arrangement, as
		 * seen in the "multitilesort.conf" configuration), the
		 * SPU may rely on state set during the MakeCurrent() that
		 * may not be present yet, because no MakeCurrent() has
		 * yet been dispatched.
		 *
		 * This headache will have to be revisited in the future;
		 * for now, SPUs that could head a crserver's SPU chain
		 * will have to detect the case that their functions are
		 * being called outside of a MakeCurrent(), and will have
		 * to handle the situation gracefully.  (This is currently
		 * the case with the "tilesort" SPU.)
		 */

#if 0
		crStateMakeCurrent( cr_server.curClient->currentCtx );
#else
		crStateMakeCurrent( cr_server.curClient->currentCtx );

		/* Check if the current window is the one that the client wants to
		 * draw into.  If not, dispatch a MakeCurrent to activate the proper
		 * window.
		 */
		if (cr_server.curClient) {
			 int clientWindow = cr_server.curClient->currentWindow;
			 int clientContext = cr_server.curClient->currentContextNumber;
			 if (clientWindow && clientWindow != cr_server.currentWindow) {
				 crServerDispatchMakeCurrent(clientWindow, 0, clientContext);
				 /*
				 CRASSERT(cr_server.currentWindow == clientWindow);
				 */
			 }
		}
#endif

		/* Force scissor, viewport and projection matrix update in
		 * crServerSetOutputBounds().
		 */
		cr_server.currentSerialNo = 0;

		/* Commands get dispatched here */
		crServerDispatchMessage(msg);

		crNetFree( conn, msg );

		if (qEntry->blocked) {
			/* Note/assert: we should not be inside a glBegin/End or glNewList/
			 * glEndList pair at this time!
			 */
			return CLIENT_NEXT;
		}

	} /* while */

	/*
	 * Check if client/connection is gone
	 */
	if (!conn || conn->type == CR_NO_CONNECTION) {
		crDebug("Delete client %p at %d", cr_server.run_queue->client, __LINE__);
		crServerDeleteClient( cr_server.run_queue->client );
		return CLIENT_GONE;
	}

	/*
	 * Determine if we can advance to next client.
	 * If we're currently inside a glBegin/End primitive or building a display
	 * list we can't service another client until we're done with the
	 * primitive/list.
	 */
	if (crServerClientInBeginEnd(cr_server.curClient)) {
		/* The next message has to come from the current client's connection. */
		CRASSERT(!qEntry->blocked);
		return CLIENT_MORE;
	}
	else {
		/* get next client */
		return CLIENT_NEXT;
	}
}
Example #2
0
/**
 * Receive the next message on the given connection.
 * If we're being called by crSDPRecv(), we already know there's
 * something to receive.
 */
static void
crSDPReceiveMessage(CRConnection *conn)
{
	CRMessage *msg;
	CRMessageType cached_type;
	CRSDPBuffer *sdp_buffer;
	unsigned int len, total, leftover;
	const CRSocket sock = conn->sdp_socket;

	/* this reads the length of the message */
	if ( __sdp_read_exact( sock, &len, sizeof(len)) <= 0 )
	{
		__sdp_dead_connection( conn );
		return;
	}

	if (conn->swap)
		len = SWAP32(len);

	CRASSERT( len > 0 );

	if ( len <= conn->buffer_size )
	{
		sdp_buffer = (CRSDPBuffer *) crSDPAlloc( conn ) - 1;
		CRASSERT(sdp_buffer->magic == CR_SDP_BUFFER_MAGIC);
		CRASSERT(sdp_buffer->allocated > 0);
	}
	else
	{
		crWarning("Sending as BIG, the performance is going to tank!!!.  You need larger buffers!!!");
		sdp_buffer = (CRSDPBuffer *) crAlloc( sizeof(*sdp_buffer) + len );
		sdp_buffer->magic = CR_SDP_BUFFER_MAGIC;
		sdp_buffer->kind  = CRSDPMemoryBig;
		sdp_buffer->pad   = 0;
	}

	sdp_buffer->len = len;

	/* if we have set a userbuf, and there is room in it, we probably 
	 * want to stick the message into that, instead of our allocated
	 * buffer.  */
	leftover = 0;
	total = len;
	if ((conn->userbuf != NULL) && (conn->userbuf_len >= (int) sizeof(CRMessageHeader)))
	{
		leftover = len - sizeof(CRMessageHeader);
		total = sizeof(CRMessageHeader);
	}
	if ( __sdp_read_exact( sock, sdp_buffer + 1, total) <= 0 )
	{
		crWarning( "Bad juju: %d %d on sock %x", sdp_buffer->allocated, total, sock );
		crFree( sdp_buffer );
		__sdp_dead_connection( conn );
		return;
	}

	conn->recv_credits -= total;
	conn->total_bytes_recv +=  total;
    
	msg = (CRMessage *) (sdp_buffer + 1);
	cached_type = msg->header.type;
	if (conn->swap)
	{
		msg->header.type = (CRMessageType) SWAP32( msg->header.type );
		msg->header.conn_id = (CRMessageType) SWAP32( msg->header.conn_id );
	}
    
	/* if there is still data pending, it should go into the user buffer */
	if (leftover)
	{
		unsigned int handled = crSDPUserbufRecv(conn, msg);
      
		/* if there is anything left, plop it into the recv_buffer */
		if (leftover - handled)
		{
			if ( __sdp_read_exact( sock, sdp_buffer + 1 + total, leftover-handled) <= 0 )
			{
				crWarning( "Bad juju: %d %d", sdp_buffer->allocated, leftover-handled);
				crFree( sdp_buffer );
				__sdp_dead_connection( conn );
				return;
			}
		}

		conn->recv_credits -= handled;
		conn->total_bytes_recv +=  handled;
	}

	crNetDispatchMessage( cr_sdp.recv_list, conn, msg, len );

	/* CR_MESSAGE_OPCODES is freed in crserverlib/server_stream.c with crNetFree.
	 * OOB messages are the programmer's problem.  -- Humper 12/17/01
	 */
	if (cached_type != CR_MESSAGE_OPCODES && cached_type != CR_MESSAGE_OOB
			&&	cached_type != CR_MESSAGE_GATHER) 
	{
		crSDPFree( conn, sdp_buffer + 1 );
	}
}
static DWORD WINAPI renderSPUWindowThreadProc(void* unused)
{
    MSG msg;
    bool bRet;

    (void) unused;

    /* Force system to create the message queue.
     * Else, there's a chance that render spu will issue PostThreadMessage
     * before this thread calls GetMessage for first time.
     */
    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

    crDebug("RenderSPU: Window thread started (%x)", crThreadID());
    SetEvent(render_spu.hWinThreadReadyEvent);

    while( (bRet = GetMessage( &msg, 0, 0, 0 )) != 0)
    {
        if (bRet == -1)
        {
            crError("RenderSPU: Window thread GetMessage failed (%x)", GetLastError());
            break;
        }
        else
        {
            if (msg.message == WM_VBOX_RENDERSPU_CREATE_WINDOW)
            {
                LPCREATESTRUCT pCS = (LPCREATESTRUCT) msg.lParam;
                HWND *phWnd;

                CRASSERT(msg.lParam && !msg.wParam && pCS->lpCreateParams);

                phWnd = pCS->lpCreateParams;

                *phWnd = CreateWindowEx(pCS->dwExStyle, pCS->lpszName, pCS->lpszClass, pCS->style,
                                        pCS->x, pCS->y, pCS->cx, pCS->cy,
                                        pCS->hwndParent, pCS->hMenu, pCS->hInstance, &render_spu);

                SetEvent(render_spu.hWinThreadReadyEvent);
            }
            else if (msg.message == WM_VBOX_RENDERSPU_DESTROY_WINDOW)
            {
                CRASSERT(msg.lParam && !msg.wParam);

                DestroyWindow(((VBOX_RENDERSPU_DESTROY_WINDOW*) msg.lParam)->hWnd);

                SetEvent(render_spu.hWinThreadReadyEvent);
            }
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }

    render_spu.dwWinThreadId = 0;

    crDebug("RenderSPU: Window thread stopped (%x)", crThreadID());
    SetEvent(render_spu.hWinThreadReadyEvent);

    return 0;
}
Example #4
0
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;
}
Example #5
0
DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version)
{
    int32_t  rc, i;
    uint32_t ui, uiNumElems;
    unsigned long key;

    if (!cr_server.bIsInLoadingState)
    {
        /* AssertRCReturn(...) will leave us in loading state, but it doesn't matter as we'd be failing anyway */
        cr_server.bIsInLoadingState = GL_TRUE;

        /* Read number of clients */
        rc = SSMR3GetU32(pSSM, &g_hackVBoxServerSaveLoadCallsLeft);
        AssertRCReturn(rc, rc);
    }

    g_hackVBoxServerSaveLoadCallsLeft--;

    /* Do nothing until we're being called last time */
    if (g_hackVBoxServerSaveLoadCallsLeft>0)
    {
        return VINF_SUCCESS;
    }

    if (version!=SHCROGL_SSM_VERSION)
    {
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Load and recreate rendering contexts */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRCreateInfo_t createInfo;
        char psz[200];
        GLint ctxID;
        CRContext* pContext;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
        AssertRCReturn(rc, rc);

        if (createInfo.pszDpyName)
        {
            rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
            AssertRCReturn(rc, rc);
            createInfo.pszDpyName = psz;
        }

        ctxID = crServerDispatchCreateContextEx(createInfo.pszDpyName, createInfo.visualBits, 0, key, createInfo.internalID);
        CRASSERT((int64_t)ctxID == (int64_t)key);

        pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key);
        CRASSERT(pContext);
        pContext->shared->id=-1;
    }

    /* Restore context state data */
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRContext *pContext;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);

        pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key);
        CRASSERT(pContext);

        rc = crStateLoadContext(pContext, cr_server.contextTable, pSSM);
        AssertRCReturn(rc, rc);
    }

    /* Load windows */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRCreateInfo_t createInfo;
        char psz[200];
        GLint winID;
        unsigned long key;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
        AssertRCReturn(rc, rc);

        if (createInfo.pszDpyName)
        {
            rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
            AssertRCReturn(rc, rc);
            createInfo.pszDpyName = psz;
        }

        winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key);
        CRASSERT((int64_t)winID == (int64_t)key);
    }

    /* Load cr_server.muralTable */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRMuralInfo muralInfo;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &muralInfo, sizeof(muralInfo));
        AssertRCReturn(rc, rc);

        if (muralInfo.pVisibleRects)
        {
            muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects);
            if (!muralInfo.pVisibleRects)
            {
                return VERR_NO_MEMORY;
            }

            rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects);
            AssertRCReturn(rc, rc);
        }

        /* Restore windows geometry info */
        crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height);
        crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY);
        /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/
        if (muralInfo.bReceivedRects)
        {
            crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects);
        }
        crServerDispatchWindowShow(key, muralInfo.bVisible);

        if (muralInfo.pVisibleRects)
        {
            crFree(muralInfo.pVisibleRects);
        }
    }

    /* Load starting free context and window IDs */
    rc = SSMR3GetMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool));
    CRASSERT(rc == VINF_SUCCESS);

    /* Load clients info */
    for (i = 0; i < cr_server.numClients; i++)
    {
        if (cr_server.clients[i] && cr_server.clients[i]->conn)
        {
            CRClient *pClient = cr_server.clients[i];
            CRClient client;
            unsigned long ctxID=-1, winID=-1;

            rc = SSMR3GetU32(pSSM, &ui);
            AssertRCReturn(rc, rc);
            /* If this assert fires, then we should search correct client in the list first*/
            CRASSERT(ui == pClient->conn->u32ClientID);

            if (version>=4)
            {
                rc = SSMR3GetU32(pSSM, &pClient->conn->vMajor);
                AssertRCReturn(rc, rc);

                rc = SSMR3GetU32(pSSM, &pClient->conn->vMinor);
                AssertRCReturn(rc, rc);
            }

            rc = SSMR3GetMem(pSSM, &client, sizeof(client));
            CRASSERT(rc == VINF_SUCCESS);

            client.conn = pClient->conn;
            /* We can't reassign client number, as we'd get wrong results in TranslateTextureID
             * and fail to bind old textures.
             */
            /*client.number = pClient->number;*/
            *pClient = client;

            pClient->currentContextNumber = -1;
            pClient->currentCtx = cr_server.DummyContext;
            pClient->currentMural = NULL;
            pClient->currentWindow = -1;

            cr_server.curClient = pClient;

            if (client.currentCtx && client.currentContextNumber>=0)
            {
                rc = SSMR3GetMem(pSSM, &ctxID, sizeof(ctxID));
                AssertRCReturn(rc, rc);
                client.currentCtx = (CRContext*) crHashtableSearch(cr_server.contextTable, ctxID);
                CRASSERT(client.currentCtx);
                //pClient->currentCtx = client.currentCtx;
                //pClient->currentContextNumber = ctxID;
            }

            if (client.currentMural && client.currentWindow>=0)
            {
                rc = SSMR3GetMem(pSSM, &winID, sizeof(winID));
                AssertRCReturn(rc, rc);
                client.currentMural = (CRMuralInfo*) crHashtableSearch(cr_server.muralTable, winID);
                CRASSERT(client.currentMural);
                //pClient->currentMural = client.currentMural;
                //pClient->currentWindow = winID;
            }

            /* Restore client active context and window */
            crServerDispatchMakeCurrent(winID, 0, ctxID);

            if (0)
            {
            CRContext *tmpCtx;
            CRCreateInfo_t *createInfo;
            GLfloat one[4] = { 1, 1, 1, 1 };
            GLfloat amb[4] = { 0.4f, 0.4f, 0.4f, 1.0f };

            crServerDispatchMakeCurrent(winID, 0, ctxID);

            crHashtableWalk(client.currentCtx->shared->textureTable, crVBoxServerSyncTextureCB, client.currentCtx);

            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base1D, GL_TRUE);
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base2D, GL_TRUE);
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base3D, GL_TRUE);
#ifdef CR_ARB_texture_cube_map
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseCubeMap, GL_TRUE);
#endif
#ifdef CR_NV_texture_rectangle
            //@todo this doesn't work as expected
            //crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseRect, GL_TRUE);
#endif
            /*cr_server.head_spu->dispatch_table.Materialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
            cr_server.head_spu->dispatch_table.LightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
            cr_server.head_spu->dispatch_table.Lightfv(GL_LIGHT1, GL_DIFFUSE, one);

            cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING);
            cr_server.head_spu->dispatch_table.Enable(GL_LIGHT0);
            cr_server.head_spu->dispatch_table.Enable(GL_LIGHT1);

            cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE);
            cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);*/

            //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);

            //crStateLoadIdentity();
            //cr_server.head_spu->dispatch_table.LoadIdentity();

            //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();

                /*createInfo = (CRCreateInfo_t *) crHashtableSearch(cr_server.pContextCreateInfoTable, ctxID);
                CRASSERT(createInfo);
                tmpCtx = crStateCreateContext(NULL, createInfo->visualBits, NULL);
                CRASSERT(tmpCtx);
                crStateDiffContext(tmpCtx, client.currentCtx);
                crStateDestroyContext(tmpCtx);*/
            }
        }
    }

    //crServerDispatchMakeCurrent(-1, 0, -1);

    cr_server.curClient = NULL;

    {
        GLenum err = crServerDispatchGetError();

        if (err != GL_NO_ERROR)
        {
            crWarning("crServer: glGetError %d after loading snapshot", err);
        }
    }

    cr_server.bIsInLoadingState = GL_FALSE;

    return VINF_SUCCESS;
}
Example #6
0
DECLEXPORT(void) STATE_APIENTRY 
crStateGLSLProgramCacheUniforms(GLuint program, GLsizei maxcbData, GLsizei *cbData, GLvoid *pData)
{
    CRGLSLProgram *pProgram = crStateGetProgramObj(program);
    GLint maxUniformLen, activeUniforms=0, fakeUniformsCount, i, j;
    char *pCurrent = pData;
    GLsizei cbWritten;

    if (!pProgram)
    {
        crWarning("Unknown program %d", program);
        return;
    }

    diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLen);
    diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORMS, &activeUniforms);

    *cbData = 0;

    cbWritten = sizeof(GLsizei);
    if (cbWritten>maxcbData)
    {
        crWarning("crStateGLSLProgramCacheUniforms: buffer too small");
        return;
    }
    ((GLsizei*)pCurrent)[0] = activeUniforms;
    fakeUniformsCount = activeUniforms;
    pCurrent += sizeof(GLsizei);

    crDebug("crStateGLSLProgramCacheUniforms: %i active uniforms", activeUniforms);

    if (activeUniforms>0)
    {
        /*+8 to make sure our array uniforms with higher indices and [] will fit in as well*/
        GLchar *name = (GLchar *) crAlloc(maxUniformLen+8);
        GLenum type;
        GLint size;
        GLsizei cbName;
        GLint location;

        if (!name)
        {
            crWarning("crStateGLSLProgramCacheUniforms: no memory");
            return;
        }

        for (i=0; i<activeUniforms; ++i)
        {
            diff_api.GetActiveUniform(pProgram->hwid, i, maxUniformLen, &cbName, &size, &type, name);
            location = diff_api.GetUniformLocation(pProgram->hwid, name);

            if (!crStateGLSLProgramCacheOneUniform(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
                return;

            /* Only one active uniform variable will be reported for a uniform array by glGetActiveUniform,
             * so we insert fake elements for other array elements.
             */
            if (size!=1)
            {
                char *pIndexStr = crStrchr(name, '[');
                GLint firstIndex=1;
                fakeUniformsCount += size;

                crDebug("crStateGLSLProgramCacheUniforms: expanding array uniform, size=%i", size);

                /*For array uniforms it's valid to query location of 1st element as both uniform and uniform[0].
                 *The name returned by glGetActiveUniform is driver dependent,
                 *atleast it's with [0] on win/ati and without [0] on linux/nvidia.
                 */                
                if (!pIndexStr)
                {
                    pIndexStr = name+cbName;
                    firstIndex=0;
                }
                else
                {
                    cbName = pIndexStr-name;
                    if (!crStateGLSLProgramCacheOneUniform(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
                        return;
                }

                for (j=firstIndex; j<size; ++j)
                {
                    sprintf(pIndexStr, "[%i]", j);
                    cbName = crStrlen(name);

                    location = diff_api.GetUniformLocation(pProgram->hwid, name);

                    if (!crStateGLSLProgramCacheOneUniform(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
                        return;
                }
            }
        }

        crFree(name);
    }

    if (fakeUniformsCount!=activeUniforms)
    {
        ((GLsizei*)pData)[0] = fakeUniformsCount;
        crDebug("FakeCount %i", fakeUniformsCount);
    }

    *cbData = cbWritten;

    CRASSERT((pCurrent-((char*)pData))==cbWritten);
}
static void crStateBufferObjectIntCmp(CRBufferObjectBits *bb, CRbitvalue *bitID,
                                      CRContext *fromCtx, CRContext *toCtx,
                                      GLboolean bSwitch)
{
    CRBufferObjectState *from = &(fromCtx->bufferobject);
    const CRBufferObjectState *to = &(toCtx->bufferobject);

    /* ARRAY_BUFFER */
    if (CHECKDIRTY(bb->arrayBinding, bitID)) 
    {
        if (from->arrayBuffer != to->arrayBuffer)
        {
            GLuint bufferID = to->arrayBuffer ? to->arrayBuffer->hwid : 0;
            diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, bufferID);
            if (bSwitch)
            {
                FILLDIRTY(bb->arrayBinding);
                FILLDIRTY(bb->dirty);
            }
            else
            {
                CLEARDIRTY2(bb->arrayBinding, bitID);
                from->arrayBuffer = to->arrayBuffer;
            }
        }
        if (bSwitch) CLEARDIRTY2(bb->arrayBinding, bitID);
    }

    if (to->arrayBuffer && CHECKDIRTY(to->arrayBuffer->dirty, bitID))
    {
        /* update array buffer data */
        CRBufferObject *bufObj = to->arrayBuffer;
        CRASSERT(bufObj);
        if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) 
        {
            /* update whole buffer */
            diff_api.BufferDataARB(GL_ARRAY_BUFFER_ARB, bufObj->size,
                                   bufObj->data, bufObj->usage);
        }
        else 
        {
            /* update sub buffer */
            diff_api.BufferSubDataARB(GL_ARRAY_BUFFER_ARB,
                                      bufObj->dirtyStart, bufObj->dirtyLength,
                                      (char *) bufObj->data + bufObj->dirtyStart);
        }
        if (bSwitch) FILLDIRTY(bufObj->dirty);
        CLEARDIRTY2(bufObj->dirty, bitID);
    }

    /* ELEMENTS_BUFFER */
    if (CHECKDIRTY(bb->elementsBinding, bitID)) 
    {
        if (from->elementsBuffer != to->elementsBuffer)
        {
            GLuint bufferID = to->elementsBuffer ? to->elementsBuffer->hwid : 0;
            diff_api.BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferID);
            if (bSwitch)
            {
                FILLDIRTY(bb->elementsBinding);
                FILLDIRTY(bb->dirty);
            }
            else
            {
                CLEARDIRTY2(bb->elementsBinding, bitID);
                from->elementsBuffer = to->elementsBuffer;
            }
        }
        if (bSwitch) CLEARDIRTY2(bb->elementsBinding, bitID);
    }

    if (to->elementsBuffer && CHECKDIRTY(to->elementsBuffer->dirty, bitID))
    {
        /* update array buffer data */
        CRBufferObject *bufObj = to->elementsBuffer;
        CRASSERT(bufObj);
        if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) 
        {
            /* update whole buffer */
            diff_api.BufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufObj->size,
                                   bufObj->data, bufObj->usage);
        }
        else 
        {
            /* update sub buffer */
            diff_api.BufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
                                      bufObj->dirtyStart, bufObj->dirtyLength,
                                      (char *) bufObj->data + bufObj->dirtyStart);
        }
        if (bSwitch) FILLDIRTY(bufObj->dirty);
        CLEARDIRTY2(bufObj->dirty, bitID);
    }

#ifdef CR_ARB_pixel_buffer_object
    /* PIXEL_PACK_BUFFER */
    if (CHECKDIRTY(bb->packBinding, bitID)) 
    {
        if (from->packBuffer != to->packBuffer)
        {
            GLuint bufferID = to->packBuffer ? to->packBuffer->hwid : 0;
            diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, bufferID);
            if (bSwitch)
            {
                FILLDIRTY(bb->packBinding);
                FILLDIRTY(bb->dirty);
            }
            else
            {
                CLEARDIRTY2(bb->packBinding, bitID);
                from->packBuffer = to->packBuffer;
            }
        }
        if (bSwitch) CLEARDIRTY2(bb->packBinding, bitID);
    }

    if (to->packBuffer && CHECKDIRTY(to->packBuffer->dirty, bitID))
    {
        /* update array buffer data */
        CRBufferObject *bufObj = to->packBuffer;
        CRASSERT(bufObj);
        if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) 
        {
            /* update whole buffer */
            diff_api.BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, bufObj->size,
                                   bufObj->data, bufObj->usage);
        }
        else 
        {
            /* update sub buffer */
            diff_api.BufferSubDataARB(GL_PIXEL_PACK_BUFFER_ARB,
                                      bufObj->dirtyStart, bufObj->dirtyLength,
                                      (char *) bufObj->data + bufObj->dirtyStart);
        }
        if (bSwitch) FILLDIRTY(bufObj->dirty);
        CLEARDIRTY2(bufObj->dirty, bitID);
    }

    /* PIXEL_UNPACK_BUFFER */
    if (CHECKDIRTY(bb->unpackBinding, bitID)) 
    {
        if (from->unpackBuffer != to->unpackBuffer)
        {
            GLuint bufferID = to->unpackBuffer ? to->unpackBuffer->hwid : 0;
            diff_api.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, bufferID);
            if (bSwitch)
            {
                FILLDIRTY(bb->unpackBinding);
                FILLDIRTY(bb->dirty);
            }
            else
            {
                CLEARDIRTY2(bb->unpackBinding, bitID);
                from->unpackBuffer = to->unpackBuffer;
            }
        }
        if (bSwitch) CLEARDIRTY2(bb->unpackBinding, bitID);
    }

    if (to->unpackBuffer && CHECKDIRTY(to->unpackBuffer->dirty, bitID))
    {
        /* update array buffer data */
        CRBufferObject *bufObj = to->unpackBuffer;
        CRASSERT(bufObj);
        if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) 
        {
            /* update whole buffer */
            diff_api.BufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, bufObj->size,
                                   bufObj->data, bufObj->usage);
        }
        else 
        {
            /* update sub buffer */
            diff_api.BufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
                                      bufObj->dirtyStart, bufObj->dirtyLength,
                                      (char *) bufObj->data + bufObj->dirtyStart);
        }
        if (bSwitch) FILLDIRTY(bufObj->dirty);
        CLEARDIRTY2(bufObj->dirty, bitID);
    }
#endif /*ifdef CR_ARB_pixel_buffer_object*/
}
Example #8
0
void crServerCheckMuralGeometry(CRMuralInfo *mural)
{
    int tlS, brS, trS, blS;
    int overlappingScreenCount, primaryS, i;

    if (!mural->width || !mural->height)
        return;

    if (cr_server.screenCount<2 && !cr_server.bForceOffscreenRendering)
    {
        CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
        CRASSERT(cr_server.screenCount>0);

        mural->hX = mural->gX-cr_server.screen[0].x;
        mural->hY = mural->gY-cr_server.screen[0].y;

        cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y);

        return;
    }

    tlS = crServerGetPointScreen(mural->gX, mural->gY);
    brS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY+mural->height-1);

    if (tlS==brS && tlS>=0)
    {
        overlappingScreenCount = 1;
        primaryS = tlS;
    }
    else
    {
        trS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY);
        blS = crServerGetPointScreen(mural->gX, mural->gY+mural->height-1);

        primaryS = -1; overlappingScreenCount = 0;
        for (i=0; i<cr_server.screenCount; ++i)
        {
            if ((i==tlS) || (i==brS) || (i==trS) || (i==blS)
                || crServerMuralCoverScreen(mural, i))
            {
                overlappingScreenCount++;
                primaryS = primaryS<0 ? i:primaryS;
            }
        }

        if (!overlappingScreenCount)
        {
            primaryS = 0;
        }
    }

    if (primaryS!=mural->screenId)
    {
        mural->screenId = primaryS;

        renderspuSetWindowId(cr_server.screen[primaryS].winID);
        renderspuReparentWindow(mural->spuWindow);
        renderspuSetWindowId(cr_server.screen[0].winID);
    }

    mural->hX = mural->gX-cr_server.screen[primaryS].x;
    mural->hY = mural->gY-cr_server.screen[primaryS].y;

    if (overlappingScreenCount<2 && !cr_server.bForceOffscreenRendering)
    {
        CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];

        if (mural->bUseFBO)
        {
            crServerRedirMuralFBO(mural, GL_FALSE);
            crServerDeleteMuralFBO(mural);
        }

        cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y);
    }
    else
    {
        if (mural->spuWindow)
        {
            if (!mural->bUseFBO)
            {
                crServerRedirMuralFBO(mural, GL_TRUE);
            }
            else
            {
                if (mural->width!=mural->fboWidth
                    || mural->height!=mural->height)
                {
                    crServerRedirMuralFBO(mural, GL_FALSE);
                    crServerDeleteMuralFBO(mural);
                    crServerRedirMuralFBO(mural, GL_TRUE);
                }
            }
        }
#ifdef DEBUG_misha
        else
        {
            Assert(!mural->bUseFBO);
        }
#endif

        if (!mural->bUseFBO)
        {
            CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];

            cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y);
        }
    }

    if (mural->pvOutputRedirectInstance)
    {
        cr_server.outputRedirect.CRORGeometry(mural->pvOutputRedirectInstance,
                                              mural->hX, mural->hY,
                                              mural->width, mural->height);
    }
}
Example #9
0
/*
 * Helper for crStateCreateContext, below.
 */
static CRContext *
crStateCreateContextId(int i, const CRLimitsState *limits,
                                             GLint visBits, CRContext *shareCtx)
{
    CRContext *ctx = (CRContext *) crCalloc( sizeof( *ctx ) );
    int j;
    int node32 = i >> 5;
    int node = i & 0x1f;

    ctx->id = i;
#ifdef CHROMIUM_THREADSAFE
    VBoxTlsRefInit(ctx, crStateContextDtor);
#endif
    ctx->flush_func = NULL;
    for (j=0;j<CR_MAX_BITARRAY;j++){
        if (j == node32) {
            ctx->bitid[j] = (1 << node);
        } else {
            ctx->bitid[j] = 0;
        }
        ctx->neg_bitid[j] = ~(ctx->bitid[j]);
    }

    if (shareCtx) {
        CRASSERT(shareCtx->shared);
        ctx->shared = shareCtx->shared;
        ctx->shared->refCount ++;
    }
    else {
        ctx->shared = crStateAllocShared();
        ctx->shared->id = ctx->id;
    }

    /* use Chromium's OpenGL defaults */
    crStateLimitsInit( &(ctx->limits) );
    crStateExtensionsInit( &(ctx->limits), &(ctx->extensions) );

    crStateBufferObjectInit( ctx ); /* must precede client state init! */
    crStateClientInit( &(ctx->client) );

    crStateBufferInit( ctx );
    crStateCurrentInit( ctx );
    crStateEvaluatorInit( ctx );
    crStateFogInit( ctx );
    crStateHintInit( ctx );
    crStateLightingInit( ctx );
    crStateLineInit( ctx );
    crStateListsInit( ctx );
    crStateMultisampleInit( ctx );
    crStateOcclusionInit( ctx );
    crStatePixelInit( ctx );
    crStatePolygonInit( ctx );
    crStatePointInit( ctx );
    crStateProgramInit( ctx );
    crStateRegCombinerInit( ctx );
    crStateStencilInit( ctx );
    crStateTextureInit( ctx );
    crStateTransformInit( ctx );
    crStateViewportInit ( ctx );
    crStateFramebufferObjectInit(ctx);
    crStateGLSLInit(ctx);

    /* This has to come last. */
    crStateAttribInit( &(ctx->attrib) );

    ctx->renderMode = GL_RENDER;

    /* Initialize values that depend on the visual mode */
    if (visBits & CR_DOUBLE_BIT) {
        ctx->limits.doubleBuffer = GL_TRUE;
    }
    if (visBits & CR_RGB_BIT) {
        ctx->limits.redBits = 8;
        ctx->limits.greenBits = 8;
        ctx->limits.blueBits = 8;
        if (visBits & CR_ALPHA_BIT) {
            ctx->limits.alphaBits = 8;
        }
    }
    else {
        ctx->limits.indexBits = 8;
    }
    if (visBits & CR_DEPTH_BIT) {
        ctx->limits.depthBits = 24;
    }
    if (visBits & CR_STENCIL_BIT) {
        ctx->limits.stencilBits = 8;
    }
    if (visBits & CR_ACCUM_BIT) {
        ctx->limits.accumRedBits = 16;
        ctx->limits.accumGreenBits = 16;
        ctx->limits.accumBlueBits = 16;
        if (visBits & CR_ALPHA_BIT) {
            ctx->limits.accumAlphaBits = 16;
        }
    }
    if (visBits & CR_STEREO_BIT) {
        ctx->limits.stereo = GL_TRUE;
    }
    if (visBits & CR_MULTISAMPLE_BIT) {
        ctx->limits.sampleBuffers = 1;
        ctx->limits.samples = 4;
        ctx->multisample.enabled = GL_TRUE;
    }

    if (visBits & CR_OVERLAY_BIT) {
        ctx->limits.level = 1;
    }

    return ctx;
}
Example #10
0
void crServerCreateMuralFBO(CRMuralInfo *mural)
{
    CRContext *ctx = crStateGetCurrent();
    GLuint uid;
    GLenum status;
    SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
    CRContextInfo *pMuralContextInfo;
    int RestoreSpuWindow = -1;
    int RestoreSpuContext = -1;

    CRASSERT(mural->idFBO==0);

    pMuralContextInfo = cr_server.currentCtxInfo;
    if (!pMuralContextInfo)
    {
        /* happens on saved state load */
        CRASSERT(cr_server.MainContextInfo.SpuContext);
        pMuralContextInfo = &cr_server.MainContextInfo;
        cr_server.head_spu->dispatch_table.MakeCurrent(mural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
        RestoreSpuWindow = 0;
        RestoreSpuContext = 0;
    }

    /*Color texture*/
    gl->GenTextures(1, &mural->idColorTex);
    gl->BindTexture(GL_TEXTURE_2D, mural->idColorTex);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
    {
        gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    }
    gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mural->width, mural->height,
                   0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);

    /*Depth&Stencil*/
    gl->GenRenderbuffersEXT(1, &mural->idDepthStencilRB);
    gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
    gl->RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
                               mural->width, mural->height);

    /*FBO*/
    gl->GenFramebuffersEXT(1, &mural->idFBO);
    gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mural->idFBO);

    gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                GL_TEXTURE_2D, mural->idColorTex, 0);
    gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                   GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
    gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                   GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);

    status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status!=GL_FRAMEBUFFER_COMPLETE_EXT)
    {
        crWarning("FBO status(0x%x) isn't complete", status);
    }

    mural->fboWidth = mural->width;
    mural->fboHeight = mural->height;

    /*PBO*/
    if (cr_server.bUsePBOForReadback)
    {
        gl->GenBuffersARB(1, &mural->idPBO);
        gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, mural->idPBO);
        gl->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, mural->width*mural->height*4, 0, GL_STREAM_READ_ARB);
        gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);

        if (!mural->idPBO)
        {
            crWarning("PBO create failed");
        }
    }

    /*Restore gl state*/
    uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
    gl->BindTexture(GL_TEXTURE_2D, uid);

    uid = ctx->framebufferobject.renderbuffer ? ctx->framebufferobject.renderbuffer->hwid:0;
    gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, uid);

    uid = ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0;
    gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, uid);

    uid = ctx->framebufferobject.readFB ? ctx->framebufferobject.readFB->hwid:0;
    gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER, uid);

    if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
    {
        gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
    }

    if (RestoreSpuWindow >= 0 && RestoreSpuContext >= 0)
    {
        cr_server.head_spu->dispatch_table.MakeCurrent(RestoreSpuWindow, 0, RestoreSpuContext);
    }
}
Example #11
0
void crServerPresentFBO(CRMuralInfo *mural)
{
    char *pixels=NULL, *tmppixels;
    GLuint uid;
    int i, j;
    CRrecti rect, rectwr, sectr;
    GLboolean bUsePBO;
    CRContext *ctx = crStateGetCurrent();

    CRASSERT(cr_server.pfnPresentFBO);

    if (!mural->bVisible)
    {
        return;
    }

    if (!mural->width || !mural->height)
    {
        return;
    }

    if (cr_server.bUsePBOForReadback && !mural->idPBO)
    {
        crWarning("Mural doesn't have PBO even though bUsePBOForReadback is set!");
    }

    bUsePBO = cr_server.bUsePBOForReadback && mural->idPBO;

    cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, mural->idColorTex);

    if (bUsePBO)
    {
        CRASSERT(mural->idPBO);
        cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, mural->idPBO);
    }
    else
    {
        if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
        {
            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
        }

        pixels = crAlloc(4*mural->fboWidth*mural->fboHeight);
        if (!pixels)
        {
            crWarning("Out of memory in crServerPresentFBO");
            return;
        }
    }

    /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/    
    cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

    /*restore gl state*/
    uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
    cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, uid);

    if (bUsePBO)
    {
        pixels = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
        if (!pixels)
        {
            crWarning("Failed to MapBuffer in crServerPresentFBO");
            return;
        }
    }

    for (i=0; i<cr_server.screenCount; ++i)
    {
        if (crServerIntersectScreen(mural, i, &rect))
        {
            /* rect in window relative coords */
            crServerTransformRect(&rectwr, &rect, -mural->gX, -mural->gY);

            if (!mural->pVisibleRects)
            {
                /*we don't get any rects info for guest compiz windows, so we treat windows as visible unless explicitly received 0 visible rects*/
                if (!mural->bReceivedRects)
                {
                    tmppixels = crAlloc(4*(rect.x2-rect.x1)*(rect.y2-rect.y1));
                    if (!tmppixels)
                    {
                        crWarning("Out of memory in crServerPresentFBO");
                        crFree(pixels);
                        return;
                    }

                    crServerCopySubImage(tmppixels, pixels, &rectwr, mural->fboWidth, mural->fboHeight);
                    /*Note: pfnPresentFBO would free tmppixels*/
                    cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, rect.y2-rect.y1);
                }
            }
            else
            {
                for (j=0; j<mural->cVisibleRects; ++j)
                {
                    if (crServerIntersectRect(&rectwr, (CRrecti*) &mural->pVisibleRects[4*j], &sectr))
                    {
                        tmppixels = crAlloc(4*(sectr.x2-sectr.x1)*(sectr.y2-sectr.y1));
                        if (!tmppixels)
                        {
                            crWarning("Out of memory in crServerPresentFBO");
                            crFree(pixels);
                            return;
                        }

                        crServerCopySubImage(tmppixels, pixels, &sectr, mural->fboWidth, mural->fboHeight);
                        /*Note: pfnPresentFBO would free tmppixels*/
                        cr_server.pfnPresentFBO(tmppixels, i,
                                                sectr.x1+mural->gX-cr_server.screen[i].x,
                                                sectr.y1+mural->gY-cr_server.screen[i].y,
                                                sectr.x2-sectr.x1, sectr.y2-sectr.y1);
                    }
                }
            }
        }
    }

    if (mural->pvOutputRedirectInstance)
    {
        /* @todo find out why presentfbo is not called but crorframe is called. */
        cr_server.outputRedirect.CRORFrame(mural->pvOutputRedirectInstance,
                                           pixels,
                                           4 * mural->fboWidth * mural->fboHeight);
    }

    if (bUsePBO)
    {
        cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
        cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
    }
    else
    {
        crFree(pixels);
        if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
        {
            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
        }
    }
}
void crStatePointSwitch(CRPointBits *b, CRbitvalue *bitID,
        CRContext *fromCtx, CRContext *toCtx)
{
    PCRStateTracker pState = fromCtx->pStateTracker;
    CRPointState *from = &(fromCtx->point);
    CRPointState *to = &(toCtx->point);
    unsigned int j, i;
    GLboolean fEnabled;
    CRbitvalue nbitID[CR_MAX_BITARRAY];

    CRASSERT(fromCtx->pStateTracker == toCtx->pStateTracker);

    for (j=0;j<CR_MAX_BITARRAY;j++)
        nbitID[j] = ~bitID[j];
    i = 0; /* silence compiler */
    if (CHECKDIRTY(b->enableSmooth, bitID))
    {
        glAble able[2];
        able[0] = pState->diff_api.Disable;
        able[1] = pState->diff_api.Enable;
        if (from->pointSmooth != to->pointSmooth)
        {
            able[to->pointSmooth](GL_POINT_SMOOTH);
            FILLDIRTY(b->enableSmooth);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->enableSmooth, nbitID);
    }
    if (CHECKDIRTY(b->size, bitID))
    {
        if (from->pointSize != to->pointSize)
        {
            pState->diff_api.PointSize (to->pointSize);
            FILLDIRTY(b->size);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->size, nbitID);
    }
    if (CHECKDIRTY(b->minSize, bitID))
    {
        if (from->minSize != to->minSize)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_SIZE_MIN_ARB, to->minSize);
            FILLDIRTY(b->minSize);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->minSize, nbitID);
    }
    if (CHECKDIRTY(b->maxSize, bitID))
    {
        if (from->maxSize != to->maxSize)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_SIZE_MAX_ARB, to->maxSize);
            FILLDIRTY(b->maxSize);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->maxSize, nbitID);
    }
    if (CHECKDIRTY(b->fadeThresholdSize, bitID))
    {
        if (from->fadeThresholdSize != to->fadeThresholdSize)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_FADE_THRESHOLD_SIZE_ARB, to->fadeThresholdSize);
            FILLDIRTY(b->fadeThresholdSize);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->fadeThresholdSize, nbitID);
    }
    if (CHECKDIRTY(b->spriteCoordOrigin, bitID))
    {
        if (from->spriteCoordOrigin != to->spriteCoordOrigin)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_SPRITE_COORD_ORIGIN, to->spriteCoordOrigin);
            FILLDIRTY(b->spriteCoordOrigin);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->spriteCoordOrigin, nbitID);
    }
    if (CHECKDIRTY(b->distanceAttenuation, bitID))
    {
        if (from->distanceAttenuation[0] != to->distanceAttenuation[0] || from->distanceAttenuation[1] != to->distanceAttenuation[1] || from->distanceAttenuation[2] != to->distanceAttenuation[2]) {
            pState->diff_api.PointParameterfvARB (GL_POINT_DISTANCE_ATTENUATION_ARB, to->distanceAttenuation);
            FILLDIRTY(b->distanceAttenuation);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->distanceAttenuation, nbitID);
    }
    fEnabled = from->pointSprite;
    {
        unsigned int activeUnit = (unsigned int) -1;
        for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++) {
            if (CHECKDIRTY(b->coordReplacement[i], bitID))
            {
                if (!fEnabled)
                {
                    pState->diff_api.Enable(GL_POINT_SPRITE_ARB);
                    fEnabled = GL_TRUE;
                }
#if 0
                /*don't set coord replacement, it will be set just before drawing points when necessary,
                 * to work around gpu driver bugs
                 * See crServerDispatch[Begin|End|Draw*] */
                GLint replacement = to->coordReplacement[i];
                if (activeUnit != i) {
                     diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB );
                     activeUnit = i;
                }
                diff_api.TexEnviv(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, &replacement);
#endif
                CLEARDIRTY(b->coordReplacement[i], nbitID);
            }
        }
        if (activeUnit != toCtx->texture.curTextureUnit)
           pState->diff_api.ActiveTextureARB(GL_TEXTURE0 + toCtx->texture.curTextureUnit);
    }
    if (CHECKDIRTY(b->enableSprite, bitID))
    {
        glAble able[2];
        able[0] = pState->diff_api.Disable;
        able[1] = pState->diff_api.Enable;
        if (fEnabled != to->pointSprite)
        {
            able[to->pointSprite](GL_POINT_SPRITE_ARB);
            FILLDIRTY(b->enableSprite);
            FILLDIRTY(b->dirty);
        }
        CLEARDIRTY(b->enableSprite, nbitID);
    }
    else if (fEnabled != to->pointSprite)
    {
        glAble able[2];
        able[0] = pState->diff_api.Disable;
        able[1] = pState->diff_api.Enable;
        able[to->pointSprite](GL_POINT_SPRITE_ARB);
    }
    CLEARDIRTY(b->dirty, nbitID);
}
void crStatePointDiff(CRPointBits *b, CRbitvalue *bitID,
        CRContext *fromCtx, CRContext *toCtx)
{
    PCRStateTracker pState = fromCtx->pStateTracker;
    CRPointState *from = &(fromCtx->point);
    CRPointState *to = &(toCtx->point);
    unsigned int j, i;
    CRbitvalue nbitID[CR_MAX_BITARRAY];
    Assert(0); /** @todo Is this never called? */

    CRASSERT(fromCtx->pStateTracker == toCtx->pStateTracker);

    for (j=0;j<CR_MAX_BITARRAY;j++)
        nbitID[j] = ~bitID[j];
    i = 0; /* silence compiler */
    if (CHECKDIRTY(b->enableSmooth, bitID))
    {
        glAble able[2];
        able[0] = pState->diff_api.Disable;
        able[1] = pState->diff_api.Enable;
        if (from->pointSmooth != to->pointSmooth)
        {
            able[to->pointSmooth](GL_POINT_SMOOTH);
            from->pointSmooth = to->pointSmooth;
        }
        CLEARDIRTY(b->enableSmooth, nbitID);
    }
    if (CHECKDIRTY(b->size, bitID))
    {
        if (from->pointSize != to->pointSize)
        {
            pState->diff_api.PointSize (to->pointSize);
            from->pointSize = to->pointSize;
        }
        CLEARDIRTY(b->size, nbitID);
    }
    if (CHECKDIRTY(b->minSize, bitID))
    {
        if (from->minSize != to->minSize)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_SIZE_MIN_ARB, to->minSize);
            from->minSize = to->minSize;
        }
        CLEARDIRTY(b->minSize, nbitID);
    }
    if (CHECKDIRTY(b->maxSize, bitID))
    {
        if (from->maxSize != to->maxSize)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_SIZE_MAX_ARB, to->maxSize);
            from->maxSize = to->maxSize;
        }
        CLEARDIRTY(b->maxSize, nbitID);
    }
    if (CHECKDIRTY(b->fadeThresholdSize, bitID))
    {
        if (from->fadeThresholdSize != to->fadeThresholdSize)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_FADE_THRESHOLD_SIZE_ARB, to->fadeThresholdSize);
            from->fadeThresholdSize = to->fadeThresholdSize;
        }
        CLEARDIRTY(b->fadeThresholdSize, nbitID);
    }
    if (CHECKDIRTY(b->spriteCoordOrigin, bitID))
    {
        if (from->spriteCoordOrigin != to->spriteCoordOrigin)
        {
            pState->diff_api.PointParameterfARB (GL_POINT_SPRITE_COORD_ORIGIN, to->spriteCoordOrigin);
            from->spriteCoordOrigin = to->spriteCoordOrigin;
        }
        CLEARDIRTY(b->spriteCoordOrigin, nbitID);
    }
    if (CHECKDIRTY(b->distanceAttenuation, bitID))
    {
        if (from->distanceAttenuation[0] != to->distanceAttenuation[0] || from->distanceAttenuation[1] != to->distanceAttenuation[1] || from->distanceAttenuation[2] != to->distanceAttenuation[2]) {
            pState->diff_api.PointParameterfvARB (GL_POINT_DISTANCE_ATTENUATION_ARB, to->distanceAttenuation);
            from->distanceAttenuation[0] = to->distanceAttenuation[0];
            from->distanceAttenuation[1] = to->distanceAttenuation[1];
            from->distanceAttenuation[2] = to->distanceAttenuation[2];
        }
        CLEARDIRTY(b->distanceAttenuation, nbitID);
    }
    if (CHECKDIRTY(b->enableSprite, bitID))
    {
        glAble able[2];
        able[0] = pState->diff_api.Disable;
        able[1] = pState->diff_api.Enable;
        if (from->pointSprite != to->pointSprite)
        {
            able[to->pointSprite](GL_POINT_SPRITE_ARB);
            from->pointSprite = to->pointSprite;
        }
        CLEARDIRTY(b->enableSprite, nbitID);
    }
    {
        unsigned int activeUnit = (unsigned int) -1;
        for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++) {
            if (CHECKDIRTY(b->coordReplacement[i], bitID))
            {
                GLint replacement = to->coordReplacement[i];
                if (activeUnit != i) {
                     pState->diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB );
                     activeUnit = i;
                }
                pState->diff_api.TexEnviv(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, &replacement);
                from->coordReplacement[i] = to->coordReplacement[i];
                CLEARDIRTY(b->coordReplacement[i], nbitID);
            }
        }
        if (activeUnit != toCtx->texture.curTextureUnit)
           pState->diff_api.ActiveTextureARB(GL_TEXTURE0 + toCtx->texture.curTextureUnit);
    }
    CLEARDIRTY(b->dirty, nbitID);
}
Example #14
0
GLint RENDER_APIENTRY
renderspuWindowCreate( const char *dpyName, GLint visBits )
{
	WindowInfo *window;
	VisualInfo *visual;
	GLboolean showIt;

	if (!dpyName || crStrlen(render_spu.display_string) > 0)
		dpyName = render_spu.display_string;

	visual = renderspuFindVisual( dpyName, visBits );
	if (!visual)
	{
		crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
		return -1;
	}

	/* Allocate WindowInfo */
	window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
	if (!window)
	{
		crWarning( "Render SPU: Couldn't create a window" );
		return -1;
	}

	crHashtableAdd(render_spu.windowTable, render_spu.window_id, window);
	window->id = render_spu.window_id;
	render_spu.window_id++;

	window->x = render_spu.defaultX;
	window->y = render_spu.defaultY;
	window->width  = render_spu.defaultWidth;
	window->height = render_spu.defaultHeight;

	if ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER"))
		showIt = 0;
	else
		showIt = window->id > 0;

	/* Set window->title, replacing %i with the window ID number */
	{
		const char *s = crStrstr(render_spu.window_title, "%i");
		if (s) {
			int i, j, k;
			window->title = crAlloc(crStrlen(render_spu.window_title) + 10);
			for (i = 0; render_spu.window_title[i] != '%'; i++)
				window->title[i] = render_spu.window_title[i];
			k = sprintf(window->title + i, "%d", window->id);
			CRASSERT(k < 10);
			i++; /* skip the 'i' after the '%' */
			j = i + k;
			for (; (window->title[j] = s[i]) != 0; i++, j++)
				;
		}
		else {
			window->title = crStrdup(render_spu.window_title);
		}
	}

	/*
	crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->id);
	*/
	/* Have GLX/WGL/AGL create the window */
	if (!renderspu_SystemCreateWindow( visual, showIt, window ))
	{
		crFree(window);
		crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
		return -1;
	}

	CRASSERT(window->visual == visual);

	return window->id;
}
Example #15
0
static void crStateGLSLCreateProgramCB(unsigned long key, void *data1, void *data2)
{
    CRGLSLProgram *pProgram = (CRGLSLProgram*) data1;
    CRContext *ctx = (CRContext *) data2;
    GLuint i;

    pProgram->hwid = diff_api.CreateProgram();

    if (pProgram->linked)
    {
        CRASSERT(pProgram->activeState.attachedShaders);

        crHashtableWalk(pProgram->activeState.attachedShaders, crStateFixAttachedShaderHWIDsCB, ctx);
        crHashtableWalk(pProgram->activeState.attachedShaders, crStateAttachShaderCB, pProgram);

        for (i=0; i<pProgram->activeState.cAttribs; ++i)
        {
            diff_api.BindAttribLocation(pProgram->hwid, pProgram->activeState.pAttribs[i].index, pProgram->activeState.pAttribs[i].name);
        }

        if (pProgram->validated)
            diff_api.ValidateProgram(pProgram->hwid);

        diff_api.LinkProgram(pProgram->hwid);
    }

    diff_api.UseProgram(pProgram->hwid);

    for (i=0; i<pProgram->cUniforms; ++i)
    {
        GLint location;
        GLfloat *pFdata = (GLfloat*)pProgram->pUniforms[i].data;
        GLint *pIdata = (GLint*)pProgram->pUniforms[i].data;

        location = diff_api.GetUniformLocation(pProgram->hwid, pProgram->pUniforms[i].name);
        switch (pProgram->pUniforms[i].type)
        {
            case GL_FLOAT:
                diff_api.Uniform1fv(location, 1, pFdata);
                break;
            case GL_FLOAT_VEC2:
                diff_api.Uniform2fv(location, 1, pFdata);
                break;
            case GL_FLOAT_VEC3:
                diff_api.Uniform3fv(location, 1, pFdata);
                break;
            case GL_FLOAT_VEC4:
                diff_api.Uniform4fv(location, 1, pFdata);
                break;
            case GL_INT:
            case GL_BOOL:
                diff_api.Uniform1iv(location, 1, pIdata);
                break;
            case GL_INT_VEC2:
            case GL_BOOL_VEC2:
                diff_api.Uniform2iv(location, 1, pIdata);
                break;
            case GL_INT_VEC3:
            case GL_BOOL_VEC3:
                diff_api.Uniform3iv(location, 1, pIdata);
                break;
            case GL_INT_VEC4:
            case GL_BOOL_VEC4:
                diff_api.Uniform4iv(location, 1, pIdata);
                break;
            case GL_FLOAT_MAT2:
                diff_api.UniformMatrix2fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_FLOAT_MAT3:
                diff_api.UniformMatrix3fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_FLOAT_MAT4:
                diff_api.UniformMatrix4fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_SAMPLER_1D:
            case GL_SAMPLER_2D:
            case GL_SAMPLER_3D:
            case GL_SAMPLER_CUBE:
            case GL_SAMPLER_1D_SHADOW:
            case GL_SAMPLER_2D_SHADOW:
            case GL_SAMPLER_2D_RECT_ARB:
            case GL_SAMPLER_2D_RECT_SHADOW_ARB:
                diff_api.Uniform1iv(location, 1, pIdata);
                break;
#ifdef CR_OPENGL_VERSION_2_1
            case GL_FLOAT_MAT2x3:
                diff_api.UniformMatrix2x3fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_FLOAT_MAT2x4:
                diff_api.UniformMatrix2x4fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_FLOAT_MAT3x2:
                diff_api.UniformMatrix3x2fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_FLOAT_MAT3x4:
                diff_api.UniformMatrix3x4fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_FLOAT_MAT4x2:
                diff_api.UniformMatrix4x2fv(location, 1, GL_FALSE, pFdata);
                break;
            case GL_FLOAT_MAT4x3:
                diff_api.UniformMatrix4x3fv(location, 1, GL_FALSE, pFdata);
                break;
#endif
        default:
            crWarning("crStateGLSLCreateProgramCB: unknown uniform type 0x%x", (GLint)pProgram->pUniforms[i].type);
            break;
        }
        crFree(pProgram->pUniforms[i].data);
        crFree(pProgram->pUniforms[i].name);
    } /*for (i=0; i<pProgram->cUniforms; ++i)*/
    if (pProgram->pUniforms) crFree(pProgram->pUniforms);
    pProgram->pUniforms = NULL;
    pProgram->cUniforms = 0;

    crHashtableWalk(pProgram->activeState.attachedShaders, crStateDetachShaderCB, pProgram);
    crHashtableWalk(pProgram->currentState.attachedShaders, crStateAttachShaderCB, pProgram);
}
Example #16
0
void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
{
    int i;
    GET_THREAD(thread);

    if (thread)
    {
        crLockMutex(&_PackMutex);

        for (i=0; i<MAX_THREADS; ++i)
        {
            if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
                && thread->id==crThreadID() && thread->netServer.conn)
            {
                CRASSERT(pack_spu.numThreads>0);

                packspuFlush((void *) thread);

                if (pack_spu.thread[i].packer)
                {
                    CR_LOCK_PACKER_CONTEXT(thread->packer);
                    crPackSetContext(NULL);
                    CR_UNLOCK_PACKER_CONTEXT(thread->packer);
                    crPackDeleteContext(pack_spu.thread[i].packer);
                }
                crNetFreeConnection(pack_spu.thread[i].netServer.conn);

                pack_spu.numThreads--;
                /*note can't shift the array here, because other threads have TLS references to array elements*/
                crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));

                crSetTSD(&_PackTSD, NULL);

                if (i==pack_spu.idxThreadInUse)
                {
                    for (i=0; i<MAX_THREADS; ++i)
                    {
                        if (pack_spu.thread[i].inUse)
                        {
                            pack_spu.idxThreadInUse=i;
                            break;
                        }
                    }
                }

                break;
            }
        }

        for (i=0; i<CR_MAX_CONTEXTS; ++i)
        {
            ContextInfo *ctx = &pack_spu.context[i];
            if (ctx->currentThread == thread)
            {
                CRASSERT(ctx->fAutoFlush);
                ctx->currentThread = NULL;
            }
        }

        crUnlockMutex(&_PackMutex);
    }
}
Example #17
0
DECLEXPORT(void) STATE_APIENTRY 
crStateGLSLProgramCacheUniforms(GLuint program, GLsizei cbData, GLvoid *pData)
{
    CRGLSLProgram *pProgram = crStateGetProgramObj(program);
    char *pCurrent = pData;
    GLsizei cbRead, cbName;
    GLuint i;

    if (!pProgram)
    {
        crWarning("Unknown program %d", program);
        return;
    }

    if (pProgram->bUniformsSynced)
    {
        crWarning("crStateGLSLProgramCacheUniforms: this shouldn't happen!");
        crStateFreeProgramUniforms(pProgram);
    }

    if (cbData<sizeof(GLsizei))
    {
        crWarning("crStateGLSLProgramCacheUniforms: data too short");
        return;
    }

    pProgram->cUniforms = ((GLsizei*)pCurrent)[0];
    pCurrent += sizeof(GLsizei);
    cbRead = sizeof(GLsizei);

    crDebug("crStateGLSLProgramCacheUniforms: %i active uniforms", pProgram->cUniforms);

    if (pProgram->cUniforms)
    {
        pProgram->pUniforms = crAlloc(pProgram->cUniforms*sizeof(CRGLSLUniform));
        if (!pProgram->pUniforms)
        {
            crWarning("crStateGLSLProgramCacheUniforms: no memory");
            pProgram->cUniforms = 0;
            return;
        }
    }

    for (i=0; i<pProgram->cUniforms; ++i)
    {
        cbRead += sizeof(GLuint)+sizeof(GLsizei);
        if (cbRead>cbData)
        {
            crWarning("crStateGLSLProgramCacheUniforms: out of data reading uniform %i", i);
            return;
        }
        pProgram->pUniforms[i].data = NULL;
        pProgram->pUniforms[i].location = ((GLint*)pCurrent)[0];
        pCurrent += sizeof(GLint);
        cbName = ((GLsizei*)pCurrent)[0];
        pCurrent += sizeof(GLsizei);

        cbRead += cbName;
        if (cbRead>cbData)
        {
            crWarning("crStateGLSLProgramCacheUniforms: out of data reading uniform's name %i", i);
            return;
        }

        pProgram->pUniforms[i].name = crStrndup(pCurrent, cbName);
        pCurrent += cbName;

        crDebug("crStateGLSLProgramCacheUniforms: uniform[%i]=%d, %s", i, pProgram->pUniforms[i].location, pProgram->pUniforms[i].name);
    }

    pProgram->bUniformsSynced = GL_TRUE;

    CRASSERT((pCurrent-((char*)pData))==cbRead);
    CRASSERT(cbRead==cbData);
}
Example #18
0
void REPLICATESPU_APIENTRY
replicatespu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
{
	unsigned int i;
	unsigned int show_window = 0;
	WindowInfo *winInfo = (WindowInfo *) crHashtableSearch( replicate_spu.windowTable, window );
	ContextInfo *newCtx = (ContextInfo *) crHashtableSearch( replicate_spu.contextTable, ctx );
	GET_THREAD(thread);

	if (!winInfo) {
		crWarning("Replicate SPU: Invalid window ID %d passed to MakeCurrent", window);
		return;
	}

	if (thread)
		replicatespuFlushAll( (void *)thread );

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

	if (newCtx && winInfo) {
		newCtx->currentWindow = winInfo;

#if 000
		/* This appears to be obsolete code */
		if (replicate_spu.render_to_crut_window && !nativeWindow) {
			char response[8096];
			CRConnection *conn = crMothershipConnect();
			if (!conn) {
				crError("Replicate SPU: Couldn't connect to the mothership to get CRUT drawable-- "
								"I have no idea what to do!");
			}
			crMothershipGetParam( conn, "crut_drawable", response );
			nativeWindow = crStrToInt(response);
			crDebug("Replicate SPU: using CRUT drawable: 0x%x", nativeWindow);
			crMothershipDisconnect(conn);
		}
#endif

		if (replicate_spu.glx_display
				&& winInfo
				&& winInfo->nativeWindow != nativeWindow)
		{
			winInfo->nativeWindow = nativeWindow;
			replicatespuMonitorWindow(winInfo);
			replicatespuRePositionWindow(winInfo);
			show_window = 1;
		}

		CRASSERT(newCtx->State);  /* verify valid */

		crPackSetContext( thread->packer );
	}

	/*
	 * Send the MakeCurrent to all crservers (vnc viewers)
	 */
	for (i = 0; i < CR_MAX_REPLICANTS; i++) {
		const GLint serverWin = winInfo ? winInfo->id[i] : -1;
		const GLint serverCtx = newCtx ? newCtx->rserverCtx[i] : -1;

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

		/* Note: app's native window ID not needed on server side; pass zero */
		if (replicate_spu.swap)
			crPackMakeCurrentSWAP(serverWin, 0, serverCtx);
		else
			crPackMakeCurrent(serverWin, 0, serverCtx);

		if (show_window) {
			/* We may find that the window was mapped before we
			 * called MakeCurrent, if that's the case then ensure
			 * the remote end gets the WindowShow event */
			if (winInfo->viewable) {
				if (replicate_spu.swap)
					crPackWindowShowSWAP(serverWin, GL_TRUE);
				else
					crPackWindowShow(serverWin, GL_TRUE);
			}
		}

		replicatespuFlushOne(thread, i);
	}

	if (newCtx) {
		crStateMakeCurrent( newCtx->State );
		crDLMSetCurrentState(newCtx->dlmState);
	}
	else {
		crStateMakeCurrent( NULL );
		crDLMSetCurrentState(NULL);
	}

	thread->currentContext = newCtx;
}
void STATE_APIENTRY
crStateBindBufferARB (GLenum target, GLuint buffer)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &(g->bufferobject);
    CRStateBits *sb = GetCurrentBits();
    CRBufferObjectBits *bb = &(sb->bufferobject);
    CRBufferObject *oldObj, *newObj;

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glBindBufferARB called in begin/end");
        return;
    }

    FLUSH();

    oldObj = crStateGetBoundBufferObject(target, b);
    if (!oldObj)
    {
        crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glBindBufferARB(target)");
        return;
    }

    if (buffer == 0) {
        newObj = b->nullBuffer;
    }
    else {
        newObj = (CRBufferObject *) crHashtableSearch(g->shared->buffersTable, buffer);
        if (!newObj) {
            newObj = AllocBufferObject(buffer);
            if (!newObj) {
                crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glBindBuffer");
                return;
            }
            crHashtableAdd( g->shared->buffersTable, buffer, newObj );
        }
    }

    newObj->refCount++;
    oldObj->refCount--;

    switch (target)
    {
        case GL_ARRAY_BUFFER_ARB:
            b->arrayBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->arrayBinding, g->neg_bitid);
            break;
        case GL_ELEMENT_ARRAY_BUFFER_ARB:
            b->elementsBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->elementsBinding, g->neg_bitid);
            break;
#ifdef CR_ARB_pixel_buffer_object
        case GL_PIXEL_PACK_BUFFER_ARB:
            b->packBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->packBinding, g->neg_bitid);
            break;
        case GL_PIXEL_UNPACK_BUFFER_ARB:
            b->unpackBuffer = newObj;
            DIRTY(bb->dirty, g->neg_bitid);
            DIRTY(bb->unpackBinding, g->neg_bitid);
            break;
#endif
        default: /*can't get here*/
            CRASSERT(false);
            return;
    }

    if (oldObj->refCount <= 0) {
        /*we shouldn't reach this point*/
        CRASSERT(false);
        crHashtableDelete(g->shared->buffersTable, (unsigned long) oldObj->id, crStateFreeBufferObject);
    }

#ifdef IN_GUEST
    if (target == GL_PIXEL_PACK_BUFFER_ARB)
    {
        newObj->bResyncOnRead = GL_TRUE;
    }
#endif
}
Example #20
0
/**
 * Determine if the X VNC extension is available.
 * Get list of clients/viewers attached, and replicate to them.
 * Can't call this until we have an X display name (see CreateContext).
 */
static void
replicatespuStartVnc(const char *dpyName)
{
	int maj, min;

#ifdef CHROMIUM_THREADSAFE_notyet
	crLockMutex(&_ReplicateMutex);
#endif

	if (replicate_spu.StartedVnc) {
#ifdef CHROMIUM_THREADSAFE_notyet
		crUnlockMutex(&_ReplicateMutex);
#endif
		return;
	}

#ifdef CHROMIUM_THREADSAFE_notyet
	crUnlockMutex(&_ReplicateMutex);
#endif

	/* Open the named display */
	if (!replicate_spu.glx_display) {
		replicate_spu.glx_display = XOpenDisplay(dpyName);
		if (!replicate_spu.glx_display) {
			/* Try local display */
			crWarning("Replicate SPU: Unable to open X display %s, trying :0 next",
								dpyName);
			replicate_spu.glx_display = XOpenDisplay(":0");
		}
		if (!replicate_spu.glx_display) {
			crError("Replicate SPU: Unable to open X display :0");
		}
	}

	CRASSERT(replicate_spu.glx_display);

	/* NOTE: should probably check the major/minor version too!! */
	if (!XVncQueryExtension(replicate_spu.glx_display, &maj, &min)) {
		crWarning("Replicate SPU: X server VNC extension is not available.");
		replicate_spu.vncAvailable = GL_FALSE;
	} else {
		crWarning("Replicate SPU: X server VNC extension available.");
		replicate_spu.vncAvailable = GL_TRUE;
	}

	if (replicate_spu.vncAvailable) {
		VncConnectionList *vnclist;
		int num_conn;
		int i;

		replicate_spu.VncEventsBase = XVncGetEventBase(replicate_spu.glx_display);
		XVncSelectNotify(replicate_spu.glx_display, 1);

		vnclist = XVncListConnections(replicate_spu.glx_display, &num_conn);
		crDebug("Replicate SPU: Found %d open VNC connections", num_conn);
		for (i = 0; i < num_conn; i++) {
			if (vnclist[i].ipaddress) {
				replicatespuReplicate(vnclist[i].ipaddress);
			}
			else {
				crWarning("Replicate SPU: vnc client connection with no ipaddress!");
			}
		}

	}

	replicate_spu.StartedVnc = 1;
}
Example #21
0
int
main(int argc, char *argv[])
{
	const int port = 10000;
	CRConnection *conn[MAX_SERVERS];
	const char *servers[MAX_SERVERS];
	int numServers = 0;
	int bufferSize = 10000;
	int numBuffers = 10;
	int autoMode = 0;
	int size;
	int i, j;

	if (argc < 2) {
		PrintHelp();
		return 0;
	}

	for (i = 1; i < argc; i++) {
		if (!crStrcmp(argv[i], "-a")) {
			autoMode = 1;
		}
		else if (!crStrcmp(argv[i], "-b") && (i + 1 < argc)) {
			bufferSize = crStrToInt(argv[i + 1]);
			i++;
		}
		else if (!crStrcmp(argv[i], "-h")) {
			PrintHelp();
			return 0;
		}
		else if (!crStrcmp(argv[i], "-m") && (i + 1 < argc)) {
			MTU = crStrToInt(argv[i + 1]);
			i++;
		}
		else if (!crStrcmp(argv[i], "-n") && (i + 1 < argc)) {
			numBuffers = crStrToInt(argv[i + 1]);
			i++;
		}
		else if ((argv[i][0] != '-') && (numServers < MAX_SERVERS)) {
			servers[numServers] = argv[i];
			numServers++;
		}
	}

	if (numServers == 0) {
		printf("npclient error: need to specify at least one server\n");
		return 1;
	}

	if (autoMode)
		printf("npclient:  MTU=%d  (automatic buffer sizing)\n", MTU);
	else
		printf("npclient:  MTU=%d  bufferSize=%d  numBuffers=%d\n",
					 MTU, bufferSize, numBuffers);

	MyTimer = crTimerNewTimer();
	crNetInit( ReceiveFunc, CloseFunc );

	printf("npclient:  Connecting to servers\n");
	for (i = 0; i < numServers; i++) {
		conn[i] = crNetConnectToServer(servers[i], (unsigned short) port, MTU, 0);
		if (conn[i]) {
			printf("npclient:  Connection to %s OK.\n", servers[i]);
		}
		else {
			printf("npclient:  Connection to %s failed!\n", servers[i]);
			exit(1);
		}
	}

	printf("npclient:  Testing...\n");

	if (autoMode) {
		bufferSize = 10000;
		for (size = 0; size < 5; size++) {
			double t0, t1, dt, rate;
			double bytes;
			int buffers;

			bytes = 0.0;
			buffers = 0;
			crStartTimer(MyTimer);
			t0 = crTimerTime(MyTimer);

			do {
				for (j = 0; j < numServers; j++) {
					SendOpcodes(conn[j], bufferSize, 0);
				}
				bytes += (double) bufferSize;
				buffers++;
				t1 = crTimerTime(MyTimer);
			} while (t1 - t0 < 5.0);

			crStopTimer(MyTimer);

			dt = t1 - t0;
			rate = (double) bytes / dt / 1000000.0;
			printf("npclient:  %8.3f MB/s (%d bytes / buffer, %d buffers, %d servers)\n",
						 rate, bufferSize, buffers, numServers);
			if (rate < 0.0) {
				char *t = 0;
				*t = 0;
				CRASSERT(rate >= 0.0);
			}
			bufferSize *= 10;
		}
	}
	else {
		double t0, t1, dt, rate;
		double bytes;

		crStartTimer(MyTimer);
		t0 = crTimerTime(MyTimer);
		bytes = 0.0;
		for (i = 0; i < numBuffers; i++) {
			for (j = 0; j < numServers; j++) {
				SendOpcodes(conn[j], bufferSize, 0);
			}
			bytes += (double) bufferSize;
		}
		t1 = crTimerTime(MyTimer);

		dt = t1 - t0;
		rate = (double) bytes / dt / 1000000.0;
		printf("npclient:  %8.3f MB/s (%d bytes / buffer, %d buffers, %d servers)\n",
					 rate, bufferSize, numBuffers, numServers);
	}


	/* Send exit message to servers */
	for (j = 0; j < numServers; j++) {
		SendOpcodes(conn[j], 100, 1);
	}

	for (j = 0; j < numServers; j++) {
		crNetDisconnect(conn[j]);
	}

	printf("npclient:  done!\n");

	return 0;
}
void SERVER_DISPATCH_APIENTRY
crServerDispatchDestroyContext( GLint ctx )
{
    CRContextInfo *crCtxInfo;
    CRContext *crCtx;
    int32_t client;
    CRClientNode *pNode;
    int found=false;

    crCtxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, ctx);
    if (!crCtxInfo) {
        crWarning("CRServer: DestroyContext invalid context %d", ctx);
        return;
    }
    crCtx = crCtxInfo->pContext;
    CRASSERT(crCtx);

    crDebug("CRServer: DestroyContext context %d", ctx);

    if (cr_server.currentCtxInfo == crCtxInfo)
    {
        CRMuralInfo *dummyMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits);
        crServerPerformMakeCurrent(dummyMural, &cr_server.MainContextInfo);
        CRASSERT(cr_server.currentCtxInfo == &cr_server.MainContextInfo);
    }

    crHashtableWalk(cr_server.muralTable, crServerCleanupMuralCtxUsageCB, crCtx);
    crCtxInfo->currentMural = NULL;
    crHashtableDelete(cr_server.contextTable, ctx, NULL);
    crStateDestroyContext( crCtx );

    if (crCtxInfo->CreateInfo.pszDpyName)
        crFree(crCtxInfo->CreateInfo.pszDpyName);

    if (crCtxInfo->SpuContext >= 0)
        cr_server.head_spu->dispatch_table.DestroyContext(crCtxInfo->SpuContext);

    crFree(crCtxInfo);

    if (cr_server.curClient)
    {
        /* If we delete our current context, default back to the null context */
        if (cr_server.curClient->currentCtxInfo == crCtxInfo) {
            cr_server.curClient->currentContextNumber = -1;
            cr_server.curClient->currentCtxInfo = &cr_server.MainContextInfo;
        }

        found = crServerRemoveClientContext(cr_server.curClient, ctx);

        /*Some application call destroy context not in a thread where it was created...have do deal with it.*/
        if (!found)
        {
            for (client=0; client<cr_server.numClients; ++client)
            {
                if (cr_server.clients[client]==cr_server.curClient)
                    continue;

                found = crServerRemoveClientContext(cr_server.clients[client], ctx);

                if (found) break;
            }
        }

        if (!found)
        {
            pNode=cr_server.pCleanupClient;

            while (pNode && !found)
            {
                found = crServerRemoveClientContext(pNode->pClient, ctx);
                pNode = pNode->next;
            }
        }

        CRASSERT(found);
    }

    /*Make sure this context isn't active in other clients*/
    for (client=0; client<cr_server.numClients; ++client)
    {
        if (cr_server.clients[client]->currentCtxInfo == crCtxInfo)
        {
            cr_server.clients[client]->currentContextNumber = -1;
            cr_server.clients[client]->currentCtxInfo = &cr_server.MainContextInfo;
        }
    }

    pNode=cr_server.pCleanupClient;
    while (pNode)
    {
        if (pNode->pClient->currentCtxInfo == crCtxInfo)
        {
            pNode->pClient->currentContextNumber = -1;
            pNode->pClient->currentCtxInfo = &cr_server.MainContextInfo;
        }
        pNode = pNode->next;
    }

    CRASSERT(cr_server.currentCtxInfo != crCtxInfo);
}
Example #23
0
DECLEXPORT(int32_t) crVBoxServerSaveState(PSSMHANDLE pSSM)
{
    int32_t  rc, i;
    uint32_t ui32;
    GLboolean b;
    unsigned long key;
#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    unsigned long ctxID=-1, winID=-1;
#endif

    /* We shouldn't be called if there's no clients at all*/
    CRASSERT(cr_server.numClients>0);

    /* @todo it's hack atm */
    /* We want to be called only once to save server state but atm we're being called from svcSaveState
     * for every connected client (e.g. guest opengl application)
     */
    if (!cr_server.bIsInSavingState) /* It's first call */
    {
        cr_server.bIsInSavingState = GL_TRUE;

        /* Store number of clients */
        rc = SSMR3PutU32(pSSM, (uint32_t) cr_server.numClients);
        AssertRCReturn(rc, rc);

        g_hackVBoxServerSaveLoadCallsLeft = cr_server.numClients;
    }

    g_hackVBoxServerSaveLoadCallsLeft--;

    /* Do nothing until we're being called last time */
    if (g_hackVBoxServerSaveLoadCallsLeft>0)
    {
        return VINF_SUCCESS;
    }

    /* Save rendering contexts creation info */
    ui32 = crHashtableNumElements(cr_server.pContextCreateInfoTable);
    rc = SSMR3PutU32(pSSM, (uint32_t) ui32);
    AssertRCReturn(rc, rc);
    crHashtableWalk(cr_server.pContextCreateInfoTable, crVBoxServerSaveCreateInfoCB, pSSM);

#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    /* Save current win and ctx IDs, as we'd rebind contexts when saving textures */
    if (cr_server.curClient)
    {
        ctxID = cr_server.curClient->currentContextNumber;
        winID = cr_server.curClient->currentWindow;
    }
#endif

    /* Save contexts state tracker data */
    /* @todo For now just some blind data dumps,
     * but I've a feeling those should be saved/restored in a very strict sequence to
     * allow diff_api to work correctly.
     * Should be tested more with multiply guest opengl apps working when saving VM snapshot.
     */
    crHashtableWalk(cr_server.contextTable, crVBoxServerSaveContextStateCB, pSSM);

#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    /* Restore original win and ctx IDs*/
    if (cr_server.curClient)
    {
        crServerDispatchMakeCurrent(winID, 0, ctxID);
    }
#endif

    /* Save windows creation info */
    ui32 = crHashtableNumElements(cr_server.pWindowCreateInfoTable);
    rc = SSMR3PutU32(pSSM, (uint32_t) ui32);
    AssertRCReturn(rc, rc);
    crHashtableWalk(cr_server.pWindowCreateInfoTable, crVBoxServerSaveCreateInfoCB, pSSM);

    /* Save cr_server.muralTable
     * @todo we don't need it all, just geometry info actually
     */
    ui32 = crHashtableNumElements(cr_server.muralTable);
    /* There should be default mural always */
    CRASSERT(ui32>=1);
    rc = SSMR3PutU32(pSSM, (uint32_t) ui32-1);
    AssertRCReturn(rc, rc);
    crHashtableWalk(cr_server.muralTable, crVBoxServerSaveMuralCB, pSSM);

    /* Save starting free context and window IDs */
    rc = SSMR3PutMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool));
    AssertRCReturn(rc, rc);

    /* Save clients info */
    for (i = 0; i < cr_server.numClients; i++)
    {
        if (cr_server.clients[i] && cr_server.clients[i]->conn)
        {
            CRClient *pClient = cr_server.clients[i];

            rc = SSMR3PutU32(pSSM, pClient->conn->u32ClientID);
            AssertRCReturn(rc, rc);

            rc = SSMR3PutU32(pSSM, pClient->conn->vMajor);
            AssertRCReturn(rc, rc);

            rc = SSMR3PutU32(pSSM, pClient->conn->vMinor);
            AssertRCReturn(rc, rc);

            rc = SSMR3PutMem(pSSM, pClient, sizeof(*pClient));
            AssertRCReturn(rc, rc);

            if (pClient->currentCtx && pClient->currentContextNumber>=0)
            {
                b = crHashtableGetDataKey(cr_server.contextTable, pClient->currentCtx, &key);
                CRASSERT(b);
                rc = SSMR3PutMem(pSSM, &key, sizeof(key));
                AssertRCReturn(rc, rc);
            }

            if (pClient->currentMural && pClient->currentWindow>=0)
            {
                b = crHashtableGetDataKey(cr_server.muralTable, pClient->currentMural, &key);
                CRASSERT(b);
                rc = SSMR3PutMem(pSSM, &key, sizeof(key));
                AssertRCReturn(rc, rc);
            }
        }
    }

    cr_server.bIsInSavingState = GL_FALSE;

    return VINF_SUCCESS;
}
GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID)
{
    GLint retVal = -1;
    CRContext *newCtx;
    CRContextInfo *pContextInfo;
    GLboolean fFirst = GL_FALSE;

    dpyName = "";

    if (shareCtx > 0) {
        crWarning("CRServer: context sharing not implemented.");
        shareCtx = 0;
    }

    pContextInfo = (CRContextInfo *) crAlloc(sizeof (CRContextInfo));
    if (!pContextInfo)
    {
        crWarning("failed to alloc context info!");
        return -1;
    }

    pContextInfo->currentMural = NULL;

    pContextInfo->CreateInfo.requestedVisualBits = visualBits;

    if (cr_server.fVisualBitsDefault)
        visualBits = cr_server.fVisualBitsDefault;

    pContextInfo->CreateInfo.realVisualBits = visualBits;

    /* Since the Cr server serialized all incoming clients/contexts into
     * one outgoing GL stream, we only need to create one context for the
     * head SPU.  We'll only have to make it current once too, below.
     */
    if (cr_server.firstCallCreateContext) {
        cr_server.MainContextInfo.CreateInfo.realVisualBits = visualBits;
        cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table.
            CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, shareCtx);
        if (cr_server.MainContextInfo.SpuContext < 0) {
            crWarning("crServerDispatchCreateContext() failed.");
            crFree(pContextInfo);
            return -1;
        }
        cr_server.MainContextInfo.pContext = crStateCreateContext(&cr_server.limits, visualBits, NULL);
        CRASSERT(cr_server.MainContextInfo.pContext);
        cr_server.firstCallCreateContext = GL_FALSE;
        fFirst = GL_TRUE;

        cr_server.head_spu->dispatch_table.ChromiumParameteriCR(GL_HH_SET_DEFAULT_SHARED_CTX, cr_server.MainContextInfo.SpuContext);
    }
    else {
        /* second or third or ... context */
        if (!cr_server.bUseMultipleContexts && ((visualBits & cr_server.MainContextInfo.CreateInfo.realVisualBits) != visualBits)) {
            int oldSpuContext;
            /* should never be here */
            CRASSERT(0);
            /* the new context needs new visual attributes */
            cr_server.MainContextInfo.CreateInfo.realVisualBits |= visualBits;
            crWarning("crServerDispatchCreateContext requires new visual (0x%x).",
                    cr_server.MainContextInfo.CreateInfo.realVisualBits);

            /* Here, we used to just destroy the old rendering context.
             * Unfortunately, this had the side effect of destroying
             * all display lists and textures that had been loaded on
             * the old context as well.
             *
             * Now, first try to create a new context, with a suitable
             * visual, sharing display lists and textures with the
             * old context.  Then destroy the old context.
             */

            /* create new rendering context with suitable visual */
            oldSpuContext = cr_server.MainContextInfo.SpuContext;
            cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table.
                CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, cr_server.MainContextInfo.SpuContext);
            /* destroy old rendering context */
            cr_server.head_spu->dispatch_table.DestroyContext(oldSpuContext);
            if (cr_server.MainContextInfo.SpuContext < 0) {
                crWarning("crServerDispatchCreateContext() failed.");
                crFree(pContextInfo);
                return -1;
            }

            /* we do not need to clean up the old default context explicitly, since the above cr_server.head_spu->dispatch_table.DestroyContext call
             * will do that for us */
            cr_server.head_spu->dispatch_table.ChromiumParameteriCR(GL_HH_SET_DEFAULT_SHARED_CTX, cr_server.MainContextInfo.SpuContext);
        }
    }

    if (cr_server.bUseMultipleContexts) {
        pContextInfo->SpuContext = cr_server.head_spu->dispatch_table.
                CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, cr_server.MainContextInfo.SpuContext);
        if (pContextInfo->SpuContext < 0) {
            crWarning("crServerDispatchCreateContext() failed.");
            crStateEnableDiffOnMakeCurrent(GL_TRUE);
            cr_server.bUseMultipleContexts = GL_FALSE;
            if (!fFirst)
                crError("creating shared context failed, while it is expected to work!");
        }
        else if (fFirst)
        {
            crStateEnableDiffOnMakeCurrent(GL_FALSE);
        }
    }
    else
    {
        pContextInfo->SpuContext = -1;
    }

    /* Now create a new state-tracker context and initialize the
     * dispatch function pointers.
     */
    newCtx = crStateCreateContextEx(&cr_server.limits, visualBits, NULL, internalID);
    if (newCtx) {
        crStateSetCurrentPointers( newCtx, &(cr_server.current) );
        crStateResetCurrentPointers(&(cr_server.current));
        retVal = preloadCtxID<0 ? (GLint)crHashtableAllocKeys( cr_server.contextTable, 1 ) : preloadCtxID;

        pContextInfo->pContext = newCtx;
        Assert(pContextInfo->CreateInfo.realVisualBits == visualBits);
        pContextInfo->CreateInfo.externalID = retVal;
        pContextInfo->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
        crHashtableAdd(cr_server.contextTable, retVal, pContextInfo);
    }

    if (retVal != -1 && !cr_server.bIsInLoadingState) {
        int pos;
        for (pos = 0; pos < CR_MAX_CONTEXTS; pos++) {
            if (cr_server.curClient->contextList[pos] == 0) {
                cr_server.curClient->contextList[pos] = retVal;
                break;
            }
        }
    }

    crServerReturnValue( &retVal, sizeof(retVal) );

    return retVal;
}
Example #25
0
/**
 * Transform a bounding box from object space to NDC space.
 * This routine is used by most of the bucketing algorithms.
 * \param  winInfo - which window/mural
 * \param      server - which server (usually not needed)
 * \param      objMin, objMax - bounds in object space
 * \param xmin, ymin, zmin, xmax, ymax, zmax - bounds in NDC
 * \param      ibounds - bounds in screen coords
 * \return  GL_TRUE if the resulting screen-space NDC bbox is visible,
 *         GL_FALSE if the resulting screen-space NDC bbox is not visible.
 */
static GLboolean
TransformBBox(const WindowInfo *winInfo, int server,
							const GLvectorf *objMin, const GLvectorf *objMax,
							float *xmin, float *ymin, float *zmin,
							float *xmax, float *ymax, float *zmax,
							CRrecti *ibounds)
{
	GET_THREAD(thread);
	CRContext *g = thread->currentContext->State;
	CRTransformState *t = &(g->transform);

	if (thread->currentContext->providedBBOX == GL_SCREEN_BBOX_CR) {
		/* objMin, objMax are in NDC screen coords already */
		*xmin = objMin->x;
		*ymin = objMin->y;
		*zmin = objMin->z;
		*xmax = objMax->x;
		*ymax = objMax->y;
		*zmax = objMax->z;
	}
	else if (winInfo->matrixSource == MATRIX_SOURCE_SERVERS) {
		/* Use matrices obtained from the servers */
		const ServerWindowInfo *servWinInfo = winInfo->server + server;
		CRmatrix pv, pvm;
		int eye = (thread->currentContext->stereoDestFlags & EYE_RIGHT) ? 1:0;

		/* XXX \todo we could multiply this earlier! */
		/* pv = proj matrix * view matrix */
		crMatrixMultiply(&pv, &servWinInfo->projectionMatrix[eye],
														&servWinInfo->viewMatrix[eye]);
		/* pvm = pv * model matrix */
		crMatrixMultiply(&pvm, &pv, t->modelViewStack.top);

		/* Transform bbox by modelview * projection, and project to screen */
		crTransformBBox( objMin->x, objMin->y, objMin->z,
										 objMax->x, objMax->y, objMax->z, &pvm,
										 xmin, ymin, zmin, xmax, ymax, zmax );
	}
	else if (winInfo->matrixSource == MATRIX_SOURCE_CONFIG &&
					 thread->currentContext->stereoDestFlags != (EYE_LEFT | EYE_RIGHT)) {
		/* use special left or right eye matrices (set via config options) */
		const int curEye = thread->currentContext->stereoDestFlags - 1;
		CRmatrix pv, pvm;

		CRASSERT(curEye == 0 || curEye == 1);

		/* XXX \todo we could multiply this earlier! */
		/* pv = proj matrix * view matrix */
		crMatrixMultiply(&pv, &tilesort_spu.stereoProjMatrices[curEye],
														&tilesort_spu.stereoViewMatrices[curEye]);
		/* pvm = pv * model matrix */
		crMatrixMultiply(&pvm, &pv, t->modelViewStack.top);

		/* Transform bbox by modelview * projection, and project to screen */
		crTransformBBox( objMin->x, objMin->y, objMin->z,
										 objMax->x, objMax->y, objMax->z, &pvm,
										 xmin, ymin, zmin, xmax, ymax, zmax );
	}
	else {
		const CRmatrix *mvp = &(t->modelViewProjection);

		CRASSERT(winInfo->matrixSource == MATRIX_SOURCE_APP ||
				 thread->currentContext->stereoDestFlags == (EYE_LEFT | EYE_RIGHT));

		/* Check to make sure the transform is valid */
		if (!t->modelViewProjectionValid)
		{
			/* I'm pretty sure this is always the case, but I'll leave it. */
			crStateTransformUpdateTransform(t);
		}

		/* Transform bbox by modelview * projection, and project to screen */
		crTransformBBox( objMin->x, objMin->y, objMin->z,
										 objMax->x, objMax->y, objMax->z, mvp,
										 xmin, ymin, zmin, xmax, ymax, zmax );
	}

	/* trivial rejection test */
	if (*xmin > 1.0f || *ymin > 1.0f || *xmax < -1.0f || *ymax < -1.0f) {
		/* bbox doesn't intersect screen */
		return GL_FALSE;
	}

	/* clamp */
	if (*xmin < -1.0f) *xmin = -1.0f;
	if (*ymin < -1.0f) *ymin = -1.0f;
	if (*xmax > 1.0f) *xmax = 1.0f;
	if (*ymax > 1.0f) *ymax = 1.0f;

	if (ibounds) {
		/* return screen pixel coords too */
		ibounds->x1 = (int) (winInfo->halfViewportWidth * *xmin + winInfo->viewportCenterX);
		ibounds->x2 = (int) (winInfo->halfViewportWidth * *xmax + winInfo->viewportCenterX);
		ibounds->y1 = (int) (winInfo->halfViewportHeight * *ymin + winInfo->viewportCenterY);
		ibounds->y2 = (int) (winInfo->halfViewportHeight * *ymax + winInfo->viewportCenterY);
	}
	return GL_TRUE;
}
void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo )
{
    CRMuralInfo *oldMural;
    CRContext *ctx, *oldCtx = NULL;
    GLuint idDrawFBO, idReadFBO;
    GLint context = ctxInfo->CreateInfo.externalID;
    GLint window = mural->CreateInfo.externalID;

    cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE;

    ctx = ctxInfo->pContext;
    CRASSERT(ctx);

    oldMural = cr_server.currentMural;

    /* Ubuntu 11.04 hosts misbehave if context window switch is
     * done with non-default framebuffer object settings.
     * crStateSwitchPrepare & crStateSwitchPostprocess are supposed to work around this problem
     * crStateSwitchPrepare restores the FBO state to its default values before the context window switch,
     * while crStateSwitchPostprocess restores it back to the original values */
    oldCtx = crStateGetCurrent();
    if (oldMural && oldMural->fRedirected && crServerSupportRedirMuralFBO())
    {
        idDrawFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurDrawBuffer);
        idReadFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurReadBuffer);
    }
    else
    {
        idDrawFBO = 0;
        idReadFBO = 0;
    }
    crStateSwitchPrepare(cr_server.bUseMultipleContexts ? NULL : ctx, oldCtx, idDrawFBO, idReadFBO);

    if (cr_server.curClient)
    {
        /*
        crDebug("**** %s client %d  curCtx=%d curWin=%d", __func__,
                        cr_server.curClient->number, ctxPos, window);
        */
        cr_server.curClient->currentContextNumber = context;
        cr_server.curClient->currentCtxInfo = ctxInfo;
        cr_server.curClient->currentMural = mural;
        cr_server.curClient->currentWindow = window;

        CRASSERT(cr_server.curClient->currentCtxInfo);
        CRASSERT(cr_server.curClient->currentCtxInfo->pContext);
    }

    /* This is a hack to force updating the 'current' attribs */
    crStateUpdateColorBits();

    if (ctx)
        crStateSetCurrentPointers( ctx, &(cr_server.current) );

    /* check if being made current for first time, update viewport */
#if 0
    if (ctx) {
        /* initialize the viewport */
        if (ctx->viewport.viewportW == 0) {
            ctx->viewport.viewportW = mural->width;
            ctx->viewport.viewportH = mural->height;
            ctx->viewport.scissorW = mural->width;
            ctx->viewport.scissorH = mural->height;
        }
    }
#endif

    /*
    crDebug("**** %s  currentWindow %d  newWindow %d", __func__,
                    cr_server.currentWindow, window);
    */

    if (1/*cr_server.firstCallMakeCurrent ||
            cr_server.currentWindow != window ||
            cr_server.currentNativeWindow != nativeWindow*/) {
        /* Since the cr server serialized all incoming contexts/clients into
         * one output stream of GL commands, we only need to call the head
         * SPU's MakeCurrent() function once.
         * BUT, if we're rendering to multiple windows, we do have to issue
         * MakeCurrent() calls sometimes.  The same GL context will always be
         * used though.
         */
        cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow,
                                                        0,
                                                        ctxInfo->SpuContext >= 0
                                                            ? ctxInfo->SpuContext
                                                              : cr_server.MainContextInfo.SpuContext);

        CR_STATE_SHAREDOBJ_USAGE_SET(mural, ctx);
        if (cr_server.currentCtxInfo)
            cr_server.currentCtxInfo->currentMural = NULL;
        ctxInfo->currentMural = mural;

        cr_server.firstCallMakeCurrent = GL_FALSE;
        cr_server.currentCtxInfo = ctxInfo;
        cr_server.currentWindow = window;
        cr_server.currentNativeWindow = 0;
        cr_server.currentMural = mural;
    }

    /* This used to be earlier, after crStateUpdateColorBits() call */
    crStateMakeCurrent( ctx );

    if (mural && mural->fRedirected  && crServerSupportRedirMuralFBO())
    {
        GLuint id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.drawBuffer);
        if (id != mural->iCurDrawBuffer)
        {
            crDebug("DBO draw buffer changed on make current");
            mural->iCurDrawBuffer = id;
        }

        id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.readBuffer);
        if (id != mural->iCurReadBuffer)
        {
            crDebug("DBO read buffer changed on make current");
            mural->iCurReadBuffer = id;
        }

        idDrawFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer);
        idReadFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurReadBuffer);
    }
    else
    {
        idDrawFBO = 0;
        idReadFBO = 0;
    }
    crStateSwitchPostprocess(ctx, cr_server.bUseMultipleContexts ? NULL : oldCtx, idDrawFBO, idReadFBO);

    if (!ctx->framebufferobject.drawFB
            && (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT)
            && cr_server.curClient)
        cr_server.curClient->currentMural->bFbDraw = GL_TRUE;

    if (!mural->fRedirected)
    {
        ctx->buffer.width = mural->width;
        ctx->buffer.height = mural->height;
    }
    else
    {
        ctx->buffer.width = 0;
        ctx->buffer.height = 0;
    }
}
static SPUFunctions *
renderSPUInit( int id, SPU *child, SPU *self,
               unsigned int context_id, unsigned int num_contexts )
{
    int numFuncs, numSpecial;
    GLint defaultWin, defaultCtx;
    WindowInfo *windowInfo;

    (void) child;
    (void) context_id;
    (void) num_contexts;

    self->privatePtr = (void *) &render_spu;

#ifdef CHROMIUM_THREADSAFE
    crDebug("Render SPU: thread-safe");
#endif

    crMemZero(&render_spu, sizeof(render_spu));

    render_spu.id = id;
    renderspuSetVBoxConfiguration(&render_spu);

    if (render_spu.swap_master_url)
        swapsyncConnect();


    /* Get our special functions. */
    numSpecial = renderspuCreateFunctions( _cr_render_table );

#ifdef RT_OS_WINDOWS
    /* Start thread to create windows and process window messages */
    crDebug("RenderSPU: Starting windows serving thread");
    render_spu.hWinThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!render_spu.hWinThreadReadyEvent)
    {
        crError("RenderSPU: Failed to create WinThreadReadyEvent! (%x)", GetLastError());
        return NULL;
    }

    if (!CreateThread(NULL, 0, renderSPUWindowThreadProc, 0, 0, &render_spu.dwWinThreadId))
    {
        crError("RenderSPU: Failed to start windows thread! (%x)", GetLastError());
        return NULL;
    }
    WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);
#endif

    /* Get the OpenGL functions. */
    numFuncs = crLoadOpenGL( &render_spu.ws, _cr_render_table + numSpecial );
    if (numFuncs == 0) {
        crError("The render SPU was unable to load the native OpenGL library");
        return NULL;
    }

    numFuncs += numSpecial;

#ifdef GLX
    if (!render_spu.use_glxchoosevisual) {
        /* sometimes want to set this option with ATI drivers */
        render_spu.ws.glXChooseVisual = NULL;
    }
#endif

    render_spu.window_id = 0;
    render_spu.context_id = 0;
    render_spu.contextTable = crAllocHashtable();
    render_spu.windowTable = crAllocHashtable();

    CRASSERT(render_spu.default_visual & CR_RGB_BIT);

#ifdef USE_OSMESA
    if (render_spu.use_osmesa) {
        if (!crLoadOSMesa(&render_spu.OSMesaCreateContext,
                          &render_spu.OSMesaMakeCurrent,
                          &render_spu.OSMesaDestroyContext)) {
            crError("Unable to load OSMesa library");
        }
    }
#endif

#ifdef DARWIN
# ifdef VBOX_WITH_COCOA_QT
# else /* VBOX_WITH_COCOA_QT */
    render_spu.hRootVisibleRegion = 0;
    render_spu.currentBufferName = 1;
    render_spu.uiDockUpdateTS = 0;
    /* Create a mutex for synchronizing events from the main Qt thread & this
       thread */
    RTSemFastMutexCreate(&render_spu.syncMutex);
    /* Create our window groups */
    CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &render_spu.pMasterGroup);
    CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &render_spu.pParentGroup);
    /* Make the correct z-layering */
    SendWindowGroupBehind (render_spu.pParentGroup, render_spu.pMasterGroup);
    /* and set the gParentGroup as parent for gMasterGroup. */
    SetWindowGroupParent (render_spu.pMasterGroup, render_spu.pParentGroup);
    /* Install the event handlers */
    EventTypeSpec eventList[] =
    {
        {kEventClassVBox, kEventVBoxUpdateContext}, /* Update the context after show/size/move events */
        {kEventClassVBox, kEventVBoxBoundsChanged}  /* Clip/Pos the OpenGL windows when the main window is changed in pos/size */
    };
    /* We need to process events from our main window */
    render_spu.hParentEventHandler = NewEventHandlerUPP(windowEvtHndlr);
    InstallApplicationEventHandler (render_spu.hParentEventHandler,
                                    GetEventTypeCount(eventList), eventList,
                                    NULL, NULL);
    render_spu.fInit = true;
# endif /* VBOX_WITH_COCOA_QT */
#endif /* DARWIN */

    /*
     * Create the default window and context.  Their indexes are zero and
     * a client can use them without calling CreateContext or WindowCreate.
     */
    crDebug("Render SPU: Creating default window (visBits=0x%x, id=0)",
            render_spu.default_visual);
    defaultWin = renderspuWindowCreate( NULL, render_spu.default_visual );
    if (defaultWin != 0) {
        crError("Render SPU: Couldn't get a double-buffered, RGB visual with Z!");
        return NULL;
    }
    crDebug( "Render SPU: WindowCreate returned %d (0=normal)", defaultWin );

    crDebug("Render SPU: Creating default context, visBits=0x%x",
            render_spu.default_visual );
    defaultCtx = renderspuCreateContext( NULL, render_spu.default_visual, 0 );
    CRASSERT(defaultCtx == 0);

    renderspuMakeCurrent( defaultWin, 0, defaultCtx );

    /* Get windowInfo for the default window */
    windowInfo = (WindowInfo *) crHashtableSearch(render_spu.windowTable, 0);
    CRASSERT(windowInfo);
    windowInfo->mapPending = GL_TRUE;

    /*
     * Get the OpenGL extension functions.
     * SIGH -- we have to wait until the very bitter end to load the
     * extensions, because the context has to be bound before
     * wglGetProcAddress will work correctly.  No such issue with GLX though.
     */
    numFuncs += crLoadOpenGLExtensions( &render_spu.ws, _cr_render_table + numFuncs );
    CRASSERT(numFuncs < 1000);

#ifdef WINDOWS
    /*
     * Same problem as above, these are extensions so we need to
     * load them after a context has been bound. As they're WGL
     * extensions too, we can't simply tag them into the spu_loader.
     * So we do them here for now.
     * Grrr, NVIDIA driver uses EXT for GetExtensionsStringEXT,
     * but ARB for others. Need further testing here....
     */
    render_spu.ws.wglGetExtensionsStringEXT =
        (wglGetExtensionsStringEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetExtensionsStringEXT" );
    render_spu.ws.wglChoosePixelFormatEXT =
        (wglChoosePixelFormatEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglChoosePixelFormatARB" );
    render_spu.ws.wglGetPixelFormatAttribivEXT =
        (wglGetPixelFormatAttribivEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribivARB" );
    render_spu.ws.wglGetPixelFormatAttribfvEXT =
        (wglGetPixelFormatAttribfvEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribfvARB" );

    if (render_spu.ws.wglGetProcAddress("glCopyTexSubImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("CopyTexSubImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glCopyTexSubImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glCopyTexSubImage3D function");
    }

    if (render_spu.ws.wglGetProcAddress("glDrawRangeElements"))
    {
        _cr_render_table[numFuncs].name = crStrdup("DrawRangeElements");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glDrawRangeElements");
        ++numFuncs;
        crDebug("Render SPU: Found glDrawRangeElements function");
    }

    if (render_spu.ws.wglGetProcAddress("glTexSubImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("TexSubImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glTexSubImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glTexSubImage3D function");
    }

    if (render_spu.ws.wglGetProcAddress("glTexImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("TexImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glTexImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glTexImage3D function");
    }

    if (render_spu.ws.wglGetExtensionsStringEXT) {
        crDebug("WGL - found wglGetExtensionsStringEXT\n");
    }
    if (render_spu.ws.wglChoosePixelFormatEXT) {
        crDebug("WGL - found wglChoosePixelFormatEXT\n");
    }
#endif

    render_spu.barrierHash = crAllocHashtable();

    render_spu.cursorX = 0;
    render_spu.cursorY = 0;
    render_spu.use_L2 = 0;

    render_spu.gather_conns = NULL;

    crDebug("Render SPU: ---------- End of Init -------------");

    return &render_functions;
}
	void CDX9Renderer::EndBatch()
	{
		if (batch.empty())
			return;

		if(begin_scene_nest == 0)
		{
			// Its better if this doesn't happen...but if it does...force direct x to have 
			// a begin scene otherwise it will crash. This messes up parallel processing, 
			// but its better than the runtime crashing! - Davo
			CRASSERT(d3d9_device != NULL);
			hr = d3d9_device->BeginScene();
		}

		batches_per_present++;

#ifdef CR_DEBUG
		if (debug_save_next_batch)
			DoBatchLog();
#endif

		// Lock exactly the right number of indices and vertices
		vertex* vertex_mem;
		unsigned short* index_mem;

		unsigned int vertex_bytes = vertices_vector.size() * sizeof(vertex);
		unsigned int index_bytes = indices_vector.size() * sizeof(unsigned short);

		// Update only when bytes are to be copied (D3D interprets 0 as 'lock entire buffer'!)
		if (vertex_bytes != 0) {

			batch_buffer->Lock(0, vertex_bytes, (void**)&vertex_mem, D3DLOCK_DISCARD);
			memcpy(vertex_mem, &(vertices_vector.front()), vertex_bytes);
			batch_buffer->Unlock();
		}
		if (index_bytes != 0) {

			index_buffer->Lock(0, index_bytes, (void**)&index_mem, D3DLOCK_DISCARD);
			memcpy(index_mem, &(indices_vector.front()), index_bytes);
			index_buffer->Unlock();
		}

		// Loop the batch doing every item
		BatchIterator i = batch.begin();
		BatchIterator batch_end = batch.end();

		for ( ; i != batch_end; ++i)
			(*i)->Do();

		if(begin_scene_nest == 0)
		{
			// Its better if this doesn't happen...but if it does...force direct x to have 
			// a begin scene otherwise it will crash. This messes up parallel processing, 
			// but its better than it crashing! - Davo
			CRASSERT(d3d9_device != NULL);
			hr = d3d9_device->EndScene();
		}

		// Put everything back
		ResetBatch();
	}
Example #29
0
/**
 * Make sure the response matches the opt's parameters (right number
 * and type of values, etc.)
 * Return 1 if OK, 0 if error.
 */
static int validate_option( const SPUOptions *opt, const char *response )
{
    const char *min = opt->min;
    const char *max = opt->max;
    int i = 0;
    int retval;

    if (opt->type == CR_STRING)
        return 1;
   
    CRASSERT(opt->numValues > 0);

    /* skip leading [ for multi-value options */
    if (opt->numValues > 1) {
        /* multi-valued options must be enclosed in brackets */
        if (*response != '[')
            return 0;
        response++; /* skip [ */
        /* make sure min and max are bracketed as well */
        if (min) {
            CRASSERT(*min == '[');  /* error in <foo>spu_config.c code!!! */
            min++;
        }
        if (max) {
            CRASSERT(*max == '[');  /* error in <foo>spu_config.c code!!! */
            max++;
        }
    }

    for (;;)
    {
        if (!validate_one_option( opt, response, min, max ))
        {
            retval = 0;
            break;
        }
        if (++i == opt->numValues)
        {
            retval = 1; /* all done! */
            break;
        }
        /* advance pointers to next item */
        if (min)
        {
            while (*min != ' ' && *min)
                min++;
            while (*min == ' ')
                min++;
        }
        if (max)
        {
            while (*max != ' ' && *max)
                max++;
            while (*max == ' ')
                max++;
        }
        if (response)
        {
            while (*response != ' ' && *response)
                response++;
            while (*response == ' ')
                response++;
        }
    }

    return retval;
}
Example #30
0
static void
crServerDeleteClient( CRClient *client )
{
	int i, j;

	crDebug("Deleting client %p (%d msgs left)", client,
					crNetNumMessages(client->conn));

#if 0
	if (crNetNumMessages(client->conn) > 0) {
		crDebug("Delay destroying client: message still pending");
		return;
	}
#endif

	if (!FindClientInQueue(client)) {
		/* this should never happen */
		crError("CRServer: client %p not found in the queue!", client);
	}

	/* remove from clients[] array */
	for (i = 0; i < cr_server.numClients; i++) {
		if (cr_server.clients[i] == client) {
			/* found it */
			for (j = i; j < cr_server.numClients - 1; j++)
				cr_server.clients[j] = cr_server.clients[j + 1];
			cr_server.numClients--;
			break;
		}
	}

	/* remove from the run queue */
	if (cr_server.run_queue)
	{
		RunQueue *q = cr_server.run_queue;
		RunQueue *qStart = cr_server.run_queue; 
		do {
			if (q->client == client)
			{
				/* this test seems a bit excessive */
				if ((q->next == q->prev) && (q->next == q) && (cr_server.run_queue == q))
				{
					/* We're removing/deleting the only client */
					CRASSERT(cr_server.numClients == 0);
					crFree(q);
					cr_server.run_queue = NULL;
					cr_server.curClient = NULL;
					crDebug("Last client deleted - empty run queue.");
				} 
				else
				{
					/* remove from doubly linked list and free the node */
					if (cr_server.curClient == q->client)
						cr_server.curClient = NULL;
					if (cr_server.run_queue == q)
						cr_server.run_queue = q->next;
					q->prev->next = q->next;
					q->next->prev = q->prev;
					crFree(q);
				}
				break;
			}
			q = q->next;
		} while (q != qStart);
	}

	crNetFreeConnection(client->conn);
	crFree(client);
}