VirtualBox

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

Last change on this file since 27889 was 27889, checked in by vboxsync, 15 years ago

crOpenGL: more code for multiscreen support

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