VirtualBox

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

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

crOpenGL: build fix to the host service

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.2 KB
Line 
1/* $Id: crservice.cpp 21624 2009-07-15 19:41:58Z 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 3
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 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
211
212 /* The state itself */
213 rc = crVBoxServerLoadState(pSSM);
214 AssertRCReturn(rc, rc);
215
216 /* End of data */
217 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
218 AssertRCReturn(rc, rc);
219 if (strcmp(gszVBoxOGLSSMMagic, psz))
220 return VERR_SSM_UNEXPECTED_DATA;
221
222 return VINF_SUCCESS;
223}
224
225static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
226{
227 LogRel(("SHARED_CROPENGL: unsupported client version %d.%d\n", minor, major));
228 /*todo add warning window*/
229}
230
231static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
232{
233 int rc = VINF_SUCCESS;
234
235 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
236
237 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
238
239#ifdef DEBUG
240 uint32_t i;
241
242 for (i = 0; i < cParms; i++)
243 {
244 /** @todo parameters other than 32 bit */
245 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
246 }
247#endif
248
249 switch (u32Function)
250 {
251 case SHCRGL_GUEST_FN_WRITE:
252 {
253 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
254
255 /* Verify parameter count and types. */
256 if (cParms != SHCRGL_CPARMS_WRITE)
257 {
258 rc = VERR_INVALID_PARAMETER;
259 }
260 else
261 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
262 )
263 {
264 rc = VERR_INVALID_PARAMETER;
265 }
266 else
267 {
268 /* Fetch parameters. */
269 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
270 uint32_t cbBuffer = paParms[0].u.pointer.size;
271
272 /* Execute the function. */
273 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
274 if (!RT_SUCCESS(rc))
275 {
276 Assert(VERR_NOT_SUPPORTED==rc);
277 svcClientVersionUnsupported(0, 0);
278 }
279
280 }
281 break;
282 }
283
284 case SHCRGL_GUEST_FN_READ:
285 {
286 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
287
288 /* Verify parameter count and types. */
289 if (cParms != SHCRGL_CPARMS_READ)
290 {
291 rc = VERR_INVALID_PARAMETER;
292 }
293 else
294 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
295 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
296 )
297 {
298 rc = VERR_INVALID_PARAMETER;
299 }
300
301 /* Fetch parameters. */
302 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
303 uint32_t cbBuffer = paParms[0].u.pointer.size;
304
305 /* Execute the function. */
306 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
307
308 if (RT_SUCCESS(rc))
309 {
310 /* Update parameters.*/
311 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
312 } else if (VERR_NOT_SUPPORTED==rc)
313 {
314 svcClientVersionUnsupported(0, 0);
315 }
316
317 /* Return the required buffer size always */
318 paParms[1].u.uint32 = cbBuffer;
319
320 break;
321 }
322
323 case SHCRGL_GUEST_FN_WRITE_READ:
324 {
325 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
326
327 /* Verify parameter count and types. */
328 if (cParms != SHCRGL_CPARMS_WRITE_READ)
329 {
330 rc = VERR_INVALID_PARAMETER;
331 }
332 else
333 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
334 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
335 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
336 )
337 {
338 rc = VERR_INVALID_PARAMETER;
339 }
340 else
341 {
342 /* Fetch parameters. */
343 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
344 uint32_t cbBuffer = paParms[0].u.pointer.size;
345
346 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
347 uint32_t cbWriteback = paParms[1].u.pointer.size;
348
349 /* Execute the function. */
350 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
351 if (!RT_SUCCESS(rc))
352 {
353 Assert(VERR_NOT_SUPPORTED==rc);
354 svcClientVersionUnsupported(0, 0);
355 }
356
357 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
358
359 if (RT_SUCCESS(rc))
360 {
361 /* Update parameters.*/
362 paParms[1].u.pointer.size = cbWriteback;
363 }
364 /* Return the required buffer size always */
365 paParms[2].u.uint32 = cbWriteback;
366 }
367 break;
368 }
369
370 case SHCRGL_GUEST_FN_SET_VERSION:
371 {
372 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
373
374 /* Verify parameter count and types. */
375 if (cParms != SHCRGL_CPARMS_SET_VERSION)
376 {
377 rc = VERR_INVALID_PARAMETER;
378 }
379 else
380 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
381 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
382 )
383 {
384 rc = VERR_INVALID_PARAMETER;
385 }
386 else
387 {
388 /* Fetch parameters. */
389 uint32_t vMajor = paParms[0].u.uint32;
390 uint32_t vMinor = paParms[1].u.uint32;
391
392 /* Execute the function. */
393 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
394
395 if (!RT_SUCCESS(rc))
396 {
397 /*@todo, add warning window*/
398 svcClientVersionUnsupported(vMajor, vMinor);
399 }
400 }
401
402 break;
403 }
404
405 default:
406 {
407 rc = VERR_NOT_IMPLEMENTED;
408 }
409 }
410
411
412 LogFlow(("svcCall: rc = %Rrc\n", rc));
413
414 g_pHelpers->pfnCallComplete (callHandle, rc);
415}
416
417/*
418 * We differentiate between a function handler for the guest and one for the host.
419 */
420static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
421{
422 int rc = VINF_SUCCESS;
423
424 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
425
426#ifdef DEBUG
427 uint32_t i;
428
429 for (i = 0; i < cParms; i++)
430 {
431 /** @todo parameters other than 32 bit */
432 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
433 }
434#endif
435
436 switch (u32Function)
437 {
438 case SHCRGL_HOST_FN_SET_FRAMEBUFFER:
439 {
440 Log(("svcCall: SHCRGL_HOST_FN_SET_FRAMEBUFFER\n"));
441
442 /* Verify parameter count and types. */
443 if (cParms != SHCRGL_CPARMS_SET_FRAMEBUFFER)
444 {
445 rc = VERR_INVALID_PARAMETER;
446 }
447 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
448 {
449 rc = VERR_INVALID_PARAMETER;
450 }
451 else
452 {
453 /* Fetch parameters. */
454 IFramebuffer* pFrameBuffer = (IFramebuffer*)paParms[0].u.pointer.addr;
455 uint32_t cbData = paParms[0].u.pointer.size;
456
457 /* Verify parameters values. */
458 if (cbData != sizeof (IFramebuffer*))
459 {
460 rc = VERR_INVALID_PARAMETER;
461 }
462 else
463 {
464 /* Execute the function. */
465 g_pFrameBuffer = pFrameBuffer;
466 rc = VINF_SUCCESS;
467 }
468 }
469 break;
470 }
471 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
472 {
473 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
474
475 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
476 {
477 rc = VERR_INVALID_PARAMETER;
478 break;
479 }
480
481 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
482 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
483 )
484 {
485 rc = VERR_INVALID_PARAMETER;
486 break;
487 }
488
489 Assert(sizeof(RTRECT)==4*sizeof(GLint));
490
491 renderspuSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
492 break;
493 }
494 default:
495 rc = VERR_NOT_IMPLEMENTED;
496 break;
497 }
498
499 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
500 return rc;
501}
502
503extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
504{
505 int rc = VINF_SUCCESS;
506
507 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
508
509 if (!ptable)
510 {
511 rc = VERR_INVALID_PARAMETER;
512 }
513 else
514 {
515 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
516
517 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
518 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
519 {
520 rc = VERR_INVALID_PARAMETER;
521 }
522 else
523 {
524 g_pHelpers = ptable->pHelpers;
525
526 ptable->cbClient = sizeof (VBOXOGLCTX);
527
528 ptable->pfnUnload = svcUnload;
529 ptable->pfnConnect = svcConnect;
530 ptable->pfnDisconnect = svcDisconnect;
531 ptable->pfnCall = svcCall;
532 ptable->pfnHostCall = svcHostCall;
533 ptable->pfnSaveState = svcSaveState;
534 ptable->pfnLoadState = svcLoadState;
535 ptable->pvService = NULL;
536#ifdef CR_USE_HGCM
537 if (!crVBoxServerInit())
538 return VERR_NOT_SUPPORTED;
539#endif
540 }
541 }
542
543 return rc;
544}
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