VirtualBox

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

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

crOpenGL: add opcodes counter

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