Changeset 3153 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jun 19, 2007 9:40:23 AM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 22071
- Location:
- trunk/src/VBox/Main
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleVRDPServer.cpp
r2981 r3153 41 41 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSetCallback) (HVRDPSERVER hServer, VRDPSERVERCALLBACK *pcallback, void *pvUser); 42 42 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPShutdownServer) (HVRDPSERVER hServer); 43 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendUpdateBitmap)(HVRDPSERVER hServer, unsigned x, unsigned y, unsigned w, unsigned h);43 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendUpdateBitmap)(HVRDPSERVER hServer, unsigned uScreenId, unsigned x, unsigned y, unsigned w, unsigned h); 44 44 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendResize) (HVRDPSERVER hServer); 45 45 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendAudioSamples)(HVRDPSERVER hserver, void *pvSamples, uint32_t cSamples, VRDPAUDIOFORMAT format); … … 50 50 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendUSBRequest) (HVRDPSERVER hserver, void *pvParms, uint32_t cbParms); 51 51 #endif /* VRDP_MC */ 52 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendUpdate) (HVRDPSERVER hServer, void *pvUpdate, uint32_t cbUpdate);52 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendUpdate) (HVRDPSERVER hServer, unsigned uScreenId, void *pvUpdate, uint32_t cbUpdate); 53 53 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPQueryInfo) (HVRDPSERVER hserver, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut); 54 54 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPClipboard) (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData, uint32_t *pcbActualRead); … … 125 125 if (VBOX_SUCCESS(rc)) 126 126 { 127 #ifndef VRDP_MC 127 128 LogFlow(("VRDP server created: %p, will set mFramebuffer\n", mhServer)); 128 129 … … 133 134 134 135 LogFlow(("Framebuffer %p set for the VRDP server\n", framebuffer)); 135 136 #endif /* !VRDP_MC */ 136 137 #ifdef VBOX_WITH_USB 137 138 #ifdef VRDP_MC … … 923 924 924 925 925 void ConsoleVRDPServer::SendUpdate ( void *pvUpdate, uint32_t cbUpdate) const926 void ConsoleVRDPServer::SendUpdate (unsigned uScreenId, void *pvUpdate, uint32_t cbUpdate) const 926 927 { 927 928 #ifdef VBOX_VRDP 928 929 if (mpfnVRDPSendUpdate) 929 mpfnVRDPSendUpdate (mhServer, pvUpdate, cbUpdate);930 mpfnVRDPSendUpdate (mhServer, uScreenId, pvUpdate, cbUpdate); 930 931 #endif 931 932 } … … 939 940 } 940 941 941 void ConsoleVRDPServer::SendUpdateBitmap (u int32_t x, uint32_t y, uint32_t w, uint32_t h) const942 void ConsoleVRDPServer::SendUpdateBitmap (unsigned uScreenId, uint32_t x, uint32_t y, uint32_t w, uint32_t h) const 942 943 { 943 944 #ifdef VBOX_VRDP 944 945 if (mpfnVRDPSendUpdateBitmap) 945 mpfnVRDPSendUpdateBitmap (mhServer, x, y, w, h);946 mpfnVRDPSendUpdateBitmap (mhServer, uScreenId, x, y, w, h); 946 947 #endif 947 948 } … … 1022 1023 { 1023 1024 DEFSYMENTRY(VRDPStartServer), 1025 #ifndef VRDP_MC 1024 1026 DEFSYMENTRY(VRDPSetFramebuffer), 1027 #endif /* VRDP_MC */ 1025 1028 DEFSYMENTRY(VRDPSetCallback), 1026 1029 DEFSYMENTRY(VRDPShutdownServer), -
trunk/src/VBox/Main/DisplayImpl.cpp
r3110 r3153 91 91 mLastHeight = 0; 92 92 93 mu32ResizeStatus = ResizeStatus_Void;93 // mu32ResizeStatus = ResizeStatus_Void; 94 94 95 95 return S_OK; … … 128 128 // by default, we have an internal framebuffer which is 129 129 // NULL, i.e. a black hole for no display output 130 mFramebuffer = 0;130 // mFramebuffer = 0; 131 131 mInternalFramebuffer = true; 132 132 mFramebufferOpened = false; 133 133 mSupportedAccelOps = 0; 134 134 135 ULONG ul; 136 mParent->machine()->COMGETTER(MonitorCount)(&ul); 137 mcMonitors = ul; 138 139 for (ul = 0; ul < mcMonitors; ul++) 140 { 141 maFramebuffers[ul].u32Offset = 0; 142 maFramebuffers[ul].u32MaxFramebufferSize = 0; 143 maFramebuffers[ul].u32InformationSize = 0; 144 145 maFramebuffers[ul].pFramebuffer = NULL; 146 147 maFramebuffers[ul].xOrigin = 0; 148 maFramebuffers[ul].yOrigin = 0; 149 150 maFramebuffers[ul].w = 0; 151 maFramebuffers[ul].h = 0; 152 153 maFramebuffers[ul].pHostEvents = NULL; 154 155 maFramebuffers[ul].u32ResizeStatus = ResizeStatus_Void; 156 157 maFramebuffers[ul].fDefaultFormat = false; 158 159 memset (&maFramebuffers[ul].dirtyRect, 0 , sizeof (maFramebuffers[ul].dirtyRect)); 160 } 161 135 162 mParent->RegisterCallback(this); 136 163 … … 150 177 AssertReturn (isReady(), (void) 0); 151 178 152 mFramebuffer.setNull(); 179 // mFramebuffer.setNull(); 180 ULONG ul; 181 for (ul = 0; ul < mcMonitors; ul++) 182 { 183 maFramebuffers[ul].pFramebuffer = NULL; 184 } 185 153 186 RTSemEventMultiDestroy(mUpdateSem); 154 187 … … 189 222 * @thread EMT 190 223 */ 191 static int callFramebufferResize (IFramebuffer *pFramebuffer, FramebufferPixelFormat_T pixelFormat, void *pvVRAM, uint32_t cbLine, int w, int h)224 static int callFramebufferResize (IFramebuffer *pFramebuffer, unsigned uScreenId, FramebufferPixelFormat_T pixelFormat, void *pvVRAM, uint32_t cbLine, int w, int h) 192 225 { 193 226 Assert (pFramebuffer); … … 196 229 BOOL finished = TRUE; 197 230 198 pFramebuffer->RequestResize ( pixelFormat, (BYTE *) pvVRAM, cbLine, w, h, &finished);231 pFramebuffer->RequestResize (uScreenId, pixelFormat, (BYTE *) pvVRAM, cbLine, w, h, &finished); 199 232 200 233 if (!finished) … … 219 252 * @thread EMT 220 253 */ 221 int Display::handleDisplayResize (u int32_t bpp, void *pvVRAM, uint32_t cbLine, int w, int h)222 { 223 LogRel (("Display::handleDisplayResize(): pvVRAM=%p w=%d h=%d bpp=%d cbLine=0x%X\n",224 pvVRAM, w, h, bpp, cbLine));254 int Display::handleDisplayResize (unsigned uScreenId, uint32_t bpp, void *pvVRAM, uint32_t cbLine, int w, int h) 255 { 256 LogRel (("Display::handleDisplayResize(): uScreenId = %d, pvVRAM=%p w=%d h=%d bpp=%d cbLine=0x%X\n", 257 uScreenId, pvVRAM, w, h, bpp, cbLine)); 225 258 226 259 /* If there is no framebuffer, this call is not interesting. */ 227 if (mFramebuffer.isNull()) 260 if ( uScreenId >= mcMonitors 261 || maFramebuffers[uScreenId].pFramebuffer.isNull()) 228 262 { 229 263 return VINF_SUCCESS; … … 249 283 * disable access to the VGA device by the EMT thread. 250 284 */ 251 bool f = ASMAtomicCmpXchgU32 (&m u32ResizeStatus, ResizeStatus_InProgress, ResizeStatus_Void);285 bool f = ASMAtomicCmpXchgU32 (&maFramebuffers[uScreenId].u32ResizeStatus, ResizeStatus_InProgress, ResizeStatus_Void); 252 286 AssertReleaseMsg(f, ("f = %d\n", f));NOREF(f); 253 287 … … 255 289 * The lock is kept, because the framebuffer is in undefined state. 256 290 */ 257 m Framebuffer->Lock();258 259 int rc = callFramebufferResize (m Framebuffer, pixelFormat, pvVRAM, cbLine, w, h);291 maFramebuffers[uScreenId].pFramebuffer->Lock(); 292 293 int rc = callFramebufferResize (maFramebuffers[uScreenId].pFramebuffer, uScreenId, pixelFormat, pvVRAM, cbLine, w, h); 260 294 if (rc == VINF_VGA_RESIZE_IN_PROGRESS) 261 295 { … … 269 303 270 304 /* Set the status so the 'handleResizeCompleted' would work. */ 271 f = ASMAtomicCmpXchgU32 (&m u32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress);305 f = ASMAtomicCmpXchgU32 (&maFramebuffers[uScreenId].u32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress); 272 306 AssertRelease(f);NOREF(f); 273 307 … … 287 321 { 288 322 LogFlowFunc(("\n")); 289 if (!mFramebuffer.isNull())290 {291 /* Framebuffer has completed the resize. Update the connector data. */292 updateDisplayData();293 323 294 /* Check the framebuffer pixel format to setup the rendering in VGA device. */ 295 FramebufferPixelFormat_T newPixelFormat; 296 297 mFramebuffer->COMGETTER(PixelFormat) (&newPixelFormat); 298 299 mpDrv->pUpPort->pfnSetRenderVRAM (mpDrv->pUpPort, newPixelFormat == FramebufferPixelFormat_PixelFormatDefault); 300 } 324 unsigned uScreenId; 325 for (uScreenId = 0; uScreenId < mcMonitors; uScreenId++) 326 { 327 DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId]; 328 329 /* Try to into non resizing state. */ 330 bool f = ASMAtomicCmpXchgU32 (&pFBInfo->u32ResizeStatus, ResizeStatus_Void, ResizeStatus_UpdateDisplayData); 331 332 if (f == false) 333 { 334 /* This is not the display that has completed resizing. */ 335 continue; 336 } 337 338 if (uScreenId == VBOX_VIDEO_PRIMARY_SCREEN && !pFBInfo->pFramebuffer.isNull()) 339 { 340 /* Primary framebuffer has completed the resize. Update the connector data for VGA device. */ 341 updateDisplayData(); 342 343 /* Check the framebuffer pixel format to setup the rendering in VGA device. */ 344 FramebufferPixelFormat_T newPixelFormat; 345 pFBInfo->pFramebuffer->COMGETTER(PixelFormat) (&newPixelFormat); 346 347 pFBInfo->fDefaultFormat = (newPixelFormat == FramebufferPixelFormat_PixelFormatDefault); 348 349 mpDrv->pUpPort->pfnSetRenderVRAM (mpDrv->pUpPort, pFBInfo->fDefaultFormat); 350 } 301 351 302 352 #ifdef DEBUG_sunlover 303 if (!stam)304 {305 /* protect mpVM */306 Console::SafeVMPtr pVM (mParent);307 AssertComRC (pVM.rc());308 309 STAM_REG(pVM, &StatDisplayRefresh, STAMTYPE_PROFILE, "/PROF/Display/Refresh", STAMUNIT_TICKS_PER_CALL, "Time spent in EMT for display updates.");310 stam = 1;311 }353 if (!stam) 354 { 355 /* protect mpVM */ 356 Console::SafeVMPtr pVM (mParent); 357 AssertComRC (pVM.rc()); 358 359 STAM_REG(pVM, &StatDisplayRefresh, STAMTYPE_PROFILE, "/PROF/Display/Refresh", STAMUNIT_TICKS_PER_CALL, "Time spent in EMT for display updates."); 360 stam = 1; 361 } 312 362 #endif /* DEBUG_sunlover */ 313 363 314 /* Inform VRDP server about the change of display parameters. */ 315 LogFlowFunc (("Calling VRDP\n")); 316 mParent->consoleVRDPServer()->SendResize(); 317 318 /* Go into non resizing state. */ 319 bool f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_Void, ResizeStatus_UpdateDisplayData); 320 AssertRelease(f);NOREF(f); 321 322 if (!mFramebuffer.isNull()) 323 { 324 /* Unlock framebuffer after evrything is done. */ 325 mFramebuffer->Unlock(); 364 /* Inform VRDP server about the change of display parameters. */ 365 LogFlowFunc (("Calling VRDP\n")); 366 mParent->consoleVRDPServer()->SendResize(); 367 368 if (!pFBInfo->pFramebuffer.isNull()) 369 { 370 /* Unlock framebuffer after evrything is done. */ 371 pFBInfo->pFramebuffer->Unlock(); 372 } 326 373 } 327 374 } … … 359 406 } 360 407 } 408 409 unsigned mapCoordsToScreen(DISPLAYFBINFO *pInfos, unsigned cInfos, int *px, int *py, int *pw, int *ph) 410 { 411 DISPLAYFBINFO *pInfo = pInfos; 412 unsigned uScreenId; 413 Log(("mapCoordsToScreen: %d,%d %dx%d\n", *px, *py, *pw, *ph)); 414 for (uScreenId = 0; uScreenId < cInfos; uScreenId++, pInfo++) 415 { 416 Log((" [%d] %d,%d %dx%d\n", uScreenId, pInfo->xOrigin, pInfo->yOrigin, pInfo->w, pInfo->h)); 417 if ( (pInfo->xOrigin <= *px && *px < pInfo->xOrigin + (int)pInfo->w) 418 && (pInfo->yOrigin <= *py && *py < pInfo->yOrigin + (int)pInfo->h)) 419 { 420 /* The rectangle belongs to the screen. Correct coordinates. */ 421 *px -= pInfo->xOrigin; 422 *py -= pInfo->yOrigin; 423 Log((" -> %d,%d", *px, *py)); 424 break; 425 } 426 } 427 if (uScreenId == cInfos) 428 { 429 /* Map to primary screen. */ 430 uScreenId = 0; 431 } 432 Log((" scr %d\n", uScreenId)); 433 return uScreenId; 434 } 435 361 436 362 437 /** … … 372 447 void Display::handleDisplayUpdate (int x, int y, int w, int h) 373 448 { 374 // if there is no framebuffer, this call is not interesting375 if (mFramebuffer.isNull())376 return;377 378 mFramebuffer->Lock();379 380 449 #ifdef DEBUG_sunlover 381 450 LogFlowFunc (("%d,%d %dx%d (%d,%d)\n", … … 383 452 #endif /* DEBUG_sunlover */ 384 453 454 #ifdef VRDP_MC 455 unsigned uScreenId = mapCoordsToScreen(maFramebuffers, mcMonitors, &x, &y, &w, &h); 456 #else 385 457 checkCoordBounds (&x, &y, &w, &h, mpDrv->Connector.cx, mpDrv->Connector.cy); 458 #endif /* VRDP_MC */ 386 459 387 460 #ifdef DEBUG_sunlover … … 389 462 #endif /* DEBUG_sunlover */ 390 463 464 IFramebuffer *pFramebuffer = maFramebuffers[uScreenId].pFramebuffer; 465 466 // if there is no framebuffer, this call is not interesting 467 if (pFramebuffer == NULL) 468 return; 469 470 pFramebuffer->Lock(); 471 391 472 /* special processing for the internal framebuffer */ 392 473 if (mInternalFramebuffer) 393 474 { 394 mFramebuffer->Unlock();475 pFramebuffer->Unlock(); 395 476 } else 396 477 { … … 400 481 RTSemEventMultiReset(mUpdateSem); 401 482 402 mFramebuffer->NotifyUpdate(x, y, w, h, &finished);483 pFramebuffer->NotifyUpdate(x, y, w, h, &finished); 403 484 404 485 if (!finished) … … 408 489 * the event so we have to halt the VM until it's done 409 490 */ 410 mFramebuffer->Unlock();491 pFramebuffer->Unlock(); 411 492 RTSemEventMultiWait(mUpdateSem, RT_INDEFINITE_WAIT); 412 493 } else 413 494 { 414 mFramebuffer->Unlock();495 pFramebuffer->Unlock(); 415 496 } 416 497 … … 420 501 * Inform the server here only if VBVA is disabled. 421 502 */ 422 mParent->consoleVRDPServer()->SendUpdateBitmap( x, y, w, h);503 mParent->consoleVRDPServer()->SendUpdateBitmap(uScreenId, x, y, w, h); 423 504 } 424 505 } … … 429 510 { 430 511 /* Copies of object's pointers used by vbvaRgn functions. */ 431 IFramebuffer *pFramebuffer; 512 DISPLAYFBINFO *paFramebuffers; 513 unsigned cMonitors; 432 514 Display *pDisplay; 433 515 PPDMIDISPLAYPORT pPort; 434 516 435 /* The Framebuffer has default format and must be updates immediately. */436 bool fDefaultFormat;437 438 /* Merged rectangles. */439 int32_t xLeft;440 int32_t xRight;441 int32_t yTop;442 int32_t yBottom;443 444 517 } VBVADIRTYREGION; 445 518 446 static void vbvaRgnInit (VBVADIRTYREGION *prgn, IFramebuffer *pfb, Display *pd, PPDMIDISPLAYPORT pp) 447 { 448 memset (prgn, 0, sizeof (VBVADIRTYREGION)); 449 450 prgn->pFramebuffer = pfb; 519 static void vbvaRgnInit (VBVADIRTYREGION *prgn, DISPLAYFBINFO *paFramebuffers, unsigned cMonitors, Display *pd, PPDMIDISPLAYPORT pp) 520 { 521 prgn->paFramebuffers = paFramebuffers; 522 prgn->cMonitors = cMonitors; 451 523 prgn->pDisplay = pd; 452 524 prgn->pPort = pp; 453 454 if (pfb) 455 { 456 FramebufferPixelFormat_T pixelFormat; 457 pfb->COMGETTER(PixelFormat) (&pixelFormat); 458 prgn->fDefaultFormat = (pixelFormat == FramebufferPixelFormat_PixelFormatDefault); 459 } 460 461 return; 462 } 463 464 static void vbvaRgnDirtyRect (VBVADIRTYREGION *prgn, VBVACMDHDR *phdr) 525 526 unsigned uScreenId; 527 for (uScreenId = 0; uScreenId < cMonitors; uScreenId++) 528 { 529 DISPLAYFBINFO *pFBInfo = &prgn->paFramebuffers[uScreenId]; 530 531 memset (&pFBInfo->dirtyRect, 0, sizeof (pFBInfo->dirtyRect)); 532 } 533 } 534 535 static void vbvaRgnDirtyRect (VBVADIRTYREGION *prgn, unsigned uScreenId, VBVACMDHDR *phdr) 465 536 { 466 537 LogFlowFunc (("x = %d, y = %d, w = %d, h = %d\n", … … 483 554 int32_t yBottom = phdr->y + phdr->h; 484 555 485 if (prgn->xRight == 0) 556 DISPLAYFBINFO *pFBInfo = &prgn->paFramebuffers[uScreenId]; 557 558 if (pFBInfo->dirtyRect.xRight == 0) 486 559 { 487 560 /* This is the first rectangle to be added. */ 488 p rgn->xLeft = phdr->x;489 p rgn->yTop = phdr->y;490 p rgn->xRight = xRight;491 p rgn->yBottom = yBottom;561 pFBInfo->dirtyRect.xLeft = phdr->x; 562 pFBInfo->dirtyRect.yTop = phdr->y; 563 pFBInfo->dirtyRect.xRight = xRight; 564 pFBInfo->dirtyRect.yBottom = yBottom; 492 565 } 493 566 else 494 567 { 495 568 /* Adjust region coordinates. */ 496 if (prgn->xLeft > phdr->x) 497 { 498 prgn->xLeft = phdr->x; 499 } 500 501 if (prgn->yTop > phdr->y) 502 { 503 prgn->yTop = phdr->y; 504 } 505 506 if (prgn->xRight < xRight) 507 { 508 prgn->xRight = xRight; 509 } 510 511 if (prgn->yBottom < yBottom) 512 { 513 prgn->yBottom = yBottom; 514 } 515 } 516 517 if (prgn->fDefaultFormat) 518 { 569 if (pFBInfo->dirtyRect.xLeft > phdr->x) 570 { 571 pFBInfo->dirtyRect.xLeft = phdr->x; 572 } 573 574 if (pFBInfo->dirtyRect.yTop > phdr->y) 575 { 576 pFBInfo->dirtyRect.yTop = phdr->y; 577 } 578 579 if (pFBInfo->dirtyRect.xRight < xRight) 580 { 581 pFBInfo->dirtyRect.xRight = xRight; 582 } 583 584 if (pFBInfo->dirtyRect.yBottom < yBottom) 585 { 586 pFBInfo->dirtyRect.yBottom = yBottom; 587 } 588 } 589 590 if (pFBInfo->fDefaultFormat) 591 { 592 //@todo pfnUpdateDisplayRect must take the vram offset parameter for the framebuffer 519 593 prgn->pPort->pfnUpdateDisplayRect (prgn->pPort, phdr->x, phdr->y, phdr->w, phdr->h); 520 594 prgn->pDisplay->handleDisplayUpdate (phdr->x, phdr->y, phdr->w, phdr->h); … … 524 598 } 525 599 526 static void vbvaRgnUpdateFramebuffer (VBVADIRTYREGION *prgn) 527 { 528 uint32_t w = prgn->xRight - prgn->xLeft; 529 uint32_t h = prgn->yBottom - prgn->yTop; 530 531 if (!prgn->fDefaultFormat && prgn->pFramebuffer && w != 0 && h != 0) 532 { 533 prgn->pPort->pfnUpdateDisplayRect (prgn->pPort, prgn->xLeft, prgn->yTop, w, h); 534 prgn->pDisplay->handleDisplayUpdate (prgn->xLeft, prgn->yTop, w, h); 600 static void vbvaRgnUpdateFramebuffer (VBVADIRTYREGION *prgn, unsigned uScreenId) 601 { 602 DISPLAYFBINFO *pFBInfo = &prgn->paFramebuffers[uScreenId]; 603 604 uint32_t w = pFBInfo->dirtyRect.xRight - pFBInfo->dirtyRect.xLeft; 605 uint32_t h = pFBInfo->dirtyRect.yBottom - pFBInfo->dirtyRect.yTop; 606 607 if (!pFBInfo->fDefaultFormat && pFBInfo->pFramebuffer && w != 0 && h != 0) 608 { 609 //@todo pfnUpdateDisplayRect must take the vram offset parameter for the framebuffer 610 prgn->pPort->pfnUpdateDisplayRect (prgn->pPort, pFBInfo->dirtyRect.xLeft, pFBInfo->dirtyRect.yTop, w, h); 611 prgn->pDisplay->handleDisplayUpdate (pFBInfo->dirtyRect.xLeft, pFBInfo->dirtyRect.yTop, w, h); 535 612 } 536 613 } … … 539 616 bool fVideoAccelEnabled, 540 617 bool fVideoAccelVRDP, 541 uint32_t fu32SupportedOrders) 618 uint32_t fu32SupportedOrders, 619 DISPLAYFBINFO *paFBInfos, 620 unsigned cFBInfos) 542 621 { 543 622 if (pVbvaMemory) … … 559 638 560 639 pVbvaMemory->fu32ModeFlags = fu32Flags; 640 } 641 642 unsigned uScreenId; 643 for (uScreenId = 0; uScreenId < cFBInfos; uScreenId++) 644 { 645 if (paFBInfos[uScreenId].pHostEvents) 646 { 647 paFBInfos[uScreenId].pHostEvents->fu32Events |= VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET; 648 } 561 649 } 562 650 } … … 636 724 637 725 /* Update entire display. */ 638 if (m u32ResizeStatus == ResizeStatus_Void)726 if (maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].u32ResizeStatus == ResizeStatus_Void) 639 727 { 640 728 mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort); … … 659 747 660 748 /* Initialize the hardware memory. */ 661 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders );749 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders, maFramebuffers, mcMonitors); 662 750 mpVbvaMemory->off32Data = 0; 663 751 mpVbvaMemory->off32Free = 0; … … 706 794 mfu32SupportedOrders = 0; 707 795 708 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders );796 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders, maFramebuffers, mcMonitors); 709 797 710 798 LogRel(("VBVA: VRDP acceleration has been disabled.\n")); … … 721 809 mfu32SupportedOrders = ~0; 722 810 723 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders );811 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders, maFramebuffers, mcMonitors); 724 812 725 813 LogRel(("VBVA: VRDP acceleration has been requested.\n")); … … 749 837 } 750 838 751 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders );839 vbvaSetMemoryFlags (mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP, mfu32SupportedOrders, maFramebuffers, mcMonitors); 752 840 753 841 LogRel(("VBVA: VRDP acceleration has been %s.\n", fEnable? "requested": "disabled")); … … 1054 1142 1055 1143 /* Process the ring buffer */ 1056 1057 bool fFramebufferIsNull = mFramebuffer.isNull(); 1058 1059 if (!fFramebufferIsNull) 1060 { 1061 mFramebuffer->Lock(); 1144 unsigned uScreenId; 1145 for (uScreenId = 0; uScreenId < mcMonitors; uScreenId++) 1146 { 1147 if (!maFramebuffers[uScreenId].pFramebuffer.isNull()) 1148 { 1149 maFramebuffers[uScreenId].pFramebuffer->Lock (); 1150 } 1062 1151 } 1063 1152 1064 1153 /* Initialize dirty rectangles accumulator. */ 1065 1154 VBVADIRTYREGION rgn; 1066 vbvaRgnInit (&rgn, m Framebuffer, this, mpDrv->pUpPort);1155 vbvaRgnInit (&rgn, maFramebuffers, mcMonitors, this, mpDrv->pUpPort); 1067 1156 1068 1157 for (;;) … … 1089 1178 } 1090 1179 1091 if (cbCmd != 0 && !fFramebufferIsNull)1180 if (cbCmd != 0) 1092 1181 { 1093 1182 #ifdef DEBUG_sunlover … … 1096 1185 #endif /* DEBUG_sunlover */ 1097 1186 1098 if (mu32ResizeStatus == ResizeStatus_Void) 1187 VBVACMDHDR hdrSaved = *phdr; 1188 1189 int x = phdr->x; 1190 int y = phdr->y; 1191 int w = phdr->w; 1192 int h = phdr->h; 1193 1194 uScreenId = mapCoordsToScreen(maFramebuffers, mcMonitors, &x, &y, &w, &h); 1195 1196 phdr->x = (int16_t)x; 1197 phdr->y = (int16_t)y; 1198 phdr->w = (uint16_t)w; 1199 phdr->h = (uint16_t)h; 1200 1201 DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId]; 1202 1203 if (pFBInfo->u32ResizeStatus == ResizeStatus_Void) 1099 1204 { 1100 1205 /* Handle the command. … … 1111 1216 1112 1217 /* Accumulate the update. */ 1113 vbvaRgnDirtyRect (&rgn, phdr);1218 vbvaRgnDirtyRect (&rgn, uScreenId, phdr); 1114 1219 1115 1220 /* Forward the command to VRDP server. */ 1116 mParent->consoleVRDPServer()->SendUpdate (phdr, cbCmd); 1221 mParent->consoleVRDPServer()->SendUpdate (uScreenId, phdr, cbCmd); 1222 1223 *phdr = hdrSaved; 1117 1224 } 1118 1225 } … … 1121 1228 } 1122 1229 1123 if (!fFramebufferIsNull) 1124 { 1125 mFramebuffer->Unlock (); 1126 } 1127 1128 if (mu32ResizeStatus == ResizeStatus_Void) 1129 { 1130 /* Draw the framebuffer. */ 1131 vbvaRgnUpdateFramebuffer (&rgn); 1230 for (uScreenId = 0; uScreenId < mcMonitors; uScreenId++) 1231 { 1232 if (!maFramebuffers[uScreenId].pFramebuffer.isNull()) 1233 { 1234 maFramebuffers[uScreenId].pFramebuffer->Unlock (); 1235 } 1236 1237 if (maFramebuffers[uScreenId].u32ResizeStatus == ResizeStatus_Void) 1238 { 1239 /* Draw the framebuffer. */ 1240 vbvaRgnUpdateFramebuffer (&rgn, uScreenId); 1241 } 1132 1242 } 1133 1243 } … … 1235 1345 (PFNRT) changeFramebuffer, 3, 1236 1346 this, static_cast <IFramebuffer *> (frameBuf), 1237 true /* aInternal */ );1347 true /* aInternal */, VBOX_VIDEO_PRIMARY_SCREEN); 1238 1348 if (VBOX_SUCCESS (vrc)) 1239 1349 vrc = pReq->iStatus; … … 1247 1357 { 1248 1358 /* No VM is created (VM is powered off), do a direct call */ 1249 int vrc = changeFramebuffer (this, frameBuf, true /* aInternal */ );1359 int vrc = changeFramebuffer (this, frameBuf, true /* aInternal */, VBOX_VIDEO_PRIMARY_SCREEN); 1250 1360 ComAssertRCRet (vrc, E_FAIL); 1251 1361 } … … 1263 1373 1264 1374 /* only allowed for internal framebuffers */ 1265 if (mInternalFramebuffer && !mFramebufferOpened && !m Framebuffer.isNull())1375 if (mInternalFramebuffer && !mFramebufferOpened && !maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].pFramebuffer.isNull()) 1266 1376 { 1267 1377 CHECK_CONSOLE_DRV (mpDrv); 1268 1378 1269 m Framebuffer->Lock();1379 maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].pFramebuffer->Lock(); 1270 1380 mFramebufferOpened = true; 1271 1381 *address = mpDrv->Connector.pu8Data; … … 1286 1396 CHECK_CONSOLE_DRV (mpDrv); 1287 1397 1288 m Framebuffer->Unlock();1398 maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].pFramebuffer->Unlock(); 1289 1399 mFramebufferOpened = false; 1290 1400 return S_OK; … … 1315 1425 int vrc = VMR3ReqCall (pVM, &pReq, RT_INDEFINITE_WAIT, 1316 1426 (PFNRT) changeFramebuffer, 3, 1317 this, frameBuf, false /* aInternal */ );1427 this, frameBuf, false /* aInternal */, VBOX_VIDEO_PRIMARY_SCREEN); 1318 1428 if (VBOX_SUCCESS (vrc)) 1319 1429 vrc = pReq->iStatus; … … 1327 1437 { 1328 1438 /* No VM is created (VM is powered off), do a direct call */ 1329 int vrc = changeFramebuffer (this, frameBuf, false /* aInternal */ );1439 int vrc = changeFramebuffer (this, frameBuf, false /* aInternal */, VBOX_VIDEO_PRIMARY_SCREEN); 1330 1440 ComAssertRCRet (vrc, E_FAIL); 1331 1441 } 1442 1443 return S_OK; 1444 } 1445 1446 STDMETHODIMP Display::SetFramebuffer (ULONG aScreenId, IFramebuffer * aFramebuffer) 1447 { 1448 LogFlowFunc (("\n")); 1449 1450 if (!aFramebuffer) 1451 return E_POINTER; 1452 1453 AutoLock lock (this); 1454 CHECK_READY(); 1455 1456 Console::SafeVMPtrQuiet pVM (mParent); 1457 if (pVM.isOk()) 1458 { 1459 /* Must leave the lock here because the changeFramebuffer will also obtain it. */ 1460 lock.leave (); 1461 1462 /* send request to the EMT thread */ 1463 PVMREQ pReq = NULL; 1464 int vrc = VMR3ReqCall (pVM, &pReq, RT_INDEFINITE_WAIT, 1465 (PFNRT) changeFramebuffer, 3, 1466 this, aFramebuffer, false /* aInternal */, aScreenId); 1467 if (VBOX_SUCCESS (vrc)) 1468 vrc = pReq->iStatus; 1469 VMR3ReqFree (pReq); 1470 1471 lock.enter (); 1472 1473 ComAssertRCRet (vrc, E_FAIL); 1474 } 1475 else 1476 { 1477 /* No VM is created (VM is powered off), do a direct call */ 1478 int vrc = changeFramebuffer (this, aFramebuffer, false /* aInternal */, aScreenId); 1479 ComAssertRCRet (vrc, E_FAIL); 1480 } 1481 1482 return S_OK; 1483 } 1484 1485 STDMETHODIMP Display::QueryFramebuffer (ULONG aScreenId, IFramebuffer * * aFramebuffer, LONG * aXOrigin, LONG * aYOrigin) 1486 { 1487 LogFlowFunc (("aScreenId = %d\n", aScreenId)); 1488 1489 if (!aFramebuffer) 1490 return E_POINTER; 1491 1492 AutoLock lock (this); 1493 CHECK_READY(); 1494 1495 /* @todo this should be actually done on EMT. */ 1496 DISPLAYFBINFO *pFBInfo = &maFramebuffers[aScreenId]; 1497 1498 *aFramebuffer = pFBInfo->pFramebuffer; 1499 if (*aFramebuffer) 1500 (*aFramebuffer)->AddRef (); 1501 if (aXOrigin) 1502 *aXOrigin = pFBInfo->xOrigin; 1503 if (aYOrigin) 1504 *aYOrigin = pFBInfo->yOrigin; 1332 1505 1333 1506 return S_OK; … … 1555 1728 * @returns COM status code 1556 1729 */ 1557 STDMETHODIMP Display::ResizeCompleted( )1730 STDMETHODIMP Display::ResizeCompleted(ULONG aScreenId) 1558 1731 { 1559 1732 LogFlowFunc (("\n")); … … 1576 1749 1577 1750 /* Set the flag indicating that the resize has completed and display data need to be updated. */ 1578 bool f = ASMAtomicCmpXchgU32 (&m u32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress);1751 bool f = ASMAtomicCmpXchgU32 (&maFramebuffers[aScreenId].u32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress); 1579 1752 AssertRelease(f);NOREF(f); 1580 1753 … … 1608 1781 "for external framebuffers")); 1609 1782 1610 m Framebuffer->Lock();1783 maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].pFramebuffer->Lock(); 1611 1784 /* signal our semaphore */ 1612 1785 RTSemEventMultiSignal(mUpdateSem); 1613 m Framebuffer->Unlock();1786 maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].pFramebuffer->Unlock(); 1614 1787 1615 1788 return S_OK; … … 1647 1820 #endif 1648 1821 1649 if (mFramebuffer) 1822 /* The method is only relevant to the primary framebuffer. */ 1823 IFramebuffer *pFramebuffer = maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].pFramebuffer; 1824 1825 if (pFramebuffer) 1650 1826 { 1651 1827 HRESULT rc; 1652 1828 BYTE *address = 0; 1653 rc = mFramebuffer->COMGETTER(Address) (&address);1829 rc = pFramebuffer->COMGETTER(Address) (&address); 1654 1830 AssertComRC (rc); 1655 1831 ULONG lineSize = 0; 1656 rc = mFramebuffer->COMGETTER(LineSize) (&lineSize);1832 rc = pFramebuffer->COMGETTER(LineSize) (&lineSize); 1657 1833 AssertComRC (rc); 1658 1834 ULONG colorDepth = 0; 1659 rc = mFramebuffer->COMGETTER(ColorDepth) (&colorDepth);1835 rc = pFramebuffer->COMGETTER(ColorDepth) (&colorDepth); 1660 1836 AssertComRC (rc); 1661 1837 ULONG width = 0; 1662 rc = mFramebuffer->COMGETTER(Width) (&width);1838 rc = pFramebuffer->COMGETTER(Width) (&width); 1663 1839 AssertComRC (rc); 1664 1840 ULONG height = 0; 1665 rc = mFramebuffer->COMGETTER(Height) (&height);1841 rc = pFramebuffer->COMGETTER(Height) (&height); 1666 1842 AssertComRC (rc); 1667 1843 … … 1679 1855 mLastHeight != (int) height)) 1680 1856 { 1681 handleDisplayResize ( mLastColorDepth,1857 handleDisplayResize (VBOX_VIDEO_PRIMARY_SCREEN, mLastColorDepth, 1682 1858 mLastAddress, 1683 1859 mLastLineSize, … … 1713 1889 /* static */ 1714 1890 DECLCALLBACK(int) Display::changeFramebuffer (Display *that, IFramebuffer *aFB, 1715 bool aInternal )1716 { 1717 LogFlowFunc ((" \n"));1891 bool aInternal, unsigned uScreenId) 1892 { 1893 LogFlowFunc (("uScreenId = %d\n", uScreenId)); 1718 1894 1719 1895 AssertReturn (that, VERR_INVALID_PARAMETER); 1720 1896 AssertReturn (aFB || aInternal, VERR_INVALID_PARAMETER); 1897 AssertReturn (uScreenId >= 0 && uScreenId < that->mcMonitors, VERR_INVALID_PARAMETER); 1721 1898 1722 1899 /// @todo (r=dmik) AutoCaller … … 1724 1901 AutoLock alock (that); 1725 1902 1726 that->mFramebuffer = aFB; 1903 DISPLAYFBINFO *pDisplayFBInfo = &that->maFramebuffers[uScreenId]; 1904 pDisplayFBInfo->pFramebuffer = aFB; 1905 1727 1906 that->mInternalFramebuffer = aInternal; 1728 1907 that->mSupportedAccelOps = 0; … … 1748 1927 } 1749 1928 1750 that->mParent->consoleVRDPServer()-> 1751 SetFramebuffer (aFB, aFB ? VRDP_EXTERNAL_FRAMEBUFFER : 1752 VRDP_INTERNAL_FRAMEBUFFER); 1929 that->mParent->consoleVRDPServer()->SendResize (); 1753 1930 1754 1931 that->updateDisplayData (true /* aCheckParams */); … … 1758 1935 1759 1936 /** 1760 * Handle display resize event .1937 * Handle display resize event issued by the VGA device for the primary screen. 1761 1938 * 1762 1939 * @see PDMIDISPLAYCONNECTOR::pfnResize … … 1770 1947 bpp, pvVRAM, cbLine, cx, cy)); 1771 1948 1772 return pDrv->pDisplay->handleDisplayResize( bpp, pvVRAM, cbLine, cx, cy);1949 return pDrv->pDisplay->handleDisplayResize(VBOX_VIDEO_PRIMARY_SCREEN, bpp, pvVRAM, cbLine, cx, cy); 1773 1950 } 1774 1951 … … 1816 1993 Display *pDisplay = pDrv->pDisplay; 1817 1994 1818 /* Check the resize status. The status can be checked normally because 1819 * the status affects only the EMT. 1820 */ 1821 uint32_t u32ResizeStatus = pDisplay->mu32ResizeStatus; 1822 1823 if (u32ResizeStatus == ResizeStatus_UpdateDisplayData) 1824 { 1825 LogFlowFunc (("ResizeStatus_UpdateDisplayData\n")); 1826 /* The framebuffer was resized and display data need to be updated. */ 1827 pDisplay->handleResizeCompletedEMT (); 1828 /* Continue with normal processing because the status here is ResizeStatus_Void. */ 1829 Assert (pDisplay->mu32ResizeStatus == ResizeStatus_Void); 1830 /* Repaint the display because VM continued to run during the framebuffer resize. */ 1831 if (!pDisplay->mFramebuffer.isNull()) 1832 pDrv->pUpPort->pfnUpdateDisplayAll(pDrv->pUpPort); 1833 /* Ignore the refresh to replay the logic. */ 1834 return; 1835 } 1836 else if (u32ResizeStatus == ResizeStatus_InProgress) 1837 { 1838 /* The framebuffer is being resized. Do not call the VGA device back. Immediately return. */ 1839 LogFlowFunc (("ResizeStatus_InProcess\n")); 1840 return; 1841 } 1842 1843 if (pDisplay->mFramebuffer.isNull()) 1844 { 1845 /* 1846 * Do nothing in the "black hole" mode to avoid copying guest 1847 * video memory to the frame buffer 1995 unsigned uScreenId; 1996 for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++) 1997 { 1998 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId]; 1999 2000 /* Check the resize status. The status can be checked normally because 2001 * the status affects only the EMT. 1848 2002 */ 1849 } 1850 else 1851 { 1852 if (pDisplay->mfPendingVideoAccelEnable) 1853 { 1854 /* Acceleration was enabled while machine was not yet running 1855 * due to restoring from saved state. Update entire display and 1856 * actually enable acceleration. 2003 uint32_t u32ResizeStatus = pFBInfo->u32ResizeStatus; 2004 2005 if (u32ResizeStatus == ResizeStatus_UpdateDisplayData) 2006 { 2007 LogFlowFunc (("ResizeStatus_UpdateDisplayData %d\n", uScreenId)); 2008 /* The framebuffer was resized and display data need to be updated. */ 2009 pDisplay->handleResizeCompletedEMT (); 2010 /* Continue with normal processing because the status here is ResizeStatus_Void. */ 2011 Assert (pFBInfo->u32ResizeStatus == ResizeStatus_Void); 2012 if (uScreenId == VBOX_VIDEO_PRIMARY_SCREEN) 2013 { 2014 /* Repaint the display because VM continued to run during the framebuffer resize. */ 2015 if (!pFBInfo->pFramebuffer.isNull()) 2016 pDrv->pUpPort->pfnUpdateDisplayAll(pDrv->pUpPort); 2017 } 2018 /* Ignore the refresh for the screen to replay the logic. */ 2019 continue; 2020 } 2021 else if (u32ResizeStatus == ResizeStatus_InProgress) 2022 { 2023 /* The framebuffer is being resized. Do not call the VGA device back. Immediately return. */ 2024 LogFlowFunc (("ResizeStatus_InProcess\n")); 2025 continue; 2026 } 2027 2028 if (pFBInfo->pFramebuffer.isNull()) 2029 { 2030 /* 2031 * Do nothing in the "black hole" mode to avoid copying guest 2032 * video memory to the frame buffer 1857 2033 */ 1858 Assert(pDisplay->mpPendingVbvaMemory); 1859 1860 /* Acceleration can not be yet enabled.*/ 1861 Assert(pDisplay->mpVbvaMemory == NULL); 1862 Assert(!pDisplay->mfVideoAccelEnabled); 1863 1864 if (pDisplay->mfMachineRunning) 2034 } 2035 else 2036 { 2037 if (pDisplay->mfPendingVideoAccelEnable) 1865 2038 { 1866 pDisplay->VideoAccelEnable (pDisplay->mfPendingVideoAccelEnable, 1867 pDisplay->mpPendingVbvaMemory); 1868 1869 /* Reset the pending state. */ 1870 pDisplay->mfPendingVideoAccelEnable = false; 1871 pDisplay->mpPendingVbvaMemory = NULL; 1872 } 1873 } 1874 else 1875 { 1876 Assert(pDisplay->mpPendingVbvaMemory == NULL); 1877 1878 if (pDisplay->mfVideoAccelEnabled) 1879 { 1880 Assert(pDisplay->mpVbvaMemory); 1881 pDisplay->VideoAccelFlush (); 2039 /* Acceleration was enabled while machine was not yet running 2040 * due to restoring from saved state. Update entire display and 2041 * actually enable acceleration. 2042 */ 2043 Assert(pDisplay->mpPendingVbvaMemory); 2044 2045 /* Acceleration can not be yet enabled.*/ 2046 Assert(pDisplay->mpVbvaMemory == NULL); 2047 Assert(!pDisplay->mfVideoAccelEnabled); 2048 2049 if (pDisplay->mfMachineRunning) 2050 { 2051 pDisplay->VideoAccelEnable (pDisplay->mfPendingVideoAccelEnable, 2052 pDisplay->mpPendingVbvaMemory); 2053 2054 /* Reset the pending state. */ 2055 pDisplay->mfPendingVideoAccelEnable = false; 2056 pDisplay->mpPendingVbvaMemory = NULL; 2057 } 1882 2058 } 1883 2059 else 1884 2060 { 1885 Assert(pDrv->Connector.pu8Data); 1886 pDrv->pUpPort->pfnUpdateDisplay(pDrv->pUpPort); 2061 Assert(pDisplay->mpPendingVbvaMemory == NULL); 2062 2063 if (pDisplay->mfVideoAccelEnabled) 2064 { 2065 Assert(pDisplay->mpVbvaMemory); 2066 pDisplay->VideoAccelFlush (); 2067 } 2068 else 2069 { 2070 Assert(pDrv->Connector.pu8Data); 2071 pDrv->pUpPort->pfnUpdateDisplay(pDrv->pUpPort); 2072 } 1887 2073 } 1888 }1889 2074 #ifdef VRDP_MC 1890 /* Inform to VRDP server that the current display update sequence is1891 * completed. At this moment the framebuffer memory contains a definite1892 * image, that is synchronized with the orders already sent to VRDP client.1893 * The server can now process redraw requests from clients or initial1894 * fullscreen updates for new clients.1895 */1896 Assert (pDisplay->mParent && pDisplay->mParent->consoleVRDPServer());1897 pDisplay->mParent->consoleVRDPServer()->SendUpdate (NULL, 0);2075 /* Inform to VRDP server that the current display update sequence is 2076 * completed. At this moment the framebuffer memory contains a definite 2077 * image, that is synchronized with the orders already sent to VRDP client. 2078 * The server can now process redraw requests from clients or initial 2079 * fullscreen updates for new clients. 2080 */ 2081 Assert (pDisplay->mParent && pDisplay->mParent->consoleVRDPServer()); 2082 pDisplay->mParent->consoleVRDPServer()->SendUpdate (uScreenId, NULL, 0); 1898 2083 #endif /* VRDP_MC */ 2084 } 1899 2085 } 1900 2086 1901 2087 #ifdef DEBUG_sunlover 1902 2088 STAM_PROFILE_STOP(&StatDisplayRefresh, a); 2089 LogFlowFunc (("leave\n")); 1903 2090 #endif /* DEBUG_sunlover */ 1904 2091 } … … 1934 2121 /* Disable VBVA mode in any case. The guest driver reenables VBVA mode if necessary. */ 1935 2122 pDrv->pDisplay->VideoAccelEnable (false, NULL); 2123 } 2124 2125 /** 2126 * Adapter information change notification. 2127 * 2128 * @see PDMIDISPLAYCONNECTOR::pfnProcessAdapterData 2129 */ 2130 DECLCALLBACK(void) Display::displayProcessAdapterDataCallback(PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, uint32_t u32VRAMSize) 2131 { 2132 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2133 2134 if (pvVRAM == NULL) 2135 { 2136 unsigned i; 2137 for (i = 0; i < pDrv->pDisplay->mcMonitors; i++) 2138 { 2139 DISPLAYFBINFO *pFBInfo = &pDrv->pDisplay->maFramebuffers[i]; 2140 2141 pFBInfo->u32Offset = 0; 2142 pFBInfo->u32MaxFramebufferSize = 0; 2143 pFBInfo->u32InformationSize = 0; 2144 } 2145 } 2146 else 2147 { 2148 uint8_t *pu8 = (uint8_t *)pvVRAM; 2149 pu8 += u32VRAMSize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 2150 2151 // @todo 2152 uint8_t *pu8End = pu8 + VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 2153 2154 VBOXVIDEOINFOHDR *pHdr; 2155 2156 for (;;) 2157 { 2158 pHdr = (VBOXVIDEOINFOHDR *)pu8; 2159 pu8 += sizeof (VBOXVIDEOINFOHDR); 2160 2161 if (pu8 >= pu8End) 2162 { 2163 LogRel(("VBoxVideo: Guest adapter information overflow!!!\n")); 2164 break; 2165 } 2166 2167 if (pHdr->u8Type == VBOX_VIDEO_INFO_TYPE_DISPLAY) 2168 { 2169 if (pHdr->u16Length != sizeof (VBOXVIDEOINFODISPLAY)) 2170 { 2171 LogRel(("VBoxVideo: Guest adapter information %s invalid length %d!!!\n", "DISPLAY", pHdr->u16Length)); 2172 break; 2173 } 2174 2175 VBOXVIDEOINFODISPLAY *pDisplay = (VBOXVIDEOINFODISPLAY *)pu8; 2176 2177 if (pDisplay->u32Index >= pDrv->pDisplay->mcMonitors) 2178 { 2179 LogRel(("VBoxVideo: Guest adapter information invalid display index %d!!!\n", pDisplay->u32Index)); 2180 break; 2181 } 2182 2183 DISPLAYFBINFO *pFBInfo = &pDrv->pDisplay->maFramebuffers[pDisplay->u32Index]; 2184 2185 pFBInfo->u32Offset = pDisplay->u32Offset; 2186 pFBInfo->u32MaxFramebufferSize = pDisplay->u32FramebufferSize; 2187 pFBInfo->u32InformationSize = pDisplay->u32InformationSize; 2188 2189 LogFlow(("VBOX_VIDEO_INFO_TYPE_DISPLAY: %d: at 0x%08X, size 0x%08X, info 0x%08X\n", pDisplay->u32Index, pDisplay->u32Offset, pDisplay->u32FramebufferSize, pDisplay->u32InformationSize)); 2190 } 2191 else if (pHdr->u8Type == VBOX_VIDEO_INFO_TYPE_END) 2192 { 2193 if (pHdr->u16Length != 0) 2194 { 2195 LogRel(("VBoxVideo: Guest adapter information %s invalid length %d!!!\n", "END", pHdr->u16Length)); 2196 break; 2197 } 2198 2199 break; 2200 } 2201 else 2202 { 2203 LogRel(("Guest adapter information contains unsupported type %d\n", pHdr->u8Type)); 2204 } 2205 2206 pu8 += pHdr->u16Length; 2207 } 2208 } 2209 } 2210 2211 /** 2212 * Display information change notification. 2213 * 2214 * @see PDMIDISPLAYCONNECTOR::pfnProcessDisplayData 2215 */ 2216 DECLCALLBACK(void) Display::displayProcessDisplayDataCallback(PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, unsigned uScreenId) 2217 { 2218 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2219 2220 if (uScreenId >= pDrv->pDisplay->mcMonitors) 2221 { 2222 LogRel(("VBoxVideo: Guest display information invalid display index %d!!!\n", uScreenId)); 2223 return; 2224 } 2225 2226 /* Get the display information strcuture. */ 2227 DISPLAYFBINFO *pFBInfo = &pDrv->pDisplay->maFramebuffers[uScreenId]; 2228 2229 uint8_t *pu8 = (uint8_t *)pvVRAM; 2230 pu8 += pFBInfo->u32Offset + pFBInfo->u32MaxFramebufferSize; 2231 2232 // @todo 2233 uint8_t *pu8End = pu8 + pFBInfo->u32InformationSize; 2234 2235 VBOXVIDEOINFOHDR *pHdr; 2236 2237 for (;;) 2238 { 2239 pHdr = (VBOXVIDEOINFOHDR *)pu8; 2240 pu8 += sizeof (VBOXVIDEOINFOHDR); 2241 2242 if (pu8 >= pu8End) 2243 { 2244 LogRel(("VBoxVideo: Guest display information overflow!!!\n")); 2245 break; 2246 } 2247 2248 if (pHdr->u8Type == VBOX_VIDEO_INFO_TYPE_SCREEN) 2249 { 2250 if (pHdr->u16Length != sizeof (VBOXVIDEOINFOSCREEN)) 2251 { 2252 LogRel(("VBoxVideo: Guest display information %s invalid length %d!!!\n", "SCREEN", pHdr->u16Length)); 2253 break; 2254 } 2255 2256 VBOXVIDEOINFOSCREEN *pScreen = (VBOXVIDEOINFOSCREEN *)pu8; 2257 2258 pFBInfo->xOrigin = pScreen->xOrigin; 2259 pFBInfo->yOrigin = pScreen->yOrigin; 2260 2261 pFBInfo->w = pScreen->u16Width; 2262 pFBInfo->h = pScreen->u16Height; 2263 2264 LogFlow(("VBOX_VIDEO_INFO_TYPE_SCREEN: (%p) %d: at %d,%d, linesize 0x%X, size %dx%d, bpp %d, flags 0x%02X\n", 2265 pHdr, uScreenId, pScreen->xOrigin, pScreen->yOrigin, pScreen->u32LineSize, pScreen->u16Width, pScreen->u16Height, pScreen->bitsPerPixel, pScreen->u8Flags)); 2266 2267 if (uScreenId != VBOX_VIDEO_PRIMARY_SCREEN) 2268 { 2269 /* Primary screen resize is initiated by the VGA device. */ 2270 pDrv->pDisplay->handleDisplayResize(uScreenId, pScreen->bitsPerPixel, (uint8_t *)pvVRAM + pFBInfo->u32Offset, pScreen->u32LineSize, pScreen->u16Width, pScreen->u16Height); 2271 } 2272 } 2273 else if (pHdr->u8Type == VBOX_VIDEO_INFO_TYPE_END) 2274 { 2275 if (pHdr->u16Length != 0) 2276 { 2277 LogRel(("VBoxVideo: Guest adapter information %s invalid length %d!!!\n", "END", pHdr->u16Length)); 2278 break; 2279 } 2280 2281 break; 2282 } 2283 else if (pHdr->u8Type == VBOX_VIDEO_INFO_TYPE_HOST_EVENTS) 2284 { 2285 if (pHdr->u16Length != sizeof (VBOXVIDEOINFOHOSTEVENTS)) 2286 { 2287 LogRel(("VBoxVideo: Guest display information %s invalid length %d!!!\n", "HOST_EVENTS", pHdr->u16Length)); 2288 break; 2289 } 2290 2291 VBOXVIDEOINFOHOSTEVENTS *pHostEvents = (VBOXVIDEOINFOHOSTEVENTS *)pu8; 2292 2293 pFBInfo->pHostEvents = pHostEvents; 2294 2295 LogFlow(("VBOX_VIDEO_INFO_TYPE_HOSTEVENTS: (%p)\n", 2296 pHostEvents)); 2297 } 2298 else if (pHdr->u8Type == VBOX_VIDEO_INFO_TYPE_LINK) 2299 { 2300 if (pHdr->u16Length != sizeof (VBOXVIDEOINFOLINK)) 2301 { 2302 LogRel(("VBoxVideo: Guest adapter information %s invalid length %d!!!\n", "LINK", pHdr->u16Length)); 2303 break; 2304 } 2305 2306 VBOXVIDEOINFOLINK *pLink = (VBOXVIDEOINFOLINK *)pu8; 2307 pu8 += pLink->i32Offset; 2308 } 2309 else 2310 { 2311 LogRel(("Guest display information contains unsupported type %d\n", pHdr->u8Type)); 2312 } 2313 2314 pu8 += pHdr->u16Length; 2315 } 1936 2316 } 1937 2317 … … 2022 2402 pData->Connector.pfnReset = Display::displayResetCallback; 2023 2403 pData->Connector.pfnLFBModeChange = Display::displayLFBModeChangeCallback; 2404 pData->Connector.pfnProcessAdapterData = Display::displayProcessAdapterDataCallback; 2405 pData->Connector.pfnProcessDisplayData = Display::displayProcessDisplayDataCallback; 2024 2406 2025 2407 /* -
trunk/src/VBox/Main/FramebufferImpl.cpp
r2981 r3153 149 149 150 150 STDMETHODIMP 151 InternalFramebuffer::RequestResize( FramebufferPixelFormat_T pixelFormat, BYTE *vram,151 InternalFramebuffer::RequestResize(ULONG iScreenId, FramebufferPixelFormat_T pixelFormat, BYTE *vram, 152 152 ULONG lineSize, ULONG w, ULONG h, 153 153 BOOL *finished) -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r3110 r3153 6048 6048 <interface 6049 6049 name="IFramebuffer" extends="$unknown" 6050 uuid=" 4481F27F-5C79-48d9-86C1-A2EC6747034D"6050 uuid="9f3eba23-6a75-49f3-93e7-cad00fb605f6" 6051 6051 wsmap="suppress" 6052 6052 > … … 6168 6168 </note> 6169 6169 </desc> 6170 <param name="screenId" type="unsigned long" dir="in"> 6171 <desc>The value to be used in the <link to="IDisplay::resizeCompleted()"/> call.</desc> 6172 </param> 6170 6173 <param name="pixelFormat" type="FramebufferPixelFormat" dir="in"> 6171 6174 <desc>Pixel format of the surface (BPP and layout)</desc> … … 6298 6301 <interface 6299 6302 name="IDisplay" extends="$unknown" 6300 uuid=" 0a6a7746-5469-47e4-9a00-8b1ea28891b8"6303 uuid="e740a435-88d1-4f14-b9ca-a1b30e2c5038" 6301 6304 wsmap="suppress" 6302 6305 > … … 6341 6344 </desc> 6342 6345 <param name="framebuffer" type="IFramebuffer" dir="in"/> 6346 </method> 6347 6348 <method name="setFramebuffer"> 6349 <desc> 6350 Sets the framebuffer for given screen. 6351 </desc> 6352 <param name="screenId" type="unsigned long" dir="in"/> 6353 <param name="framebuffer" type="IFramebuffer" dir="in"/> 6354 </method> 6355 6356 <method name="queryFramebuffer"> 6357 <desc> 6358 Queries the framebuffer for given screen. 6359 </desc> 6360 <param name="screenId" type="unsigned long" dir="in"/> 6361 <param name="framebuffer" type="IFramebuffer" dir="out"/> 6362 <param name="xOrigin" type="long" dir="out"/> 6363 <param name="yOrigin" type="long" dir="out"/> 6343 6364 </method> 6344 6365 … … 6396 6417 Signals that a framebuffer has completed the resize operation. 6397 6418 </desc> 6419 <param name="screenId" type="unsigned long" dir="in"/> 6398 6420 </method> 6399 6421 -
trunk/src/VBox/Main/include/ConsoleVRDPServer.h
r2981 r3153 79 79 * Forwarders to VRDP server library. 80 80 */ 81 void SendUpdate ( void *pvUpdate, uint32_t cbUpdate) const;81 void SendUpdate (unsigned uScreenId, void *pvUpdate, uint32_t cbUpdate) const; 82 82 void SendResize (void) const; 83 void SendUpdateBitmap (u int32_t x, uint32_t y, uint32_t w, uint32_t h) const;83 void SendUpdateBitmap (unsigned uScreenId, uint32_t x, uint32_t y, uint32_t w, uint32_t h) const; 84 84 void SetFramebuffer (IFramebuffer *framebuffer, uint32_t fFlags) const; 85 85 … … 113 113 static void (VBOXCALL *mpfnVRDPSetCallback) (HVRDPSERVER hServer, VRDPSERVERCALLBACK *pcallback, void *pvUser); 114 114 static void (VBOXCALL *mpfnVRDPShutdownServer) (HVRDPSERVER hServer); 115 static void (VBOXCALL *mpfnVRDPSendUpdateBitmap)(HVRDPSERVER hServer, unsigned x, unsigned y, unsigned w, unsigned h);115 static void (VBOXCALL *mpfnVRDPSendUpdateBitmap)(HVRDPSERVER hServer, unsigned uScreenId, unsigned x, unsigned y, unsigned w, unsigned h); 116 116 static void (VBOXCALL *mpfnVRDPSendResize) (HVRDPSERVER hServer); 117 117 static void (VBOXCALL *mpfnVRDPSendAudioSamples)(HVRDPSERVER hserver, void *pvSamples, uint32_t cSamples, VRDPAUDIOFORMAT format); … … 122 122 static void (VBOXCALL *mpfnVRDPSendUSBRequest) (HVRDPSERVER hserver, void *pvParms, uint32_t cbParms); 123 123 #endif /* VRDP_MC */ 124 static void (VBOXCALL *mpfnVRDPSendUpdate) (HVRDPSERVER hServer, void *pvUpdate, uint32_t cbUpdate);124 static void (VBOXCALL *mpfnVRDPSendUpdate) (HVRDPSERVER hServer, unsigned uScreenId, void *pvUpdate, uint32_t cbUpdate); 125 125 static void (VBOXCALL *mpfnVRDPQueryInfo) (HVRDPSERVER hserver, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut); 126 126 static void (VBOXCALL *mpfnVRDPClipboard) (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData, uint32_t *pcbActualRead); -
trunk/src/VBox/Main/include/DisplayImpl.h
r3110 r3153 24 24 25 25 #include "VirtualBoxBase.h" 26 #include "SchemaDefs.h" 26 27 #include <iprt/semaphore.h> 27 28 #include <VBox/pdm.h> 28 29 #include <VBox/VBoxGuest.h> 30 #include <VBox/VBoxVideo.h> 29 31 30 32 class Console; 33 34 enum { 35 ResizeStatus_Void, 36 ResizeStatus_InProgress, 37 ResizeStatus_UpdateDisplayData 38 }; 39 40 typedef struct _DISPLAYFBINFO 41 { 42 uint32_t u32Offset; 43 uint32_t u32MaxFramebufferSize; 44 uint32_t u32InformationSize; 45 46 ComPtr<IFramebuffer> pFramebuffer; 47 48 LONG xOrigin; 49 LONG yOrigin; 50 51 ULONG w; 52 ULONG h; 53 54 VBOXVIDEOINFOHOSTEVENTS *pHostEvents; 55 56 volatile uint32_t u32ResizeStatus; 57 58 /* The Framebuffer has default format and must be updates immediately. */ 59 bool fDefaultFormat; 60 61 struct { 62 /* The rectangle that includes all dirty rectangles. */ 63 int32_t xLeft; 64 int32_t xRight; 65 int32_t yTop; 66 int32_t yBottom; 67 } dirtyRect; 68 69 } DISPLAYFBINFO; 31 70 32 71 class ATL_NO_VTABLE Display : … … 59 98 60 99 // public methods only for internal purposes 61 int handleDisplayResize (u int32_t bpp, void *pvVRAM, uint32_t cbLine, int w, int h);100 int handleDisplayResize (unsigned uScreenId, uint32_t bpp, void *pvVRAM, uint32_t cbLine, int w, int h); 62 101 void handleDisplayUpdate (int x, int y, int cx, int cy); 63 102 IFramebuffer *getFramebuffer() 64 103 { 65 return m Framebuffer;104 return maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].pFramebuffer; 66 105 } 67 106 … … 138 177 STDMETHOD(UnlockFramebuffer)(); 139 178 STDMETHOD(RegisterExternalFramebuffer)(IFramebuffer *frameBuf); 179 STDMETHOD(SetFramebuffer)(ULONG aScreenId, IFramebuffer * aFramebuffer); 180 STDMETHOD(QueryFramebuffer)(ULONG aScreenId, IFramebuffer * * aFramebuffer, LONG * aXOrigin, LONG * aYOrigin); 140 181 STDMETHOD(SetVideoModeHint)(ULONG width, ULONG height, ULONG colorDepth, ULONG display); 141 182 STDMETHOD(TakeScreenShot)(BYTE *address, ULONG width, ULONG height); 142 183 STDMETHOD(DrawToScreen)(BYTE *address, ULONG x, ULONG y, ULONG width, ULONG height); 143 184 STDMETHOD(InvalidateAndUpdate)(); 144 STDMETHOD(ResizeCompleted)( );185 STDMETHOD(ResizeCompleted)(ULONG aScreenId); 145 186 STDMETHOD(UpdateCompleted)(); 146 187 … … 155 196 156 197 static DECLCALLBACK(int) changeFramebuffer (Display *that, IFramebuffer *aFB, 157 bool aInternal );198 bool aInternal, unsigned uScreenId); 158 199 159 200 static DECLCALLBACK(void*) drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface); … … 166 207 static DECLCALLBACK(void) displayResetCallback(PPDMIDISPLAYCONNECTOR pInterface); 167 208 static DECLCALLBACK(void) displayLFBModeChangeCallback(PPDMIDISPLAYCONNECTOR pInterface, bool fEnabled); 209 static DECLCALLBACK(void) displayProcessAdapterDataCallback(PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, uint32_t u32VRAMSize); 210 static DECLCALLBACK(void) displayProcessDisplayDataCallback(PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, unsigned uScreenId); 168 211 169 212 ComObjPtr <Console, ComWeakRef> mParent; … … 175 218 bool mfVMMDevInited; 176 219 bool mInternalFramebuffer; 177 ComPtr<IFramebuffer> mFramebuffer; 220 // ComPtr<IFramebuffer> mFramebuffer; 221 222 unsigned mcMonitors; 223 DISPLAYFBINFO maFramebuffers[SchemaDefs::MaxGuestMonitors]; 224 178 225 bool mFramebufferOpened; 179 226 /** bitmask of acceleration operations supported by current framebuffer */ … … 206 253 207 254 void handleResizeCompletedEMT (void); 208 volatile uint32_t mu32ResizeStatus; 209 210 enum { 211 ResizeStatus_Void, 212 ResizeStatus_InProgress, 213 ResizeStatus_UpdateDisplayData 214 }; 255 // volatile uint32_t mu32ResizeStatus; 215 256 }; 216 257 -
trunk/src/VBox/Main/include/FramebufferImpl.h
r2981 r3153 63 63 ULONG w, ULONG h, 64 64 BOOL *finished); 65 STDMETHOD(RequestResize)( FramebufferPixelFormat_T pixelFormat, BYTE *vram,65 STDMETHOD(RequestResize)(ULONG uScreenId, FramebufferPixelFormat_T pixelFormat, BYTE *vram, 66 66 ULONG lineSize, ULONG w, ULONG h, 67 67 BOOL *finished);
Note:
See TracChangeset
for help on using the changeset viewer.