VirtualBox

Changeset 6645 in vbox


Ignore:
Timestamp:
Jan 31, 2008 10:02:59 AM (17 years ago)
Author:
vboxsync
Message:

Mac OS X: Added Quartz2D framebuffer implementation.
This fixes the outstanding seamless issues also. Added commandline switch
"-rmode quartz2d" to VirtualBox. As from now the Quartz2D framebuffer
is the default painting engine on Mac OS X.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r6572 r6645  
    251251        src/darwin/DarwinCursor.cpp \
    252252        src/darwin/VBoxAquaStyle.cpp \
    253         src/darwin/VBoxUtils-darwin.cpp
     253        src/darwin/VBoxUtils-darwin.cpp \
     254        src/VBoxFBQuartz2D.cpp
    254255
    255256ifneq ($(BUILD_TARGET),win)
     
    269270VirtualBox_DEFS           = VBOX_GUI_SEPARATE_VM_PROCESS
    270271VirtualBox_DEFS.debug     = VBOX_GUI_DEBUG VBOX_CHECK_STATE # QT_FATAL_ASSERT
    271 VirtualBox_DEFS.darwin    = VBOX_GUI_USE_QIMAGE VBOX_WITHOUT_QHTTP
     272VirtualBox_DEFS.darwin    = VBOX_GUI_USE_QUARTZ2D VBOX_GUI_USE_QIMAGE VBOX_WITHOUT_QHTTP
    272273VirtualBox_DEFS.freebsd   = VBOX_GUI_USE_QIMAGE VBOX_GUI_USE_SDL
    273274VirtualBox_DEFS.linux     = VBOX_GUI_USE_SDL
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h

    r5999 r6645  
    115115    enum RenderMode
    116116    {
    117         InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode
     117        InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode, Quartz2DMode
    118118    };
    119119
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h

    r5999 r6645  
    459459#endif
    460460
     461/////////////////////////////////////////////////////////////////////////////
     462
     463#if defined(Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
     464
     465#include <Carbon/Carbon.h>
     466class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
     467{
     468public:
     469
     470    VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
     471    virtual ~VBoxQuartz2DFrameBuffer ();
     472
     473    STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
     474                              ULONG aW, ULONG aH,
     475                              BOOL *aFinished);
     476    STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
     477
     478    uchar *address () { return mDataAddress; }
     479    ulong bitsPerPixel () { return CGImageGetBitsPerPixel (mImage); }
     480    ulong bytesPerLine () { return CGImageGetBytesPerRow (mImage); }
     481    ulong pixelFormat () { return mPixelFormat; };
     482    bool usesGuestVRAM () { return mBitmapData == NULL; }
     483
     484    const CGImageRef imageRef () const { return mImage; }
     485
     486    void paintEvent (QPaintEvent *pe);
     487    void resizeEvent (VBoxResizeEvent *re);
     488
     489private:
     490    inline CGRect QRectToCGRect (const QRect &aRect) const
     491    {
     492        return CGRectMake (aRect.x (), aRect.y (), aRect.width (), aRect.height ());
     493    }
     494    inline QRect mapYOrigin (const QRect &aRect, int aHeight) const
     495    {
     496        /* The cgcontext has a fliped y-coord relative to the
     497         * qt coord system. So we need some mapping here */
     498        return QRect (aRect.x (), aHeight - (aRect.y () + aRect.height ()), aRect.width (), aRect.height ());
     499    }
     500    void clean ();
     501
     502    uchar *mDataAddress;
     503    void *mBitmapData;
     504    ulong mPixelFormat;
     505    CGImageRef mImage;
     506    CGRect *mRegionRects;
     507    ULONG mRegionCount;
     508};
     509
     510#endif
     511
    461512#endif // __VBoxFrameBuffer_h__
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxUtils.h

    r6482 r6645  
    255255CGImageRef DarwinQPixmapFromMimeSourceToCGImage (const char *aSource);
    256256CGImageRef DarwinCreateDockBadge (const char *aSource);
     257CGImageRef DarwinCreateDockPreview (CGImageRef aVMImage, CGImageRef aOverlayImage);
    257258CGImageRef DarwinCreateDockPreview (VBoxFrameBuffer *aFrameBuffer, CGImageRef aOverlayImage);
    258259OSStatus DarwinRegionHandler (EventHandlerCallRef aInHandlerCallRef, EventRef aInEvent, void *aInUserData);
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r6482 r6645  
    706706        case VBoxDefs::DDRAWMode:
    707707            mFrameBuf = new VBoxDDRAWFrameBuffer (this);
     708            break;
     709#endif
     710#if defined (VBOX_GUI_USE_QUARTZ2D)
     711        case VBoxDefs::Quartz2DMode:
     712            mFrameBuf = new VBoxQuartz2DFrameBuffer (this);
    708713            break;
    709714#endif
     
    28072812#ifdef Q_WS_MAC
    28082813            /* Update the dock icon if we are in the running state */
    2809             if (isRunning())
    2810                 SetApplicationDockTileImage (::DarwinCreateDockPreview(mFrameBuf, mMainWnd->dockImageState ()));
     2814            if (isRunning ())
     2815            {
     2816# if defined (VBOX_GUI_USE_QUARTZ2D)
     2817                if (mode == VBoxDefs::Quartz2DMode)
     2818                {
     2819                    /* If the render mode is Quartz2D we could use the CGImageRef of the framebuffer
     2820                     * for the dock icon creation. This saves some conversation time. */
     2821                    CGImageRef ir = static_cast<VBoxQuartz2DFrameBuffer*>(mFrameBuf)->imageRef ();
     2822                    SetApplicationDockTileImage (::DarwinCreateDockPreview (ir, mMainWnd->dockImageState ()));
     2823                }else
     2824# endif
     2825                    SetApplicationDockTileImage (::DarwinCreateDockPreview (mFrameBuf, mMainWnd->dockImageState ()));
     2826            }
    28112827#endif
    28122828            return;
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp

    r6603 r6645  
    21022102            status = SetWindowAlpha(WindowRef, 0.999);
    21032103            Assert (status == noErr);
     2104            /* For now disable the shadow of the window. This feature cause errors
     2105             * if a window in vbox looses focus, is reselected and than moved.
     2106             * todo: Search for an option to enable this again. A shadow on every
     2107             * window has a big coolness factor. */
     2108            ChangeWindowAttributes (WindowRef, kWindowNoShadowAttribute, 0);
    21042109        }
    21052110#else
     
    26662671    mPrevRegion = region;
    26672672#elif defined(Q_WS_MAC)
    2668     /* This is necessary to avoid the flicker by an mask update.
    2669      * See http://lists.apple.com/archives/Carbon-development/2001/Apr/msg01651.html
    2670      * for the hint.
    2671      * There *must* be a better solution. */
    2672     if (!region.isEmpty ())
    2673         region |= QRect (0, 0, 1, 1);
    2674     /* Save the current region for later processing in the darwin event handler. */
    2675     mCurrRegion = region;
    2676     /* We repaint the screen before the ReshapeCustomWindow command. Unfortunately
    2677      * this command flushes a copy of the backbuffer to the screen after the new
    2678      * mask is set. This leads into a missplaced drawing of the content. Currently
    2679      * no alternative to this and also this is not 100% perfect. */
    2680     repaint ();
    2681     qApp->processEvents ();
    2682     /* Now force the reshaping of the window. This is definitly necessary. */
    2683     ReshapeCustomWindow (reinterpret_cast<WindowPtr>(winId()));
     2673# if defined(VBOX_GUI_USE_QUARTZ2D)
     2674    if (vboxGlobal().vmRenderMode() == VBoxDefs::Quartz2DMode)
     2675    {
     2676        /* If we are using the Quartz2D backend we have to trigger
     2677         * an repaint only. All the magic clipping stuff is done
     2678         * in the paint engine. */
     2679        repaint ();
     2680//        qApp->processEvents ();
     2681    }
     2682    else
     2683# endif
     2684    {
     2685        /* This is necessary to avoid the flicker by an mask update.
     2686         * See http://lists.apple.com/archives/Carbon-development/2001/Apr/msg01651.html
     2687         * for the hint.
     2688         * There *must* be a better solution. */
     2689        if (!region.isEmpty ())
     2690            region |= QRect (0, 0, 1, 1);
     2691        /* Save the current region for later processing in the darwin event handler. */
     2692        mCurrRegion = region;
     2693        /* We repaint the screen before the ReshapeCustomWindow command. Unfortunately
     2694         * this command flushes a copy of the backbuffer to the screen after the new
     2695         * mask is set. This leads into a missplaced drawing of the content. Currently
     2696         * no alternative to this and also this is not 100% perfect. */
     2697        repaint ();
     2698        qApp->processEvents ();
     2699        /* Now force the reshaping of the window. This is definitly necessary. */
     2700        ReshapeCustomWindow (reinterpret_cast<WindowPtr>(winId()));
     2701    }
    26842702#else
    26852703    QMainWindow::setMask (region);
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp

    r5999 r6645  
    632632
    633633#endif
     634
     635//
     636// VBoxQuartz2DFrameBuffer class
     637/////////////////////////////////////////////////////////////////////////////
     638
     639#if defined (VBOX_GUI_USE_QUARTZ2D)
     640
     641/* The class is defined in VBoxQuartz2D.cpp */
     642
     643#endif
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp

    r6616 r6645  
    678678    VBoxDefs::RenderMode mode = VBoxDefs::InvalidRenderMode;
    679679
    680 #if (defined (Q_WS_WIN32) || defined (Q_WS_PM)) && defined (VBOX_GUI_USE_QIMAGE)
     680#if defined (Q_WS_MAC) && defined(VBOX_GUI_USE_QUARTZ2D)
     681    mode = VBoxDefs::Quartz2DMode;
     682#elif (defined (Q_WS_WIN32) || defined (Q_WS_PM)) && defined (VBOX_GUI_USE_QIMAGE)
    681683    mode = VBoxDefs::QImageMode;
    682684#elif defined (Q_WS_X11) && defined (VBOX_GUI_USE_SDL)
     
    706708        else if (::strcmp (aModeStr, "ddraw") == 0)
    707709            mode = VBoxDefs::DDRAWMode;
     710#endif
     711#if defined (VBOX_GUI_USE_QUARTZ2D)
     712        else if (::strcmp (aModeStr, "quartz2d") == 0)
     713            mode = VBoxDefs::Quartz2DMode;
    708714#endif
    709715    }
  • trunk/src/VBox/Frontends/VirtualBox/src/darwin/VBoxUtils-darwin.cpp

    r6491 r6645  
    3333 * @param   info        Pointer to the QImage.
    3434 */
    35 static void darwinDataProviderReleaseQImage(void *info, const void *, size_t)
     35static void darwinDataProviderReleaseQImage (void *info, const void *, size_t)
    3636{
    3737    QImage *qimg = (QImage *)info;
     
    4545 * @param   aPixmap     Pointer to the QPixmap instance to convert.
    4646 */
    47 CGImageRef DarwinQImageToCGImage(const QImage *aImage)
    48 {
    49     QImage *imageCopy = new QImage(*aImage);
     47CGImageRef DarwinQImageToCGImage (const QImage *aImage)
     48{
     49    QImage *imageCopy = new QImage (*aImage);
    5050    /** @todo this code assumes 32-bit image input, the lazy bird convert image to 32-bit method is anything but optimal... */
    51     if (imageCopy->depth() != 32)
     51    if (imageCopy->depth () != 32)
    5252        *imageCopy = imageCopy->convertDepth (32);
    53     Assert (!imageCopy->isNull());
    54 
    55     CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    56     CGDataProviderRef dp = CGDataProviderCreateWithData (imageCopy, aImage->bits(), aImage->numBytes(), darwinDataProviderReleaseQImage);
    57 
    58     CGBitmapInfo bmpInfo = imageCopy->hasAlphaBuffer() ? kCGImageAlphaFirst : kCGImageAlphaNoneSkipFirst;
     53    Assert (!imageCopy->isNull ());
     54
     55    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
     56    CGDataProviderRef dp = CGDataProviderCreateWithData (imageCopy, aImage->bits (), aImage->numBytes (), darwinDataProviderReleaseQImage);
     57
     58    CGBitmapInfo bmpInfo = imageCopy->hasAlphaBuffer () ? kCGImageAlphaFirst : kCGImageAlphaNoneSkipFirst;
    5959    bmpInfo |= kCGBitmapByteOrder32Host;
    60     CGImageRef ir = CGImageCreate (imageCopy->width(), imageCopy->height(), 8, 32, imageCopy->bytesPerLine(), cs,
     60    CGImageRef ir = CGImageCreate (imageCopy->width (), imageCopy->height (), 8, 32, imageCopy->bytesPerLine (), cs,
    6161                                   bmpInfo, dp, 0 /*decode */, 0 /* shouldInterpolate */,
    6262                                   kCGRenderingIntentDefault);
     
    7474 * @param   aPixmap     Pointer to the QPixmap instance to convert.
    7575 */
    76 CGImageRef DarwinQPixmapToCGImage(const QPixmap *aPixmap)
    77 {
    78     QImage qimg = aPixmap->convertToImage();
    79     Assert (!qimg.isNull());
    80     return DarwinQImageToCGImage(&qimg);
     76CGImageRef DarwinQPixmapToCGImage (const QPixmap *aPixmap)
     77{
     78    QImage qimg = aPixmap->convertToImage ();
     79    Assert (!qimg.isNull ());
     80    return DarwinQImageToCGImage (&qimg);
    8181}
    8282
     
    9090{
    9191    QPixmap qpm = QPixmap::fromMimeSource (aSource);
    92     Assert (!qpm.isNull());
     92    Assert (!qpm.isNull ());
    9393    return DarwinQPixmapToCGImage (&qpm);
    9494}
     
    108108       just created one that I can load. The Qt gurus can fix this if they like :-) */
    109109    QPixmap back (QPixmap::fromMimeSource ("dock_128x128_transparent.png"));
    110     Assert (!back.isNull());
    111     Assert (back.width() == 128 && back.height() == 128);
     110    Assert (!back.isNull ());
     111    Assert (back.width () == 128 && back.height () == 128);
    112112
    113113    /* load the badge */
    114114    QPixmap badge = QPixmap::fromMimeSource (aSource);
    115     Assert (!badge.isNull());
     115    Assert (!badge.isNull ());
    116116
    117117    /* resize it and copy it onto the background. */
    118     if (badge.width() < 32)
    119         badge = badge.convertToImage().smoothScale (32, 32);
    120     copyBlt (&back, back.width() - badge.width(), back.height() - badge.height(),
     118    if (badge.width () < 32)
     119        badge = badge.convertToImage ().smoothScale (32, 32);
     120    copyBlt (&back, back.width () - badge.width (), back.height () - badge.height (),
    121121             &badge, 0, 0,
    122              badge.width(), badge.height());
    123     Assert (!back.isNull());
    124     Assert (back.width() == 128 && back.height() == 128);
     122             badge.width (), badge.height ());
     123    Assert (!back.isNull ());
     124    Assert (back.width () == 128 && back.height () == 128);
    125125
    126126    /* Convert it to a CGImage. */
     
    128128}
    129129
     130
    130131/**
    131132 * Creates a dock preview image.
     
    134135 *
    135136 * @returns CGImageRef for the new image. (Remember to release it when finished with it.)
    136  * @param   aFrameBuffer    The guest frame buffer.
    137  */
    138 CGImageRef DarwinCreateDockPreview (VBoxFrameBuffer *aFrameBuffer, CGImageRef aOverlayImage)
    139 {
    140     CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    141 
    142     /* Create the image copy of the framebuffer */
    143     CGDataProviderRef dp = CGDataProviderCreateWithData (aFrameBuffer, aFrameBuffer->address(), aFrameBuffer->bitsPerPixel() / 8 * aFrameBuffer->width() * aFrameBuffer->height() , NULL);
    144     CGImageRef ir = CGImageCreate (aFrameBuffer->width(), aFrameBuffer->height(), 8, 32, aFrameBuffer->bytesPerLine(), cs,
    145                                    kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
    146                                    kCGRenderingIntentDefault);
    147 
     137 * @param   aVMImage   the vm screen as a CGImageRef
     138 * @param   aOverlayImage   an optional overlay image to add at the bottom right of the icon
     139 */
     140CGImageRef DarwinCreateDockPreview (CGImageRef aVMImage, CGImageRef aOverlayImage)
     141{
     142    Assert (aVMImage);
     143
     144    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
    148145    Assert (cs);
    149     Assert (dp);
    150     Assert (ir);
    151146
    152147    /* Calc the size of the dock icon image and fit it into 128x128 */
     
    155150    int scaledWidth;
    156151    int scaledHeight;
    157     float aspect = static_cast<float>(aFrameBuffer->width()) / aFrameBuffer->height();
     152    float aspect = static_cast<float>(CGImageGetWidth (aVMImage)) / CGImageGetHeight (aVMImage);
    158153    if (aspect > 1.0)
    159154    {
     
    179174        /* rounded corners */
    180175//        CGContextSetLineJoin (context, kCGLineJoinRound);
    181 //        CGContextSetShadow (context, CGSizeMake(10, 5), 1);
     176//        CGContextSetShadow (context, CGSizeMake (10, 5), 1);
    182177//        CGContextSetAllowsAntialiasing (context, true);
    183178        /* some little boarder */
     
    193188        /* vm content */
    194189        iconRect = CGRectInset (iconRect, 1, 1);
    195         CGContextDrawImage (context, iconRect, ir);
     190        CGContextDrawImage (context, iconRect, aVMImage);
    196191        /* the overlay image */
    197192        if (aOverlayImage)
     
    207202
    208203    CGColorSpaceRelease (cs);
     204
     205    Assert (dockImage);
     206    return dockImage;
     207}
     208
     209/**
     210 * Creates a dock preview image.
     211 *
     212 * This method is a callback that creates a 128x128 preview image of the VM window.
     213 *
     214 * @returns CGImageRef for the new image. (Remember to release it when finished with it.)
     215 * @param   aFrameBuffer    The guest frame buffer.
     216 * @param   aOverlayImage   an optional overlay image to add at the bottom right of the icon
     217 */
     218CGImageRef DarwinCreateDockPreview (VBoxFrameBuffer *aFrameBuffer, CGImageRef aOverlayImage)
     219{
     220    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
     221    Assert (cs);
     222    /* Create the image copy of the framebuffer */
     223    CGDataProviderRef dp = CGDataProviderCreateWithData (aFrameBuffer, aFrameBuffer->address (), aFrameBuffer->bitsPerPixel () / 8 * aFrameBuffer->width () * aFrameBuffer->height (), NULL);
     224    Assert (dp);
     225    CGImageRef ir = CGImageCreate (aFrameBuffer->width (), aFrameBuffer->height (), 8, 32, aFrameBuffer->bytesPerLine (), cs,
     226                                   kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
     227                                   kCGRenderingIntentDefault);
     228    /* Create the preview icon */
     229    CGImageRef dockImage = DarwinCreateDockPreview (ir, aOverlayImage);
     230    /* Release the temp data and image */
    209231    CGDataProviderRelease (dp);
    210232    CGImageRelease (ir);
    211 
    212     Assert (dockImage);
     233    CGColorSpaceRelease (cs);
     234
    213235    return dockImage;
    214236}
     
    216238OSStatus DarwinRegionHandler (EventHandlerCallRef aInHandlerCallRef, EventRef aInEvent, void *aInUserData)
    217239{
    218     NOREF(aInHandlerCallRef);
     240    NOREF (aInHandlerCallRef);
    219241
    220242    OSStatus status = eventNotHandledErr;
     
    241263            {
    242264                GetEventParameter (aInEvent, kEventParamRgnHandle, typeQDRgnHandle, NULL, sizeof (rgn), NULL, &rgn);
    243                 QRegion *pRegion = static_cast <QRegion*>(aInUserData);
    244                 if(!pRegion->isNull () && pRegion)
     265                QRegion *pRegion = static_cast <QRegion*> (aInUserData);
     266                if (!pRegion->isNull () && pRegion)
    245267                {
    246                     CopyRgn (pRegion->handle(), rgn);
     268                    CopyRgn (pRegion->handle (), rgn);
    247269                    status = noErr;
    248270                }
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