/* * At this point we know that the tiles are uniformly sized so we can use * a hash-based bucketing method. Setup the hash table now. */ static GLboolean fillBucketingHash(CRMuralInfo *mural) { #if 0 int i, j, k, m; int r_len = 0; int xinc, yinc; int rlist_alloc = 64 * 128; BucketRegion *rptr; struct BucketingInfo *bucketInfo; if (mural->bucketInfo) { crFree(mural->bucketInfo->rlist); crFree(mural->bucketInfo); mural->bucketInfo = NULL; } bucketInfo = (struct BucketingInfo *) crCalloc(sizeof(struct BucketingInfo)); if (!bucketInfo) return GL_FALSE; /* Allocate rlist (don't free it!!!) */ bucketInfo->rlist = (BucketRegion *) crAlloc(rlist_alloc * sizeof(BucketRegion)); for ( i = 0; i < HASHRANGE; i++ ) { for ( j = 0; j < HASHRANGE; j++ ) { bucketInfo->rhash[i][j] = NULL; } } /* Fill the rlist */ xinc = mural->extents[0].imagewindow.x2 - mural->extents[0].imagewindow.x1; yinc = mural->extents[0].imagewindow.y2 - mural->extents[0].imagewindow.y1; CRASSERT(xinc > 0 || mural->width == 0); CRASSERT(yinc > 0 || mural->height == 0); rptr = bucketInfo->rlist; for (i=0; i < (int) mural->width; i+=xinc) { for (j=0; j < (int) mural->height; j+=yinc) { for (k=0; k < mural->numExtents; k++) { if (mural->extents[k].imagewindow.x1 == i && mural->extents[k].imagewindow.y1 == j) { rptr->extents = mural->extents[k].imagewindow; /* x1,y1,x2,y2 */ rptr->id = k; break; } } if (k == mural->numExtents) { rptr->extents.x1 = i; rptr->extents.y1 = j; rptr->extents.x2 = i + xinc; rptr->extents.y2 = j + yinc; rptr->id = -1; } rptr++; } } r_len = rptr - bucketInfo->rlist; /* Fill hash table */ for (i = 0; i < r_len; i++) { BucketRegion *r = &bucketInfo->rlist[i]; for (k=BKT_DOWNHASH(r->extents.x1, (int)mural->width); k<=BKT_UPHASH(r->extents.x2, (int)mural->width) && k < HASHRANGE; k++) { for (m=BKT_DOWNHASH(r->extents.y1, (int)mural->height); m<=BKT_UPHASH(r->extents.y2, (int)mural->height) && m < HASHRANGE; m++) { if ( bucketInfo->rhash[m][k] == NULL || (bucketInfo->rhash[m][k]->extents.x1 > r->extents.x1 && bucketInfo->rhash[m][k]->extents.y1 > r->extents.y1)) { bucketInfo->rhash[m][k] = r; } } } } /* Initialize links */ for (i=0; i<r_len; i++) { BucketRegion *r = &bucketInfo->rlist[i]; r->right = NULL; r->up = NULL; } /* Build links */ for (i=0; i<r_len; i++) { BucketRegion *r = &bucketInfo->rlist[i]; for (j=0; j<r_len; j++) { BucketRegion *q = &bucketInfo->rlist[j]; if (r==q) continue; /* Right Edge */ if (r->extents.x2 == q->extents.x1 && r->extents.y1 == q->extents.y1 && r->extents.y2 == q->extents.y2) { r->right = q; } /* Upper Edge */ if (r->extents.y2 == q->extents.y1 && r->extents.x1 == q->extents.x1 && r->extents.x2 == q->extents.x2) { r->up = q; } } } mural->bucketInfo = bucketInfo; #endif return GL_TRUE; }
/** * Initialize the hash table used for optimized UNIFORM_GRID bucketing. * \param winInfo - which window/mural * \return GL_FALSE - invalid tile size(s) or position(s) * GL_TRUE - success! */ static GLboolean initHashBucketing(WindowInfo *winInfo) { int i, j, k, m; int r_len = 0; int id; int rlist_alloc = 64 * 128; HashInfo *hash; hash = (HashInfo *) crCalloc(sizeof(HashInfo)); if (!hash) return GL_FALSE; /* First, check that all the tiles are the same size! */ { int reqWidth = 0, reqHeight = 0; for (i = 0; i < tilesort_spu.num_servers; i++) { ServerWindowInfo *servWinInfo = winInfo->server + i; for (j = 0; j < servWinInfo->num_extents; j++) { int x = servWinInfo->extents[j].x1; int y = servWinInfo->extents[j].y1; int w = servWinInfo->extents[j].x2 - x; int h = servWinInfo->extents[j].y2 - y; if (reqWidth == 0 || reqHeight == 0) { reqWidth = w; reqHeight = h; } else if (w != reqWidth || h != reqHeight) { crWarning("Tile %d on server %d is not the right size!", j, i); crWarning("All tiles must be same size when bucket_mode = " "'Uniform Grid'."); return GL_FALSE; } else if ((x % reqWidth) != 0 || (y % reqHeight) != 0) { /* (x,y) should be an integer multiple of the tile size */ crWarning("Tile %d on server %d is not positioned correctly!", j, i); crWarning("Position (%d, %d) is not an integer multiple of the " "tile size (%d x %d)", x, y, reqWidth, reqHeight); return GL_FALSE; } } } } /* rlist_alloc = GLCONFIG_MAX_PROJECTORS*GLCONFIG_MAX_EXTENTS; */ hash->rlist = (BucketRegion *) crAlloc(rlist_alloc * sizeof(BucketRegion)); if (!hash->rlist) { crFree(hash); return GL_FALSE; } for (i=0; i<HASHRANGE; i++) { for (j=0; j<HASHRANGE; j++) { hash->rhash[i][j] = NULL; } } /* Fill hash table */ id = 0; for (i = 0; i < tilesort_spu.num_servers; i++) { ServerWindowInfo *servWinInfo = winInfo->server + i; int node32 = i >> 5; int node = i & 0x1f; for (j = 0; j < servWinInfo->num_extents; j++) { BucketRegion *r = &hash->rlist[id++]; for (k=0;k<CR_MAX_BITARRAY;k++) r->id[k] = 0; r->id[node32] = (1 << node); r->extents = servWinInfo->extents[j]; /* copy x1,y1,x2,y2 */ for (k=BKT_DOWNHASH(r->extents.x1, winInfo->muralWidth); k<=BKT_UPHASH(r->extents.x2, winInfo->muralWidth) && k < HASHRANGE; k++) { for (m=BKT_DOWNHASH(r->extents.y1, winInfo->muralHeight); m<=BKT_UPHASH(r->extents.y2, winInfo->muralHeight) && m < HASHRANGE; m++) { if ( hash->rhash[m][k] == NULL || (hash->rhash[m][k]->extents.x1 > r->extents.x1 && hash->rhash[m][k]->extents.y1 > r->extents.y1)) { hash->rhash[m][k] = r; } } } } } r_len = id; /* Initialize links */ for (i=0; i<r_len; i++) { BucketRegion *r = &hash->rlist[i]; r->right = NULL; r->up = NULL; } /* Build links */ for (i=0; i<r_len; i++) { BucketRegion *r = &hash->rlist[i]; for (j=0; j<r_len; j++) { BucketRegion *q = &hash->rlist[j]; if (r==q) { continue; } /* Right Edge */ if (r->extents.x2 == q->extents.x1 && r->extents.y1 == q->extents.y1 && r->extents.y2 == q->extents.y2) { r->right = q; } /* Upper Edge */ if (r->extents.y2 == q->extents.y1 && r->extents.x1 == q->extents.x1 && r->extents.x2 == q->extents.x2) { r->up = q; } } } winInfo->bucketInfo = (void *) hash; return GL_TRUE; }