Changeset 51487 in vbox for trunk/src/VBox
- Timestamp:
- Jun 2, 2014 2:15:35 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 94096
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp
r51401 r51487 4400 4400 { 4401 4401 /* we do not to miss notify updates, because we have to update bg textures for it, 4402 * so no not check for m_f IsMarkedAsUnused here,4402 * so no not check for m_fUnused here, 4403 4403 * mOverlay will store the required info for us */ 4404 4404 QRect r(aX, aY, aW, aH); -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h
r51459 r51487 1839 1839 T::lock(); 1840 1840 /* Make sure frame-buffer is used: */ 1841 if (T::m_f IsMarkedAsUnused)1841 if (T::m_fUnused) 1842 1842 { 1843 1843 LogRel2(("ProcessVHWACommand: Postponed!\n")); … … 1869 1869 T::lock(); 1870 1870 /* Make sure frame-buffer is used: */ 1871 if (T::m_f IsMarkedAsUnused)1871 if (T::m_fUnused) 1872 1872 { 1873 1873 LogRel2(("NotifyUpdate: Ignored!\n")); -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
r51459 r51487 5 5 6 6 /* 7 * Copyright (C) 2010-201 3Oracle Corporation7 * Copyright (C) 2010-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 # include "precomp.h" 20 20 #else /* !VBOX_WITH_PRECOMPILED_HEADERS */ 21 22 21 /* GUI includes: */ 22 # include "UIFrameBuffer.h" 23 23 # include "UIMachineView.h" 24 # include "UIFrameBuffer.h"25 24 # include "UIMessageCenter.h" 26 25 # include "VBoxGlobal.h" … … 28 27 # include "UIMachineWindow.h" 29 28 # endif /* !VBOX_WITH_TRANSLUCENT_SEAMLESS */ 30 29 /* COM includes: */ 30 #include "CConsole.h" 31 #include "CDisplay.h" 31 32 /* Other VBox includes: */ 32 33 # include <VBox/VBoxVideo3D.h> 33 34 34 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 35 35 36 #include "CConsole.h" 37 #include "CDisplay.h" 38 39 #if defined (Q_OS_WIN32) 36 /* COM stuff: */ 37 #ifdef Q_WS_WIN 40 38 static CComModule _Module; 41 #else 42 NS_DECL_CLASSINFO 43 NS_IMPL_THREADSAFE_ISUPPORTS1_CI 44 #endif 39 #else /* !Q_WS_WIN */ 40 NS_DECL_CLASSINFO(UIFrameBuffer) 41 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(UIFrameBuffer, IFramebuffer) 42 #endif /* !Q_WS_WIN */ 45 43 46 44 UIFrameBuffer::UIFrameBuffer(UIMachineView *pMachineView) 47 45 : m_pMachineView(pMachineView) 48 46 , m_width(0), m_height(0) 49 , m_f IsMarkedAsUnused(false)50 , m_f IsAutoEnabled(false)47 , m_fUnused(false) 48 , m_fAutoEnabled(false) 51 49 , m_fIsUpdatesAllowed(true) 52 50 #ifdef Q_OS_WIN … … 58 56 /* Assign mahine-view: */ 59 57 AssertMsg(m_pMachineView, ("UIMachineView must not be NULL\n")); 60 m_WinId = (m_pMachineView && m_pMachineView->viewport()) ? (LONG64)m_pMachineView->viewport()->winId() : 0; 58 /* Cache window ID: */ 59 m_winId = (m_pMachineView && m_pMachineView->viewport()) ? (LONG64)m_pMachineView->viewport()->winId() : 0; 61 60 62 61 /* Initialize critical-section: */ … … 79 78 } 80 79 81 /** 82 * Sets the framebuffer <b>unused</b> status. 83 * @param fIsMarkAsUnused determines whether framebuffer should ignore EMT events or not. 84 * @note Call to this (and any EMT callback) method is synchronized between calling threads (from GUI side). 85 */ 86 void UIFrameBuffer::setMarkAsUnused(bool fIsMarkAsUnused) 87 { 88 lock(); 89 m_fIsMarkedAsUnused = fIsMarkAsUnused; 90 unlock(); 91 } 92 93 /** 94 * Returns the framebuffer <b>auto-enabled</b> status. 95 * @returns @c true if guest-screen corresponding to this framebuffer was automatically enabled by 96 the auto-mount guest-screen auto-pilot, @c false otherwise. 97 * @note <i>Auto-enabled</i> status means the framebuffer was automatically enabled by the multi-screen layout 98 * and so have potentially incorrect guest size hint posted into guest event queue. Machine-view will try to 99 * automatically adjust guest-screen size as soon as possible. 100 */ 101 bool UIFrameBuffer::isAutoEnabled() const 102 { 103 return m_fIsAutoEnabled; 104 } 105 106 /** 107 * Sets the framebuffer <b>auto-enabled</b> status. 108 * @param fIsAutoEnabled determines whether guest-screen corresponding to this framebuffer 109 * was automatically enabled by the auto-mount guest-screen auto-pilot. 110 * @note <i>Auto-enabled</i> status means the framebuffer was automatically enabled by the multi-screen layout 111 * and so have potentially incorrect guest size hint posted into guest event queue. Machine-view will try to 112 * automatically adjust guest-screen size as soon as possible. 113 */ 114 void UIFrameBuffer::setAutoEnabled(bool fIsAutoEnabled) 115 { 116 m_fIsAutoEnabled = fIsAutoEnabled; 117 } 118 119 STDMETHODIMP UIFrameBuffer::COMGETTER(Address) (BYTE **ppAddress) 80 void UIFrameBuffer::setView(UIMachineView *pMachineView) 81 { 82 /* Disconnect old handlers: */ 83 if (m_pMachineView) 84 cleanupConnections(); 85 86 /* Reassign machine-view: */ 87 m_pMachineView = pMachineView; 88 /* Recache window ID: */ 89 m_winId = (m_pMachineView && m_pMachineView->viewport()) ? (LONG64)m_pMachineView->viewport()->winId() : 0; 90 91 /* Connect new handlers: */ 92 if (m_pMachineView) 93 prepareConnections(); 94 } 95 96 void UIFrameBuffer::setMarkAsUnused(bool fUnused) 97 { 98 lock(); 99 m_fUnused = fUnused; 100 unlock(); 101 } 102 103 STDMETHODIMP UIFrameBuffer::COMGETTER(Address)(BYTE **ppAddress) 120 104 { 121 105 if (!ppAddress) … … 125 109 } 126 110 127 STDMETHODIMP UIFrameBuffer::COMGETTER(Width) 111 STDMETHODIMP UIFrameBuffer::COMGETTER(Width)(ULONG *puWidth) 128 112 { 129 113 if (!puWidth) … … 133 117 } 134 118 135 STDMETHODIMP UIFrameBuffer::COMGETTER(Height) 119 STDMETHODIMP UIFrameBuffer::COMGETTER(Height)(ULONG *puHeight) 136 120 { 137 121 if (!puHeight) … … 141 125 } 142 126 143 STDMETHODIMP UIFrameBuffer::COMGETTER(BitsPerPixel) 127 STDMETHODIMP UIFrameBuffer::COMGETTER(BitsPerPixel)(ULONG *puBitsPerPixel) 144 128 { 145 129 if (!puBitsPerPixel) … … 149 133 } 150 134 151 STDMETHODIMP UIFrameBuffer::COMGETTER(BytesPerLine) 135 STDMETHODIMP UIFrameBuffer::COMGETTER(BytesPerLine)(ULONG *puBytesPerLine) 152 136 { 153 137 if (!puBytesPerLine) … … 157 141 } 158 142 159 STDMETHODIMP UIFrameBuffer::COMGETTER(PixelFormat) 143 STDMETHODIMP UIFrameBuffer::COMGETTER(PixelFormat)(ULONG *puPixelFormat) 160 144 { 161 145 if (!puPixelFormat) … … 165 149 } 166 150 167 STDMETHODIMP UIFrameBuffer::COMGETTER(UsesGuestVRAM) 151 STDMETHODIMP UIFrameBuffer::COMGETTER(UsesGuestVRAM)(BOOL *pbUsesGuestVRAM) 168 152 { 169 153 if (!pbUsesGuestVRAM) … … 173 157 } 174 158 175 STDMETHODIMP UIFrameBuffer::COMGETTER(HeightReduction) 159 STDMETHODIMP UIFrameBuffer::COMGETTER(HeightReduction)(ULONG *puHeightReduction) 176 160 { 177 161 if (!puHeightReduction) … … 181 165 } 182 166 183 STDMETHODIMP UIFrameBuffer::COMGETTER(Overlay) 167 STDMETHODIMP UIFrameBuffer::COMGETTER(Overlay)(IFramebufferOverlay **ppOverlay) 184 168 { 185 169 if (!ppOverlay) 186 170 return E_POINTER; 187 /* not yet implemented */188 171 *ppOverlay = 0; 189 172 return S_OK; 190 173 } 191 174 192 STDMETHODIMP UIFrameBuffer::COMGETTER(WinId) 175 STDMETHODIMP UIFrameBuffer::COMGETTER(WinId)(LONG64 *pWinId) 193 176 { 194 177 if (!pWinId) 195 178 return E_POINTER; 196 *pWinId = m_ WinId;179 *pWinId = m_winId; 197 180 return S_OK; 198 181 } … … 210 193 } 211 194 212 /** 213 * EMT callback: Requests a size and pixel format change. 214 * @param uScreenId Guest screen number. Must be used in the corresponding call to CDisplay::ResizeCompleted if this call is made. 215 * @param uPixelFormat Pixel format of the memory buffer pointed to by @a pVRAM. 216 * @param pVRAM Pointer to the virtual video card's VRAM (may be <i>null</i>). 217 * @param uBitsPerPixel Color depth, bits per pixel. 218 * @param uBytesPerLine Size of one scan line, in bytes. 219 * @param uWidth Width of the guest display, in pixels. 220 * @param uHeight Height of the guest display, in pixels. 221 * @param pfFinished Can the VM start using the new frame buffer immediately after this method returns or it should wait for CDisplay::ResizeCompleted. 222 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed. 223 * @note Calls to this and #setMarkAsUnused method are synchronized between calling threads (from GUI side). 224 */ 225 STDMETHODIMP UIFrameBuffer::RequestResize(ULONG uScreenId, ULONG uPixelFormat, 226 BYTE *pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine, 227 ULONG uWidth, ULONG uHeight, 228 BOOL *pfFinished) 229 { 230 /* Make sure result pointer is valid: */ 231 if (!pfFinished) 232 { 233 LogRel(("UIFrameBuffer::RequestResize: " 234 "Screen=%lu, Format=%lu, " 235 "BitsPerPixel=%lu, BytesPerLine=%lu, " 236 "Size=%lux%lu, Invalid pfFinished pointer!\n", 237 (unsigned long)uScreenId, (unsigned long)uPixelFormat, 238 (unsigned long)uBitsPerPixel, (unsigned long)uBytesPerLine, 195 STDMETHODIMP UIFrameBuffer::NotifyChange(ULONG uScreenId, ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight) 196 { 197 /* Lock access to frame-buffer: */ 198 lock(); 199 200 /* Make sure frame-buffer is used: */ 201 if (m_fUnused) 202 { 203 LogRel(("UIFrameBuffer::NotifyChange: Screen=%lu, Origin=%lux%lu, Size=%lux%lu, Ignored!\n", 204 (unsigned long)uScreenId, 205 (unsigned long)uX, (unsigned long)uY, 239 206 (unsigned long)uWidth, (unsigned long)uHeight)); 240 241 return E_POINTER;242 }243 244 /* Lock access to frame-buffer: */245 lock();246 247 /* Make sure frame-buffer is used: */248 if (m_fIsMarkedAsUnused)249 {250 LogRel(("UIFrameBuffer::RequestResize: "251 "Screen=%lu, Format=%lu, "252 "BitsPerPixel=%lu, BytesPerLine=%lu, "253 "Size=%lux%lu, Ignored!\n",254 (unsigned long)uScreenId, (unsigned long)uPixelFormat,255 (unsigned long)uBitsPerPixel, (unsigned long)uBytesPerLine,256 (unsigned long)uWidth, (unsigned long)uHeight));257 258 /* Mark request as finished.259 * It is required to report to the VM thread that we finished resizing and rely on the260 * later synchronisation when the new view is attached. */261 *pfFinished = TRUE;262 207 263 208 /* Unlock access to frame-buffer: */ 264 209 unlock(); 265 210 266 /* Ignore RequestResize: */211 /* Ignore NotifyChange: */ 267 212 return E_FAIL; 268 213 } 269 214 270 /* Mark request as not-yet-finished: */ 271 *pfFinished = FALSE; 215 /* Acquire new pending bitmap: */ 216 m_pendingSourceBitmap = 0; 217 m_pMachineView->session().GetConsole().GetDisplay().QuerySourceBitmap(uScreenId, m_pendingSourceBitmap); 272 218 273 219 /* Widget resize is NOT thread-safe and *probably* never will be, 274 220 * We have to notify machine-view with the async-signal to perform resize operation. */ 275 LogRel(("UIFrameBuffer::RequestResize: " 276 "Screen=%lu, Format=%lu, " 277 "BitsPerPixel=%lu, BytesPerLine=%lu, " 278 "Size=%lux%lu, Sending to async-handler..\n", 279 (unsigned long)uScreenId, (unsigned long)uPixelFormat, 280 (unsigned long)uBitsPerPixel, (unsigned long)uBytesPerLine, 221 LogRel(("UIFrameBuffer::NotifyChange: Screen=%lu, Origin=%lux%lu, Size=%lux%lu, Sending to async-handler..\n", 222 (unsigned long)uScreenId, 223 (unsigned long)uX, (unsigned long)uY, 281 224 (unsigned long)uWidth, (unsigned long)uHeight)); 282 emit sig RequestResize(uPixelFormat, pVRAM, uBitsPerPixel, uBytesPerLine, uWidth, uHeight);225 emit sigNotifyChange(uScreenId, uWidth, uHeight); 283 226 284 227 /* Unlock access to frame-buffer: */ 285 228 unlock(); 286 229 287 /* Confirm RequestResize: */ 288 return S_OK; 230 /* Give up control token to other thread: */ 231 RTThreadYield(); 232 233 /* Confirm NotifyChange: */ 234 return S_OK; 235 } 236 237 STDMETHODIMP UIFrameBuffer::NotifyUpdate(ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight) 238 { 239 /* Retina screens with physical-to-logical scaling requires 240 * odd/even pixel updates to be taken into account, 241 * otherwise we have artifacts on the borders of incoming rectangle. */ 242 uX = qMax(0, (int)uX - 1); 243 uY = qMax(0, (int)uY - 1); 244 uWidth = qMin((int)m_width, (int)uWidth + 2); 245 uHeight = qMin((int)m_height, (int)uHeight + 2); 246 247 /* Lock access to frame-buffer: */ 248 lock(); 249 250 /* Make sure frame-buffer is used: */ 251 if (m_fUnused) 252 { 253 LogRel2(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu, Ignored!\n", 254 (unsigned long)uX, (unsigned long)uY, 255 (unsigned long)uWidth, (unsigned long)uHeight)); 256 257 /* Unlock access to frame-buffer: */ 258 unlock(); 259 260 /* Ignore NotifyUpdate: */ 261 return E_FAIL; 262 } 263 264 /* Widget update is NOT thread-safe and *seems* never will be, 265 * We have to notify machine-view with the async-signal to perform update operation. */ 266 LogRel2(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu, Sending to async-handler..\n", 267 (unsigned long)uX, (unsigned long)uY, 268 (unsigned long)uWidth, (unsigned long)uHeight)); 269 emit sigNotifyUpdate(uX, uY, uWidth, uHeight); 270 271 /* Unlock access to frame-buffer: */ 272 unlock(); 273 274 /* Confirm NotifyUpdate: */ 275 return S_OK; 276 } 277 278 STDMETHODIMP UIFrameBuffer::VideoModeSupported(ULONG uWidth, ULONG uHeight, ULONG uBPP, BOOL *pfSupported) 279 { 280 /* Make sure result pointer is valid: */ 281 if (!pfSupported) 282 { 283 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu, Invalid pfSupported pointer!\n", 284 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight)); 285 286 return E_POINTER; 287 } 288 289 /* Lock access to frame-buffer: */ 290 lock(); 291 292 /* Make sure frame-buffer is used: */ 293 if (m_fUnused) 294 { 295 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu, Ignored!\n", 296 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight)); 297 298 /* Unlock access to frame-buffer: */ 299 unlock(); 300 301 /* Ignore VideoModeSupported: */ 302 return E_FAIL; 303 } 304 305 /* Determine if supported: */ 306 *pfSupported = TRUE; 307 QSize screenSize = m_pMachineView->maxGuestSize(); 308 if ( (screenSize.width() != 0) 309 && (uWidth > (ULONG)screenSize.width()) 310 && (uWidth > (ULONG)width())) 311 *pfSupported = FALSE; 312 if ( (screenSize.height() != 0) 313 && (uHeight > (ULONG)screenSize.height()) 314 && (uHeight > (ULONG)height())) 315 *pfSupported = FALSE; 316 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu, Supported=%s\n", 317 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight, *pfSupported ? "TRUE" : "FALSE")); 318 319 /* Unlock access to frame-buffer: */ 320 unlock(); 321 322 /* Confirm VideoModeSupported: */ 323 return S_OK; 324 } 325 326 STDMETHODIMP UIFrameBuffer::GetVisibleRegion(BYTE *pRectangles, ULONG uCount, ULONG *puCountCopied) 327 { 328 PRTRECT rects = (PRTRECT)pRectangles; 329 330 if (!rects) 331 return E_POINTER; 332 333 Q_UNUSED(uCount); 334 Q_UNUSED(puCountCopied); 335 336 return S_OK; 337 } 338 339 STDMETHODIMP UIFrameBuffer::SetVisibleRegion(BYTE *pRectangles, ULONG uCount) 340 { 341 /* Make sure rectangles were passed: */ 342 if (!pRectangles) 343 { 344 LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu, Invalid pRectangles pointer!\n", 345 (unsigned long)uCount)); 346 347 return E_POINTER; 348 } 349 350 /* Lock access to frame-buffer: */ 351 lock(); 352 353 /* Make sure frame-buffer is used: */ 354 if (m_fUnused) 355 { 356 LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu, Ignored!\n", 357 (unsigned long)uCount)); 358 359 /* Unlock access to frame-buffer: */ 360 unlock(); 361 362 /* Ignore SetVisibleRegion: */ 363 return E_FAIL; 364 } 365 366 /* Compose region: */ 367 QRegion region; 368 PRTRECT rects = (PRTRECT)pRectangles; 369 for (ULONG ind = 0; ind < uCount; ++ind) 370 { 371 /* Get current rectangle: */ 372 QRect rect; 373 rect.setLeft(rects->xLeft); 374 rect.setTop(rects->yTop); 375 /* Which is inclusive: */ 376 rect.setRight(rects->xRight - 1); 377 rect.setBottom(rects->yBottom - 1); 378 /* Append region: */ 379 region += rect; 380 ++rects; 381 } 382 383 /* We are directly updating synchronous visible-region: */ 384 m_syncVisibleRegion = region; 385 /* And send async-signal to update asynchronous one: */ 386 LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu, Sending to async-handler..\n", 387 (unsigned long)uCount)); 388 emit sigSetVisibleRegion(region); 389 390 /* Unlock access to frame-buffer: */ 391 unlock(); 392 393 /* Confirm SetVisibleRegion: */ 394 return S_OK; 395 } 396 397 STDMETHODIMP UIFrameBuffer::ProcessVHWACommand(BYTE *pCommand) 398 { 399 Q_UNUSED(pCommand); 400 return E_NOTIMPL; 401 } 402 403 STDMETHODIMP UIFrameBuffer::Notify3DEvent(ULONG uType, BYTE *pData) 404 { 405 /* Lock access to frame-buffer: */ 406 lock(); 407 408 /* Make sure frame-buffer is used: */ 409 if (m_fUnused) 410 { 411 LogRel2(("UIFrameBuffer::Notify3DEvent: Ignored!\n")); 412 413 /* Unlock access to frame-buffer: */ 414 unlock(); 415 416 /* Ignore Notify3DEvent: */ 417 return E_FAIL; 418 } 419 420 switch (uType) 421 { 422 case VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA: 423 { 424 /* Notify machine-view with the async-signal 425 * about 3D overlay visibility change: */ 426 BOOL fVisible = !!pData; 427 LogRel2(("UIFrameBuffer::Notify3DEvent: Sending to async-handler: " 428 "(VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA = %s)\n", 429 fVisible ? "TRUE" : "FALSE")); 430 emit sigNotifyAbout3DOverlayVisibilityChange(fVisible); 431 432 /* Unlock access to frame-buffer: */ 433 unlock(); 434 435 /* Confirm Notify3DEvent: */ 436 return S_OK; 437 } 438 439 case VBOX3D_NOTIFY_EVENT_TYPE_TEST_FUNCTIONAL: 440 { 441 HRESULT hr = m_fUnused ? E_FAIL : S_OK; 442 unlock(); 443 return hr; 444 } 445 446 default: 447 break; 448 } 449 450 /* Unlock access to frame-buffer: */ 451 unlock(); 452 453 /* Ignore Notify3DEvent: */ 454 return E_INVALIDARG; 289 455 } 290 456 … … 335 501 } 336 502 337 /**338 * EMT callback: Informs about source bitmap change.339 * @param uScreenId Guest screen number.340 * @param uX Horizontal origin of the update rectangle, in pixels.341 * @param uY Vertical origin of the update rectangle, in pixels.342 * @param uWidth Width of the guest display, in pixels.343 * @param uHeight Height of the guest display, in pixels.344 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed.345 * @note Calls to this and #setMarkAsUnused method are synchronized between calling threads (from GUI side).346 */347 STDMETHODIMP UIFrameBuffer::NotifyChange(ULONG uScreenId,348 ULONG uX,349 ULONG uY,350 ULONG uWidth,351 ULONG uHeight)352 {353 /* Lock access to frame-buffer: */354 lock();355 356 /* Make sure frame-buffer is used: */357 if (m_fIsMarkedAsUnused)358 {359 LogRel(("UIFrameBuffer::NotifyChange: Screen=%lu, Origin=%lux%lu, Size=%lux%lu, Ignored!\n",360 (unsigned long)uScreenId,361 (unsigned long)uX, (unsigned long)uY,362 (unsigned long)uWidth, (unsigned long)uHeight));363 364 /* Unlock access to frame-buffer: */365 unlock();366 367 /* Ignore NotifyChange: */368 return E_FAIL;369 }370 371 /* Acquire new pending bitmap: */372 m_pendingSourceBitmap = 0;373 m_pMachineView->session().GetConsole().GetDisplay().QuerySourceBitmap(uScreenId, m_pendingSourceBitmap);374 375 /* Widget resize is NOT thread-safe and *probably* never will be,376 * We have to notify machine-view with the async-signal to perform resize operation. */377 LogRel(("UIFrameBuffer::NotifyChange: Screen=%lu, Origin=%lux%lu, Size=%lux%lu, Sending to async-handler..\n",378 (unsigned long)uScreenId,379 (unsigned long)uX, (unsigned long)uY,380 (unsigned long)uWidth, (unsigned long)uHeight));381 emit sigNotifyChange(uScreenId, uWidth, uHeight);382 383 /* Unlock access to frame-buffer: */384 unlock();385 386 /* Give up control token to other thread: */387 RTThreadYield();388 389 /* Confirm NotifyChange: */390 return S_OK;391 }392 393 /**394 * EMT callback: Informs about an update.395 * @param uX Horizontal origin of the update rectangle, in pixels.396 * @param uY Vertical origin of the update rectangle, in pixels.397 * @param uWidth Width of the update rectangle, in pixels.398 * @param uHeight Height of the update rectangle, in pixels.399 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed.400 * @note Calls to this and #setMarkAsUnused method are synchronized between calling threads (from GUI side).401 */402 STDMETHODIMP UIFrameBuffer::NotifyUpdate(ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight)403 {404 /* Retina screens with physical-to-logical scaling requires405 * odd/even pixel updates to be taken into account,406 * otherwise we have artifacts on the borders of incoming rectangle. */407 uX = qMax(0, (int)uX - 1);408 uY = qMax(0, (int)uY - 1);409 uWidth = qMin((int)m_width, (int)uWidth + 2);410 uHeight = qMin((int)m_height, (int)uHeight + 2);411 412 /* Lock access to frame-buffer: */413 lock();414 415 /* Make sure frame-buffer is used: */416 if (m_fIsMarkedAsUnused)417 {418 LogRel2(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu, Ignored!\n",419 (unsigned long)uX, (unsigned long)uY,420 (unsigned long)uWidth, (unsigned long)uHeight));421 422 /* Unlock access to frame-buffer: */423 unlock();424 425 /* Ignore NotifyUpdate: */426 return E_FAIL;427 }428 429 /* Widget update is NOT thread-safe and *seems* never will be,430 * We have to notify machine-view with the async-signal to perform update operation. */431 LogRel2(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu, Sending to async-handler..\n",432 (unsigned long)uX, (unsigned long)uY,433 (unsigned long)uWidth, (unsigned long)uHeight));434 emit sigNotifyUpdate(uX, uY, uWidth, uHeight);435 436 /* Unlock access to frame-buffer: */437 unlock();438 439 /* Confirm NotifyUpdate: */440 return S_OK;441 }442 443 /**444 * EMT callback: Returns whether the framebuffer implementation is willing to support a given video mode.445 * @param uWidth Width of the guest display, in pixels.446 * @param uHeight Height of the guest display, in pixels.447 * @param uBPP Color depth, bits per pixel.448 * @param pfSupported Is framebuffer able/willing to render the video mode or not.449 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed.450 * @note Calls to this and #setMarkAsUnused method are synchronized between calling threads (from GUI side).451 */452 STDMETHODIMP UIFrameBuffer::VideoModeSupported(ULONG uWidth, ULONG uHeight, ULONG uBPP, BOOL *pfSupported)453 {454 /* Make sure result pointer is valid: */455 if (!pfSupported)456 {457 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu, Invalid pfSupported pointer!\n",458 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight));459 460 return E_POINTER;461 }462 463 /* Lock access to frame-buffer: */464 lock();465 466 /* Make sure frame-buffer is used: */467 if (m_fIsMarkedAsUnused)468 {469 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu, Ignored!\n",470 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight));471 472 /* Unlock access to frame-buffer: */473 unlock();474 475 /* Ignore VideoModeSupported: */476 return E_FAIL;477 }478 479 /* Determine if supported: */480 *pfSupported = TRUE;481 QSize screenSize = m_pMachineView->maxGuestSize();482 if ( (screenSize.width() != 0)483 && (uWidth > (ULONG)screenSize.width())484 && (uWidth > (ULONG)width()))485 *pfSupported = FALSE;486 if ( (screenSize.height() != 0)487 && (uHeight > (ULONG)screenSize.height())488 && (uHeight > (ULONG)height()))489 *pfSupported = FALSE;490 LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu, Supported=%s\n",491 (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight, *pfSupported ? "TRUE" : "FALSE"));492 493 /* Unlock access to frame-buffer: */494 unlock();495 496 /* Confirm VideoModeSupported: */497 return S_OK;498 }499 500 STDMETHODIMP UIFrameBuffer::GetVisibleRegion(BYTE *pRectangles, ULONG uCount, ULONG *puCountCopied)501 {502 PRTRECT rects = (PRTRECT)pRectangles;503 504 if (!rects)505 return E_POINTER;506 507 Q_UNUSED(uCount);508 Q_UNUSED(puCountCopied);509 510 return S_OK;511 }512 513 /**514 * EMT callback: Suggests a new visible region to this framebuffer.515 * @param pRectangles Pointer to the RTRECT array.516 * @param uCount Number of RTRECT elements in the rectangles array.517 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed.518 * @note Calls to this and #setMarkAsUnused method are synchronized between calling threads (from GUI side).519 */520 STDMETHODIMP UIFrameBuffer::SetVisibleRegion(BYTE *pRectangles, ULONG uCount)521 {522 /* Make sure rectangles were passed: */523 if (!pRectangles)524 {525 LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu, Invalid pRectangles pointer!\n",526 (unsigned long)uCount));527 528 return E_POINTER;529 }530 531 /* Lock access to frame-buffer: */532 lock();533 534 /* Make sure frame-buffer is used: */535 if (m_fIsMarkedAsUnused)536 {537 LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu, Ignored!\n",538 (unsigned long)uCount));539 540 /* Unlock access to frame-buffer: */541 unlock();542 543 /* Ignore SetVisibleRegion: */544 return E_FAIL;545 }546 547 /* Compose region: */548 QRegion region;549 PRTRECT rects = (PRTRECT)pRectangles;550 for (ULONG ind = 0; ind < uCount; ++ind)551 {552 /* Get current rectangle: */553 QRect rect;554 rect.setLeft(rects->xLeft);555 rect.setTop(rects->yTop);556 /* Which is inclusive: */557 rect.setRight(rects->xRight - 1);558 rect.setBottom(rects->yBottom - 1);559 /* Append region: */560 region += rect;561 ++rects;562 }563 564 /* We are directly updating synchronous visible-region: */565 m_syncVisibleRegion = region;566 /* And send async-signal to update asynchronous one: */567 LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu, Sending to async-handler..\n",568 (unsigned long)uCount));569 emit sigSetVisibleRegion(region);570 571 /* Unlock access to frame-buffer: */572 unlock();573 574 /* Confirm SetVisibleRegion: */575 return S_OK;576 }577 578 STDMETHODIMP UIFrameBuffer::ProcessVHWACommand(BYTE *pCommand)579 {580 Q_UNUSED(pCommand);581 return E_NOTIMPL;582 }583 584 /**585 * EMT callback: Notifies framebuffer about 3D backend event.586 * @param uType Event type. Currently only VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA is supported.587 * @param pData Event-specific data, depends on the supplied event type.588 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed.589 * @note Calls to this and #setMarkAsUnused method are synchronized between calling threads (from GUI side).590 */591 STDMETHODIMP UIFrameBuffer::Notify3DEvent(ULONG uType, BYTE *pData)592 {593 /* Lock access to frame-buffer: */594 lock();595 596 /* Make sure frame-buffer is used: */597 if (m_fIsMarkedAsUnused)598 {599 LogRel2(("UIFrameBuffer::Notify3DEvent: Ignored!\n"));600 601 /* Unlock access to frame-buffer: */602 unlock();603 604 /* Ignore Notify3DEvent: */605 return E_FAIL;606 }607 608 switch (uType)609 {610 case VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA:611 {612 /* Notify machine-view with the async-signal613 * about 3D overlay visibility change: */614 BOOL fVisible = !!pData;615 LogRel2(("UIFrameBuffer::Notify3DEvent: Sending to async-handler: "616 "(VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA = %s)\n",617 fVisible ? "TRUE" : "FALSE"));618 emit sigNotifyAbout3DOverlayVisibilityChange(fVisible);619 620 /* Unlock access to frame-buffer: */621 unlock();622 623 /* Confirm Notify3DEvent: */624 return S_OK;625 }626 627 case VBOX3D_NOTIFY_EVENT_TYPE_TEST_FUNCTIONAL:628 {629 HRESULT hr = m_fIsMarkedAsUnused ? E_FAIL : S_OK;630 unlock();631 return hr;632 }633 634 default:635 break;636 }637 638 /* Unlock access to frame-buffer: */639 unlock();640 641 /* Ignore Notify3DEvent: */642 return E_INVALIDARG;643 }644 645 503 void UIFrameBuffer::applyVisibleRegion(const QRegion ®ion) 646 504 { … … 669 527 /* should never be here */ 670 528 AssertBreakpoint(); 529 // TODO: Is this required? ^ 671 530 } 672 531 #endif /* VBOX_WITH_VIDEOHWACCEL */ 673 532 674 void UIFrameBuffer::setView(UIMachineView * pView)675 {676 /* Disconnect handlers: */677 if (m_pMachineView)678 cleanupConnections();679 680 /* Reassign machine-view: */681 m_pMachineView = pView;682 m_WinId = (m_pMachineView && m_pMachineView->viewport()) ? (LONG64)m_pMachineView->viewport()->winId() : 0;683 684 /* Connect handlers: */685 if (m_pMachineView)686 prepareConnections();687 }688 689 void UIFrameBuffer::setHiDPIOptimizationType(HiDPIOptimizationType optimizationType)690 {691 /* Make sure 'HiDPI optimization type' changed: */692 if (m_hiDPIOptimizationType == optimizationType)693 return;694 695 /* Update 'HiDPI optimization type': */696 m_hiDPIOptimizationType = optimizationType;697 }698 699 void UIFrameBuffer::setBackingScaleFactor(double dBackingScaleFactor)700 {701 /* Make sure 'backing scale factor' changed: */702 if (m_dBackingScaleFactor == dBackingScaleFactor)703 return;704 705 /* Update 'backing scale factor': */706 m_dBackingScaleFactor = dBackingScaleFactor;707 }708 709 533 void UIFrameBuffer::prepareConnections() 710 534 { 711 connect(this, SIGNAL(sigRequestResize(int, uchar*, int, int, int, int)),712 m_pMachineView, SLOT(sltHandleRequestResize(int, uchar*, int, int, int, int)),713 Qt::QueuedConnection);714 535 connect(this, SIGNAL(sigNotifyChange(ulong, int, int)), 715 536 m_pMachineView, SLOT(sltHandleNotifyChange(ulong, int, int)), … … 728 549 void UIFrameBuffer::cleanupConnections() 729 550 { 730 disconnect(this, SIGNAL(sigRequestResize(int, uchar*, int, int, int, int)),731 m_pMachineView, SLOT(sltHandleRequestResize(int, uchar*, int, int, int, int)));732 551 disconnect(this, SIGNAL(sigNotifyChange(ulong, int, int)), 733 552 m_pMachineView, SLOT(sltHandleNotifyChange(ulong, int, int))); -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
r51459 r51487 4 4 5 5 /* 6 * Copyright (C) 2010-201 3Oracle Corporation6 * Copyright (C) 2010-2014 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 /* Qt includes: */ 21 21 #include <QRegion> 22 #include <QPaintEvent>23 22 24 23 /* GUI includes: */ … … 34 33 35 34 /* Forward declarations: */ 35 class QResizeEvent; 36 class QPaintEvent; 36 37 class UIMachineView; 37 38 38 /** 39 * Frame buffer resize event. 40 */ 39 /** Frame-buffer resize-event. */ 41 40 class UIResizeEvent : public QEvent 42 41 { … … 66 65 }; 67 66 68 /** 69 * Common IFramebuffer implementation for all methods used by GUI to maintain 70 * the VM display video memory. 71 * 72 * Note that although this class can be called from multiple threads 73 * (in particular, the GUI thread and EMT) it doesn't protect access to every 74 * data field using its mutex lock. This is because all synchronization between 75 * the GUI and the EMT thread is supposed to be done using the 76 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods 77 * (in particular, the \a aFinished parameter of these methods is responsible 78 * for the synchronization). These methods are always called on EMT and 79 * therefore always follow one another but never in parallel. 80 * 81 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and 82 * IFramebuffer::Unlock() implementations) usually makes sense only if some 83 * third-party thread (i.e. other than GUI or EMT) needs to make sure that 84 * *no* VM display update or resize event can occur while it is accessing 85 * IFramebuffer properties or the underlying display memory storage area. 86 * 87 * See IFramebuffer documentation for more info. 88 */ 67 /** Common IFramebuffer implementation used to maintain VM display video memory. */ 89 68 class UIFrameBuffer : public QObject, VBOX_SCRIPTABLE_IMPL(IFramebuffer) 90 69 { … … 93 72 signals: 94 73 95 /* Notifiers: EMT<->GUI interthread stuff: */ 96 void sigRequestResize(int iPixelFormat, uchar *pVRAM, 97 int iBitsPerPixel, int iBytesPerLine, 98 int iWidth, int iHeight); 74 /** Notifies listener about guest-screen resolution changes. */ 99 75 void sigNotifyChange(ulong uScreenId, int iWidth, int iHeight); 76 /** Notifies listener about guest-screen updates. */ 100 77 void sigNotifyUpdate(int iX, int iY, int iWidth, int iHeight); 78 /** Notifies listener about guest-screen visible-region changes. */ 101 79 void sigSetVisibleRegion(QRegion region); 80 /** Notifies listener about guest 3D capability changes. */ 102 81 void sigNotifyAbout3DOverlayVisibilityChange(bool fVisible); 103 82 104 83 public: 105 84 106 UIFrameBuffer(UIMachineView *aView); 107 virtual ~UIFrameBuffer(); 108 109 /* API: [Un]used status stuff: */ 110 void setMarkAsUnused(bool fIsMarkAsUnused); 111 112 /* API: Auto-enabled stuff: */ 113 bool isAutoEnabled() const; 114 void setAutoEnabled(bool fIsAutoEnabled); 85 /** Frame-buffer constructor. 86 * @param pMachineView defines machine-view this frame-buffer is bounded to. */ 87 UIFrameBuffer(UIMachineView *pMachineView); 88 /** Frame-buffer destructor. */ 89 ~UIFrameBuffer(); 90 91 /** Assigns machine-view frame-buffer will be bounded to. 92 * @param pMachineView defines machine-view this frame-buffer is bounded to. */ 93 void setView(UIMachineView *pMachineView); 94 95 /** Defines whether frame-buffer is <b>unused</b>. 96 * @note Refer to m_fUnused for more information. 97 * @note Calls to this and any other EMT callback are synchronized (from GUI side). */ 98 void setMarkAsUnused(bool fUnused); 99 100 /** Returns whether frame-buffer is <b>auto-enabled</b>. 101 * @note Refer to m_fAutoEnabled for more information. */ 102 bool isAutoEnabled() const { return m_fAutoEnabled; } 103 /** Defines whether frame-buffer is <b>auto-enabled</b>. 104 * @note Refer to m_fAutoEnabled for more information. */ 105 void setAutoEnabled(bool fAutoEnabled) { m_fAutoEnabled = fAutoEnabled; } 115 106 116 107 NS_DECL_ISUPPORTS 117 108 118 109 #ifdef Q_OS_WIN 110 /** Windows: Increments reference-counter. */ 119 111 STDMETHOD_(ULONG, AddRef)() 120 112 { … … 122 114 } 123 115 116 /** Windows: Decrements reference-counter. */ 124 117 STDMETHOD_(ULONG, Release)() 125 118 { 126 long cnt= ::InterlockedDecrement(&m_iRefCnt);127 if ( cnt== 0)119 long iCounter = ::InterlockedDecrement(&m_iRefCnt); 120 if (iCounter == 0) 128 121 delete this; 129 return cnt;122 return iCounter; 130 123 } 131 124 #endif /* Q_OS_WIN */ … … 133 126 VBOX_SCRIPTABLE_DISPATCH_IMPL(IFramebuffer) 134 127 135 /* IFramebuffer COM methods */ 136 STDMETHOD(COMGETTER(Address)) (BYTE **ppAddress); 137 STDMETHOD(COMGETTER(Width)) (ULONG *puWidth); 138 STDMETHOD(COMGETTER(Height)) (ULONG *puHeight); 139 STDMETHOD(COMGETTER(BitsPerPixel)) (ULONG *puBitsPerPixel); 140 STDMETHOD(COMGETTER(BytesPerLine)) (ULONG *puBytesPerLine); 141 STDMETHOD(COMGETTER(PixelFormat)) (ULONG *puPixelFormat); 142 STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *pbUsesGuestVRAM); 143 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *puHeightReduction); 144 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **ppOverlay); 145 STDMETHOD(COMGETTER(WinId)) (LONG64 *pWinId); 146 128 /* IFramebuffer COM methods: */ 129 STDMETHOD(COMGETTER(Address))(BYTE **ppAddress); 130 STDMETHOD(COMGETTER(Width))(ULONG *puWidth); 131 STDMETHOD(COMGETTER(Height))(ULONG *puHeight); 132 STDMETHOD(COMGETTER(BitsPerPixel))(ULONG *puBitsPerPixel); 133 STDMETHOD(COMGETTER(BytesPerLine))(ULONG *puBytesPerLine); 134 STDMETHOD(COMGETTER(PixelFormat))(ULONG *puPixelFormat); 135 STDMETHOD(COMGETTER(UsesGuestVRAM))(BOOL *pbUsesGuestVRAM); 136 STDMETHOD(COMGETTER(HeightReduction))(ULONG *puHeightReduction); 137 STDMETHOD(COMGETTER(Overlay))(IFramebufferOverlay **ppOverlay); 138 STDMETHOD(COMGETTER(WinId))(LONG64 *pWinId); 139 140 /* IFramebuffer sync methods: */ 147 141 STDMETHOD(Lock)(); 148 142 STDMETHOD(Unlock)(); 149 143 150 STDMETHOD(RequestResize) (ULONG uScreenId, ULONG uPixelFormat, 151 BYTE *pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine, 152 ULONG uWidth, ULONG uHeight, 153 BOOL *pbFinished); 154 STDMETHOD(NotifyChange)(ULONG uScreenId, 155 ULONG uX, 156 ULONG uY, 157 ULONG uWidth, 158 ULONG uHeight); 159 160 STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight); 161 162 STDMETHOD(VideoModeSupported) (ULONG uWidth, ULONG uHeight, ULONG uBPP, 163 BOOL *pbSupported); 164 144 /** EMT callback: Notifies frame-buffer about guest-screen size change. 145 * @param uScreenId Guest screen number. 146 * @param uX Horizontal origin of the update rectangle, in pixels. 147 * @param uY Vertical origin of the update rectangle, in pixels. 148 * @param uWidth Width of the guest display, in pixels. 149 * @param uHeight Height of the guest display, in pixels. 150 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed. 151 * @note Calls to this and #setMarkAsUnused method are synchronized (from GUI side). */ 152 STDMETHOD(NotifyChange)(ULONG uScreenId, ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight); 153 154 /** EMT callback: Notifies frame-buffer about guest-screen update. 155 * @param uX Horizontal origin of the update rectangle, in pixels. 156 * @param uY Vertical origin of the update rectangle, in pixels. 157 * @param uWidth Width of the update rectangle, in pixels. 158 * @param uHeight Height of the update rectangle, in pixels. 159 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed. 160 * @note Calls to this and #setMarkAsUnused method are synchronized (from GUI side). */ 161 STDMETHOD(NotifyUpdate)(ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight); 162 163 /** EMT callback: Returns whether the frame-buffer implementation is willing to support a given video-mode. 164 * @param uWidth Width of the guest display, in pixels. 165 * @param uHeight Height of the guest display, in pixels. 166 * @param uBPP Color depth, bits per pixel. 167 * @param pfSupported Is frame-buffer able/willing to render the video mode or not. 168 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed. 169 * @note Calls to this and #setMarkAsUnused method are synchronized (from GUI side). */ 170 STDMETHOD(VideoModeSupported)(ULONG uWidth, ULONG uHeight, ULONG uBPP, BOOL *pbSupported); 171 172 /** EMT callback which is not used in current implementation. */ 165 173 STDMETHOD(GetVisibleRegion)(BYTE *pRectangles, ULONG uCount, ULONG *puCountCopied); 174 /** EMT callback: Suggests new visible-region to this frame-buffer. 175 * @param pRectangles Pointer to the RTRECT array. 176 * @param uCount Number of RTRECT elements in the rectangles array. 177 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed. 178 * @note Calls to this and #setMarkAsUnused method are synchronized (from GUI side). */ 166 179 STDMETHOD(SetVisibleRegion)(BYTE *pRectangles, ULONG uCount); 167 180 181 /** EMT callback which is not used in current implementation. */ 168 182 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand); 169 183 184 /** EMT callback: Notifies frame-buffer about 3D backend event. 185 * @param uType Event type. Currently only VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA is supported. 186 * @param pData Event-specific data, depends on the supplied event type. 187 * @note Any EMT callback is subsequent. No any other EMT callback can be called until this one processed. 188 * @note Calls to this and #setMarkAsUnused method are synchronized (from GUI side). */ 170 189 STDMETHOD(Notify3DEvent)(ULONG uType, BYTE *pData); 171 190 191 /** Returns frame-buffer data address. */ 192 virtual uchar *address() = 0; 193 /** Returns frame-buffer width. */ 172 194 ulong width() { return m_width; } 195 /** Returns frame-buffer height. */ 173 196 ulong height() { return m_height; } 174 197 /** Returns frame-buffer bits-per-pixel value. */ 198 virtual ulong bitsPerPixel() = 0; 199 /** Returns frame-buffer bytes-per-line value. */ 200 virtual ulong bytesPerLine() = 0; 201 /** Returns default frame-buffer pixel-format. */ 202 virtual ulong pixelFormat() { return FramebufferPixelFormat_FOURCC_RGB; } 203 204 /** Locks frame-buffer access. */ 205 void lock() const { RTCritSectEnter(&m_critSect); } 206 /** Unlocks frame-buffer access. */ 207 void unlock() const { RTCritSectLeave(&m_critSect); } 208 209 /** Returns host-to-guest scale ratio. */ 210 QSize scaledSize() const { return m_scaledSize; } 211 /** Defines host-to-guest scale ratio as @a size. */ 212 void setScaledSize(const QSize &size = QSize()) { m_scaledSize = size; } 213 /** Returns x-origin of the host (scaled) content corresponding to x-origin of guest (actual) content. */ 175 214 inline int convertGuestXTo(int x) const { return m_scaledSize.isValid() ? qRound((double)m_scaledSize.width() / m_width * x) : x; } 215 /** Returns y-origin of the host (scaled) content corresponding to y-origin of guest (actual) content. */ 176 216 inline int convertGuestYTo(int y) const { return m_scaledSize.isValid() ? qRound((double)m_scaledSize.height() / m_height * y) : y; } 217 /** Returns x-origin of the guest (actual) content corresponding to x-origin of host (scaled) content. */ 177 218 inline int convertHostXTo(int x) const { return m_scaledSize.isValid() ? qRound((double)m_width / m_scaledSize.width() * x) : x; } 219 /** Returns y-origin of the guest (actual) content corresponding to y-origin of host (scaled) content. */ 178 220 inline int convertHostYTo(int y) const { return m_scaledSize.isValid() ? qRound((double)m_height / m_scaledSize.height() * y) : y; } 179 221 180 virtual QSize scaledSize() const { return m_scaledSize; } 181 virtual void setScaledSize(const QSize &size = QSize()) { m_scaledSize = size; } 182 183 virtual ulong pixelFormat() 184 { 185 return FramebufferPixelFormat_FOURCC_RGB; 186 } 187 188 void lock() const { RTCritSectEnter(&m_critSect); } 189 void unlock() const { RTCritSectLeave(&m_critSect); } 190 191 virtual uchar *address() = 0; 192 virtual ulong bitsPerPixel() = 0; 193 virtual ulong bytesPerLine() = 0; 194 195 /* API: Event-delegate stuff: */ 196 virtual void moveEvent(QMoveEvent* /*pEvent*/) {} 222 /** Handles frame-buffer notify-change-event. */ 223 void notifyChange(); 224 /** Handles frame-buffer resize-event. */ 197 225 virtual void resizeEvent(UIResizeEvent *pEvent) = 0; 226 /** Handles frame-buffer paint-event. */ 198 227 virtual void paintEvent(QPaintEvent *pEvent) = 0; 199 virtual void applyVisibleRegion(const QRegion ®ion); 200 201 void notifyChange(); 228 /** Handles frame-buffer apply-visible-region-event. */ 229 void applyVisibleRegion(const QRegion ®ion); 202 230 203 231 #ifdef VBOX_WITH_VIDEOHWACCEL 204 /* this method is called from the GUI thread 205 * to perform the actual Video HW Acceleration command processing 206 * the event is framebuffer implementation specific */ 207 virtual void doProcessVHWACommand(QEvent * pEvent); 208 232 /** Performs Video HW Acceleration command. */ 233 virtual void doProcessVHWACommand(QEvent *pEvent); 234 /** Handles viewport resize-event. */ 209 235 virtual void viewportResized(QResizeEvent * /* pEvent */) {} 210 236 /** Handles viewport scroll-event. */ 211 237 virtual void viewportScrolled(int /* iX */, int /* iY */) {} 212 238 #endif /* VBOX_WITH_VIDEOHWACCEL */ 213 214 virtual void setView(UIMachineView * pView);215 239 216 240 /** Return HiDPI frame-buffer optimization type. */ 217 241 HiDPIOptimizationType hiDPIOptimizationType() const { return m_hiDPIOptimizationType; } 218 242 /** Define HiDPI frame-buffer optimization type: */ 219 void setHiDPIOptimizationType(HiDPIOptimizationType optimizationType) ;243 void setHiDPIOptimizationType(HiDPIOptimizationType optimizationType) { m_hiDPIOptimizationType = optimizationType; } 220 244 221 245 /** Return backing scale factor used by HiDPI frame-buffer. */ 222 246 double backingScaleFactor() const { return m_dBackingScaleFactor; } 223 247 /** Define backing scale factor used by HiDPI frame-buffer. */ 224 void setBackingScaleFactor(double dBackingScaleFactor) ;248 void setBackingScaleFactor(double dBackingScaleFactor) { m_dBackingScaleFactor = dBackingScaleFactor; } 225 249 226 250 protected: 227 251 252 /** Machine-view this frame-buffer is bounded to. */ 228 253 UIMachineView *m_pMachineView; 254 /** Cached window ID. */ 255 int64_t m_winId; 256 /** RTCRITSECT object to protect frame-buffer access. */ 229 257 mutable RTCRITSECT m_critSect; 258 /** Frame-buffer width. */ 230 259 ulong m_width; 260 /** Frame-buffer height. */ 231 261 ulong m_height; 262 /** Frame-buffer scaled size. */ 232 263 QSize m_scaledSize; 233 int64_t m_WinId; 234 bool m_fIsMarkedAsUnused; 235 bool m_fIsAutoEnabled; 264 /** Defines whether frame-buffer is <b>unused</b>. 265 * <b>Unused</b> status determines whether frame-buffer should ignore EMT events or not. */ 266 bool m_fUnused; 267 /** Defines whether frame-buffer is <b>auto-enabled</b>. 268 * <b>Auto-enabled</b> status means that guest-screen corresponding to this frame-buffer 269 * was automatically enabled by the multi-screen layout (auto-mount guest-screen) functionality, 270 * so have potentially incorrect size-hint posted into guest event queue. 271 * Machine-view will try to automatically adjust guest-screen size as soon as possible. */ 272 bool m_fAutoEnabled; 236 273 237 274 /** Source bitmap from IDisplay. */ 238 275 CDisplaySourceBitmap m_sourceBitmap; 239 /** Source bitmap from IDisplay acquired but not yet applied. */276 /** Source bitmap from IDisplay (acquired but not yet applied). */ 240 277 CDisplaySourceBitmap m_pendingSourceBitmap; 241 /** Reflects whether screen-updates a llowed. */278 /** Reflects whether screen-updates are allowed. */ 242 279 bool m_fIsUpdatesAllowed; 243 280 244 /* To avoid a seamless flicker, 245 * which caused by the latency between the 246 * initial visible-region arriving from EMT thread 247 * and actual visible-region application on GUI thread 248 * it was decided to use two visible-region instances: 249 * 1. 'Sync-one' which being updated synchronously by locking EMT thread, 250 * and used for immediate manual clipping of the painting operations. 251 * 2. 'Async-one' which updated asynchronously by posting async-event from EMT to GUI thread, 252 which is used to update viewport parts for visible-region changes, 253 because NotifyUpdate doesn't take into account these changes. */ 281 /* To avoid a seamless flicker which caused by the latency between 282 * the initial visible-region arriving from EMT thread 283 * and actual visible-region appliance on GUI thread 284 * it was decided to use two visible-region instances: */ 285 /** Sync visible-region which being updated synchronously by locking EMT thread. 286 * Used for immediate manual clipping of the painting operations. */ 254 287 QRegion m_syncVisibleRegion; 288 /** Async visible-region which being updated asynchronously by posting async-event from EMT to GUI thread, 289 * Used to update viewport parts for visible-region changes, 290 * because NotifyUpdate doesn't take into account these changes. */ 255 291 QRegion m_asyncVisibleRegion; 256 292 257 293 private: 258 294 259 /* Helpers: Prepare/cleanup stuff:*/295 /** Prepare connections routine. */ 260 296 void prepareConnections(); 297 /** Cleanup connections routine. */ 261 298 void cleanupConnections(); 262 299 263 300 #ifdef Q_OS_WIN 301 /** Windows: Holds the reference counter. */ 264 302 long m_iRefCnt; 265 303 #endif /* Q_OS_WIN */ … … 272 310 }; 273 311 274 #endif / / !___UIFrameBuffer_h___312 #endif /* !___UIFrameBuffer_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
r51484 r51487 215 215 QString strKey = makeExtraDataKeyPerMonitor(GUI_LastGuestSizeHintWasFullscreen); 216 216 machine.SetExtraData(strKey, isFullscreenOrSeamless() ? "true" : ""); 217 }218 219 void UIMachineView::sltHandleRequestResize(int iPixelFormat, uchar *pVRAM,220 int iBitsPerPixel, int iBytesPerLine,221 int iWidth, int iHeight)222 {223 // TODO: Move to appropriate place!224 /* Some situations require frame-buffer resize-events to be ignored at all,225 * leaving machine-window, machine-view and frame-buffer sizes preserved: */226 if (uisession()->isGuestResizeIgnored())227 return;228 229 /* If machine-window is visible: */230 if (uisession()->isScreenVisible(m_uScreenId))231 {232 // TODO: Move to appropriate place!233 /* Adjust 'scale' mode for current machine-view size: */234 if (visualStateType() == UIVisualStateType_Scale)235 frameBuffer()->setScaledSize(size());236 237 /* Is there a proposal for frame-buffer resize? */238 bool fResizeProposed = (ulong)iWidth != frameBuffer()->width() ||239 (ulong)iHeight != frameBuffer()->height();240 241 /* Perform frame-buffer mode-change: */242 UIResizeEvent resizeEvent(iPixelFormat, pVRAM, iBitsPerPixel, iBytesPerLine, iWidth, iHeight);243 frameBuffer()->resizeEvent(&resizeEvent);244 245 /* Was framebuffer actually resized? */246 if (fResizeProposed)247 {248 /* Scale-mode doesn't need this.. */249 if (visualStateType() != UIVisualStateType_Scale)250 {251 /* Adjust maximum-size restriction for machine-view: */252 setMaximumSize(sizeHint());253 254 /* Disable the resize hint override hack: */255 m_sizeHintOverride = QSize(-1, -1);256 257 /* Force machine-window update own layout: */258 QCoreApplication::sendPostedEvents(0, QEvent::LayoutRequest);259 260 /* Update machine-view sliders: */261 updateSliders();262 263 /* By some reason Win host forgets to update machine-window central-widget264 * after main-layout was updated, let's do it for all the hosts: */265 machineWindow()->centralWidget()->update();266 267 /* Normalize machine-window geometry: */268 if (visualStateType() == UIVisualStateType_Normal)269 machineWindow()->normalizeGeometry(true /* adjust position */);270 }271 272 #ifdef Q_WS_MAC273 /* Update MacOS X dock icon size: */274 machineLogic()->updateDockIconSize(screenId(), iWidth, iHeight);275 #endif /* Q_WS_MAC */276 }277 }278 279 /* Emit a signal about guest was resized: */280 emit resizeHintDone();281 282 LogRelFlow(("UIMachineView::ResizeHandled: "283 "Screen=%d, Format=%d, "284 "BitsPerPixel=%d, BytesPerLine=%d, "285 "Size=%dx%d.\n",286 (unsigned long)m_uScreenId, iPixelFormat,287 iBitsPerPixel, iBytesPerLine, iWidth, iHeight));288 217 } 289 218 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
r51484 r51487 95 95 /* Slot to perform guest resize: */ 96 96 void sltPerformGuestResize(const QSize &aSize = QSize()); 97 98 /* Handler: Frame-buffer RequestResize stuff: */99 virtual void sltHandleRequestResize(int iPixelFormat, uchar *pVRAM,100 int iBitsPerPixel, int iBytesPerLine,101 int iWidth, int iHeight);102 97 103 98 /* Handler: Frame-buffer NotifyChange stuff: */
Note:
See TracChangeset
for help on using the changeset viewer.