VirtualBox

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

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

crOpenGL: add sent bytes counter

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette