VirtualBox

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

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

crOpenGL: add seamless mode clip regions to opengl ones

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 13.4 KB
Line 
1/* $Id: crservice.cpp 18637 2009-04-02 13:49:59Z 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 ULONG64 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 }
300
301 /* Return the required buffer size always */
302 paParms[1].u.uint32 = cbBuffer;
303
304 break;
305 }
306
307 case SHCRGL_GUEST_FN_WRITE_READ:
308 {
309 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
310
311 /* Verify parameter count and types. */
312 if (cParms != SHCRGL_CPARMS_WRITE_READ)
313 {
314 rc = VERR_INVALID_PARAMETER;
315 }
316 else
317 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
318 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
319 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
320 )
321 {
322 rc = VERR_INVALID_PARAMETER;
323 }
324 else
325 {
326 /* Fetch parameters. */
327 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
328 uint32_t cbBuffer = paParms[0].u.pointer.size;
329
330 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
331 uint32_t cbWriteback = paParms[1].u.pointer.size;
332
333 /* Execute the function. */
334 crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
335 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
336
337 if (RT_SUCCESS(rc))
338 {
339 /* Update parameters.*/
340 paParms[1].u.pointer.size = cbWriteback;
341 }
342 /* Return the required buffer size always */
343 paParms[2].u.uint32 = cbWriteback;
344 }
345 break;
346 }
347
348 default:
349 {
350 rc = VERR_NOT_IMPLEMENTED;
351 }
352 }
353
354
355 LogFlow(("svcCall: rc = %Rrc\n", rc));
356
357 g_pHelpers->pfnCallComplete (callHandle, rc);
358}
359
360/*
361 * We differentiate between a function handler for the guest and one for the host.
362 */
363static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
364{
365 int rc = VINF_SUCCESS;
366
367 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
368
369#ifdef DEBUG
370 uint32_t i;
371
372 for (i = 0; i < cParms; i++)
373 {
374 /** @todo parameters other than 32 bit */
375 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
376 }
377#endif
378
379 switch (u32Function)
380 {
381 case SHCRGL_HOST_FN_SET_FRAMEBUFFER:
382 {
383 Log(("svcCall: SHCRGL_HOST_FN_SET_FRAMEBUFFER\n"));
384
385 /* Verify parameter count and types. */
386 if (cParms != SHCRGL_CPARMS_SET_FRAMEBUFFER)
387 {
388 rc = VERR_INVALID_PARAMETER;
389 }
390 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
391 {
392 rc = VERR_INVALID_PARAMETER;
393 }
394 else
395 {
396 /* Fetch parameters. */
397 IFramebuffer* pFrameBuffer = (IFramebuffer*)paParms[0].u.pointer.addr;
398 uint32_t cbData = paParms[0].u.pointer.size;
399
400 /* Verify parameters values. */
401 if (cbData != sizeof (IFramebuffer*))
402 {
403 rc = VERR_INVALID_PARAMETER;
404 }
405 else
406 {
407 /* Execute the function. */
408 g_pFrameBuffer = pFrameBuffer;
409 rc = VINF_SUCCESS;
410 }
411 }
412 break;
413 }
414 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
415 {
416 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
417
418 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
419 {
420 rc = VERR_INVALID_PARAMETER;
421 break;
422 }
423
424 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
425 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
426 )
427 {
428 rc = VERR_INVALID_PARAMETER;
429 break;
430 }
431
432 Assert(sizeof(RTRECT)==4*sizeof(GLint));
433
434 renderspuSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
435 break;
436 }
437 default:
438 rc = VERR_NOT_IMPLEMENTED;
439 break;
440 }
441
442 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
443 return rc;
444}
445
446extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
447{
448 int rc = VINF_SUCCESS;
449
450 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
451
452 if (!ptable)
453 {
454 rc = VERR_INVALID_PARAMETER;
455 }
456 else
457 {
458 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
459
460 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
461 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
462 {
463 rc = VERR_INVALID_PARAMETER;
464 }
465 else
466 {
467 g_pHelpers = ptable->pHelpers;
468
469 ptable->cbClient = sizeof (VBOXOGLCTX);
470
471 ptable->pfnUnload = svcUnload;
472 ptable->pfnConnect = svcConnect;
473 ptable->pfnDisconnect = svcDisconnect;
474 ptable->pfnCall = svcCall;
475 ptable->pfnHostCall = svcHostCall;
476 ptable->pfnSaveState = svcSaveState;
477 ptable->pfnLoadState = svcLoadState;
478 ptable->pvService = NULL;
479#ifdef CR_USE_HGCM
480 if (!crVBoxServerInit())
481 return VERR_NOT_SUPPORTED;
482#endif
483 }
484 }
485
486 return rc;
487}
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