VirtualBox

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

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

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.6 KB
Line 
1/* $Id: crservice.cpp 15532 2008-12-15 18:53:11Z 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
24#ifdef RT_OS_WINDOWS
25#include <iprt/alloc.h>
26#include <iprt/string.h>
27#include <iprt/assert.h>
28#include <iprt/stream.h>
29#include <VBox/ssm.h>
30#include <VBox/hgcmsvc.h>
31#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
32#include "cr_server.h"
33#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
34#include <VBox/log.h>
35
36#include <VBox/com/com.h>
37#include <VBox/com/string.h>
38#include <VBox/com/array.h>
39#include <VBox/com/Guid.h>
40#include <VBox/com/ErrorInfo.h>
41#include <VBox/com/EventQueue.h>
42#include <VBox/com/VirtualBox.h>
43#include <VBox/com/assert.h>
44
45#else
46#include <VBox/com/VirtualBox.h>
47#include <iprt/assert.h>
48#include <VBox/ssm.h>
49#include <VBox/hgcmsvc.h>
50#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
51
52#include "cr_server.h"
53#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
54#include <VBox/log.h>
55#endif
56
57#include "render/renderspu.h"
58
59PVBOXHGCMSVCHELPERS g_pHelpers;
60static IFramebuffer* g_pFrameBuffer;
61static uint64_t g_winId = 0;
62
63#ifndef RT_OS_WINDOWS
64#define DWORD int
65#define WINAPI
66#endif
67
68#define CR_USE_HGCM
69
70static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
71#define SHCROGL_SSM_VERSION 3
72
73typedef struct
74{
75 DWORD dwThreadID;
76
77} VBOXOGLCTX, *PVBOXOGLCTX;
78
79/*@todo remove this workaround for crstate "unshareable" data*/
80static int crIsThreadWorking=0;
81
82static DWORD WINAPI crServerProc(void* pv)
83{
84 uint64_t winId = *((uint64_t*)pv);
85 renderspuSetWindowId((uint32_t)winId);
86 CRServerMain(0, NULL);
87 crIsThreadWorking = 0;
88 return 0;
89}
90
91
92static DECLCALLBACK(int) svcUnload (void *)
93{
94 int rc = VINF_SUCCESS;
95
96 Log(("SHARED_CROPENGL svcUnload\n"));
97
98 //vboxglGlobalUnload();
99 crVBoxServerTearDown();
100
101 return rc;
102}
103
104static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
105{
106 int rc = VINF_SUCCESS;
107
108 NOREF(u32ClientID);
109 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
110 Assert(pClient);
111
112 Log(("SHARED_CROPENGL svcConnect: u32ClientID = %d\n", u32ClientID));
113
114#ifndef CR_USE_HGCM
115 if (!crIsThreadWorking)
116 {
117 HANDLE h;
118 Assert(g_pFrameBuffer);
119
120 g_pFrameBuffer->COMGETTER(WinId)(&g_winId);
121 //CHECK_ERROR_RET(g_piConsole, COMGETTER(Display)(display.asOutParam()), rc);
122
123 //vboxglConnect((PVBOXOGLCTX)pvClient);
124 crIsThreadWorking=1;
125 h = CreateThread(NULL, 0, crServerProc, (void*)&g_winId, 0, &pClient->dwThreadID);
126 if (!h) rc = VERR_MAX_THRDS_REACHED;
127 }
128 else
129 rc = VERR_MAX_THRDS_REACHED;
130#else
131 g_pFrameBuffer->COMGETTER(WinId)(&g_winId);
132 renderspuSetWindowId((uint32_t)g_winId);
133 crVBoxServerAddClient(u32ClientID);
134#endif
135
136 return rc;
137}
138
139static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
140{
141 int rc = VINF_SUCCESS;
142 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
143 Assert(pClient);
144
145 Log(("SHARED_CROPENGL svcDisconnect: u32ClientID = %d\n", u32ClientID));
146
147#ifndef CR_USE_HGCM
148 if (crIsThreadWorking && pClient->dwThreadID)
149 PostThreadMessage(pClient->dwThreadID, WM_QUIT, 0, 0);
150#else
151 crVBoxServerRemoveClient(u32ClientID);
152#endif
153 //vboxglDisconnect((PVBOXOGLCTX)pvClient);
154 return rc;
155}
156
157static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
158{
159 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
160
161 NOREF(pClient);
162
163 Log(("SHARED_CROPENGL svcSaveState: u32ClientID = %d\n", u32ClientID));
164
165 int rc;
166
167 /* Start*/
168 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
169 AssertRCReturn(rc, rc);
170
171 /* Version */
172 rc = SSMR3PutU32(pSSM, (uint32_t) SHCROGL_SSM_VERSION);
173 AssertRCReturn(rc, rc);
174
175 /* The state itself */
176 rc = crVBoxServerSaveState(pSSM);
177 AssertRCReturn(rc, rc);
178
179 /* End */
180 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
181 AssertRCReturn(rc, rc);
182
183 return VINF_SUCCESS;
184}
185
186static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
187{
188 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
189
190 NOREF(pClient);
191 NOREF(pSSM);
192
193 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
194
195 char psz[2000];
196 int rc;
197 uint32_t ui32;
198
199 /* Start of data */
200 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
201 AssertRCReturn(rc, rc);
202 if (strcmp(gszVBoxOGLSSMMagic, psz))
203 return VERR_SSM_UNEXPECTED_DATA;
204
205 /* Version */
206 rc = SSMR3GetU32(pSSM, &ui32);
207 AssertRCReturn(rc, rc);
208 if (SHCROGL_SSM_VERSION != ui32)
209 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
210
211 /* The state itself */
212 rc = crVBoxServerLoadState(pSSM);
213 AssertRCReturn(rc, rc);
214
215 /* End of data */
216 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
217 AssertRCReturn(rc, rc);
218 if (strcmp(gszVBoxOGLSSMMagic, psz))
219 return VERR_SSM_UNEXPECTED_DATA;
220
221 return VINF_SUCCESS;
222}
223
224static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
225{
226 int rc = VINF_SUCCESS;
227
228 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
229
230 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
231
232#ifdef DEBUG
233 uint32_t i;
234
235 for (i = 0; i < cParms; i++)
236 {
237 /** @todo parameters other than 32 bit */
238 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
239 }
240#endif
241
242 switch (u32Function)
243 {
244 case SHCRGL_GUEST_FN_WRITE:
245 {
246 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
247
248 /* Verify parameter count and types. */
249 if (cParms != SHCRGL_CPARMS_WRITE)
250 {
251 rc = VERR_INVALID_PARAMETER;
252 }
253 else
254 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
255 )
256 {
257 rc = VERR_INVALID_PARAMETER;
258 }
259 else
260 {
261 /* Fetch parameters. */
262 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
263 uint32_t cbBuffer = paParms[0].u.pointer.size;
264
265 /* Execute the function. */
266 crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
267 }
268 break;
269 }
270
271 case SHCRGL_GUEST_FN_READ:
272 {
273 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
274
275 /* Verify parameter count and types. */
276 if (cParms != SHCRGL_CPARMS_READ)
277 {
278 rc = VERR_INVALID_PARAMETER;
279 }
280 else
281 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
282 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
283 )
284 {
285 rc = VERR_INVALID_PARAMETER;
286 }
287
288 /* Fetch parameters. */
289 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
290 uint32_t cbBuffer = paParms[0].u.pointer.size;
291
292 /* Execute the function. */
293 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
294
295 if (RT_SUCCESS(rc))
296 {
297 /* Update parameters.*/
298 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
299 paParms[1].u.uint32 = cbBuffer;
300 }
301
302 break;
303 }
304
305 case SHCRGL_GUEST_FN_WRITE_READ:
306 {
307 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
308
309 /* Verify parameter count and types. */
310 if (cParms != SHCRGL_CPARMS_WRITE_READ)
311 {
312 rc = VERR_INVALID_PARAMETER;
313 }
314 else
315 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
316 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
317 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
318 )
319 {
320 rc = VERR_INVALID_PARAMETER;
321 }
322 else
323 {
324 /* Fetch parameters. */
325 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
326 uint32_t cbBuffer = paParms[0].u.pointer.size;
327
328 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
329 uint32_t cbWriteback = paParms[1].u.pointer.size;
330
331 /* Execute the function. */
332 crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
333 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
334
335 if (RT_SUCCESS(rc))
336 {
337 /* Update parameters.*/
338 paParms[1].u.pointer.size = cbWriteback;
339 paParms[2].u.uint32 = cbWriteback;
340 }
341 }
342 break;
343 }
344
345 default:
346 {
347 rc = VERR_NOT_IMPLEMENTED;
348 }
349 }
350
351
352 LogFlow(("svcCall: rc = %Rrc\n", rc));
353
354 g_pHelpers->pfnCallComplete (callHandle, rc);
355}
356
357/*
358 * We differentiate between a function handler for the guest and one for the host.
359 */
360static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
361{
362 int rc = VINF_SUCCESS;
363
364 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
365
366#ifdef DEBUG
367 uint32_t i;
368
369 for (i = 0; i < cParms; i++)
370 {
371 /** @todo parameters other than 32 bit */
372 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
373 }
374#endif
375
376 switch (u32Function)
377 {
378 case SHCRGL_HOST_FN_SET_FRAMEBUFFER:
379 {
380 Log(("svcCall: SHCRGL_HOST_FN_SET_FRAMEBUFFER\n"));
381
382 /* Verify parameter count and types. */
383 if (cParms != SHCRGL_CPARMS_SET_FRAMEBUFFER)
384 {
385 rc = VERR_INVALID_PARAMETER;
386 }
387 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
388 {
389 rc = VERR_INVALID_PARAMETER;
390 }
391 else
392 {
393 /* Fetch parameters. */
394 IFramebuffer* pFrameBuffer = (IFramebuffer*)paParms[0].u.pointer.addr;
395 uint32_t cbData = paParms[0].u.pointer.size;
396
397 /* Verify parameters values. */
398 if (cbData != sizeof (IFramebuffer*))
399 {
400 rc = VERR_INVALID_PARAMETER;
401 }
402 else
403 {
404 /* Execute the function. */
405 g_pFrameBuffer = pFrameBuffer;
406 rc = VINF_SUCCESS;
407 }
408 }
409 break;
410 }
411 default:
412 rc = VERR_NOT_IMPLEMENTED;
413 break;
414 }
415
416 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
417 return rc;
418}
419
420extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
421{
422 int rc = VINF_SUCCESS;
423
424 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
425
426 if (!ptable)
427 {
428 rc = VERR_INVALID_PARAMETER;
429 }
430 else
431 {
432 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
433
434 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
435 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
436 {
437 rc = VERR_INVALID_PARAMETER;
438 }
439 else
440 {
441 g_pHelpers = ptable->pHelpers;
442
443 ptable->cbClient = sizeof (VBOXOGLCTX);
444
445 ptable->pfnUnload = svcUnload;
446 ptable->pfnConnect = svcConnect;
447 ptable->pfnDisconnect = svcDisconnect;
448 ptable->pfnCall = svcCall;
449 ptable->pfnHostCall = svcHostCall;
450 ptable->pfnSaveState = svcSaveState;
451 ptable->pfnLoadState = svcLoadState;
452 ptable->pvService = NULL;
453#ifdef CR_USE_HGCM
454 if (!crVBoxServerInit())
455 return VERR_NOT_SUPPORTED;
456#endif
457 }
458 }
459
460 return rc;
461}
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