/**
 * This function takes the given message (which should be a buffer of
 * rendering commands) and executes it.
 */
static void
crServerDispatchMessage(CRConnection *conn, CRMessage *msg)
{
    const CRMessageOpcodes *msg_opcodes;
    int opcodeBytes;
    const char *data_ptr;
#ifdef VBOX_WITH_CRHGSMI
    PCRVBOXHGSMI_CMDDATA pCmdData = NULL;
#endif

    if (msg->header.type == CR_MESSAGE_REDIR_PTR)
    {
#ifdef VBOX_WITH_CRHGSMI
        pCmdData = &msg->redirptr.CmdData;
#endif
        msg = (CRMessage *) msg->redirptr.pMessage;
    }

    CRASSERT(msg->header.type == CR_MESSAGE_OPCODES);

    msg_opcodes = (const CRMessageOpcodes *) msg;
    opcodeBytes = (msg_opcodes->numOpcodes + 3) & ~0x03;

#ifdef VBOXCR_LOGFPS
    CRASSERT(cr_server.curClient && cr_server.curClient->conn && cr_server.curClient->conn->id == msg->header.conn_id);
    cr_server.curClient->conn->opcodes_count += msg_opcodes->numOpcodes;
#endif

    data_ptr = (const char *) msg_opcodes + sizeof(CRMessageOpcodes) + opcodeBytes;
    crUnpack(data_ptr,                 /* first command's operands */
             data_ptr - 1,             /* first command's opcode */
             msg_opcodes->numOpcodes,  /* how many opcodes */
             &(cr_server.dispatch));   /* the CR dispatch table */

#ifdef VBOX_WITH_CRHGSMI
    if (pCmdData)
    {
        int rc = VINF_SUCCESS;
        CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(pCmdData);
        if (CRVBOXHGSMI_CMDDATA_IS_SETWB(pCmdData))
        {
            uint32_t cbWriteback = pCmdData->cbWriteback;
            rc = crVBoxServerInternalClientRead(conn->pClient, (uint8_t*)pCmdData->pWriteback, &cbWriteback);
            CRASSERT(rc == VINF_SUCCESS || rc == VERR_BUFFER_OVERFLOW);
            *pCmdData->pcbWriteback = cbWriteback;
        }
        VBOXCRHGSMI_CMD_CHECK_COMPLETE(pCmdData, rc);
    }
#endif
}
Exemple #2
0
/**
 * This function takes the given message (which should be a buffer of
 * rendering commands) and executes it.
 */
static void
glStubDispatchMessage(CRMessage *msg)
{
	 const CRMessageOpcodes *msg_opcodes;
	 int opcodeBytes;
	 const char *data_ptr;

	 CRASSERT(msg->header.type == CR_MESSAGE_OPCODES);

	 msg_opcodes = (const CRMessageOpcodes *) msg;
	 opcodeBytes = (msg_opcodes->numOpcodes + 3) & ~0x03;

	 data_ptr = (const char *) msg_opcodes + sizeof(CRMessageOpcodes) + opcodeBytes;
	 crUnpack(data_ptr,                 /* first command's operands */
						data_ptr - 1,             /* first command's opcode */
						msg_opcodes->numOpcodes,  /* how many opcodes */
						&(cr_server.dispatch));  /* the CR dispatch table */
}
/**
 * Process a crBoundsInfoCR message/function.  This is a bounding box
 * followed by a payload of arbitrary Chromium rendering commands.
 * The tilesort SPU will send this.
 * Note: the bounding box is in mural pixel coordinates (y=0=bottom)
 */
void SERVER_DISPATCH_APIENTRY
crServerDispatchBoundsInfoCR( const CRrecti *bounds, const GLbyte *payload,
															GLint len, GLint num_opcodes )
{
	CRMuralInfo *mural = cr_server.curClient->currentMural;
	char *data_ptr = (char*)(payload + ((num_opcodes + 3 ) & ~0x03));
	unsigned int bx, by;

	/* Save current unpacker state */
	crUnpackPush();
#if 0
	/* pass bounds info to first SPU */
	{
		/* bias bounds to extent/window coords */
		CRrecti bounds2;
		const int dx = mural->extents[0].imagewindow.x1;
		const int dy = mural->extents[0].imagewindow.y1;
		if (bounds->x1 == -CR_MAXINT) {
			/* "infinite" bounds: convert to full image bounds */
			bounds2.x1 = 0;
			bounds2.y1 = 0;
			bounds2.x2 = mural->extents[0].imagewindow.x2 - dx; /* width */
			bounds2.y2 = mural->extents[0].imagewindow.y2 - dy; /* height */
		}
		else {
			bounds2.x1 = bounds->x1 - dx;
			bounds2.y1 = bounds->y1 - dy;
			bounds2.x2 = bounds->x2 - dx;
			bounds2.y2 = bounds->y2 - dy;
		}
		cr_server.head_spu->dispatch_table.BoundsInfoCR(&bounds2, NULL, 0, 0);
	}

	if (!mural->viewportValidated) {
		crServerComputeViewportBounds(&(cr_server.curClient->currentCtx->viewport),
																	mural);
	}

	bx = BKT_DOWNHASH(bounds->x1, mural->width);
	by = BKT_DOWNHASH(bounds->y1, mural->height);

	/* Check for out of bounds, and optimizeBucket to enable */
	if (mural->optimizeBucket && (bx <= HASHRANGE) && (by <= HASHRANGE))
	{
		const struct BucketingInfo *bucketInfo = mural->bucketInfo;
		const BucketRegion *r;
		const BucketRegion *p;

		CRASSERT(bucketInfo);

		for (r = bucketInfo->rhash[by][bx]; r && bounds->y2 >= r->extents.y1;
		     r = r->up)
		{
			for (p=r; p && bounds->x2 >= p->extents.x1; p = p->right)
			{
				if ( p->id != (unsigned int) -1 &&
					bounds->x1 < p->extents.x2  &&
					bounds->y1 < p->extents.y2 &&
					bounds->y2 >= p->extents.y1 )
				{
					mural->curExtent = p->id;
					if (cr_server.run_queue->client->currentCtx) {
						crServerSetOutputBounds( mural, mural->curExtent );
					}
					crUnpack( data_ptr, data_ptr-1, num_opcodes, &(cr_server.dispatch) );
				}
			}
		}
	} 
	else 
	{
		/* non-optimized bucketing - unpack/render for each tile/extent */
		int i;
		for ( i = 0; i < mural->numExtents; i++ )
		{
			CRExtent *extent = &mural->extents[i];

			if (cr_server.localTileSpec ||
			    (extent->imagewindow.x2 > bounds->x1 &&
					 extent->imagewindow.x1 < bounds->x2 &&
					 extent->imagewindow.y2 > bounds->y1 &&
					 extent->imagewindow.y1 < bounds->y2))
			{
				mural->curExtent = i;
				if (cr_server.run_queue->client->currentCtx) {
					crServerSetOutputBounds( mural, i );
				}
				crUnpack( data_ptr, data_ptr-1, num_opcodes, &(cr_server.dispatch) );
			}
		}
	}
#endif
	/* Restore previous unpacker state */
	crUnpackPop();
}