/* * Called via unpacker module. * Note: when there's a tilesort SPU upstream, the viewport dimensions * will typically match the mural size. That is, the viewport dimensions * probably won't be the same values that the application issues. */ void SERVER_DISPATCH_APIENTRY crServerDispatchViewport( GLint x, GLint y, GLsizei width, GLsizei height ) { CRMuralInfo *mural = cr_server.curClient->currentMural; CRContext *ctx = crStateGetCurrent(); if (ctx->viewport.viewportX != x || ctx->viewport.viewportY != y || ctx->viewport.viewportW != width || ctx->viewport.viewportH != height) { /* Note -- If there are tiles, this will be overridden in the * process of decoding the BoundsInfo packet, so no worries. */ crStateViewport( x, y, width, height ); mural->viewportValidated = GL_FALSE; } if (mural->numExtents == 0) { /* non-tiling arrangment */ cr_server.head_spu->dispatch_table.Viewport(x, y, width, height); } else { if (!mural->viewportValidated) { CRViewportState *vp = &(cr_server.curClient->currentCtx->viewport); crServerComputeViewportBounds(vp, mural); crServerSetOutputBounds(mural, 0); } } }
/** * 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(); }