VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_clear.c@ 50149

Last change on this file since 50149 was 50095, checked in by vboxsync, 11 years ago

crOpenGL: presentation infrastructure rework (still work in progress)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
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 CRMuralInfo *mural = cr_server.curClient->currentMural;
165 const RunQueue *q = cr_server.run_queue;
166
167 if (cr_server.only_swap_once)
168 {
169 /* NOTE: we only do the clear for the _last_ client in the list.
170 * This is because in multi-threaded apps the zeroeth client may
171 * be idle and never call glClear at all. See threadtest.c
172 * It's pretty likely that the last client will be active.
173 */
174 if ((mask & GL_COLOR_BUFFER_BIT) &&
175 (cr_server.curClient != cr_server.clients[cr_server.numClients - 1]))
176 return;
177 }
178
179 cr_server.head_spu->dispatch_table.Clear( mask );
180}
181
182static void __draw_poly(CRPoly *p)
183{
184 int b;
185
186 cr_server.head_spu->dispatch_table.Begin(GL_POLYGON);
187 for (b=0; b<p->npoints; b++)
188 cr_server.head_spu->dispatch_table.Vertex2dv(p->points+2*b);
189 cr_server.head_spu->dispatch_table.End();
190}
191
192
193void SERVER_DISPATCH_APIENTRY
194crServerDispatchSwapBuffers( GLint window, GLint flags )
195{
196 CRMuralInfo *mural;
197 CRContext *ctx;
198
199#ifdef VBOXCR_LOGFPS
200 static VBOXCRFPS Fps;
201 static bool bFpsInited = false;
202
203 if (!bFpsInited)
204 {
205 vboxCrFpsInit(&Fps, 64 /* cPeriods */);
206 bFpsInited = true;
207 }
208 vboxCrFpsReportFrame(&Fps);
209 if(!(vboxCrFpsGetNumFrames(&Fps) % 31))
210 {
211 double fps = vboxCrFpsGetFps(&Fps);
212 double bps = vboxCrFpsGetBps(&Fps);
213 double bpsSent = vboxCrFpsGetBpsSent(&Fps);
214 double cps = vboxCrFpsGetCps(&Fps);
215 double ops = vboxCrFpsGetOps(&Fps);
216 double tup = vboxCrFpsGetTimeProcPercent(&Fps);
217 crDebug("fps: %f, rec Mbps: %.1f, send Mbps: %.1f, cps: %.1f, ops: %.0f, host %.1f%%",
218 fps, bps/(1024.0*1024.0), bpsSent/(1024.0*1024.0), cps, ops, tup);
219 }
220#endif
221 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
222 if (!mural) {
223 return;
224 }
225
226
227 if (cr_server.only_swap_once)
228 {
229 /* NOTE: we only do the clear for the _last_ client in the list.
230 * This is because in multi-threaded apps the zeroeth client may
231 * be idle and never call glClear at all. See threadtest.c
232 * It's pretty likely that the last client will be active.
233 */
234 if (cr_server.curClient != cr_server.clients[cr_server.numClients - 1])
235 {
236 return;
237 }
238 }
239
240#if 0
241 if (cr_server.overlapBlending)
242 {
243 int a;
244 CRPoly *p;
245 GLboolean lighting, fog, blend, cull, tex[3];
246 GLenum mm, blendSrc, blendDst;
247 GLcolorf col;
248 CRContext *ctx = crStateGetCurrent();
249 const CRmatrix *baseProj;
250
251 /*
252 * I've probably missed some state here, or it
253 * might be easier just to push/pop it....
254 */
255 lighting = ctx->lighting.lighting;
256 fog = ctx->fog.enable;
257 tex[0] = 0;
258 for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
259 {
260 if (!ctx->texture.unit[a].enabled1D) continue;
261
262 tex[0] = 1;
263 break;
264 }
265 tex[1] = 0;
266 for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
267 {
268 if (!ctx->texture.unit[a].enabled2D) continue;
269
270 tex[1] = 1;
271 break;
272 }
273 tex[2] = 0;
274 for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
275 {
276 if (!ctx->texture.unit[a].enabled3D) continue;
277
278 tex[2] = 1;
279 break;
280 }
281
282 cull = ctx->polygon.cullFace;
283 blend = ctx->buffer.blend;
284 blendSrc = ctx->buffer.blendSrcRGB;
285 blendDst = ctx->buffer.blendDstRGB;
286 mm = ctx->transform.matrixMode;
287 col.r = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][0];
288 col.g = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][1];
289 col.b = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][2];
290 col.a = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][3];
291
292 baseProj = &(cr_server.curClient->currentMural->extents[0].baseProjection);
293
294 switch(mm)
295 {
296 case GL_PROJECTION:
297 cr_server.head_spu->dispatch_table.PushMatrix();
298 cr_server.head_spu->dispatch_table.LoadMatrixf((GLfloat *) baseProj);
299 cr_server.head_spu->dispatch_table.MultMatrixf(cr_server.unnormalized_alignment_matrix);
300 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
301 cr_server.head_spu->dispatch_table.PushMatrix();
302 cr_server.head_spu->dispatch_table.LoadIdentity();
303 break;
304
305 default:
306 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
307 /* fall through */
308
309 case GL_MODELVIEW:
310 cr_server.head_spu->dispatch_table.PushMatrix();
311 cr_server.head_spu->dispatch_table.LoadIdentity();
312 cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
313 cr_server.head_spu->dispatch_table.PushMatrix();
314 cr_server.head_spu->dispatch_table.LoadMatrixf((GLfloat *) baseProj);
315 cr_server.head_spu->dispatch_table.MultMatrixf(cr_server.unnormalized_alignment_matrix);
316 break;
317 }
318
319 /* fix state */
320 if (lighting)
321 cr_server.head_spu->dispatch_table.Disable(GL_LIGHTING);
322 if (fog)
323 cr_server.head_spu->dispatch_table.Disable(GL_FOG);
324 if (tex[0])
325 cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_1D);
326 if (tex[1])
327 cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_2D);
328 if (tex[2])
329 cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_3D);
330 if (cull)
331 cr_server.head_spu->dispatch_table.Disable(GL_CULL_FACE);
332
333 /* Regular Blending */
334 if (cr_server.overlapBlending == 1)
335 {
336 if (!blend)
337 cr_server.head_spu->dispatch_table.Enable(GL_BLEND);
338 if ((blendSrc != GL_ZERO) && (blendDst != GL_SRC_ALPHA))
339 cr_server.head_spu->dispatch_table.BlendFunc(GL_ZERO, GL_SRC_ALPHA);
340
341 /* draw the blends */
342 for (a=1; a<cr_server.num_overlap_levels; a++)
343 {
344 if (a-1 < cr_server.num_overlap_intens)
345 {
346 cr_server.head_spu->dispatch_table.Color4f(0, 0, 0,
347 cr_server.overlap_intens[a-1]);
348 }
349 else
350 {
351 cr_server.head_spu->dispatch_table.Color4f(0, 0, 0, 1);
352 }
353
354 p = cr_server.overlap_geom[a];
355 while (p)
356 {
357 /* hopefully this isnt concave... */
358 __draw_poly(p);
359 p = p->next;
360 }
361 }
362
363 if (!blend)
364 cr_server.head_spu->dispatch_table.Disable(GL_BLEND);
365 if ((blendSrc != GL_ZERO) && (blendDst != GL_SRC_ALPHA))
366 cr_server.head_spu->dispatch_table.BlendFunc(blendSrc, blendDst);
367 }
368 else
369 /* Knockout Blending */
370 {
371 cr_server.head_spu->dispatch_table.Color4f(0, 0, 0, 1);
372
373 if (blend)
374 cr_server.head_spu->dispatch_table.Disable(GL_BLEND);
375 p = cr_server.overlap_knockout;
376 while (p)
377 {
378 __draw_poly(p);
379 p = p->next;
380 }
381 if (blend)
382 cr_server.head_spu->dispatch_table.Enable(GL_BLEND);
383 }
384
385
386 /* return things to normal */
387 switch (mm)
388 {
389 case GL_PROJECTION:
390 cr_server.head_spu->dispatch_table.PopMatrix();
391 cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
392 cr_server.head_spu->dispatch_table.PopMatrix();
393 break;
394 case GL_MODELVIEW:
395 cr_server.head_spu->dispatch_table.PopMatrix();
396 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
397 cr_server.head_spu->dispatch_table.PopMatrix();
398 break;
399 default:
400 cr_server.head_spu->dispatch_table.PopMatrix();
401 cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
402 cr_server.head_spu->dispatch_table.PopMatrix();
403 cr_server.head_spu->dispatch_table.MatrixMode(mm);
404 break;
405 }
406
407 if (lighting)
408 cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING);
409 if (fog)
410 cr_server.head_spu->dispatch_table.Enable(GL_FOG);
411 if (tex[0])
412 cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_1D);
413 if (tex[1])
414 cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);
415 if (tex[2])
416 cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_3D);
417 if (cull)
418 cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE);
419
420 cr_server.head_spu->dispatch_table.Color4f(col.r, col.g, col.b, col.a);
421 }
422#endif
423
424 /* Check if using a file network */
425 if (!cr_server.clients[0]->conn->actual_network && window == MAGIC_OFFSET)
426 window = 0;
427
428 ctx = crStateGetCurrent();
429
430 CRASSERT(cr_server.curClient && cr_server.curClient->currentMural == mural);
431
432 if (ctx->framebufferobject.drawFB
433 || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
434 mural->bFbDraw = GL_FALSE;
435
436 CR_SERVER_DUMP_SWAPBUFFERS_ENTER();
437
438 if (crServerIsRedirectedToFBO())
439 {
440 crServerMuralFBOSwapBuffers(mural);
441 crServerPresentFBO(mural);
442 }
443 else
444 {
445 cr_server.head_spu->dispatch_table.SwapBuffers( mural->spuWindow, flags );
446 }
447
448 CR_SERVER_DUMP_SWAPBUFFERS_LEAVE();
449}
450
451void SERVER_DISPATCH_APIENTRY
452crServerDispatchFlush(void)
453{
454 CRContext *ctx = crStateGetCurrent();
455 cr_server.head_spu->dispatch_table.Flush();
456
457 if (cr_server.curClient && cr_server.curClient->currentMural)
458 {
459 CRMuralInfo *mural = cr_server.curClient->currentMural;
460 if (mural->bFbDraw)
461 {
462 if (crServerIsRedirectedToFBO())
463 crServerPresentFBO(mural);
464 }
465
466 if (ctx->framebufferobject.drawFB
467 || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
468 mural->bFbDraw = GL_FALSE;
469 }
470}
471
472void SERVER_DISPATCH_APIENTRY
473crServerDispatchFinish(void)
474{
475 CRContext *ctx = crStateGetCurrent();
476
477 cr_server.head_spu->dispatch_table.Finish();
478
479 if (cr_server.curClient && cr_server.curClient->currentMural)
480 {
481 CRMuralInfo *mural = cr_server.curClient->currentMural;
482 if (mural->bFbDraw)
483 {
484 if (crServerIsRedirectedToFBO())
485 crServerPresentFBO(mural);
486 }
487
488 if (ctx->framebufferobject.drawFB
489 || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
490 mural->bFbDraw = GL_FALSE;
491 }
492}
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