Changeset 46062 in vbox
- Timestamp:
- May 14, 2013 12:26:26 PM (12 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
r44528 r46062 7 7 8 8 /* 9 * Copyright (C) 2010-201 2Oracle Corporation9 * Copyright (C) 2010-2013 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 #else /* !VBOX_WITH_PRECOMPILED_HEADERS */ 25 25 26 /* Local includes */ 26 /* Qt includes: */ 27 # include <QPainter> 28 # include <QApplication> 29 30 /* GUI includes: */ 27 31 # include "UIFrameBufferQImage.h" 28 32 # include "UIMachineView.h" … … 31 35 # include "UISession.h" 32 36 33 /* Global includes*/34 # include <QPainter>35 # include <QApplication>37 /* COM includes: */ 38 #include "COMEnums.h" 39 #include "CMachine.h" 36 40 37 41 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 38 42 39 /** @class UIFrameBufferQImage40 *41 * The UIFrameBufferQImage class is a class that implements the IFrameBuffer42 * interface and uses QImage as the direct storage for VM display data. QImage43 * is then converted to QPixmap and blitted to the console view widget.44 */45 43 UIFrameBufferQImage::UIFrameBufferQImage(UIMachineView *pMachineView) 46 44 : UIFrameBuffer(pMachineView) 47 45 { 48 /* Initialize the framebuffer the first time*/46 /* Initialize the framebuffer: */ 49 47 UIResizeEvent event(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480); 50 48 resizeEvent(&event); 51 49 } 52 50 53 /** @note This method is called on EMT from under this object's lock */54 51 STDMETHODIMP UIFrameBufferQImage::NotifyUpdate(ULONG uX, ULONG uY, ULONG uW, ULONG uH) 55 52 { 56 /* We're not on the GUI thread and update() isn't thread safe in 57 * Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is), 58 * on Linux (didn't check Qt 4.x there) and probably on other 59 * non-DOS platforms, so post the event instead. */ 53 /* QWidget::update() is not thread safe and seems never will be, 54 * So we have to post an async event to perform update operation. 55 * Later the event will be replaced by the corresponding signal stuff: */ 60 56 QApplication::postEvent(m_pMachineView, new UIRepaintEvent(uX, uY, uW, uH)); 61 62 57 return S_OK; 63 58 } … … 65 60 void UIFrameBufferQImage::paintEvent(QPaintEvent *pEvent) 66 61 { 67 /* on mode switch the paint event may come while the view is null (before the new view gets set)68 * this is seen on Windows hosts with 3D enabled,69 * ignore paint event s in that case*/62 /* On mode switch the enqueued paint event may still come 63 * while the view is already null (before the new view gets set), 64 * ignore paint event in that case. */ 70 65 if (!m_pMachineView) 71 66 return; 72 /* If the machine is NOT in 'running' state, 73 * the link between framebuffer and video memory 74 * is broken, we should go fallback now... */ 75 if (m_bUsesGuestVRAM && 76 !m_pMachineView->uisession()->isRunning() && 77 /* Online snapshotting: */ 78 m_pMachineView->uisession()->machineState() != KMachineState_Saving) 67 68 /* If the machine is NOT in 'running', 'paused' or 'saving' state, 69 * the link between the framebuffer and the video memory is broken. 70 * We should go fallback in that case. 71 * We should acquire actual machine-state to exclude 72 * situations when the state was changed already but 73 * GUI didn't received event about that or didn't processed it yet. */ 74 KMachineState machineState = m_pMachineView->uisession()->session().GetMachine().GetState(); 75 if ( m_bUsesGuestVRAM 76 /* running */ 77 && machineState != KMachineState_Running 78 && machineState != KMachineState_Teleporting 79 && machineState != KMachineState_LiveSnapshotting 80 /* paused */ 81 && machineState != KMachineState_Paused 82 && machineState != KMachineState_TeleportingPausedVM 83 /* saving */ 84 && machineState != KMachineState_Saving 85 ) 79 86 goFallback(); 80 87 … … 93 100 QImage *pSourceImage = scaledImage.isNull() ? &m_img : &scaledImage; 94 101 95 /* Apply image-size restriction: */102 /* Get clipping rectangle: */ 96 103 const QRect &r = pEvent->rect().intersected(pSourceImage->rect()); 97 /* Some outdated rectangle during processing UIResizeEvent */98 104 if (r.isEmpty()) 99 105 return; … … 103 109 #endif 104 110 111 /* Create painter: */ 105 112 QPainter painter(m_pMachineView->viewport()); 106 113 if ((ulong)r.width() < m_width * 2 / 3) 107 114 { 108 /* This method is faster for narrow updates */115 /* This method is faster for narrow updates: */ 109 116 m_PM = QPixmap::fromImage(pSourceImage->copy(r.x() + m_pMachineView->contentsX(), 110 117 r.y() + m_pMachineView->contentsY(), … … 114 121 else 115 122 { 116 /* This method is faster for wide updates */123 /* This method is faster for wide updates: */ 117 124 m_PM = QPixmap::fromImage(QImage(pSourceImage->scanLine(r.y() + m_pMachineView->contentsY()), 118 125 pSourceImage->width(), r.height(), pSourceImage->bytesPerLine(), … … 131 138 #endif 132 139 140 /* Remember new width/height: */ 133 141 m_width = pEvent->width(); 134 142 m_height = pEvent->height(); 135 143 144 /* Check if we support the pixel format and can use the guest VRAM directly: */ 136 145 bool bRemind = false; 137 146 bool bFallback = false; 138 147 ulong bitsPerLine = pEvent->bytesPerLine() * 8; 139 140 /* check if we support the pixel format and can use the guest VRAM directly */141 148 if (pEvent->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB) 142 149 { … … 144 151 switch (pEvent->bitsPerPixel()) 145 152 { 146 /* 32-, 8- and 1-bpp are the only depths supported by QImage */153 /* 32-, 8- and 1-bpp are the only depths supported by QImage: */ 147 154 case 32: 148 155 format = QImage::Format_RGB32; … … 157 164 break; 158 165 default: 159 format = QImage::Format_Invalid; /* set it to something so gcc keeps quiet. */166 format = QImage::Format_Invalid; 160 167 bRemind = true; 161 168 bFallback = true; … … 166 173 { 167 174 /* QImage only supports 32-bit aligned scan lines... */ 168 Assert 175 Assert((pEvent->bytesPerLine() & 3) == 0); 169 176 bFallback = ((pEvent->bytesPerLine() & 3) != 0); 170 177 } … … 172 179 { 173 180 /* ...and the scan lines ought to be a whole number of pixels. */ 174 Assert 181 Assert((bitsPerLine & (pEvent->bitsPerPixel() - 1)) == 0); 175 182 bFallback = ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) != 0); 176 183 } 177 184 if (!bFallback) 178 185 { 179 Assert (bitsPerLine / pEvent->bitsPerPixel() >= m_width); 180 bFallback = RT_BOOL (bitsPerLine / pEvent->bitsPerPixel() < m_width); 181 } 182 if (!bFallback) 183 { 184 m_img = QImage ((uchar *) pEvent->VRAM(), m_width, m_height, bitsPerLine / 8, format); 186 /* Make sure constraints are also passed: */ 187 Assert(bitsPerLine / pEvent->bitsPerPixel() >= m_width); 188 bFallback = RT_BOOL(bitsPerLine / pEvent->bitsPerPixel() < m_width); 189 } 190 if (!bFallback) 191 { 192 /* Finally compose image using VRAM directly: */ 193 m_img = QImage((uchar *)pEvent->VRAM(), m_width, m_height, bitsPerLine / 8, format); 185 194 m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB; 186 195 m_bUsesGuestVRAM = true; … … 188 197 } 189 198 else 190 {191 199 bFallback = true; 192 } 193 200 201 /* Fallback if requested: */ 194 202 if (bFallback) 195 {196 203 goFallback(); 197 } 198 204 205 /* Remind if requested: */ 199 206 if (bRemind) 200 207 msgCenter().remindAboutWrongColorDepth(pEvent->bitsPerPixel(), 32); … … 203 210 void UIFrameBufferQImage::goFallback() 204 211 { 205 /* We don't support either the pixel format or the color depth; 206 * or the machine is in the state which breaks link between 207 * the framebuffer and the actual video-memory: */ 212 /* We calling for fallback when we: 213 * 1. don't support either the pixel format or the color depth; 214 * 2. or the machine is in the state which breaks link between 215 * the framebuffer and the actual video-memory: */ 208 216 m_img = QImage(m_width, m_height, QImage::Format_RGB32); 209 217 m_img.fill(0); -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.h
r44529 r46062 6 6 7 7 /* 8 * Copyright (C) 2010-201 2Oracle Corporation8 * Copyright (C) 2010-2013 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 17 17 */ 18 18 19 #ifdef VBOX_GUI_USE_QIMAGE 20 19 21 #ifndef ___UIFrameBufferQImage_h___ 20 22 #define ___UIFrameBufferQImage_h___ 21 23 22 #ifdef VBOX_GUI_USE_QIMAGE 23 24 /* Local includes */ 25 #include "UIFrameBuffer.h" 26 27 /* Global includes */ 24 /* Qt includes: */ 28 25 #include <QImage> 29 26 #include <QPixmap> 30 27 28 /* GUI includes: */ 29 #include "UIFrameBuffer.h" 30 31 /* QImage frame-buffer prototype: */ 31 32 class UIFrameBufferQImage : public UIFrameBuffer 32 33 { 33 34 public: 34 35 36 /* Constructor: */ 35 37 UIFrameBufferQImage(UIMachineView *pMachineView); 36 38 37 STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH); 38 39 /* API: Frame-buffer stuff: */ 39 40 ulong pixelFormat() { return m_uPixelFormat; } 40 41 bool usesGuestVRAM() { return m_bUsesGuestVRAM; } 41 42 42 uchar *address() { return m_img.bits(); } 43 43 ulong bitsPerPixel() { return m_img.depth(); } 44 44 ulong bytesPerLine() { return m_img.bytesPerLine(); } 45 45 46 /* API: Event-delegate stuff: */ 47 void resizeEvent(UIResizeEvent *pEvent); 46 48 void paintEvent(QPaintEvent *pEvent); 47 void resizeEvent(UIResizeEvent *pEvent); 49 50 protected: 51 52 /* Callback: Guest paint-event stuff: */ 53 STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH); 48 54 49 55 private: 50 56 57 /* Helper: Fallback stuff: */ 51 58 void goFallback(); 52 59 60 /* Variables: */ 53 61 QPixmap m_PM; 54 62 QImage m_img; … … 57 65 }; 58 66 67 #endif /* !___UIFrameBufferQImage_h___ */ 68 59 69 #endif /* VBOX_GUI_USE_QIMAGE */ 60 70 61 #endif /* !___UIFrameBufferQImage_h___ */62
Note:
See TracChangeset
for help on using the changeset viewer.