VirtualBox

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

Last change on this file since 33281 was 32940, checked in by vboxsync, 14 years ago

crOpenGL: another perf counter

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