/*
 * 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;
}
Beispiel #2
0
/**
 * 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;
}