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