VirtualBox

Changeset 46062 in vbox


Ignore:
Timestamp:
May 14, 2013 12:26:26 PM (12 years ago)
Author:
vboxsync
Message:

FE/Qt: 6749: QImage frame-buffer cleanup/rework (part 1).

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  
    77
    88/*
    9  * Copyright (C) 2010-2012 Oracle Corporation
     9 * Copyright (C) 2010-2013 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2424#else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
    2525
    26 /* Local includes */
     26/* Qt includes: */
     27# include <QPainter>
     28# include <QApplication>
     29
     30/* GUI includes: */
    2731# include "UIFrameBufferQImage.h"
    2832# include "UIMachineView.h"
     
    3135# include "UISession.h"
    3236
    33 /* Global includes */
    34 # include <QPainter>
    35 # include <QApplication>
     37/* COM includes: */
     38#include "COMEnums.h"
     39#include "CMachine.h"
    3640
    3741#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    3842
    39 /** @class UIFrameBufferQImage
    40  *
    41  *  The UIFrameBufferQImage class is a class that implements the IFrameBuffer
    42  *  interface and uses QImage as the direct storage for VM display data. QImage
    43  *  is then converted to QPixmap and blitted to the console view widget.
    44  */
    4543UIFrameBufferQImage::UIFrameBufferQImage(UIMachineView *pMachineView)
    4644    : UIFrameBuffer(pMachineView)
    4745{
    48     /* Initialize the framebuffer the first time */
     46    /* Initialize the framebuffer: */
    4947    UIResizeEvent event(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480);
    5048    resizeEvent(&event);
    5149}
    5250
    53 /** @note This method is called on EMT from under this object's lock */
    5451STDMETHODIMP UIFrameBufferQImage::NotifyUpdate(ULONG uX, ULONG uY, ULONG uW, ULONG uH)
    5552{
    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: */
    6056    QApplication::postEvent(m_pMachineView, new UIRepaintEvent(uX, uY, uW, uH));
    61 
    6257    return S_OK;
    6358}
     
    6560void UIFrameBufferQImage::paintEvent(QPaintEvent *pEvent)
    6661{
    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 events 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. */
    7065    if (!m_pMachineView)
    7166        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        )
    7986        goFallback();
    8087
     
    93100    QImage *pSourceImage = scaledImage.isNull() ? &m_img : &scaledImage;
    94101
    95     /* Apply image-size restriction: */
     102    /* Get clipping rectangle: */
    96103    const QRect &r = pEvent->rect().intersected(pSourceImage->rect());
    97     /* Some outdated rectangle during processing UIResizeEvent */
    98104    if (r.isEmpty())
    99105        return;
     
    103109#endif
    104110
     111    /* Create painter: */
    105112    QPainter painter(m_pMachineView->viewport());
    106113    if ((ulong)r.width() < m_width * 2 / 3)
    107114    {
    108         /* This method is faster for narrow updates */
     115        /* This method is faster for narrow updates: */
    109116        m_PM = QPixmap::fromImage(pSourceImage->copy(r.x() + m_pMachineView->contentsX(),
    110117                                                     r.y() + m_pMachineView->contentsY(),
     
    114121    else
    115122    {
    116         /* This method is faster for wide updates */
     123        /* This method is faster for wide updates: */
    117124        m_PM = QPixmap::fromImage(QImage(pSourceImage->scanLine(r.y() + m_pMachineView->contentsY()),
    118125                                         pSourceImage->width(), r.height(), pSourceImage->bytesPerLine(),
     
    131138#endif
    132139
     140    /* Remember new width/height: */
    133141    m_width = pEvent->width();
    134142    m_height = pEvent->height();
    135143
     144    /* Check if we support the pixel format and can use the guest VRAM directly: */
    136145    bool bRemind = false;
    137146    bool bFallback = false;
    138147    ulong bitsPerLine = pEvent->bytesPerLine() * 8;
    139 
    140     /* check if we support the pixel format and can use the guest VRAM directly */
    141148    if (pEvent->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
    142149    {
     
    144151        switch (pEvent->bitsPerPixel())
    145152        {
    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: */
    147154            case 32:
    148155                format = QImage::Format_RGB32;
     
    157164                break;
    158165            default:
    159                 format = QImage::Format_Invalid; /* set it to something so gcc keeps quiet. */
     166                format = QImage::Format_Invalid;
    160167                bRemind = true;
    161168                bFallback = true;
     
    166173        {
    167174            /* QImage only supports 32-bit aligned scan lines... */
    168             Assert ((pEvent->bytesPerLine() & 3) == 0);
     175            Assert((pEvent->bytesPerLine() & 3) == 0);
    169176            bFallback = ((pEvent->bytesPerLine() & 3) != 0);
    170177        }
     
    172179        {
    173180            /* ...and the scan lines ought to be a whole number of pixels. */
    174             Assert ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) == 0);
     181            Assert((bitsPerLine & (pEvent->bitsPerPixel() - 1)) == 0);
    175182            bFallback = ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) != 0);
    176183        }
    177184        if (!bFallback)
    178185        {
    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);
    185194            m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
    186195            m_bUsesGuestVRAM = true;
     
    188197    }
    189198    else
    190     {
    191199        bFallback = true;
    192     }
    193 
     200
     201    /* Fallback if requested: */
    194202    if (bFallback)
    195     {
    196203        goFallback();
    197     }
    198 
     204
     205    /* Remind if requested: */
    199206    if (bRemind)
    200207        msgCenter().remindAboutWrongColorDepth(pEvent->bitsPerPixel(), 32);
     
    203210void UIFrameBufferQImage::goFallback()
    204211{
    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: */
    208216    m_img = QImage(m_width, m_height, QImage::Format_RGB32);
    209217    m_img.fill(0);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.h

    r44529 r46062  
    66
    77/*
    8  * Copyright (C) 2010-2012 Oracle Corporation
     8 * Copyright (C) 2010-2013 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
     19#ifdef VBOX_GUI_USE_QIMAGE
     20
    1921#ifndef ___UIFrameBufferQImage_h___
    2022#define ___UIFrameBufferQImage_h___
    2123
    22 #ifdef VBOX_GUI_USE_QIMAGE
    23 
    24 /* Local includes */
    25 #include "UIFrameBuffer.h"
    26 
    27 /* Global includes */
     24/* Qt includes: */
    2825#include <QImage>
    2926#include <QPixmap>
    3027
     28/* GUI includes: */
     29#include "UIFrameBuffer.h"
     30
     31/* QImage frame-buffer prototype: */
    3132class UIFrameBufferQImage : public UIFrameBuffer
    3233{
    3334public:
    3435
     36    /* Constructor: */
    3537    UIFrameBufferQImage(UIMachineView *pMachineView);
    3638
    37     STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH);
    38 
     39    /* API: Frame-buffer stuff: */
    3940    ulong pixelFormat() { return m_uPixelFormat; }
    4041    bool usesGuestVRAM() { return m_bUsesGuestVRAM; }
    41 
    4242    uchar *address() { return m_img.bits(); }
    4343    ulong bitsPerPixel() { return m_img.depth(); }
    4444    ulong bytesPerLine() { return m_img.bytesPerLine(); }
    4545
     46    /* API: Event-delegate stuff: */
     47    void resizeEvent(UIResizeEvent *pEvent);
    4648    void paintEvent(QPaintEvent *pEvent);
    47     void resizeEvent(UIResizeEvent *pEvent);
     49
     50protected:
     51
     52    /* Callback: Guest paint-event stuff: */
     53    STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH);
    4854
    4955private:
    5056
     57    /* Helper: Fallback stuff: */
    5158    void goFallback();
    5259
     60    /* Variables: */
    5361    QPixmap m_PM;
    5462    QImage m_img;
     
    5765};
    5866
     67#endif /* !___UIFrameBufferQImage_h___ */
     68
    5969#endif /* VBOX_GUI_USE_QIMAGE */
    6070
    61 #endif /* !___UIFrameBufferQImage_h___ */
    62 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette