VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_viewport.cpp@ 78375

Last change on this file since 78375 was 78375, checked in by vboxsync, 6 years ago

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
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 "state/cr_statetypes.h"
11
12
13static const CRmatrix identity_matrix = {
14 1.0, 0.0, 0.0, 0.0,
15 0.0, 1.0, 0.0, 0.0,
16 0.0, 0.0, 1.0, 0.0,
17 0.0, 0.0, 0.0, 1.0
18};
19
20
21/*
22 * Clip the rectangle q against the given image window.
23 */
24static void
25crServerViewportClipToWindow( const CRrecti *imagewindow, CRrecti *q)
26{
27 if (q->x1 < imagewindow->x1) q->x1 = imagewindow->x1;
28 if (q->x1 > imagewindow->x2) q->x1 = imagewindow->x2;
29
30 if (q->x2 > imagewindow->x2) q->x2 = imagewindow->x2;
31 if (q->x2 < imagewindow->x1) q->x2 = imagewindow->x1;
32
33 if (q->y1 < imagewindow->y1) q->y1 = imagewindow->y1;
34 if (q->y1 > imagewindow->y2) q->y1 = imagewindow->y2;
35
36 if (q->y2 > imagewindow->y2) q->y2 = imagewindow->y2;
37 if (q->y2 < imagewindow->y1) q->y2 = imagewindow->y1;
38}
39
40
41/*
42 * Translate the rectangle q from the image window space to the outputwindow
43 * space.
44 */
45static void
46crServerConvertToOutput( const CRrecti *imagewindow,
47 const CRrecti *outputwindow,
48 CRrecti *q )
49{
50 q->x1 = q->x1 - imagewindow->x1 + outputwindow->x1;
51 q->x2 = q->x2 - imagewindow->x2 + outputwindow->x2;
52 q->y1 = q->y1 - imagewindow->y1 + outputwindow->y1;
53 q->y2 = q->y2 - imagewindow->y2 + outputwindow->y2;
54}
55
56
57/*
58 * Compute clipped image window, scissor, viewport and base projection
59 * info for each tile in the mural.
60 * Need to call this when either the viewport or mural is changed.
61 */
62void
63crServerComputeViewportBounds(const CRViewportState *v, CRMuralInfo *mural)
64{
65#if 0
66 static GLuint serialNo = 1;
67 int i;
68
69 for (i = 0; i < mural->numExtents; i++) {
70 CRExtent *extent = &mural->extents[i];
71 CRrecti q;
72
73 /* If the scissor is disabled set it to the whole output.
74 ** We might as well use the actual scissorTest rather than
75 ** scissorValid - it never gets reset anyway.
76 */
77 if (!v->scissorTest)
78 {
79 extent->scissorBox = extent->outputwindow;
80 }
81 else
82 {
83 q.x1 = v->scissorX;
84 q.x2 = v->scissorX + v->scissorW;
85 q.y1 = v->scissorY;
86 q.y2 = v->scissorY + v->scissorH;
87
88 crServerViewportClipToWindow(&(extent->imagewindow), &q);
89 crServerConvertToOutput(&(extent->imagewindow),
90 &(extent->outputwindow), &q);
91 extent->scissorBox = q;
92 }
93
94 /* if the viewport is not valid,
95 ** set it to the entire output.
96 */
97 if (!v->viewportValid)
98 {
99 extent->clippedImagewindow = extent->imagewindow;
100 extent->viewport = extent->outputwindow;
101 }
102 else
103 {
104 q.x1 = v->viewportX;
105 q.x2 = v->viewportX + v->viewportW;
106 q.y1 = v->viewportY;
107 q.y2 = v->viewportY + v->viewportH;
108
109 /* This is where the viewport gets clamped to the max size. */
110 crServerViewportClipToWindow(&(extent->imagewindow), &q);
111
112 extent->clippedImagewindow = q;
113
114 crServerConvertToOutput(&(extent->imagewindow),
115 &(extent->outputwindow), &q);
116
117 extent->viewport = q;
118 }
119
120 /*
121 ** Now, compute the base projection.
122 */
123 if (extent->clippedImagewindow.x1 == extent->clippedImagewindow.x2 ||
124 extent->clippedImagewindow.y1 == extent->clippedImagewindow.y2) {
125 /* zero-area extent, use identity matrix (doesn't really matter) */
126 extent->baseProjection = identity_matrix;
127 }
128 else
129 {
130 const int vpx = v->viewportX;
131 const int vpy = v->viewportY;
132 const int vpw = v->viewportW;
133 const int vph = v->viewportH;
134 GLfloat xscale, yscale;
135 GLfloat xtrans, ytrans;
136 CRrectf p;
137
138 /*
139 * We need to take account of the current viewport parameters,
140 * and they are passed to this function as x, y, w, h.
141 * In the default case (from main.c) we pass the the
142 * full muralsize of 0, 0, width, height
143 */
144 p.x1 = (GLfloat) (extent->clippedImagewindow.x1 - vpx) / vpw;
145 p.y1 = (GLfloat) (extent->clippedImagewindow.y1 - vpy) / vph;
146 p.x2 = (GLfloat) (extent->clippedImagewindow.x2 - vpx) / vpw;
147 p.y2 = (GLfloat) (extent->clippedImagewindow.y2 - vpy) / vph;
148
149 /* XXX not sure this clamping is really need anymore
150 */
151 if (p.x1 < 0.0) {
152 p.x1 = 0.0;
153 if (p.x2 > 1.0) p.x2 = 1.0;
154 }
155
156 if (p.y1 < 0.0) {
157 p.y1 = 0.0;
158 if (p.y2 > 1.0) p.y2 = 1.0;
159 }
160
161 /* Rescale [0,1] -> [-1,1] */
162 p.x1 = p.x1 * 2.0f - 1.0f;
163 p.x2 = p.x2 * 2.0f - 1.0f;
164 p.y1 = p.y1 * 2.0f - 1.0f;
165 p.y2 = p.y2 * 2.0f - 1.0f;
166
167 xscale = 2.0f / (p.x2 - p.x1);
168 yscale = 2.0f / (p.y2 - p.y1);
169 xtrans = -(p.x2 + p.x1) / 2.0f;
170 ytrans = -(p.y2 + p.y1) / 2.0f;
171
172 CRASSERT(xscale == xscale); /* NaN test */
173 CRASSERT(yscale == yscale);
174
175 extent->baseProjection = identity_matrix;
176 extent->baseProjection.m00 = xscale;
177 extent->baseProjection.m11 = yscale;
178 extent->baseProjection.m30 = xtrans * xscale;
179 extent->baseProjection.m31 = ytrans * yscale;
180 }
181
182 extent->serialNo = serialNo++;
183 }
184 mural->viewportValidated = GL_TRUE;
185#else
186 RT_NOREF(v, mural);
187#endif
188}
189
190
191/*
192 * Issue the glScissor, glViewport and projection matrix needed for
193 * rendering the tile specified by extNum. We computed the scissor,
194 * viewport and projection parameters above in crServerComputeViewportBounds.
195 */
196void
197crServerSetOutputBounds( const CRMuralInfo *mural, int extNum )
198{
199#if 0
200 const CRExtent *extent = mural->extents + extNum;
201 CRASSERT(mural->viewportValidated);
202
203 /*
204 * Serial Number info:
205 * Everytime we compute new scissor, viewport, projection matrix info for
206 * a tile, we give that tile a new serial number.
207 * When we're about to render into a tile, we only update the scissor,
208 * viewport and projection matrix if the tile's serial number doesn't match
209 * the current serial number. This avoids a _LOT_ of redundant calls to
210 * those three functions.
211 */
212 if (extent->serialNo != cr_server.currentSerialNo) {
213 cr_server.head_spu->dispatch_table.Scissor(extent->scissorBox.x1,
214 extent->scissorBox.y1,
215 extent->scissorBox.x2 - extent->scissorBox.x1,
216 extent->scissorBox.y2 - extent->scissorBox.y1);
217
218 cr_server.head_spu->dispatch_table.Viewport(extent->viewport.x1,
219 extent->viewport.y1,
220 extent->viewport.x2 - extent->viewport.x1,
221 extent->viewport.y2 - extent->viewport.y1);
222
223 crServerApplyBaseProjection(&(extent->baseProjection));
224 cr_server.currentSerialNo = extent->serialNo;
225 }
226#else
227 RT_NOREF(mural, extNum);
228#endif
229}
230
231
232/*
233 * Pre-multiply the current projection matrix with the current client's
234 * base projection. I.e. P' = b * P. Note that OpenGL's glMultMatrix
235 * POST-multiplies.
236 */
237void
238crServerApplyBaseProjection(const CRmatrix *baseProj)
239{
240 const CRmatrix *projMatrix;
241 if (cr_server.projectionOverride) {
242 int eye = crServerGetCurrentEye();
243 projMatrix = &cr_server.projectionMatrix[eye];
244 }
245 else
246 projMatrix = cr_server.curClient->currentCtxInfo->pContext->transform.projectionStack.top;
247
248 cr_server.head_spu->dispatch_table.PushAttrib( GL_TRANSFORM_BIT );
249 cr_server.head_spu->dispatch_table.MatrixMode( GL_PROJECTION );
250 cr_server.head_spu->dispatch_table.LoadMatrixf( (const GLfloat *) baseProj );
251 cr_server.head_spu->dispatch_table.MultMatrixf( cr_server.alignment_matrix );
252 cr_server.head_spu->dispatch_table.MultMatrixf( (const GLfloat *) projMatrix );
253 cr_server.head_spu->dispatch_table.PopAttrib();
254}
255
256
257void
258crServerApplyViewMatrix(const CRmatrix *view)
259{
260 const CRmatrix *modelview = cr_server.curClient->currentCtxInfo->pContext->transform.modelViewStack.top;
261
262 cr_server.head_spu->dispatch_table.PushAttrib( GL_TRANSFORM_BIT );
263 cr_server.head_spu->dispatch_table.MatrixMode( GL_MODELVIEW );
264 cr_server.head_spu->dispatch_table.LoadMatrixf( (const GLfloat *) view );
265 cr_server.head_spu->dispatch_table.MultMatrixf( (const GLfloat *) modelview );
266 cr_server.head_spu->dispatch_table.PopAttrib();
267}
268
269
270/*
271 * Called via unpacker module.
272 * Note: when there's a tilesort SPU upstream, the viewport dimensions
273 * will typically match the mural size. That is, the viewport dimensions
274 * probably won't be the same values that the application issues.
275 */
276void SERVER_DISPATCH_APIENTRY crServerDispatchViewport( GLint x, GLint y, GLsizei width, GLsizei height )
277{
278 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
279
280 if (ctx->viewport.viewportX != x ||
281 ctx->viewport.viewportY != y ||
282 ctx->viewport.viewportW != width ||
283 ctx->viewport.viewportH != height) {
284 /* Note -- If there are tiles, this will be overridden in the
285 * process of decoding the BoundsInfo packet, so no worries. */
286 crStateViewport(&cr_server.StateTracker, x, y, width, height );
287 }
288
289 /* always dispatch to be safe */
290 cr_server.head_spu->dispatch_table.Viewport( x, y, width, height );
291}
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