VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_clear.cpp@ 78975

Last change on this file since 78975 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: 13.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 "cr_spu.h"
8#include "chromium.h"
9#include "cr_mem.h"
10#include "cr_net.h"
11#include "server_dispatch.h"
12#include "server.h"
13
14#ifdef VBOXCR_LOGFPS
15#include <iprt/timer.h>
16#include <iprt/ctype.h>
17typedef struct VBOXCRFPS
18{
19 uint64_t mPeriodSum;
20 uint64_t *mpaPeriods;
21 uint64_t mPrevTime;
22 uint64_t mcFrames;
23 uint32_t mcPeriods;
24 uint32_t miPeriod;
25
26 uint64_t mBytesSum;
27 uint32_t *mpaBytes;
28
29 uint64_t mBytesSentSum;
30 uint32_t *mpaBytesSent;
31
32 uint64_t mCallsSum;
33 uint32_t *mpaCalls;
34
35 uint64_t mOpsSum;
36 uint32_t *mpaOps;
37
38 uint64_t mTimeUsedSum;
39 uint64_t *mpaTimes;
40} VBOXCRFPS, *PVBOXCRFPS;
41
42void vboxCrFpsInit(PVBOXCRFPS pFps, uint32_t cPeriods)
43{
44 crMemset(pFps, 0, sizeof (*pFps));
45 pFps->mcPeriods = cPeriods;
46 pFps->mpaPeriods = crCalloc(sizeof (pFps->mpaPeriods[0]) * cPeriods);
47 pFps->mpaBytes = crCalloc(sizeof (pFps->mpaBytes[0]) * cPeriods);
48 pFps->mpaBytesSent = crCalloc(sizeof (pFps->mpaBytesSent[0]) * cPeriods);
49 pFps->mpaCalls = crCalloc(sizeof (pFps->mpaCalls[0]) * cPeriods);
50 pFps->mpaOps = crCalloc(sizeof (pFps->mpaOps[0]) * cPeriods);
51 pFps->mpaTimes = crCalloc(sizeof (pFps->mpaTimes[0]) * cPeriods);
52}
53
54void vboxCrFpsTerm(PVBOXCRFPS pFps)
55{
56 crFree(pFps->mpaPeriods);
57 crFree(pFps->mpaBytes);
58 crFree(pFps->mpaCalls);
59}
60
61void vboxCrFpsReportFrame(PVBOXCRFPS pFps)
62{
63 uint64_t cur = RTTimeNanoTS();
64 uint64_t curBytes, curBytesSent, curCalls, curOps, curTimeUsed;
65 int i;
66
67 curBytes = 0;
68 curBytesSent = 0;
69 curCalls = 0;
70 curOps = 0;
71 curTimeUsed = 0;
72
73 for (i = 0; i < cr_server.numClients; i++)
74 {
75 if (cr_server.clients[i] && cr_server.clients[i]->conn)
76 {
77 curBytes += cr_server.clients[i]->conn->total_bytes_recv;
78 curBytesSent += cr_server.clients[i]->conn->total_bytes_sent;
79 curCalls += cr_server.clients[i]->conn->recv_count;
80 curOps += cr_server.clients[i]->conn->opcodes_count;
81 curTimeUsed += cr_server.clients[i]->timeUsed;
82 cr_server.clients[i]->conn->total_bytes_recv = 0;
83 cr_server.clients[i]->conn->total_bytes_sent = 0;
84 cr_server.clients[i]->conn->recv_count = 0;
85 cr_server.clients[i]->conn->opcodes_count = 0;
86 cr_server.clients[i]->timeUsed = 0;
87 }
88 }
89
90 if(pFps->mPrevTime)
91 {
92 uint64_t curPeriod = cur - pFps->mPrevTime;
93
94 pFps->mPeriodSum += curPeriod - pFps->mpaPeriods[pFps->miPeriod];
95 pFps->mpaPeriods[pFps->miPeriod] = curPeriod;
96
97 pFps->mBytesSum += curBytes - pFps->mpaBytes[pFps->miPeriod];
98 pFps->mpaBytes[pFps->miPeriod] = curBytes;
99
100 pFps->mBytesSentSum += curBytesSent - pFps->mpaBytesSent[pFps->miPeriod];
101 pFps->mpaBytesSent[pFps->miPeriod] = curBytesSent;
102
103 pFps->mCallsSum += curCalls - pFps->mpaCalls[pFps->miPeriod];
104 pFps->mpaCalls[pFps->miPeriod] = curCalls;
105
106 pFps->mOpsSum += curOps - pFps->mpaOps[pFps->miPeriod];
107 pFps->mpaOps[pFps->miPeriod] = curOps;
108
109 pFps->mTimeUsedSum += curTimeUsed - pFps->mpaTimes[pFps->miPeriod];
110 pFps->mpaTimes[pFps->miPeriod] = curTimeUsed;
111
112 ++pFps->miPeriod;
113 pFps->miPeriod %= pFps->mcPeriods;
114 }
115 pFps->mPrevTime = cur;
116 ++pFps->mcFrames;
117}
118
119uint64_t vboxCrFpsGetEveragePeriod(PVBOXCRFPS pFps)
120{
121 return pFps->mPeriodSum / pFps->mcPeriods;
122}
123
124double vboxCrFpsGetFps(PVBOXCRFPS pFps)
125{
126 return ((double)1000000000.0) / vboxCrFpsGetEveragePeriod(pFps);
127}
128
129double vboxCrFpsGetBps(PVBOXCRFPS pFps)
130{
131 return vboxCrFpsGetFps(pFps) * pFps->mBytesSum / pFps->mcPeriods;
132}
133
134double vboxCrFpsGetBpsSent(PVBOXCRFPS pFps)
135{
136 return vboxCrFpsGetFps(pFps) * pFps->mBytesSentSum / pFps->mcPeriods;
137}
138
139double vboxCrFpsGetCps(PVBOXCRFPS pFps)
140{
141 return vboxCrFpsGetFps(pFps) * pFps->mCallsSum / pFps->mcPeriods;
142}
143
144double vboxCrFpsGetOps(PVBOXCRFPS pFps)
145{
146 return vboxCrFpsGetFps(pFps) * pFps->mOpsSum / pFps->mcPeriods;
147}
148
149double vboxCrFpsGetTimeProcPercent(PVBOXCRFPS pFps)
150{
151 return 100.0*pFps->mTimeUsedSum/pFps->mPeriodSum;
152}
153
154uint64_t vboxCrFpsGetNumFrames(PVBOXCRFPS pFps)
155{
156 return pFps->mcFrames;
157}
158
159#endif
160
161
162void SERVER_DISPATCH_APIENTRY crServerDispatchClear( GLenum mask )
163{
164 if (cr_server.only_swap_once)
165 {
166 /* NOTE: we only do the clear for the _last_ client in the list.
167 * This is because in multi-threaded apps the zeroeth client may
168 * be idle and never call glClear at all. See threadtest.c
169 * It's pretty likely that the last client will be active.
170 */
171 if ((mask & GL_COLOR_BUFFER_BIT) &&
172 (cr_server.curClient != cr_server.clients[cr_server.numClients - 1]))
173 return;
174 }
175
176 cr_server.head_spu->dispatch_table.Clear( mask );
177}
178
179static void __draw_poly(CRPoly *p)
180{
181 int b;
182
183 cr_server.head_spu->dispatch_table.Begin(GL_POLYGON);
184 for (b=0; b<p->npoints; b++)
185 cr_server.head_spu->dispatch_table.Vertex2dv(p->points+2*b);
186 cr_server.head_spu->dispatch_table.End();
187}
188
189
190void SERVER_DISPATCH_APIENTRY
191crServerDispatchSwapBuffers( GLint window, GLint flags )
192{
193 CRMuralInfo *mural;
194 CRContext *ctx;
195
196#ifdef VBOXCR_LOGFPS
197 static VBOXCRFPS Fps;
198 static bool bFpsInited = false;
199
200 if (!bFpsInited)
201 {
202 vboxCrFpsInit(&Fps, 64 /* cPeriods */);
203 bFpsInited = true;
204 }
205 vboxCrFpsReportFrame(&Fps);
206 if(!(vboxCrFpsGetNumFrames(&Fps) % 31))
207 {
208 double fps = vboxCrFpsGetFps(&Fps);
209 double bps = vboxCrFpsGetBps(&Fps);
210 double bpsSent = vboxCrFpsGetBpsSent(&Fps);
211 double cps = vboxCrFpsGetCps(&Fps);
212 double ops = vboxCrFpsGetOps(&Fps);
213 double tup = vboxCrFpsGetTimeProcPercent(&Fps);
214 crDebug("fps: %f, rec Mbps: %.1f, send Mbps: %.1f, cps: %.1f, ops: %.0f, host %.1f%%",
215 fps, bps/(1024.0*1024.0), bpsSent/(1024.0*1024.0), cps, ops, tup);
216 }
217#endif
218 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
219 if (!mural) {
220 return;
221 }
222
223
224 if (cr_server.only_swap_once)
225 {
226 /* NOTE: we only do the clear for the _last_ client in the list.
227 * This is because in multi-threaded apps the zeroeth client may
228 * be idle and never call glClear at all. See threadtest.c
229 * It's pretty likely that the last client will be active.
230 */
231 if (cr_server.curClient != cr_server.clients[cr_server.numClients - 1])
232 {
233 return;
234 }
235 }
236
237#if 0
238 if (cr_server.overlapBlending)
239 {
240 int a;
241 CRPoly *p;
242 GLboolean lighting, fog, blend, cull, tex[3];
243 GLenum mm, blendSrc, blendDst;
244 GLcolorf col;
245 CRContext *ctx = crStateGetCurrent();
246 const CRmatrix *baseProj;
247
248 /*
249 * I've probably missed some state here, or it
250 * might be easier just to push/pop it....
251 */
252 lighting = ctx->lighting.lighting;
253 fog = ctx->fog.enable;
254 tex[0] = 0;
255 for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
256 {
257 if (!ctx->texture.unit[a].enabled1D) continue;
258
259 tex[0] = 1;
260 break;
261 }
262 tex[1] = 0;
263 for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
264 {
265 if (!ctx->texture.unit[a].enabled2D) continue;
266
267 tex[1] = 1;
268 break;
269 }
270 tex[2] = 0;
271 for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
272 {
273 if (!ctx->texture.unit[a].enabled3D) continue;
274
275 tex[2] = 1;
276 break;
277 }
278
279 cull = ctx->polygon.cullFace;
280 blend = ctx->buffer.blend;
281 blendSrc = ctx->buffer.blendSrcRGB;
282 blendDst = ctx->buffer.blendDstRGB;
283 mm = ctx->transform.matrixMode;
284 col.r = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][0];
285 col.g = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][1];
286 col.b = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][2];
287 col.a = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][3];
288
289 baseProj = &(cr_server.curClient->currentMural->extents[0].baseProjection);
290
291 switch(mm)
292 {
293 case GL_PROJECTION:
294 cr_server.head_spu->dispatch_table.PushMatrix();
295 cr_server.head_spu->dispatch_table.LoadMatrixf((GLfloat *) baseProj);
296 cr_server.head_spu->dispatch_table.MultMatrixf(cr_server.unnormalized_alignment_matrix);
297 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
298 cr_server.head_spu->dispatch_table.PushMatrix();
299 cr_server.head_spu->dispatch_table.LoadIdentity();
300 break;
301
302 default:
303 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
304 /* fall through */
305
306 case GL_MODELVIEW:
307 cr_server.head_spu->dispatch_table.PushMatrix();
308 cr_server.head_spu->dispatch_table.LoadIdentity();
309 cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
310 cr_server.head_spu->dispatch_table.PushMatrix();
311 cr_server.head_spu->dispatch_table.LoadMatrixf((GLfloat *) baseProj);
312 cr_server.head_spu->dispatch_table.MultMatrixf(cr_server.unnormalized_alignment_matrix);
313 break;
314 }
315
316 /* fix state */
317 if (lighting)
318 cr_server.head_spu->dispatch_table.Disable(GL_LIGHTING);
319 if (fog)
320 cr_server.head_spu->dispatch_table.Disable(GL_FOG);
321 if (tex[0])
322 cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_1D);
323 if (tex[1])
324 cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_2D);
325 if (tex[2])
326 cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_3D);
327 if (cull)
328 cr_server.head_spu->dispatch_table.Disable(GL_CULL_FACE);
329
330 /* Regular Blending */
331 if (cr_server.overlapBlending == 1)
332 {
333 if (!blend)
334 cr_server.head_spu->dispatch_table.Enable(GL_BLEND);
335 if ((blendSrc != GL_ZERO) && (blendDst != GL_SRC_ALPHA))
336 cr_server.head_spu->dispatch_table.BlendFunc(GL_ZERO, GL_SRC_ALPHA);
337
338 /* draw the blends */
339 for (a=1; a<cr_server.num_overlap_levels; a++)
340 {
341 if (a-1 < cr_server.num_overlap_intens)
342 {
343 cr_server.head_spu->dispatch_table.Color4f(0, 0, 0,
344 cr_server.overlap_intens[a-1]);
345 }
346 else
347 {
348 cr_server.head_spu->dispatch_table.Color4f(0, 0, 0, 1);
349 }
350
351 p = cr_server.overlap_geom[a];
352 while (p)
353 {
354 /* hopefully this isnt concave... */
355 __draw_poly(p);
356 p = p->next;
357 }
358 }
359
360 if (!blend)
361 cr_server.head_spu->dispatch_table.Disable(GL_BLEND);
362 if ((blendSrc != GL_ZERO) && (blendDst != GL_SRC_ALPHA))
363 cr_server.head_spu->dispatch_table.BlendFunc(blendSrc, blendDst);
364 }
365 else
366 /* Knockout Blending */
367 {
368 cr_server.head_spu->dispatch_table.Color4f(0, 0, 0, 1);
369
370 if (blend)
371 cr_server.head_spu->dispatch_table.Disable(GL_BLEND);
372 p = cr_server.overlap_knockout;
373 while (p)
374 {
375 __draw_poly(p);
376 p = p->next;
377 }
378 if (blend)
379 cr_server.head_spu->dispatch_table.Enable(GL_BLEND);
380 }
381
382
383 /* return things to normal */
384 switch (mm)
385 {
386 case GL_PROJECTION:
387 cr_server.head_spu->dispatch_table.PopMatrix();
388 cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
389 cr_server.head_spu->dispatch_table.PopMatrix();
390 break;
391 case GL_MODELVIEW:
392 cr_server.head_spu->dispatch_table.PopMatrix();
393 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
394 cr_server.head_spu->dispatch_table.PopMatrix();
395 break;
396 default:
397 cr_server.head_spu->dispatch_table.PopMatrix();
398 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
399 cr_server.head_spu->dispatch_table.PopMatrix();
400 cr_server.head_spu->dispatch_table.MatrixMode(mm);
401 break;
402 }
403
404 if (lighting)
405 cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING);
406 if (fog)
407 cr_server.head_spu->dispatch_table.Enable(GL_FOG);
408 if (tex[0])
409 cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_1D);
410 if (tex[1])
411 cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);
412 if (tex[2])
413 cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_3D);
414 if (cull)
415 cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE);
416
417 cr_server.head_spu->dispatch_table.Color4f(col.r, col.g, col.b, col.a);
418 }
419#endif
420
421 /* Check if using a file network */
422 if (!cr_server.clients[0]->conn->actual_network && window == MAGIC_OFFSET)
423 window = 0;
424
425 ctx = crStateGetCurrent(&cr_server.StateTracker);
426
427 CRASSERT(cr_server.curClient && cr_server.curClient->currentMural == mural);
428
429 if (ctx->framebufferobject.drawFB
430 || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
431 mural->bFbDraw = GL_FALSE;
432
433 CR_SERVER_DUMP_SWAPBUFFERS_ENTER();
434
435 if (crServerIsRedirectedToFBO())
436 {
437 crServerMuralFBOSwapBuffers(mural);
438 crServerPresentFBO(mural);
439 }
440 else
441 {
442 cr_server.head_spu->dispatch_table.SwapBuffers( mural->spuWindow, flags );
443 }
444
445 CR_SERVER_DUMP_SWAPBUFFERS_LEAVE();
446}
447
448void SERVER_DISPATCH_APIENTRY
449crServerDispatchFlush(void)
450{
451 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
452 cr_server.head_spu->dispatch_table.Flush();
453
454 if (cr_server.curClient && cr_server.curClient->currentMural)
455 {
456 CRMuralInfo *mural = cr_server.curClient->currentMural;
457 if (mural->bFbDraw)
458 {
459 if (crServerIsRedirectedToFBO())
460 crServerPresentFBO(mural);
461 }
462
463 if (ctx->framebufferobject.drawFB
464 || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
465 mural->bFbDraw = GL_FALSE;
466 }
467}
468
469void SERVER_DISPATCH_APIENTRY
470crServerDispatchFinish(void)
471{
472 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
473
474 cr_server.head_spu->dispatch_table.Finish();
475
476 if (cr_server.curClient && cr_server.curClient->currentMural)
477 {
478 CRMuralInfo *mural = cr_server.curClient->currentMural;
479 if (mural->bFbDraw)
480 {
481 if (crServerIsRedirectedToFBO())
482 crServerPresentFBO(mural);
483 }
484
485 if (ctx->framebufferobject.drawFB
486 || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
487 mural->bFbDraw = GL_FALSE;
488 }
489}
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