VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_boundsinfo.c@ 21576

Last change on this file since 21576 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.5 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "server_dispatch.h"
8#include "server.h"
9#include "cr_error.h"
10#include "cr_unpack.h"
11#include "cr_mem.h"
12#include "state/cr_statetypes.h"
13
14/* This code copied from the tilesorter (fooey) */
15
16typedef struct BucketRegion *BucketRegion_ptr;
17typedef struct BucketRegion {
18 CRbitvalue id;
19 CRrecti extents;
20 BucketRegion_ptr right;
21 BucketRegion_ptr up;
22} BucketRegion;
23
24#define HASHRANGE 256
25
26#define BKT_DOWNHASH(a, range) ((a)*HASHRANGE/(range))
27#define BKT_UPHASH(a, range) ((a)*HASHRANGE/(range) + ((a)*HASHRANGE%(range)?1:0))
28
29struct BucketingInfo {
30 BucketRegion *rhash[HASHRANGE][HASHRANGE];
31 BucketRegion *rlist;
32};
33
34
35/*
36 * At this point we know that the tiles are uniformly sized so we can use
37 * a hash-based bucketing method. Setup the hash table now.
38 */
39static GLboolean
40fillBucketingHash(CRMuralInfo *mural)
41{
42 int i, j, k, m;
43 int r_len = 0;
44 int xinc, yinc;
45 int rlist_alloc = 64 * 128;
46 BucketRegion *rptr;
47 struct BucketingInfo *bucketInfo;
48
49 if (mural->bucketInfo) {
50 crFree(mural->bucketInfo->rlist);
51 crFree(mural->bucketInfo);
52 mural->bucketInfo = NULL;
53 }
54
55 bucketInfo = (struct BucketingInfo *) crCalloc(sizeof(struct BucketingInfo));
56 if (!bucketInfo)
57 return GL_FALSE;
58
59 /* Allocate rlist (don't free it!!!) */
60 bucketInfo->rlist = (BucketRegion *) crAlloc(rlist_alloc * sizeof(BucketRegion));
61
62 for ( i = 0; i < HASHRANGE; i++ )
63 {
64 for ( j = 0; j < HASHRANGE; j++ )
65 {
66 bucketInfo->rhash[i][j] = NULL;
67 }
68 }
69
70 /* Fill the rlist */
71 xinc = mural->extents[0].imagewindow.x2 - mural->extents[0].imagewindow.x1;
72 yinc = mural->extents[0].imagewindow.y2 - mural->extents[0].imagewindow.y1;
73 CRASSERT(xinc > 0 || mural->width == 0);
74 CRASSERT(yinc > 0 || mural->height == 0);
75
76 rptr = bucketInfo->rlist;
77 for (i=0; i < (int) mural->width; i+=xinc)
78 {
79 for (j=0; j < (int) mural->height; j+=yinc)
80 {
81 for (k=0; k < mural->numExtents; k++)
82 {
83 if (mural->extents[k].imagewindow.x1 == i &&
84 mural->extents[k].imagewindow.y1 == j)
85 {
86 rptr->extents = mural->extents[k].imagewindow; /* x1,y1,x2,y2 */
87 rptr->id = k;
88 break;
89 }
90 }
91 if (k == mural->numExtents)
92 {
93 rptr->extents.x1 = i;
94 rptr->extents.y1 = j;
95 rptr->extents.x2 = i + xinc;
96 rptr->extents.y2 = j + yinc;
97 rptr->id = -1;
98 }
99 rptr++;
100 }
101 }
102 r_len = rptr - bucketInfo->rlist;
103
104 /* Fill hash table */
105 for (i = 0; i < r_len; i++)
106 {
107 BucketRegion *r = &bucketInfo->rlist[i];
108
109 for (k=BKT_DOWNHASH(r->extents.x1, (int)mural->width);
110 k<=BKT_UPHASH(r->extents.x2, (int)mural->width) &&
111 k < HASHRANGE;
112 k++)
113 {
114 for (m=BKT_DOWNHASH(r->extents.y1, (int)mural->height);
115 m<=BKT_UPHASH(r->extents.y2, (int)mural->height) &&
116 m < HASHRANGE;
117 m++)
118 {
119 if ( bucketInfo->rhash[m][k] == NULL ||
120 (bucketInfo->rhash[m][k]->extents.x1 > r->extents.x1 &&
121 bucketInfo->rhash[m][k]->extents.y1 > r->extents.y1))
122 {
123 bucketInfo->rhash[m][k] = r;
124 }
125 }
126 }
127 }
128
129 /* Initialize links */
130 for (i=0; i<r_len; i++)
131 {
132 BucketRegion *r = &bucketInfo->rlist[i];
133 r->right = NULL;
134 r->up = NULL;
135 }
136
137 /* Build links */
138 for (i=0; i<r_len; i++)
139 {
140 BucketRegion *r = &bucketInfo->rlist[i];
141 for (j=0; j<r_len; j++)
142 {
143 BucketRegion *q = &bucketInfo->rlist[j];
144 if (r==q)
145 continue;
146
147 /* Right Edge */
148 if (r->extents.x2 == q->extents.x1 &&
149 r->extents.y1 == q->extents.y1 &&
150 r->extents.y2 == q->extents.y2)
151 {
152 r->right = q;
153 }
154
155 /* Upper Edge */
156 if (r->extents.y2 == q->extents.y1 &&
157 r->extents.x1 == q->extents.x1 &&
158 r->extents.x2 == q->extents.x2)
159 {
160 r->up = q;
161 }
162 }
163 }
164
165 mural->bucketInfo = bucketInfo;
166 return GL_TRUE;
167}
168
169
170/*
171 * Check if the tiles are the same size. If so, initialize hash-based
172 * bucketing.
173 */
174GLboolean
175crServerInitializeBucketing(CRMuralInfo *mural)
176{
177 int optTileWidth = 0, optTileHeight = 0;
178 int i;
179
180 for (i = 0; i < mural->numExtents; i++)
181 {
182 const int w = mural->extents[i].imagewindow.x2 -
183 mural->extents[i].imagewindow.x1;
184 const int h = mural->extents[i].imagewindow.y2 -
185 mural->extents[i].imagewindow.y1;
186
187 if (optTileWidth == 0 && optTileHeight == 0) {
188 /* First tile */
189 optTileWidth = w;
190 optTileHeight = h;
191 }
192 else
193 {
194 /* Subsequent tile - make sure it's the same size as first and
195 * falls on the expected x/y location.
196 */
197 if (w != optTileWidth || h != optTileHeight) {
198 crWarning("Tile %d, %d .. %d, %d is not the right size!",
199 mural->extents[i].imagewindow.x1, mural->extents[i].imagewindow.y1,
200 mural->extents[i].imagewindow.x2, mural->extents[i].imagewindow.y2);
201 crWarning("All tiles must be same size with optimize_bucket.");
202 crWarning("Turning off optimize_bucket for this mural.");
203 return GL_FALSE;
204 }
205 else if ((mural->extents[i].imagewindow.x1 % optTileWidth) != 0 ||
206 (mural->extents[i].imagewindow.x2 % optTileWidth) != 0 ||
207 (mural->extents[i].imagewindow.y1 % optTileHeight) != 0 ||
208 (mural->extents[i].imagewindow.y2 % optTileHeight) != 0)
209 {
210 crWarning("Tile %d, %d .. %d, %d is not positioned correctly "
211 "to use optimize_bucket.",
212 mural->extents[i].imagewindow.x1, mural->extents[i].imagewindow.y1,
213 mural->extents[i].imagewindow.x2, mural->extents[i].imagewindow.y2);
214 crWarning("Turning off optimize_bucket for this mural.");
215 return GL_FALSE;
216 }
217 }
218 }
219
220 return fillBucketingHash(mural);
221}
222
223
224/**
225 * Process a crBoundsInfoCR message/function. This is a bounding box
226 * followed by a payload of arbitrary Chromium rendering commands.
227 * The tilesort SPU will send this.
228 * Note: the bounding box is in mural pixel coordinates (y=0=bottom)
229 */
230void SERVER_DISPATCH_APIENTRY
231crServerDispatchBoundsInfoCR( const CRrecti *bounds, const GLbyte *payload,
232 GLint len, GLint num_opcodes )
233{
234 CRMuralInfo *mural = cr_server.curClient->currentMural;
235 char *data_ptr = (char*)(payload + ((num_opcodes + 3 ) & ~0x03));
236 unsigned int bx, by;
237
238 /* Save current unpacker state */
239 crUnpackPush();
240
241 /* pass bounds info to first SPU */
242 {
243 /* bias bounds to extent/window coords */
244 CRrecti bounds2;
245 const int dx = mural->extents[0].imagewindow.x1;
246 const int dy = mural->extents[0].imagewindow.y1;
247 if (bounds->x1 == -CR_MAXINT) {
248 /* "infinite" bounds: convert to full image bounds */
249 bounds2.x1 = 0;
250 bounds2.y1 = 0;
251 bounds2.x2 = mural->extents[0].imagewindow.x2 - dx; /* width */
252 bounds2.y2 = mural->extents[0].imagewindow.y2 - dy; /* height */
253 }
254 else {
255 bounds2.x1 = bounds->x1 - dx;
256 bounds2.y1 = bounds->y1 - dy;
257 bounds2.x2 = bounds->x2 - dx;
258 bounds2.y2 = bounds->y2 - dy;
259 }
260 cr_server.head_spu->dispatch_table.BoundsInfoCR(&bounds2, NULL, 0, 0);
261 }
262
263 if (!mural->viewportValidated) {
264 crServerComputeViewportBounds(&(cr_server.curClient->currentCtx->viewport),
265 mural);
266 }
267
268 bx = BKT_DOWNHASH(bounds->x1, mural->width);
269 by = BKT_DOWNHASH(bounds->y1, mural->height);
270
271 /* Check for out of bounds, and optimizeBucket to enable */
272 if (mural->optimizeBucket && (bx <= HASHRANGE) && (by <= HASHRANGE))
273 {
274 const struct BucketingInfo *bucketInfo = mural->bucketInfo;
275 const BucketRegion *r;
276 const BucketRegion *p;
277
278 CRASSERT(bucketInfo);
279
280 for (r = bucketInfo->rhash[by][bx]; r && bounds->y2 >= r->extents.y1;
281 r = r->up)
282 {
283 for (p=r; p && bounds->x2 >= p->extents.x1; p = p->right)
284 {
285 if ( p->id != (unsigned int) -1 &&
286 bounds->x1 < p->extents.x2 &&
287 bounds->y1 < p->extents.y2 &&
288 bounds->y2 >= p->extents.y1 )
289 {
290 mural->curExtent = p->id;
291 if (cr_server.run_queue->client->currentCtx) {
292 crServerSetOutputBounds( mural, mural->curExtent );
293 }
294 crUnpack( data_ptr, data_ptr-1, num_opcodes, &(cr_server.dispatch) );
295 }
296 }
297 }
298 }
299 else
300 {
301 /* non-optimized bucketing - unpack/render for each tile/extent */
302 int i;
303 for ( i = 0; i < mural->numExtents; i++ )
304 {
305 CRExtent *extent = &mural->extents[i];
306
307 if (cr_server.localTileSpec ||
308 (extent->imagewindow.x2 > bounds->x1 &&
309 extent->imagewindow.x1 < bounds->x2 &&
310 extent->imagewindow.y2 > bounds->y1 &&
311 extent->imagewindow.y1 < bounds->y2))
312 {
313 mural->curExtent = i;
314 if (cr_server.run_queue->client->currentCtx) {
315 crServerSetOutputBounds( mural, i );
316 }
317 crUnpack( data_ptr, data_ptr-1, num_opcodes, &(cr_server.dispatch) );
318 }
319 }
320 }
321
322 /* Restore previous unpacker state */
323 crUnpackPop();
324}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette