Changeset 49167 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Oct 17, 2013 6:17:16 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 90040
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/runtime
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
r48705 r49167 1 1 /* $Id$ */ 2 2 /** @file 3 * 4 * VBox frontends: Qt GUI ("VirtualBox"): 5 * UIFrameBuffer class and subclasses implementation 3 * VBox Qt GUI - UIFrameBuffer class implementation. 6 4 */ 7 5 … … 46 44 : m_pMachineView(pMachineView) 47 45 , m_width(0), m_height(0) 48 , m_fIs ScheduledToDelete(false)46 , m_fIsMarkedAsUnused(false) 49 47 #ifdef Q_OS_WIN 50 48 , m_iRefCnt(0) … … 52 50 { 53 51 /* Assign mahine-view: */ 54 AssertMsg(m_pMachineView, ("UIMachineView must not be null\n"));52 AssertMsg(m_pMachineView, ("UIMachineView must not be NULL\n")); 55 53 m_WinId = (m_pMachineView && m_pMachineView->viewport()) ? (LONG64)m_pMachineView->viewport()->winId() : 0; 54 55 /* Initialize critical-section: */ 56 int rc = RTCritSectInit(&m_critSect); 57 AssertRC(rc); 56 58 57 59 /* Connect handlers: */ 58 60 if (m_pMachineView) 59 61 prepareConnections(); 60 61 /* Initialize critical-section: */62 int rc = RTCritSectInit(&m_critSect);63 AssertRC(rc);64 62 } 65 63 66 64 UIFrameBuffer::~UIFrameBuffer() 67 65 { 68 /* Deinitialize critical-section: */69 RTCritSectDelete(&m_critSect);70 71 66 /* Disconnect handlers: */ 72 67 if (m_pMachineView) 73 68 cleanupConnections(); 69 70 /* Deinitialize critical-section: */ 71 RTCritSectDelete(&m_critSect); 72 } 73 74 /** 75 * Checks if the framebuffer marked as <b>unused</b>. 76 * @returns @c true if framebuffer ingores EMT events, @c false otherwise. 77 * @note Any call to this (and #setMarkAsUnused method) is synchronized between calling threads. 78 */ 79 bool UIFrameBuffer::isMarkedAsUnused() const 80 { 81 lock(); 82 bool fIsMarkedAsUnused = m_fIsMarkedAsUnused; 83 unlock(); 84 return fIsMarkedAsUnused; 85 } 86 87 /** 88 * Sets the framebuffer <b>unused</b> status. 89 * @param fIsMarkAsUnused determines whether framebuffer should ignore EMT events or not. 90 * @note Any call to this (and #isMarkedAsUnused method) is synchronized between calling threads. 91 */ 92 void UIFrameBuffer::setMarkAsUnused(bool fIsMarkAsUnused) 93 { 94 lock(); 95 m_fIsMarkedAsUnused = fIsMarkAsUnused; 96 unlock(); 74 97 } 75 98 … … 180 203 (unsigned long)uWidth, (unsigned long)uHeight)); 181 204 182 /* Make sure frame-buffer is not yet scheduled for removal: */ 183 if (m_fIsScheduledToDelete) 205 /* Make sure result pointer is valid: */ 206 if (!pbFinished) 207 return E_POINTER; 208 209 /* Make sure frame-buffer is used: */ 210 if (isMarkedAsUnused()) 211 { 212 LogRelFlow(("UIFrameBuffer::RequestResize: Ignored!\n")); 213 214 /* Mark request as finished. 215 * It is required to report to the VM thread that we finished resizing and rely on the 216 * later synchronisation when the new view is attached. */ 217 *pbFinished = TRUE; 218 219 /* Ignore RequestResize: */ 184 220 return E_FAIL; 185 186 /* Currently screen ID is not used: */ 187 Q_UNUSED(uScreenId); 221 } 188 222 189 223 /* Mark request as not-yet-finished: */ 190 224 *pbFinished = FALSE; 191 225 192 /* See comment in setView(): */ 193 lock(); 194 195 /* Widget resize is NOT thread safe and never will be, 196 * We have to notify the machine-view with the async signal to perform resize operation. */ 197 if (m_pMachineView) 198 emit sigRequestResize(uPixelFormat, pVRAM, uBitsPerPixel, uBytesPerLine, uWidth, uHeight); 199 else 200 /* Mark request as finished. 201 * It is required to report to the VM thread that we finished resizing and rely on the 202 * synchronisation when the new view is attached. */ 203 *pbFinished = TRUE; 204 205 /* Unlock thread finally: */ 206 unlock(); 226 /* Widget resize is NOT thread-safe and *probably* never will be, 227 * We have to notify machine-view with the async-signal to perform resize operation. */ 228 LogRelFlow(("UIFrameBuffer::RequestResize: Sending to async-handler...\n")); 229 emit sigRequestResize(uPixelFormat, pVRAM, uBitsPerPixel, uBytesPerLine, uWidth, uHeight); 207 230 208 231 /* Confirm RequestResize: */ … … 212 235 STDMETHODIMP UIFrameBuffer::NotifyUpdate(ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight) 213 236 { 214 LogRelFlow(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu\n", 215 (unsigned long)uX, (unsigned long)uY, 216 (unsigned long)uWidth, (unsigned long)uHeight)); 217 218 /* Make sure frame-buffer is not yet scheduled for removal: */ 219 if (m_fIsScheduledToDelete) 237 LogRel2(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu\n", 238 (unsigned long)uX, (unsigned long)uY, 239 (unsigned long)uWidth, (unsigned long)uHeight)); 240 241 /* Make sure frame-buffer is used: */ 242 if (isMarkedAsUnused()) 243 { 244 LogRel2(("UIFrameBuffer::NotifyUpdate: Ignored!\n")); 245 246 /* Ignore NotifyUpdate: */ 220 247 return E_FAIL; 221 222 /* See comment in setView(): */ 223 lock(); 224 225 /* QWidget::update() is NOT thread safe and seems never will be, 226 * So we have to notify the machine-view with the async signal to perform update operation. */ 227 if (m_pMachineView) 228 emit sigNotifyUpdate(uX, uY, uWidth, uHeight); 229 230 /* Unlock thread finally: */ 231 unlock(); 248 } 249 250 /* Widget update is NOT thread-safe and *seems* never will be, 251 * We have to notify machine-view with the async-signal to perform update operation. */ 252 LogRel2(("UIFrameBuffer::NotifyUpdate: Sending to async-handler...\n")); 253 emit sigNotifyUpdate(uX, uY, uWidth, uHeight); 232 254 233 255 /* Confirm NotifyUpdate: */ … … 237 259 STDMETHODIMP UIFrameBuffer::VideoModeSupported(ULONG uWidth, ULONG uHeight, ULONG uBPP, BOOL *pbSupported) 238 260 { 239 LogRelFlow(("UIFrameBuffer::VideoModeSupported: Mode: BPP=%lu, Size=%lux%lu\n", 240 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight)); 241 242 /* Make sure frame-buffer is not yet scheduled for removal: */ 243 if (m_fIsScheduledToDelete) 261 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu\n", 262 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight)); 263 264 /* Make sure frame-buffer is used: */ 265 if (isMarkedAsUnused()) 266 { 267 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Ignored!\n")); 268 269 /* Ignore VideoModeSupported: */ 244 270 return E_FAIL; 245 271 } 272 273 /* Make sure result pointer is valid: */ 246 274 if (!pbSupported) 247 275 return E_POINTER; 276 277 /* Determine if supported: */ 248 278 *pbSupported = TRUE; 249 250 /* Currently BPP is not used: */ 251 Q_UNUSED(uBPP); 252 253 /* See comment in setView(): */ 254 lock(); 255 256 QSize screenSize; 257 if (m_pMachineView) 258 screenSize = m_pMachineView->maxGuestSize(); 259 260 /* Unlock thread finally: */ 261 unlock(); 262 279 QSize screenSize = m_pMachineView->maxGuestSize(); 263 280 if ( (screenSize.width() != 0) 264 281 && (uWidth > (ULONG)screenSize.width()) 265 282 && (uWidth > (ULONG)width())) 266 283 *pbSupported = FALSE; 267 268 284 if ( (screenSize.height() != 0) 269 285 && (uHeight > (ULONG)screenSize.height()) … … 271 287 *pbSupported = FALSE; 272 288 273 LogRelFlow(("UIFrameBuffer::VideoModeSupported: Verdict: Supported=%s\n", 274 *pbSupported ? "TRUE" : "FALSE")); 289 LogRel2(("UIFrameBuffer::IsVideoModeSupported: %s\n", *pbSupported ? "TRUE" : "FALSE")); 275 290 276 291 /* Confirm VideoModeSupported: */ … … 293 308 STDMETHODIMP UIFrameBuffer::SetVisibleRegion(BYTE *pRectangles, ULONG uCount) 294 309 { 295 LogRelFlow(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu\n", (unsigned long)uCount)); 296 297 /* Make sure frame-buffer is not yet scheduled for removal: */ 298 if (m_fIsScheduledToDelete) 310 LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu\n", 311 (unsigned long)uCount)); 312 313 /* Make sure frame-buffer is used: */ 314 if (isMarkedAsUnused()) 315 { 316 LogRel2(("UIFrameBuffer::SetVisibleRegion: Ignored!\n")); 317 318 /* Ignore SetVisibleRegion: */ 299 319 return E_FAIL; 320 } 300 321 301 322 /* Make sure rectangles were passed: */ … … 320 341 } 321 342 322 /* See comment in setView(): */323 lock();324 325 343 /* We are directly updating synchronous visible-region: */ 326 344 m_syncVisibleRegion = region; 327 /* And send async signal to update asynchronous one: */ 328 if (m_pMachineView) 329 emit sigSetVisibleRegion(region); 330 331 /* Unlock thread finally: */ 332 unlock(); 345 /* And send async-signal to update asynchronous one: */ 346 LogRel2(("UIFrameBuffer::SetVisibleRegion: Sending to async-handler...\n")); 347 emit sigSetVisibleRegion(region); 333 348 334 349 /* Confirm SetVisibleRegion: */ … … 344 359 STDMETHODIMP UIFrameBuffer::Notify3DEvent(ULONG uType, BYTE *pData) 345 360 { 361 LogRel2(("UIFrameBuffer::Notify3DEvent\n")); 362 363 /* Make sure frame-buffer is used: */ 364 if (isMarkedAsUnused()) 365 { 366 LogRel2(("UIFrameBuffer::Notify3DEvent: Ignored!\n")); 367 368 /* Ignore Notify3DEvent: */ 369 return E_FAIL; 370 } 371 346 372 switch (uType) 347 373 { 348 374 case VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA: 349 375 { 350 /* Notify GUI about 3D overlay visibility change: */ 376 /* Notify machine-view with the async-signal 377 * about 3D overlay visibility change: */ 351 378 BOOL fVisible = !!pData; 352 LogRel Flow(("UIFrameBuffer::Notify3DEvent: "353 "VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA=%s\n",354 379 LogRel2(("UIFrameBuffer::Notify3DEvent: Sending to async-handler: " 380 "(VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA = %s)\n", 381 fVisible ? "TRUE" : "FALSE")); 355 382 emit sigNotifyAbout3DOverlayVisibilityChange(fVisible); 383 384 /* Confirm Notify3DEvent: */ 356 385 return S_OK; 357 386 } 358 387 default: 359 return E_INVALIDARG; 360 } 388 break; 389 } 390 391 /* Ignore Notify3DEvent: */ 392 return E_INVALIDARG; 361 393 } 362 394 … … 392 424 void UIFrameBuffer::setView(UIMachineView * pView) 393 425 { 394 /* We are not supposed to use locking for things which are done395 * on the GUI thread. Unfortunately I am not clever enough to396 * understand the original author's wise synchronisation logic397 * so I will do it anyway. */398 lock();399 400 426 /* Disconnect handlers: */ 401 427 if (m_pMachineView) … … 409 435 if (m_pMachineView) 410 436 prepareConnections(); 411 412 /* Unlock thread finally: */413 unlock();414 437 } 415 438 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
r47493 r49167 1 1 /** @file 2 * 3 * VBox frontends: Qt GUI ("VirtualBox"): 4 * UIFrameBuffer class and subclasses declarations 2 * VBox Qt GUI - UIFrameBuffer class declaration. 5 3 */ 6 4 … … 106 104 virtual ~UIFrameBuffer(); 107 105 108 void setScheduledToDelete(bool fIsScheduledToDelete) { m_fIsScheduledToDelete = fIsScheduledToDelete; } 106 /* API: [Un]used status stuff: */ 107 bool isMarkedAsUnused() const; 108 void setMarkAsUnused(bool fIsMarkAsUnused); 109 109 110 110 NS_DECL_ISUPPORTS … … 180 180 } 181 181 182 void lock() { RTCritSectEnter(&m_critSect); }183 void unlock() { RTCritSectLeave(&m_critSect); }182 void lock() const { RTCritSectEnter(&m_critSect); } 183 void unlock() const { RTCritSectLeave(&m_critSect); } 184 184 185 185 virtual uchar *address() = 0; … … 209 209 210 210 UIMachineView *m_pMachineView; 211 RTCRITSECT m_critSect;211 mutable RTCRITSECT m_critSect; 212 212 ulong m_width; 213 213 ulong m_height; 214 214 QSize m_scaledSize; 215 215 int64_t m_WinId; 216 bool m_fIs ScheduledToDelete;216 bool m_fIsMarkedAsUnused; 217 217 218 218 /* To avoid a seamless flicker, -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
r49008 r49167 284 284 /* Emit a signal about guest was resized: */ 285 285 emit resizeHintDone(); 286 287 LogRelFlow(("UIMachineView::ResizeHandled: " 288 "Screen=%d, Format=%d, " 289 "BitsPerPixel=%d, BytesPerLine=%d, " 290 "Size=%dx%d.\n\n", 291 (unsigned long)m_uScreenId, iPixelFormat, 292 iBitsPerPixel, iBytesPerLine, iWidth, iHeight)); 286 293 } 287 294 … … 412 419 case QImageMode: 413 420 { 414 UIFrameBuffer *pFrameBuffer = uisession()->frameBuffer(screenId());421 UIFrameBuffer *pFrameBuffer = uisession()->frameBuffer(screenId()); 415 422 if (pFrameBuffer) 423 { 416 424 pFrameBuffer->setView(this); 425 /* Mark framebuffer as used again: */ 426 LogRelFlow(("UIMachineView::prepareFrameBuffer: Start EMT callbacks accepting for screen: %d.\n", screenId())); 427 pFrameBuffer->setMarkAsUnused(false); 428 } 417 429 else 418 430 { … … 442 454 /* Indicate that we are doing all drawing stuff ourself: */ 443 455 viewport()->setAttribute(Qt::WA_PaintOnScreen); 444 UIFrameBuffer *pFrameBuffer = uisession()->frameBuffer(screenId());456 UIFrameBuffer *pFrameBuffer = uisession()->frameBuffer(screenId()); 445 457 if (pFrameBuffer) 458 { 446 459 pFrameBuffer->setView(this); 460 /* Mark framebuffer as used again: */ 461 LogRelFlow(("UIMachineView::prepareFrameBuffer: Start EMT callbacks accepting for screen: %d.\n", screenId())); 462 pFrameBuffer->setMarkAsUnused(false); 463 } 447 464 else 448 465 { … … 595 612 void UIMachineView::cleanupFrameBuffer() 596 613 { 597 if (m_pFrameBuffer) 598 { 599 /* Process pending frame-buffer resize events: */ 600 QApplication::sendPostedEvents(this, ResizeEventType); 601 if ( 0 602 #ifdef VBOX_GUI_USE_QIMAGE 603 || vboxGlobal().vmRenderMode() == QImageMode 604 #endif /* VBOX_GUI_USE_QIMAGE */ 605 #ifdef VBOX_GUI_USE_QUARTZ2D 606 || vboxGlobal().vmRenderMode() == Quartz2DMode 607 #endif /* VBOX_GUI_USE_QUARTZ2D */ 608 #ifdef VBOX_WITH_VIDEOHWACCEL 609 || m_fAccelerate2DVideo 610 #endif /* VBOX_WITH_VIDEOHWACCEL */ 611 ) 612 { 613 Assert(m_pFrameBuffer == uisession()->frameBuffer(screenId())); 614 CDisplay display = session().GetConsole().GetDisplay(); 615 /* Temporarily remove the framebuffer in Display while unsetting 616 * the view in order to respect the thread synchonisation logic 617 * (see UIFrameBuffer.h). */ 618 /* Note! VBOX_WITH_CROGL additionally requires us to call 619 * SetFramebuffer to ensure 3D gets notified of view being 620 * destroyed */ 621 display.SetFramebuffer(m_uScreenId, CFramebuffer(NULL)); 622 m_pFrameBuffer->setView(NULL); 623 display.SetFramebuffer(m_uScreenId, CFramebuffer(m_pFrameBuffer)); 624 } 625 else 626 { 627 /* Warn framebuffer about its no more necessary: */ 628 m_pFrameBuffer->setScheduledToDelete(true); 629 /* Detach framebuffer from Display: */ 630 CDisplay display = session().GetConsole().GetDisplay(); 631 display.SetFramebuffer(m_uScreenId, CFramebuffer(NULL)); 632 /* Release the reference: */ 633 m_pFrameBuffer->Release(); 634 // delete m_pFrameBuffer; // TODO_NEW_CORE: possibly necessary to really cleanup 635 m_pFrameBuffer = NULL; 636 } 637 } 614 /* Make sure proper framebuffer assigned: */ 615 AssertReturnVoid(m_pFrameBuffer); 616 AssertReturnVoid(m_pFrameBuffer == uisession()->frameBuffer(screenId())); 617 618 /* Mark framebuffer as unused: */ 619 LogRelFlow(("UIMachineView::cleanupFrameBuffer: Stop EMT callbacks accepting for screen: %d.\n", screenId())); 620 m_pFrameBuffer->setMarkAsUnused(true); 621 622 /* Process pending framebuffer events: */ 623 QApplication::sendPostedEvents(this, QEvent::MetaCall); 624 625 /* Temporarily detach the framebuffer from IDisplay before detaching 626 * from view in order to respect the thread synchonisation logic (see UIFrameBuffer.h). 627 * Note: VBOX_WITH_CROGL additionally requires us to call SetFramebuffer 628 * to ensure 3D gets notified of view being destroyed... */ 629 CDisplay display = session().GetConsole().GetDisplay(); 630 display.SetFramebuffer(m_uScreenId, CFramebuffer(NULL)); 631 632 /* Detach framebuffer from view: */ 633 m_pFrameBuffer->setView(NULL); 634 635 /* Attach frambuffer back to IDisplay: */ 636 display.SetFramebuffer(m_uScreenId, CFramebuffer(m_pFrameBuffer)); 638 637 } 639 638 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
r49121 r49167 1150 1150 if (pFb) 1151 1151 { 1152 /* Warn framebuffer about its no more necessary: */1153 pFb->set ScheduledToDelete(true);1152 /* Mark framebuffer as unused: */ 1153 pFb->setMarkAsUnused(true); 1154 1154 /* Detach framebuffer from Display: */ 1155 1155 CDisplay display = session().GetConsole().GetDisplay(); 1156 1156 display.SetFramebuffer(i, CFramebuffer(NULL)); 1157 /* Release thereference: */1157 /* Release framebuffer reference: */ 1158 1158 pFb->Release(); 1159 1159 }
Note:
See TracChangeset
for help on using the changeset viewer.