Changeset 36843 in vbox
- Timestamp:
- Apr 26, 2011 8:33:19 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 71402
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/HostServices/VBoxCrOpenGLSvc.h
r34571 r36843 42 42 #define SHCRGL_HOST_FN_CRHGSMI_CTL (11) 43 43 #endif 44 #define SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT (20) 44 45 /* crOpenGL guest functions */ 45 46 #define SHCRGL_GUEST_FN_WRITE (2) … … 65 66 #define SHCRGL_CPARMS_WRITE_BUFFER (4) 66 67 #define SHCRGL_CPARMS_WRITE_READ_BUFFERED (3) 67 68 #define SHCRGL_CPARMS_SET_OUTPUT_REDIRECT (1) 69 70 71 /* @todo Move to H3DOR.h begin */ 72 73 /* Names of supported output redirect formats. */ 74 #define H3DOR_FMT_RGBA_TOPDOWN "H3DOR_FMT_RGBA_TOPDOWN" 75 76 /* Comma separated list of output formats supported by the output redirect target. */ 77 #define H3DOR_PROP_FORMATS 0 78 79 #pragma pack(1) 80 typedef struct { 81 /* The caller's context of the redirection. */ 82 const void *pvContext; 83 /* Inform caller that a new window will be redirected. */ 84 DECLR3CALLBACKMEMBER(void, H3DORBegin, (const void *pvContext, void **ppvInstance, 85 const char *pszFormat)); 86 /* The window dimension has been changed. */ 87 DECLR3CALLBACKMEMBER(void, H3DORGeometry, (void *pvInstance, 88 int32_t x, int32_t y, uint32_t w, uint32_t h)); 89 /* Update the window visible region. */ 90 DECLR3CALLBACKMEMBER(void, H3DORVisibleRegion, (void *pvInstance, 91 uint32_t cRects, RTRECT *paRects)); 92 /* A rendered 3D frame is ready. Format of pvData is "pszFormat" parameter of H3DORBegin. */ 93 DECLR3CALLBACKMEMBER(void, H3DORFrame, (void *pvInstance, 94 void *pvData, uint32_t cbData)); 95 /* The window is closed. */ 96 DECLR3CALLBACKMEMBER(void, H3DOREnd, (void *pvInstance)); 97 /* Obtain caller's parameters: the list of supported formats, etc. */ 98 DECLR3CALLBACKMEMBER(int, H3DORContextProperty, (const void *pvContext, uint32_t index, 99 void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut)); 100 } H3DOUTPUTREDIRECT; 101 #pragma pack() 102 103 /* @todo Move to H3DOR.h end */ 68 104 69 105 #ifdef VBOX_WITH_CRHGSMI -
trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h
r36052 r36843 35 35 36 36 typedef DECLCALLBACKPTR(void, PFNCRSERVERPRESENTFBO) (void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h); 37 38 /* Callbacks for output of the rendered frames. 39 * 40 * This allows to pass rendered frames to an external component rather than draw them on screen. 41 * 42 * An external component registers the redirection callbacks using crVBoxServerOutputRedirectSet. 43 * 44 * The list of formats supported by the caller is obtained using CRORContextProperty. 45 * The actual format choosed by the service is passed as a CRORBegin parameter. 46 */ 47 typedef struct { 48 const void *pvContext; /* Supplied by crVBoxServerOutputRedirectSet. */ 49 DECLR3CALLBACKMEMBER(void, CRORBegin, (const void *pvContext, void **ppvInstance, 50 const char *pszFormat)); 51 DECLR3CALLBACKMEMBER(void, CRORGeometry, (void *pvInstance, 52 int32_t x, int32_t y, uint32_t w, uint32_t h)); 53 DECLR3CALLBACKMEMBER(void, CRORVisibleRegion, (void *pvInstance, 54 uint32_t cRects, RTRECT *paRects)); 55 DECLR3CALLBACKMEMBER(void, CRORFrame, (void *pvInstance, 56 void *pvData, uint32_t cbData)); 57 DECLR3CALLBACKMEMBER(void, CROREnd, (void *pvInstance)); 58 DECLR3CALLBACKMEMBER(int, CRORContextProperty, (const void *pvContext, uint32_t index, 59 void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut)); 60 } CROutputRedirect; 37 61 38 62 typedef struct { … … 71 95 GLuint fboWidth, fboHeight; 72 96 GLuint idPBO; 97 98 void *pvOutputRedirectInstance; 73 99 } CRMuralInfo; 74 100 … … 233 259 *using callback above to update vbox framebuffers*/ 234 260 GLboolean bUsePBOForReadback; /*Use PBO's for data readback*/ 261 262 GLboolean bUseOutputRedirect; /* Whether the output redirect was set. */ 263 CROutputRedirect outputRedirect; 235 264 } CRServer; 236 265 … … 265 294 extern DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value); 266 295 296 extern DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect *pCallbacks); 297 267 298 #ifdef __cplusplus 268 299 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
r36290 r36843 164 164 } 165 165 166 // @todo use critsect only to fetch the list and update the g_SvcPresentFBO's pQueueHead and pQueueTail. 166 167 rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock); 167 168 AssertRCReturn(rc, rc); … … 1242 1243 g_pConsole = pConsole; 1243 1244 1244 /*rc = crVBoxServerSetOffscreenRendering(GL_TRUE);*/1245 1245 rc = VINF_SUCCESS; 1246 1246 } … … 1349 1349 1350 1350 rc = VINF_SUCCESS; 1351 } 1352 break; 1353 } 1354 case SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT: 1355 { 1356 /* 1357 * OutputRedirect. 1358 * Note: the service calls OutputRedirect callbacks directly 1359 * and they must not block. If asynchronous processing is needed, 1360 * the callback provider must organize this. 1361 */ 1362 Log(("svcCall: SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT\n")); 1363 1364 /* Verify parameter count and types. */ 1365 if (cParms != SHCRGL_CPARMS_SET_OUTPUT_REDIRECT) 1366 { 1367 rc = VERR_INVALID_PARAMETER; 1368 } 1369 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR) 1370 { 1371 rc = VERR_INVALID_PARAMETER; 1372 } 1373 else 1374 { 1375 /* Fetch parameters. */ 1376 H3DOUTPUTREDIRECT *pOutputRedirect = (H3DOUTPUTREDIRECT *)paParms[0].u.pointer.addr; 1377 uint32_t cbData = paParms[0].u.pointer.size; 1378 1379 /* Verify parameters values. */ 1380 if (cbData != sizeof (H3DOUTPUTREDIRECT)) 1381 { 1382 rc = VERR_INVALID_PARAMETER; 1383 } 1384 else /* Execute the function. */ 1385 { 1386 rc = crVBoxServerSetOffscreenRendering(GL_TRUE); 1387 1388 if (RT_SUCCESS(rc)) 1389 { 1390 CROutputRedirect or; 1391 or.pvContext = pOutputRedirect->pvContext; 1392 or.CRORBegin = pOutputRedirect->H3DORBegin; 1393 or.CRORGeometry = pOutputRedirect->H3DORGeometry; 1394 or.CRORVisibleRegion = pOutputRedirect->H3DORVisibleRegion; 1395 or.CRORFrame = pOutputRedirect->H3DORFrame; 1396 or.CROREnd = pOutputRedirect->H3DOREnd; 1397 or.CRORContextProperty = pOutputRedirect->H3DORContextProperty; 1398 rc = crVBoxServerOutputRedirectSet(&or); 1399 } 1400 } 1351 1401 } 1352 1402 break; -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
r31808 r36843 89 89 GLuint crServerTranslateProgramID(GLuint id); 90 90 91 void crServerSetupOutputRedirect(CRMuralInfo *mural); 91 92 void crServerCheckMuralGeometry(CRMuralInfo *mural); 92 93 GLboolean crServerSupportRedirMuralFBO(void); -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
r36052 r36843 58 58 cr_server.bForceOffscreenRendering = GL_FALSE; 59 59 cr_server.bUsePBOForReadback = GL_FALSE; 60 cr_server.bUseOutputRedirect = GL_FALSE; 60 61 } 61 62 -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
r36052 r36843 1260 1260 return VINF_SUCCESS; 1261 1261 } 1262 1263 DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect *pCallbacks) 1264 { 1265 /* No need for a synchronization as this is single threaded. */ 1266 if (pCallbacks) 1267 { 1268 cr_server.outputRedirect = *pCallbacks; 1269 cr_server.bUseOutputRedirect = true; 1270 } 1271 else 1272 { 1273 cr_server.bUseOutputRedirect = false; 1274 } 1275 1276 // @todo dynamically intercept already existing output: 1277 // crHashtableWalk(cr_server.muralTable, crVBoxServerOutputRedirectCB, NULL); 1278 1279 return VINF_SUCCESS; 1280 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
r36052 r36843 46 46 } 47 47 48 /* Called when a new CRMuralInfo is created 49 * or when OutputRedirect status is changed. 50 */ 51 void crServerSetupOutputRedirect(CRMuralInfo *mural) 52 { 53 /* Unset the previous redirect. */ 54 if (mural->pvOutputRedirectInstance) 55 { 56 cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance); 57 mural->pvOutputRedirectInstance = NULL; 58 } 59 60 /* Setup a new redirect. */ 61 if (cr_server.bUseOutputRedirect) 62 { 63 /* Query supported formats. */ 64 uint32_t cbFormats = 4096; 65 char *pachFormats = (char *)crAlloc(cbFormats); 66 67 if (pachFormats) 68 { 69 int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext, 70 0 /* H3DOR_PROP_FORMATS */, // @todo from a header 71 pachFormats, cbFormats, &cbFormats); 72 if (RT_SUCCESS(rc)) 73 { 74 if (strstr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN")) 75 { 76 cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext, 77 &mural->pvOutputRedirectInstance, 78 "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header 79 } 80 } 81 82 crFree(pachFormats); 83 } 84 85 /* If this is not NULL then there was a supported format. */ 86 if (mural->pvOutputRedirectInstance) 87 { 88 cr_server.outputRedirect.CRORGeometry(mural->pvOutputRedirectInstance, 89 mural->hX, mural->hY, 90 mural->width, mural->height); 91 // @todo the code assumes that RTRECT == four of GLInts 92 cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance, 93 mural->cVisibleRects, (RTRECT *)mural->pVisibleRects); 94 } 95 } 96 } 97 48 98 void crServerCheckMuralGeometry(CRMuralInfo *mural) 49 99 { … … 136 186 cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX, mural->hY); 137 187 } 188 } 189 190 if (mural->pvOutputRedirectInstance) 191 { 192 cr_server.outputRedirect.CRORGeometry(mural->pvOutputRedirectInstance, 193 mural->hX, mural->hY, 194 mural->width, mural->height); 138 195 } 139 196 } … … 455 512 } 456 513 514 if (mural->pvOutputRedirectInstance) 515 { 516 /* @todo find out why presentfbo is not called but crorframe is called. */ 517 cr_server.outputRedirect.CRORFrame(mural->pvOutputRedirectInstance, 518 pixels, 519 4 * mural->fboWidth * mural->fboHeight); 520 } 521 457 522 if (bUsePBO) 458 523 { -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
r35998 r36843 88 88 mural->bReceivedRects = GL_FALSE; 89 89 90 mural->pvOutputRedirectInstance = NULL; 91 90 92 /* generate ID for this new window/mural (special-case for file conns) */ 91 93 if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE) … … 99 101 pCreateInfo->visualBits = visBits; 100 102 crHashtableAdd(cr_server.pWindowCreateInfoTable, windowID, pCreateInfo); 103 104 crServerSetupOutputRedirect(mural); 101 105 } 102 106 … … 148 152 } 149 153 154 if (mural->pvOutputRedirectInstance) 155 { 156 cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance); 157 mural->pvOutputRedirectInstance = NULL; 158 } 159 150 160 if (cr_server.currentWindow == window) 151 161 { … … 295 305 296 306 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects); 307 308 if (mural->pvOutputRedirectInstance) 309 { 310 /* @todo the code assumes that RTRECT == four GLInts. */ 311 cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance, 312 cRects, (RTRECT *)pRects); 313 } 297 314 } 298 315 -
trunk/src/VBox/Main/include/ConsoleVRDPServer.h
r35722 r36843 24 24 #include <VBox/VBoxAuth.h> 25 25 26 #include <VBox/RemoteDesktop/VRDEImage.h> 27 26 28 #include <VBox/HostServices/VBoxClipboardExt.h> 27 29 … … 151 153 static PFNVRDECREATESERVER mpfnVRDECreateServer; 152 154 153 static VRDEENTRYPOINTS_ 3mEntryPoints;154 static VRDEENTRYPOINTS_ 3*mpEntryPoints;155 static VRDECALLBACKS_ 3mCallbacks;155 static VRDEENTRYPOINTS_4 mEntryPoints; 156 static VRDEENTRYPOINTS_4 *mpEntryPoints; 157 static VRDECALLBACKS_4 mCallbacks; 156 158 157 159 static DECLCALLBACK(int) VRDPCallbackQueryProperty (void *pvCallback, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut); … … 224 226 225 227 uint32_t volatile mu32AudioInputClientId; 228 229 static DECLCALLBACK(void) H3DORBegin(const void *pvContext, void **ppvInstance, 230 const char *pszFormat); 231 static DECLCALLBACK(void) H3DORGeometry(void *pvInstance, 232 int32_t x, int32_t y, uint32_t w, uint32_t h); 233 static DECLCALLBACK(void) H3DORVisibleRegion(void *pvInstance, 234 uint32_t cRects, RTRECT *paRects); 235 static DECLCALLBACK(void) H3DORFrame(void *pvInstance, 236 void *pvData, uint32_t cbData); 237 static DECLCALLBACK(void) H3DOREnd(void *pvInstance); 238 static DECLCALLBACK(int) H3DORContextProperty(const void *pvContext, uint32_t index, 239 void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut); 240 241 void remote3DRedirect(void); 242 243 /* 244 * VRDE server optional interfaces. 245 */ 246 247 /* Image update interface. */ 248 bool m_fInterfaceImage; 249 VRDEIMAGECALLBACKS m_interfaceCallbacksImage; 250 VRDEIMAGEINTERFACE m_interfaceImage; 251 static DECLCALLBACK(int) VRDEImageCbNotify (void *pvContext, 252 void *pvUser, 253 HVRDEIMAGE hVideo, 254 uint32_t u32Id, 255 void *pvData, 256 uint32_t cbData); 226 257 }; 227 258 -
trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
r36063 r36843 25 25 # include "ExtPackManagerImpl.h" 26 26 #endif 27 #include "VMMDev.h" 27 28 28 29 #include "Global.h" … … 40 41 #include <VBox/RemoteDesktop/VRDEOrders.h> 41 42 #include <VBox/com/listeners.h> 43 #include <VBox/HostServices/VBoxCrOpenGLSvc.h> 42 44 43 45 class VRDPConsoleListener … … 520 522 PFNVRDECREATESERVER ConsoleVRDPServer::mpfnVRDECreateServer = NULL; 521 523 522 VRDEENTRYPOINTS_ 3ConsoleVRDPServer::mEntryPoints; /* A copy of the server entry points. */523 VRDEENTRYPOINTS_ 3*ConsoleVRDPServer::mpEntryPoints = NULL;524 525 VRDECALLBACKS_ 3ConsoleVRDPServer::mCallbacks =526 { 527 { VRDE_INTERFACE_VERSION_ 3, sizeof(VRDECALLBACKS_3) },524 VRDEENTRYPOINTS_4 ConsoleVRDPServer::mEntryPoints; /* A copy of the server entry points. */ 525 VRDEENTRYPOINTS_4 *ConsoleVRDPServer::mpEntryPoints = NULL; 526 527 VRDECALLBACKS_4 ConsoleVRDPServer::mCallbacks = 528 { 529 { VRDE_INTERFACE_VERSION_4, sizeof(VRDECALLBACKS_4) }, 528 530 ConsoleVRDPServer::VRDPCallbackQueryProperty, 529 531 ConsoleVRDPServer::VRDPCallbackClientLogon, … … 1315 1317 1316 1318 mu32AudioInputClientId = 0; 1319 1320 /* 1321 * Optional interfaces. 1322 */ 1323 m_fInterfaceImage = false; 1324 memset(&m_interfaceImage, 0, sizeof (m_interfaceImage)); 1325 memset(&m_interfaceCallbacksImage, 0, sizeof (m_interfaceCallbacksImage)); 1317 1326 } 1318 1327 … … 1395 1404 if (RT_SUCCESS(vrc)) 1396 1405 { 1397 VRDEENTRYPOINTS_ 3 *pEntryPoints3;1398 vrc = mpfnVRDECreateServer(&mCallbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints 3, &mhServer);1406 VRDEENTRYPOINTS_4 *pEntryPoints4; 1407 vrc = mpfnVRDECreateServer(&mCallbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints4, &mhServer); 1399 1408 1400 1409 if (RT_SUCCESS(vrc)) 1401 1410 { 1402 mServerInterfaceVersion = 3;1403 mEntryPoints = *pEntryPoints 3;1411 mServerInterfaceVersion = 4; 1412 mEntryPoints = *pEntryPoints4; 1404 1413 mpEntryPoints = &mEntryPoints; 1405 1414 } 1406 1415 else if (vrc == VERR_VERSION_MISMATCH) 1407 1416 { 1408 /* An older version of VRDE is installed, try version 1. */1409 VRDEENTRYPOINTS_ 1 *pEntryPoints1;1410 1411 static VRDECALLBACKS_ 1 sCallbacks=1412 { 1413 { VRDE_INTERFACE_VERSION_ 1, sizeof(VRDECALLBACKS_1) },1417 /* An older version of VRDE is installed, try version 3. */ 1418 VRDEENTRYPOINTS_3 *pEntryPoints3; 1419 1420 static VRDECALLBACKS_3 sCallbacks3 = 1421 { 1422 { VRDE_INTERFACE_VERSION_3, sizeof(VRDECALLBACKS_3) }, 1414 1423 ConsoleVRDPServer::VRDPCallbackQueryProperty, 1415 1424 ConsoleVRDPServer::VRDPCallbackClientLogon, … … 1423 1432 ConsoleVRDPServer::VRDPCallbackFramebufferUnlock, 1424 1433 ConsoleVRDPServer::VRDPCallbackInput, 1425 ConsoleVRDPServer::VRDPCallbackVideoModeHint 1434 ConsoleVRDPServer::VRDPCallbackVideoModeHint, 1435 ConsoleVRDPServer::VRDECallbackAudioIn 1426 1436 }; 1427 1437 1428 vrc = mpfnVRDECreateServer(&sCallbacks .header, this, (VRDEINTERFACEHDR **)&pEntryPoints1, &mhServer);1438 vrc = mpfnVRDECreateServer(&sCallbacks3.header, this, (VRDEINTERFACEHDR **)&pEntryPoints3, &mhServer); 1429 1439 if (RT_SUCCESS(vrc)) 1430 1440 { 1431 LogRel(("VRDE: loaded an older version of the server.\n"));1432 1433 1441 mServerInterfaceVersion = 3; 1434 mEntryPoints.header = pEntryPoints1->header; 1435 mEntryPoints.VRDEDestroy = pEntryPoints1->VRDEDestroy; 1436 mEntryPoints.VRDEEnableConnections = pEntryPoints1->VRDEEnableConnections; 1437 mEntryPoints.VRDEDisconnect = pEntryPoints1->VRDEDisconnect; 1438 mEntryPoints.VRDEResize = pEntryPoints1->VRDEResize; 1439 mEntryPoints.VRDEUpdate = pEntryPoints1->VRDEUpdate; 1440 mEntryPoints.VRDEColorPointer = pEntryPoints1->VRDEColorPointer; 1441 mEntryPoints.VRDEHidePointer = pEntryPoints1->VRDEHidePointer; 1442 mEntryPoints.VRDEAudioSamples = pEntryPoints1->VRDEAudioSamples; 1443 mEntryPoints.VRDEAudioVolume = pEntryPoints1->VRDEAudioVolume; 1444 mEntryPoints.VRDEUSBRequest = pEntryPoints1->VRDEUSBRequest; 1445 mEntryPoints.VRDEClipboard = pEntryPoints1->VRDEClipboard; 1446 mEntryPoints.VRDEQueryInfo = pEntryPoints1->VRDEQueryInfo; 1447 mEntryPoints.VRDERedirect = NULL; 1448 mEntryPoints.VRDEAudioInOpen = NULL; 1449 mEntryPoints.VRDEAudioInClose = NULL; 1442 mEntryPoints.header = pEntryPoints3->header; 1443 mEntryPoints.VRDEDestroy = pEntryPoints3->VRDEDestroy; 1444 mEntryPoints.VRDEEnableConnections = pEntryPoints3->VRDEEnableConnections; 1445 mEntryPoints.VRDEDisconnect = pEntryPoints3->VRDEDisconnect; 1446 mEntryPoints.VRDEResize = pEntryPoints3->VRDEResize; 1447 mEntryPoints.VRDEUpdate = pEntryPoints3->VRDEUpdate; 1448 mEntryPoints.VRDEColorPointer = pEntryPoints3->VRDEColorPointer; 1449 mEntryPoints.VRDEHidePointer = pEntryPoints3->VRDEHidePointer; 1450 mEntryPoints.VRDEAudioSamples = pEntryPoints3->VRDEAudioSamples; 1451 mEntryPoints.VRDEAudioVolume = pEntryPoints3->VRDEAudioVolume; 1452 mEntryPoints.VRDEUSBRequest = pEntryPoints3->VRDEUSBRequest; 1453 mEntryPoints.VRDEClipboard = pEntryPoints3->VRDEClipboard; 1454 mEntryPoints.VRDEQueryInfo = pEntryPoints3->VRDEQueryInfo; 1455 mEntryPoints.VRDERedirect = pEntryPoints3->VRDERedirect; 1456 mEntryPoints.VRDEAudioInOpen = pEntryPoints3->VRDEAudioInOpen; 1457 mEntryPoints.VRDEAudioInClose = pEntryPoints3->VRDEAudioInClose; 1458 mEntryPoints.VRDEGetInterface = NULL; 1450 1459 mpEntryPoints = &mEntryPoints; 1451 1460 } 1461 else if (vrc == VERR_VERSION_MISMATCH) 1462 { 1463 /* An older version of VRDE is installed, try version 1. */ 1464 VRDEENTRYPOINTS_1 *pEntryPoints1; 1465 1466 static VRDECALLBACKS_1 sCallbacks1 = 1467 { 1468 { VRDE_INTERFACE_VERSION_1, sizeof(VRDECALLBACKS_1) }, 1469 ConsoleVRDPServer::VRDPCallbackQueryProperty, 1470 ConsoleVRDPServer::VRDPCallbackClientLogon, 1471 ConsoleVRDPServer::VRDPCallbackClientConnect, 1472 ConsoleVRDPServer::VRDPCallbackClientDisconnect, 1473 ConsoleVRDPServer::VRDPCallbackIntercept, 1474 ConsoleVRDPServer::VRDPCallbackUSB, 1475 ConsoleVRDPServer::VRDPCallbackClipboard, 1476 ConsoleVRDPServer::VRDPCallbackFramebufferQuery, 1477 ConsoleVRDPServer::VRDPCallbackFramebufferLock, 1478 ConsoleVRDPServer::VRDPCallbackFramebufferUnlock, 1479 ConsoleVRDPServer::VRDPCallbackInput, 1480 ConsoleVRDPServer::VRDPCallbackVideoModeHint 1481 }; 1482 1483 vrc = mpfnVRDECreateServer(&sCallbacks1.header, this, (VRDEINTERFACEHDR **)&pEntryPoints1, &mhServer); 1484 if (RT_SUCCESS(vrc)) 1485 { 1486 mServerInterfaceVersion = 1; 1487 mEntryPoints.header = pEntryPoints1->header; 1488 mEntryPoints.VRDEDestroy = pEntryPoints1->VRDEDestroy; 1489 mEntryPoints.VRDEEnableConnections = pEntryPoints1->VRDEEnableConnections; 1490 mEntryPoints.VRDEDisconnect = pEntryPoints1->VRDEDisconnect; 1491 mEntryPoints.VRDEResize = pEntryPoints1->VRDEResize; 1492 mEntryPoints.VRDEUpdate = pEntryPoints1->VRDEUpdate; 1493 mEntryPoints.VRDEColorPointer = pEntryPoints1->VRDEColorPointer; 1494 mEntryPoints.VRDEHidePointer = pEntryPoints1->VRDEHidePointer; 1495 mEntryPoints.VRDEAudioSamples = pEntryPoints1->VRDEAudioSamples; 1496 mEntryPoints.VRDEAudioVolume = pEntryPoints1->VRDEAudioVolume; 1497 mEntryPoints.VRDEUSBRequest = pEntryPoints1->VRDEUSBRequest; 1498 mEntryPoints.VRDEClipboard = pEntryPoints1->VRDEClipboard; 1499 mEntryPoints.VRDEQueryInfo = pEntryPoints1->VRDEQueryInfo; 1500 mEntryPoints.VRDERedirect = NULL; 1501 mEntryPoints.VRDEAudioInOpen = NULL; 1502 mEntryPoints.VRDEAudioInClose = NULL; 1503 mEntryPoints.VRDEGetInterface = NULL; 1504 mpEntryPoints = &mEntryPoints; 1505 } 1506 } 1452 1507 } 1453 1508 1454 1509 if (RT_SUCCESS(vrc)) 1455 1510 { 1511 LogRel(("VRDE: loaded version %d of the server.\n", mServerInterfaceVersion)); 1512 1513 if (mServerInterfaceVersion >= 4) 1514 { 1515 /* The server supports optional interfaces. */ 1516 Assert(mpEntryPoints->VRDEGetInterface != NULL); 1517 1518 /* Image interface. */ 1519 m_interfaceImage.header.u64Version = 1; 1520 m_interfaceImage.header.u64Size = sizeof(m_interfaceImage); 1521 1522 m_interfaceCallbacksImage.header.u64Version = 1; 1523 m_interfaceCallbacksImage.header.u64Size = sizeof(m_interfaceCallbacksImage); 1524 m_interfaceCallbacksImage.VRDEImageCbNotify = VRDEImageCbNotify; 1525 1526 vrc = mpEntryPoints->VRDEGetInterface(mhServer, 1527 VRDE_IMAGE_INTERFACE_NAME, 1528 &m_interfaceImage.header, 1529 &m_interfaceCallbacksImage.header, 1530 this); 1531 if (RT_SUCCESS(vrc)) 1532 { 1533 m_fInterfaceImage = true; 1534 } 1535 1536 /* Since these interfaces are optional, it is always a success here. */ 1537 vrc = VINF_SUCCESS; 1538 } 1456 1539 #ifdef VBOX_WITH_USB 1457 1540 remoteUSBThreadStart(); … … 1471 1554 } 1472 1555 1556 typedef struct H3DORInstance 1557 { 1558 ConsoleVRDPServer *pThis; 1559 HVRDEIMAGE hImageBitmap; 1560 int32_t x; 1561 int32_t y; 1562 uint32_t w; 1563 uint32_t h; 1564 bool fCreated; 1565 } H3DORInstance; 1566 1567 /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORBegin(const void *pvContext, void **ppvInstance, 1568 const char *pszFormat) 1569 { 1570 LogFlowFunc(("ctx %p\n", pvContext)); 1571 1572 H3DORInstance *p = (H3DORInstance *)RTMemAlloc(sizeof (H3DORInstance)); 1573 1574 if (p) 1575 { 1576 p->pThis = (ConsoleVRDPServer *)pvContext; 1577 p->hImageBitmap = NULL; 1578 p->x = 0; 1579 p->y = 0; 1580 p->w = 0; 1581 p->h = 0; 1582 p->fCreated = false; 1583 1584 /* Host 3D service passes the actual format of data in this redirect instance. 1585 * That is what will be in the H3DORFrame's parameters pvData and cbData. 1586 */ 1587 if (RTStrICmp(pszFormat, H3DOR_FMT_RGBA_TOPDOWN) == 0) 1588 { 1589 /* Accept it. */ 1590 } 1591 else 1592 { 1593 RTMemFree(p); 1594 p = NULL; 1595 } 1596 } 1597 1598 /* Caller check this for NULL. */ 1599 *ppvInstance = p; 1600 } 1601 1602 /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORGeometry(void *pvInstance, 1603 int32_t x, int32_t y, uint32_t w, uint32_t h) 1604 { 1605 LogFlowFunc(("ins %p %d,%d %dx%d\n", pvInstance, x, y, w, h)); 1606 1607 H3DORInstance *p = (H3DORInstance *)pvInstance; 1608 Assert(p); 1609 Assert(p->pThis); 1610 1611 /* @todo find out what to do if size changes to 0x0 from non zero */ 1612 if (w == 0 || h == 0) 1613 { 1614 /* Do nothing. */ 1615 return; 1616 } 1617 1618 RTRECT rect; 1619 rect.xLeft = x; 1620 rect.yTop = y; 1621 rect.xRight = x + w; 1622 rect.yBottom = y + h; 1623 1624 if (p->hImageBitmap) 1625 { 1626 /* An image handle has been already created, 1627 * check if it has the same size as the reported geometry. 1628 */ 1629 if ( p->x == x 1630 && p->y == y 1631 && p->w == w 1632 && p->h == h) 1633 { 1634 LogFlowFunc(("geometry not changed\n")); 1635 /* Do nothing. Continue using the existing handle. */ 1636 } 1637 else 1638 { 1639 int rc = p->pThis->m_interfaceImage.VRDEImageGeometrySet(p->hImageBitmap, &rect); 1640 if (RT_SUCCESS(rc)) 1641 { 1642 p->x = x; 1643 p->y = y; 1644 p->w = w; 1645 p->h = h; 1646 } 1647 else 1648 { 1649 /* The handle must be recreated. Delete existing handle here. */ 1650 p->pThis->m_interfaceImage.VRDEImageHandleClose(p->hImageBitmap); 1651 p->hImageBitmap = NULL; 1652 } 1653 } 1654 } 1655 1656 if (!p->hImageBitmap) 1657 { 1658 /* Create a new bitmap handle. */ 1659 uint32_t u32ScreenId = 0; /* @todo clip to corresponding screens. 1660 * Clipping can be done here or in VRDP server. 1661 * If VRDP does clipping, then uScreenId parameter 1662 * is not necessary and coords must be global. 1663 * (have to check which coords are used in opengl service). 1664 * Since all VRDE API uses a ScreenId, 1665 * the clipping must be done here in ConsoleVRDPServer 1666 */ 1667 uint32_t fu32CompletionFlags = 0; 1668 int rc = p->pThis->m_interfaceImage.VRDEImageHandleCreate(p->pThis->mhServer, 1669 &p->hImageBitmap, 1670 p, 1671 u32ScreenId, 1672 VRDE_IMAGE_F_CREATE_CONTENT_3D 1673 | VRDE_IMAGE_F_CREATE_WINDOW, 1674 &rect, 1675 VRDE_IMAGE_FMT_ID_BITMAP_BGRA8, 1676 NULL, 1677 0, 1678 &fu32CompletionFlags); 1679 if (RT_SUCCESS(rc)) 1680 { 1681 p->x = x; 1682 p->y = y; 1683 p->w = w; 1684 p->h = h; 1685 1686 if ((fu32CompletionFlags & VRDE_IMAGE_F_COMPLETE_ASYNC) == 0) 1687 { 1688 p->fCreated = true; 1689 } 1690 } 1691 else 1692 { 1693 p->hImageBitmap = NULL; 1694 p->w = 0; 1695 p->h = 0; 1696 } 1697 } 1698 } 1699 1700 /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORVisibleRegion(void *pvInstance, 1701 uint32_t cRects, RTRECT *paRects) 1702 { 1703 LogFlowFunc(("ins %p %d\n", pvInstance, cRects)); 1704 1705 H3DORInstance *p = (H3DORInstance *)pvInstance; 1706 Assert(p); 1707 Assert(p->pThis); 1708 1709 if (cRects == 0) 1710 { 1711 /* Complete image is visible. */ 1712 RTRECT rect; 1713 rect.xLeft = p->x; 1714 rect.yTop = p->y; 1715 rect.xRight = p->x + p->w; 1716 rect.yBottom = p->y + p->h; 1717 p->pThis->m_interfaceImage.VRDEImageRegionSet (p->hImageBitmap, 1718 1, 1719 &rect); 1720 } 1721 else 1722 { 1723 p->pThis->m_interfaceImage.VRDEImageRegionSet (p->hImageBitmap, 1724 cRects, 1725 paRects); 1726 } 1727 } 1728 1729 /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORFrame(void *pvInstance, 1730 void *pvData, uint32_t cbData) 1731 { 1732 LogFlowFunc(("ins %p %p %d\n", pvInstance, pvData, cbData)); 1733 1734 H3DORInstance *p = (H3DORInstance *)pvInstance; 1735 Assert(p); 1736 Assert(p->pThis); 1737 1738 /* Currently only a topdown BGR0 bitmap format is supported. */ 1739 VRDEIMAGEBITMAP image; 1740 1741 image.cWidth = p->w; 1742 image.cHeight = p->h; 1743 image.pvData = pvData; 1744 image.cbData = cbData; 1745 image.pvScanLine0 = (uint8_t *)pvData + (p->h - 1) * p->w * 4; 1746 image.iScanDelta = -4 * p->w; 1747 1748 p->pThis->m_interfaceImage.VRDEImageUpdate (p->hImageBitmap, 1749 p->x, 1750 p->y, 1751 p->w, 1752 p->h, 1753 &image, 1754 sizeof(VRDEIMAGEBITMAP)); 1755 } 1756 1757 /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DOREnd(void *pvInstance) 1758 { 1759 LogFlowFunc(("ins %p\n", pvInstance)); 1760 1761 H3DORInstance *p = (H3DORInstance *)pvInstance; 1762 Assert(p); 1763 Assert(p->pThis); 1764 1765 p->pThis->m_interfaceImage.VRDEImageHandleClose(p->hImageBitmap); 1766 1767 RTMemFree(p); 1768 } 1769 1770 /* static */ DECLCALLBACK(int) ConsoleVRDPServer::H3DORContextProperty(const void *pvContext, uint32_t index, 1771 void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) 1772 { 1773 int rc = VINF_SUCCESS; 1774 1775 if (index == H3DOR_PROP_FORMATS) 1776 { 1777 /* Return a comma separated list of supported formats. */ 1778 static char *pszSupportedFormats = H3DOR_FMT_RGBA_TOPDOWN; 1779 uint32_t cbOut = (uint32_t)strlen(pszSupportedFormats) + 1; 1780 if (cbOut <= cbBuffer) 1781 { 1782 memcpy(pvBuffer, pszSupportedFormats, cbOut); 1783 } 1784 else 1785 { 1786 rc = VERR_BUFFER_OVERFLOW; 1787 } 1788 *pcbOut = cbOut; 1789 } 1790 else 1791 { 1792 rc = VERR_NOT_SUPPORTED; 1793 } 1794 1795 return rc; 1796 } 1797 1798 void ConsoleVRDPServer::remote3DRedirect(void) 1799 { 1800 if (!m_fInterfaceImage) 1801 { 1802 /* No redirect without corresponding interface. */ 1803 return; 1804 } 1805 1806 /* Check if 3D redirection has been enabled. */ 1807 com::Bstr bstr; 1808 HRESULT hrc = mConsole->getVRDEServer()->GetVRDEProperty(Bstr("H3DRedirect/Enabled").raw(), bstr.asOutParam()); 1809 1810 if (hrc != S_OK) 1811 { 1812 bstr = ""; 1813 } 1814 1815 com::Utf8Str value = bstr; 1816 1817 bool fEnabled = RTStrICmp(value.c_str(), "true") == 0 1818 || RTStrICmp(value.c_str(), "1") == 0; 1819 1820 if (!fEnabled) 1821 { 1822 return; 1823 } 1824 1825 /* Tell the host 3D service to redirect output using the ConsoleVRDPServer callbacks. */ 1826 H3DOUTPUTREDIRECT outputRedirect = 1827 { 1828 this, 1829 H3DORBegin, 1830 H3DORGeometry, 1831 H3DORVisibleRegion, 1832 H3DORFrame, 1833 H3DOREnd, 1834 H3DORContextProperty 1835 }; 1836 1837 VBOXHGCMSVCPARM parm; 1838 1839 parm.type = VBOX_HGCM_SVC_PARM_PTR; 1840 parm.u.pointer.addr = &outputRedirect; 1841 parm.u.pointer.size = sizeof(outputRedirect); 1842 1843 VMMDev *pVMMDev = mConsole->getVMMDev(); 1844 1845 if (!pVMMDev) 1846 { 1847 AssertMsgFailed(("remote3DRedirect no vmmdev\n")); 1848 return; 1849 } 1850 1851 int rc = pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", 1852 SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT, 1853 SHCRGL_CPARMS_SET_OUTPUT_REDIRECT, 1854 &parm); 1855 1856 if (!RT_SUCCESS(rc)) 1857 { 1858 AssertMsgFailed(("SHCRGL_HOST_FN_SET_CONSOLE failed with %Rrc\n", rc)); 1859 return; 1860 } 1861 1862 LogRel(("VRDE: Enabled 3D redirect.\n")); 1863 1864 return; 1865 } 1866 1867 /* static */ DECLCALLBACK(int) ConsoleVRDPServer::VRDEImageCbNotify (void *pvContext, 1868 void *pvUser, 1869 HVRDEIMAGE hVideo, 1870 uint32_t u32Id, 1871 void *pvData, 1872 uint32_t cbData) 1873 { 1874 LogFlowFunc(("pvContext %p, pvUser %p, hVideo %p, u32Id %u, pvData %p, cbData %d\n", 1875 pvContext, pvUser, hVideo, u32Id, pvData, cbData)); 1876 1877 ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvContext); 1878 H3DORInstance *p = (H3DORInstance *)pvUser; 1879 Assert(p); 1880 Assert(p->pThis); 1881 Assert(p->pThis == pServer); 1882 1883 // @todo Process u32Id 1884 1885 p->fCreated = true; 1886 1887 return VINF_SUCCESS; 1888 } 1889 1473 1890 void ConsoleVRDPServer::EnableConnections(void) 1474 1891 { … … 1476 1893 { 1477 1894 mpEntryPoints->VRDEEnableConnections(mhServer, true); 1895 1896 /* Redirect 3D output if it is enabled. */ 1897 remote3DRedirect(); 1478 1898 } 1479 1899 }
Note:
See TracChangeset
for help on using the changeset viewer.