VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp@ 21990

Last change on this file since 21990 was 21990, checked in by vboxsync, 16 years ago

crOpenGL: fix 3d failure after snapshot loading

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.3 KB
Line 
1/* $Id: crservice.cpp 21990 2009-08-05 12:28:09Z vboxsync $ */
2
3/** @file
4 * VBox crOpenGL: Host service entry points.
5 */
6
7/*
8 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#define __STDC_CONSTANT_MACROS /* needed for a definition in iprt/string.h */
24
25#ifdef RT_OS_WINDOWS
26#include <iprt/alloc.h>
27#include <iprt/string.h>
28#include <iprt/assert.h>
29#include <iprt/stream.h>
30#include <VBox/ssm.h>
31#include <VBox/hgcmsvc.h>
32#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
33#include "cr_server.h"
34#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
35#include <VBox/log.h>
36
37#include <VBox/com/com.h>
38#include <VBox/com/string.h>
39#include <VBox/com/array.h>
40#include <VBox/com/Guid.h>
41#include <VBox/com/ErrorInfo.h>
42#include <VBox/com/EventQueue.h>
43#include <VBox/com/VirtualBox.h>
44#include <VBox/com/assert.h>
45
46#else
47#include <VBox/com/VirtualBox.h>
48#include <iprt/assert.h>
49#include <VBox/ssm.h>
50#include <VBox/hgcmsvc.h>
51#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
52
53#include "cr_server.h"
54#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
55#include <VBox/log.h>
56#endif
57
58#include "render/renderspu.h"
59
60PVBOXHGCMSVCHELPERS g_pHelpers;
61static IFramebuffer* g_pFrameBuffer;
62static ULONG64 g_winId = 0;
63
64#ifndef RT_OS_WINDOWS
65#define DWORD int
66#define WINAPI
67#endif
68
69#define CR_USE_HGCM
70
71static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
72#define SHCROGL_SSM_VERSION 4
73
74typedef struct
75{
76 DWORD dwThreadID;
77
78} VBOXOGLCTX, *PVBOXOGLCTX;
79
80/*@todo remove this workaround for crstate "unshareable" data*/
81static int crIsThreadWorking=0;
82
83static DWORD WINAPI crServerProc(void* pv)
84{
85 uint64_t winId = *((uint64_t*)pv);
86 renderspuSetWindowId((uint32_t)winId);
87 CRServerMain(0, NULL);
88 crIsThreadWorking = 0;
89 return 0;
90}
91
92
93static DECLCALLBACK(int) svcUnload (void *)
94{
95 int rc = VINF_SUCCESS;
96
97 Log(("SHARED_CROPENGL svcUnload\n"));
98
99 //vboxglGlobalUnload();
100 crVBoxServerTearDown();
101
102 return rc;
103}
104
105static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
106{
107 int rc = VINF_SUCCESS;
108
109 NOREF(u32ClientID);
110 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
111 Assert(pClient);
112
113 Log(("SHARED_CROPENGL svcConnect: u32ClientID = %d\n", u32ClientID));
114
115#ifndef CR_USE_HGCM
116 if (!crIsThreadWorking)
117 {
118 HANDLE h;
119 Assert(g_pFrameBuffer);
120
121 g_pFrameBuffer->COMGETTER(WinId)(&g_winId);
122 //CHECK_ERROR_RET(g_piConsole, COMGETTER(Display)(display.asOutParam()), rc);
123
124 //vboxglConnect((PVBOXOGLCTX)pvClient);
125 crIsThreadWorking=1;
126 h = CreateThread(NULL, 0, crServerProc, (void*)&g_winId, 0, &pClient->dwThreadID);
127 if (!h) rc = VERR_MAX_THRDS_REACHED;
128 }
129 else
130 rc = VERR_MAX_THRDS_REACHED;
131#else
132 g_pFrameBuffer->COMGETTER(WinId)(&g_winId);
133 renderspuSetWindowId((uint32_t)g_winId);
134 rc = crVBoxServerAddClient(u32ClientID);
135#endif
136
137 return rc;
138}
139
140static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
141{
142 int rc = VINF_SUCCESS;
143 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
144 Assert(pClient);
145
146 Log(("SHARED_CROPENGL svcDisconnect: u32ClientID = %d\n", u32ClientID));
147
148#ifndef CR_USE_HGCM
149 if (crIsThreadWorking && pClient->dwThreadID)
150 PostThreadMessage(pClient->dwThreadID, WM_QUIT, 0, 0);
151#else
152 crVBoxServerRemoveClient(u32ClientID);
153#endif
154 //vboxglDisconnect((PVBOXOGLCTX)pvClient);
155 return rc;
156}
157
158static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
159{
160 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
161
162 NOREF(pClient);
163
164 Log(("SHARED_CROPENGL svcSaveState: u32ClientID = %d\n", u32ClientID));
165
166 int rc;
167
168 /* Start*/
169 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
170 AssertRCReturn(rc, rc);
171
172 /* Version */
173 rc = SSMR3PutU32(pSSM, (uint32_t) SHCROGL_SSM_VERSION);
174 AssertRCReturn(rc, rc);
175
176 /* The state itself */
177 rc = crVBoxServerSaveState(pSSM);
178 AssertRCReturn(rc, rc);
179
180 /* End */
181 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
182 AssertRCReturn(rc, rc);
183
184 return VINF_SUCCESS;
185}
186
187static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
188{
189 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
190
191 NOREF(pClient);
192 NOREF(pSSM);
193
194 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
195
196 char psz[2000];
197 int rc;
198 uint32_t ui32;
199
200 /* Start of data */
201 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
202 AssertRCReturn(rc, rc);
203 if (strcmp(gszVBoxOGLSSMMagic, psz))
204 return VERR_SSM_UNEXPECTED_DATA;
205
206 /* Version */
207 rc = SSMR3GetU32(pSSM, &ui32);
208 AssertRCReturn(rc, rc);
209 if ((SHCROGL_SSM_VERSION != ui32)
210 && (3 != ui32))
211 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
212
213 /* The state itself */
214 rc = crVBoxServerLoadState(pSSM, ui32);
215 AssertRCReturn(rc, rc);
216
217 /* End of data */
218 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
219 AssertRCReturn(rc, rc);
220 if (strcmp(gszVBoxOGLSSMMagic, psz))
221 return VERR_SSM_UNEXPECTED_DATA;
222
223 return VINF_SUCCESS;
224}
225
226static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
227{
228 LogRel(("SHARED_CROPENGL: unsupported client version %d.%d\n", minor, major));
229 /*todo add warning window*/
230}
231
232static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
233{
234 int rc = VINF_SUCCESS;
235
236 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
237
238 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
239
240#ifdef DEBUG
241 uint32_t i;
242
243 for (i = 0; i < cParms; i++)
244 {
245 /** @todo parameters other than 32 bit */
246 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
247 }
248#endif
249
250 switch (u32Function)
251 {
252 case SHCRGL_GUEST_FN_WRITE:
253 {
254 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
255
256 /* Verify parameter count and types. */
257 if (cParms != SHCRGL_CPARMS_WRITE)
258 {
259 rc = VERR_INVALID_PARAMETER;
260 }
261 else
262 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
263 )
264 {
265 rc = VERR_INVALID_PARAMETER;
266 }
267 else
268 {
269 /* Fetch parameters. */
270 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
271 uint32_t cbBuffer = paParms[0].u.pointer.size;
272
273 /* Execute the function. */
274 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
275 if (!RT_SUCCESS(rc))
276 {
277 Assert(VERR_NOT_SUPPORTED==rc);
278 svcClientVersionUnsupported(0, 0);
279 }
280
281 }
282 break;
283 }
284
285 case SHCRGL_GUEST_FN_READ:
286 {
287 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
288
289 /* Verify parameter count and types. */
290 if (cParms != SHCRGL_CPARMS_READ)
291 {
292 rc = VERR_INVALID_PARAMETER;
293 }
294 else
295 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
296 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
297 )
298 {
299 rc = VERR_INVALID_PARAMETER;
300 }
301
302 /* Fetch parameters. */
303 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
304 uint32_t cbBuffer = paParms[0].u.pointer.size;
305
306 /* Execute the function. */
307 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
308
309 if (RT_SUCCESS(rc))
310 {
311 /* Update parameters.*/
312 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
313 } else if (VERR_NOT_SUPPORTED==rc)
314 {
315 svcClientVersionUnsupported(0, 0);
316 }
317
318 /* Return the required buffer size always */
319 paParms[1].u.uint32 = cbBuffer;
320
321 break;
322 }
323
324 case SHCRGL_GUEST_FN_WRITE_READ:
325 {
326 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
327
328 /* Verify parameter count and types. */
329 if (cParms != SHCRGL_CPARMS_WRITE_READ)
330 {
331 rc = VERR_INVALID_PARAMETER;
332 }
333 else
334 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
335 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
336 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
337 )
338 {
339 rc = VERR_INVALID_PARAMETER;
340 }
341 else
342 {
343 /* Fetch parameters. */
344 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
345 uint32_t cbBuffer = paParms[0].u.pointer.size;
346
347 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
348 uint32_t cbWriteback = paParms[1].u.pointer.size;
349
350 /* Execute the function. */
351 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
352 if (!RT_SUCCESS(rc))
353 {
354 Assert(VERR_NOT_SUPPORTED==rc);
355 svcClientVersionUnsupported(0, 0);
356 }
357
358 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
359
360 if (RT_SUCCESS(rc))
361 {
362 /* Update parameters.*/
363 paParms[1].u.pointer.size = cbWriteback;
364 }
365 /* Return the required buffer size always */
366 paParms[2].u.uint32 = cbWriteback;
367 }
368 break;
369 }
370
371 case SHCRGL_GUEST_FN_SET_VERSION:
372 {
373 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
374
375 /* Verify parameter count and types. */
376 if (cParms != SHCRGL_CPARMS_SET_VERSION)
377 {
378 rc = VERR_INVALID_PARAMETER;
379 }
380 else
381 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
382 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
383 )
384 {
385 rc = VERR_INVALID_PARAMETER;
386 }
387 else
388 {
389 /* Fetch parameters. */
390 uint32_t vMajor = paParms[0].u.uint32;
391 uint32_t vMinor = paParms[1].u.uint32;
392
393 /* Execute the function. */
394 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
395
396 if (!RT_SUCCESS(rc))
397 {
398 /*@todo, add warning window*/
399 svcClientVersionUnsupported(vMajor, vMinor);
400 }
401 }
402
403 break;
404 }
405
406 default:
407 {
408 rc = VERR_NOT_IMPLEMENTED;
409 }
410 }
411
412
413 LogFlow(("svcCall: rc = %Rrc\n", rc));
414
415 g_pHelpers->pfnCallComplete (callHandle, rc);
416}
417
418/*
419 * We differentiate between a function handler for the guest and one for the host.
420 */
421static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
422{
423 int rc = VINF_SUCCESS;
424
425 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
426
427#ifdef DEBUG
428 uint32_t i;
429
430 for (i = 0; i < cParms; i++)
431 {
432 /** @todo parameters other than 32 bit */
433 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
434 }
435#endif
436
437 switch (u32Function)
438 {
439 case SHCRGL_HOST_FN_SET_FRAMEBUFFER:
440 {
441 Log(("svcCall: SHCRGL_HOST_FN_SET_FRAMEBUFFER\n"));
442
443 /* Verify parameter count and types. */
444 if (cParms != SHCRGL_CPARMS_SET_FRAMEBUFFER)
445 {
446 rc = VERR_INVALID_PARAMETER;
447 }
448 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
449 {
450 rc = VERR_INVALID_PARAMETER;
451 }
452 else
453 {
454 /* Fetch parameters. */
455 IFramebuffer* pFrameBuffer = (IFramebuffer*)paParms[0].u.pointer.addr;
456 uint32_t cbData = paParms[0].u.pointer.size;
457
458 /* Verify parameters values. */
459 if (cbData != sizeof (IFramebuffer*))
460 {
461 rc = VERR_INVALID_PARAMETER;
462 }
463 else
464 {
465 /* Execute the function. */
466 g_pFrameBuffer = pFrameBuffer;
467 rc = VINF_SUCCESS;
468 }
469 }
470 break;
471 }
472 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
473 {
474 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
475
476 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
477 {
478 rc = VERR_INVALID_PARAMETER;
479 break;
480 }
481
482 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
483 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
484 )
485 {
486 rc = VERR_INVALID_PARAMETER;
487 break;
488 }
489
490 Assert(sizeof(RTRECT)==4*sizeof(GLint));
491
492 renderspuSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
493 break;
494 }
495 default:
496 rc = VERR_NOT_IMPLEMENTED;
497 break;
498 }
499
500 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
501 return rc;
502}
503
504extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
505{
506 int rc = VINF_SUCCESS;
507
508 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
509
510 if (!ptable)
511 {
512 rc = VERR_INVALID_PARAMETER;
513 }
514 else
515 {
516 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
517
518 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
519 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
520 {
521 rc = VERR_INVALID_PARAMETER;
522 }
523 else
524 {
525 g_pHelpers = ptable->pHelpers;
526
527 ptable->cbClient = sizeof (VBOXOGLCTX);
528
529 ptable->pfnUnload = svcUnload;
530 ptable->pfnConnect = svcConnect;
531 ptable->pfnDisconnect = svcDisconnect;
532 ptable->pfnCall = svcCall;
533 ptable->pfnHostCall = svcHostCall;
534 ptable->pfnSaveState = svcSaveState;
535 ptable->pfnLoadState = svcLoadState;
536 ptable->pvService = NULL;
537#ifdef CR_USE_HGCM
538 if (!crVBoxServerInit())
539 return VERR_NOT_SUPPORTED;
540#endif
541 }
542 }
543
544 return rc;
545}
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