VirtualBox

Changeset 51436 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 28, 2014 9:12:15 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
93991
Message:

Main,Frontends: IDisplay provides the guest screen bitmap to frontends.

Location:
trunk/src/VBox
Files:
1 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxHeadless/Framebuffer.cpp

    r49980 r51436  
    4242
    4343    RTCritSectInit (&m_CritSect);
    44 
    45     // start with a standard size
    46     RequestResize(0, FramebufferPixelFormat_Opaque,
    47                   NULL, 0, 0, 640, 480, NULL);
    4844}
    4945
     
    241237
    242238    return S_OK;
     239}
     240
     241extern ComPtr<IDisplay> display;
     242
     243STDMETHODIMP VRDPFramebuffer::NotifyChange(ULONG aScreenId,
     244                                           ULONG aXOrigin,
     245                                           ULONG aYOrigin,
     246                                           ULONG aWidth,
     247                                           ULONG aHeight)
     248{
     249    LogRelFlow(("NotifyChange: %d %d,%d %dx%d\n",
     250                aScreenId, aXOrigin, aYOrigin, aWidth, aHeight));
     251
     252    HRESULT hr = S_OK;
     253
     254    hr = display->QuerySourceBitmap(aScreenId, mpSourceBitmap.asOutParam());
     255    if (SUCCEEDED(hr))
     256    {
     257        BYTE *pAddress = NULL;
     258        ULONG ulWidth = 0;
     259        ULONG ulHeight = 0;
     260        ULONG ulBitsPerPixel = 0;
     261        ULONG ulBytesPerLine = 0;
     262        ULONG ulPixelFormat = 0;
     263
     264        hr = mpSourceBitmap->QueryBitmapInfo(&pAddress,
     265                                        &ulWidth,
     266                                        &ulHeight,
     267                                        &ulBitsPerPixel,
     268                                        &ulBytesPerLine,
     269                                        &ulPixelFormat);
     270
     271        if (SUCCEEDED(hr))
     272        {
     273            mScreen = pAddress;
     274            mWidth = ulWidth;
     275            mHeight = ulHeight;
     276            mBitsPerPixel = ulBitsPerPixel;
     277            mBytesPerLine = ulBytesPerLine;
     278            mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
     279            mUsesGuestVRAM = TRUE;
     280
     281            Log(("Using screen bitmap, %d BPP\n", mBitsPerPixel));
     282        }
     283    }
     284
     285    if (FAILED(hr))
     286    {
     287        /* Just reset everything. */
     288        mScreen = NULL;
     289        mWidth = 0;
     290        mHeight = 0;
     291        mBitsPerPixel = 0;
     292        mBytesPerLine = 0;
     293        mPixelFormat = FramebufferPixelFormat_Opaque;
     294        mUsesGuestVRAM = FALSE;
     295
     296        Log(("No screen w = %d, h = %d!!!\n", aWidth, aHeight));
     297    }
     298
     299    return hr;
    243300}
    244301
  • trunk/src/VBox/Frontends/VBoxHeadless/Framebuffer.h

    r45940 r51436  
    6363                             ULONG bitsPerPixel, ULONG bytesPerLine, ULONG w, ULONG h,
    6464                             BOOL *finished);
     65    STDMETHOD(NotifyChange)(ULONG aScreenId,
     66                            ULONG aXOrigin,
     67                            ULONG aYOrigin,
     68                            ULONG aWidth,
     69                            ULONG aHeight);
    6570    STDMETHOD(VideoModeSupported)(ULONG width, ULONG height, ULONG bpp, BOOL *supported);
    6671
     
    9297    long refcnt;
    9398#endif
     99
     100    ComPtr<IDisplaySourceBitmap> mpSourceBitmap;
    94101};
    95102
  • trunk/src/VBox/Frontends/VBoxHeadless/NullFramebuffer.h

    r45940 r51436  
    180180        return S_OK;
    181181    }
     182    STDMETHOD(NotifyChange)(ULONG aScreenId,
     183                            ULONG aXOrigin,
     184                            ULONG aYOrigin,
     185                            ULONG aWidth,
     186                            ULONG aHeight)
     187    {
     188        /* Do nothing. */
     189        return S_OK;
     190    }
    182191    STDMETHOD(VideoModeSupported)(ULONG width, ULONG height, ULONG bpp, BOOL *supported)
    183192    {
  • trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp

    r50406 r51436  
    639639static CComModule _Module;
    640640#endif
     641
     642ComPtr<IDisplay> display;
    641643
    642644/**
     
    968970        CHECK_ERROR_BREAK(console, COMGETTER(Machine)(machine.asOutParam()));
    969971
    970         ComPtr<IDisplay> display;
    971972        CHECK_ERROR_BREAK(console, COMGETTER(Display)(display.asOutParam()));
    972973
     
    10091010                Log2(("VBoxHeadless: Registering framebuffer\n"));
    10101011                pFramebuffer->AddRef();
    1011                 display->SetFramebuffer(VBOX_VIDEO_PRIMARY_SCREEN, pFramebuffer);
     1012                display->AttachFramebuffer(VBOX_VIDEO_PRIMARY_SCREEN, pFramebuffer);
    10121013            }
    10131014            if (!RT_SUCCESS(rrc) || rcc != S_OK)
     
    10391040            }
    10401041            pVRDPFramebuffer->AddRef();
    1041             display->SetFramebuffer(uScreenId, pVRDPFramebuffer);
     1042            display->AttachFramebuffer(uScreenId, pVRDPFramebuffer);
    10421043        }
    10431044        if (uScreenId < cMonitors)
     
    10501051        {
    10511052            ComPtr<IFramebuffer> fb;
    1052             LONG xOrigin, yOrigin;
    1053             HRESULT hrc2 = display->GetFramebuffer(uScreenId,
    1054                                                    fb.asOutParam(),
    1055                                                    &xOrigin, &yOrigin);
     1053            HRESULT hrc2 = display->QueryFramebuffer(uScreenId,
     1054                                                     fb.asOutParam());
    10561055            if (hrc2 == S_OK && fb.isNull())
    10571056            {
     
    10591058                pNullFB->AddRef();
    10601059                pNullFB->init();
    1061                 display->SetFramebuffer(uScreenId, pNullFB);
     1060                display->AttachFramebuffer(uScreenId, pNullFB);
    10621061            }
    10631062        }
     
    13301329    while (0);
    13311330
     1331    display.setNull();
     1332
    13321333    /*
    13331334     * Get the machine state.
  • trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp

    r50406 r51436  
    130130    mLabelOffs      = 0;
    131131#endif
     132
     133    mfUpdates = false;
    132134
    133135    rc = RTCritSectInit(&mUpdateLock);
     
    553555}
    554556
     557extern ComPtr<IDisplay> gpDisplay;
     558
     559/* This method runs on the main SDL thread. */
     560void VBoxSDLFB::notifyChange(ULONG aScreenId)
     561{
     562    /* Disable screen updates. */
     563    RTCritSectEnter(&mUpdateLock);
     564
     565    if (mpPendingSourceBitmap.isNull())
     566    {
     567        /* Do nothing. Change event already processed. */
     568        RTCritSectLeave(&mUpdateLock);
     569        return;
     570    }
     571
     572    /* Disable screen updates. */
     573    mfUpdates = false;
     574
     575    /* Release the current bitmap and keep the pending one. */
     576    mpSourceBitmap = mpPendingSourceBitmap;
     577    mpPendingSourceBitmap.setNull();
     578
     579    RTCritSectLeave(&mUpdateLock);
     580
     581    BYTE *pAddress = NULL;
     582    ULONG ulWidth = 0;
     583    ULONG ulHeight = 0;
     584    ULONG ulBitsPerPixel = 0;
     585    ULONG ulBytesPerLine = 0;
     586    ULONG ulPixelFormat = 0;
     587
     588    mpSourceBitmap->QueryBitmapInfo(&pAddress,
     589                                    &ulWidth,
     590                                    &ulHeight,
     591                                    &ulBitsPerPixel,
     592                                    &ulBytesPerLine,
     593                                    &ulPixelFormat);
     594
     595    if (   mGuestXRes    == ulWidth
     596        && mGuestYRes    == ulHeight
     597        && mBitsPerPixel == ulBitsPerPixel
     598        && mBytesPerLine == ulBytesPerLine
     599        && mPtrVRAM == pAddress
     600       )
     601    {
     602        mfSameSizeRequested = true;
     603    }
     604    else
     605    {
     606        mfSameSizeRequested = false;
     607    }
     608
     609    mGuestXRes   = ulWidth;
     610    mGuestYRes   = ulHeight;
     611    mPixelFormat = FramebufferPixelFormat_Opaque;
     612    mPtrVRAM     = pAddress;
     613    mBitsPerPixel = ulBitsPerPixel;
     614    mBytesPerLine = ulBytesPerLine;
     615    mUsesGuestVRAM = FALSE; /* yet */
     616
     617    resizeGuest();
     618}
     619
     620STDMETHODIMP VBoxSDLFB::NotifyChange(ULONG aScreenId,
     621                                     ULONG aXOrigin,
     622                                     ULONG aYOrigin,
     623                                     ULONG aWidth,
     624                                     ULONG aHeight)
     625{
     626    LogRel(("NotifyChange: %d %d,%d %dx%d\n",
     627             aScreenId, aXOrigin, aYOrigin, aWidth, aHeight));
     628
     629    /* Obtain the new screen bitmap. */
     630    RTCritSectEnter(&mUpdateLock);
     631
     632    /* Save the new bitmap. */
     633    mpPendingSourceBitmap.setNull();
     634    gpDisplay->QuerySourceBitmap(aScreenId, mpPendingSourceBitmap.asOutParam());
     635
     636    RTCritSectLeave(&mUpdateLock);
     637
     638    SDL_Event event;
     639    event.type       = SDL_USEREVENT;
     640    event.user.type  = SDL_USER_EVENT_NOTIFYCHANGE;
     641    event.user.code  = mScreenId;
     642
     643    PushSDLEventForSure(&event);
     644
     645    RTThreadYield();
     646
     647    return S_OK;
     648}
     649
    555650/**
    556651 * Returns whether we like the given video mode.
     
    686781
    687782    /* is the guest in a linear framebuffer mode we support? */
    688     if (mUsesGuestVRAM)
     783    if (mPtrVRAM || mUsesGuestVRAM)
    689784    {
    690785        /* Create a source surface from guest VRAM. */
     
    710805        mfSameSizeRequested = false;
    711806        LogFlow(("VBoxSDL:: the same resolution requested, skipping the resize.\n"));
     807
     808        /* Enable screen updates. */
     809        RTCritSectEnter(&mUpdateLock);
     810        mfUpdates = true;
     811        RTCritSectLeave(&mUpdateLock);
     812
    712813        return;
    713814    }
     
    715816    /* now adjust the SDL resolution */
    716817    resizeSDL();
     818
     819    /* Enable screen updates. */
     820    RTCritSectEnter(&mUpdateLock);
     821    mfUpdates = true;
     822    RTCritSectLeave(&mUpdateLock);
     823
     824    repaint();
    717825}
    718826
     
    9611069        return;
    9621070
     1071    RTCritSectEnter(&mUpdateLock);
     1072    Log(("Updates %d, %d,%d %dx%d\n", mfUpdates, x, y, w, h));
     1073    if (!mfUpdates)
     1074    {
     1075        RTCritSectLeave(&mUpdateLock);
     1076        return;
     1077    }
    9631078    /* the source and destination rectangles */
    9641079    SDL_Rect srcRect;
     
    10391154        paintSecureLabel(0, 0, 0, 0, false);
    10401155#endif
     1156    RTCritSectLeave(&mUpdateLock);
    10411157}
    10421158
  • trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h

    r45940 r51436  
    8989                             ULONG bitsPerPixel, ULONG bytesPerLine,
    9090                             ULONG w, ULONG h, BOOL *finished);
     91    STDMETHOD(NotifyChange)(ULONG aScreenId,
     92                            ULONG aXOrigin,
     93                            ULONG aYOrigin,
     94                            ULONG aWidth,
     95                            ULONG aHeight);
    9196    STDMETHOD(VideoModeSupported)(ULONG width, ULONG height, ULONG bpp, BOOL *supported);
    9297
     
    100105    // internal public methods
    101106    bool initialized() { return mfInitialized; }
     107    void notifyChange(ULONG aScreenId);
    102108    void resizeGuest();
    103109    void resizeSDL();
     
    202208    BOOL mUsesGuestVRAM;
    203209    BOOL mfSameSizeRequested;
     210
     211    ComPtr<IDisplaySourceBitmap> mpSourceBitmap;
     212    ComPtr<IDisplaySourceBitmap> mpPendingSourceBitmap;
     213    bool mfUpdates;
    204214};
    205215
  • trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp

    r51122 r51436  
    202202static ComPtr<IKeyboard> gpKeyboard;
    203203static ComPtr<IMouse> gpMouse;
    204 static ComPtr<IDisplay> gpDisplay;
     204ComPtr<IDisplay> gpDisplay;
    205205static ComPtr<IVRDEServer> gpVRDEServer;
    206206static ComPtr<IProgress> gpProgress;
     
    19381938    {
    19391939        // register our framebuffer
    1940         rc = gpDisplay->SetFramebuffer(i, gpFramebuffer[i]);
     1940        rc = gpDisplay->AttachFramebuffer(i, gpFramebuffer[i]);
    19411941        if (FAILED(rc))
    19421942        {
     
    19441944            goto leave;
    19451945        }
    1946         IFramebuffer *dummyFb;
    19471946        LONG xOrigin, yOrigin;
    1948         rc = gpDisplay->GetFramebuffer(i, &dummyFb, &xOrigin, &yOrigin);
     1947        rc = gpDisplay->GetScreenResolution(i, NULL, NULL, NULL, &xOrigin, &yOrigin);
    19491948        gpFramebuffer[i]->setOrigin(xOrigin, yOrigin);
    19501949    }
     
    22182217                    {
    22192218                        LogFlow(("SDL_USER_EVENT_RESIZE\n"));
    2220                         IFramebuffer *dummyFb;
    22212219                        LONG xOrigin, yOrigin;
    22222220                        gpFramebuffer[event.user.code]->resizeGuest();
    22232221                        /* update xOrigin, yOrigin -> mouse */
    2224                         rc = gpDisplay->GetFramebuffer(event.user.code, &dummyFb, &xOrigin, &yOrigin);
     2222                        rc = gpDisplay->GetScreenResolution(event.user.code, NULL, NULL, NULL, &xOrigin, &yOrigin);
    22252223                        gpFramebuffer[event.user.code]->setOrigin(xOrigin, yOrigin);
    2226                         /* notify the display that the resize has been completed */
    2227                         gpDisplay->ResizeCompleted(event.user.code);
    22282224                        break;
    22292225                    }
     
    27032699            {
    27042700                LogFlow(("SDL_USER_EVENT_RESIZE\n"));
    2705                 IFramebuffer *dummyFb;
    27062701                LONG xOrigin, yOrigin;
    27072702                gpFramebuffer[event.user.code]->resizeGuest();
    27082703                /* update xOrigin, yOrigin -> mouse */
    2709                 rc = gpDisplay->GetFramebuffer(event.user.code, &dummyFb, &xOrigin, &yOrigin);
     2704                rc = gpDisplay->GetScreenResolution(event.user.code, NULL, NULL, NULL, &xOrigin, &yOrigin);
    27102705                gpFramebuffer[event.user.code]->setOrigin(xOrigin, yOrigin);
    2711                 /* notify the display that the resize has been completed */
    2712                 gpDisplay->ResizeCompleted(event.user.code);
     2706                break;
     2707            }
     2708
     2709            case SDL_USER_EVENT_NOTIFYCHANGE:
     2710            {
     2711                LogFlow(("SDL_USER_EVENT_NOTIFYCHANGE\n"));
     2712                LONG xOrigin, yOrigin;
     2713                gpFramebuffer[event.user.code]->notifyChange(event.user.code);
     2714                /* update xOrigin, yOrigin -> mouse */
     2715                rc = gpDisplay->GetScreenResolution(event.user.code, NULL, NULL, NULL, &xOrigin, &yOrigin);
     2716                gpFramebuffer[event.user.code]->setOrigin(xOrigin, yOrigin);
    27132717                break;
    27142718            }
     
    29172921    {
    29182922        for (unsigned i = 0; i < gcMonitors; i++)
    2919             gpDisplay->SetFramebuffer(i, NULL);
     2923            gpDisplay->DetachFramebuffer(i);
    29202924    }
    29212925
  • trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.h

    r44528 r51436  
    4747/** custom SDL user event for window resize done */
    4848#define SDL_USER_EVENT_WINDOW_RESIZE_DONE (SDL_USEREVENT + 13)
     49#define SDL_USER_EVENT_NOTIFYCHANGE       (SDL_USEREVENT + 14)
    4950
    5051
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp

    r51359 r51436  
    3333
    3434#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
     35
     36#include "CConsole.h"
     37#include "CDisplay.h"
    3538
    3639#if defined (Q_OS_WIN32)
     
    282285
    283286    /* Confirm RequestResize: */
     287    return S_OK;
     288}
     289
     290void UIFrameBuffer::notifyChange(ULONG aScreenId)
     291{
     292    /* Disable screen updates. */
     293    lock();
     294
     295    if (mpPendingSourceBitmap.isNull())
     296    {
     297        /* Do nothing. Change event already processed. */
     298        LogRelFlow(("notifyChange: already processed.\n"));
     299        unlock();
     300        return;
     301    }
     302
     303    /* Disable screen updates. */
     304    mfUpdates = false;
     305
     306    /* Release the current bitmap and keep the pending one. */
     307    mpSourceBitmap = mpPendingSourceBitmap;
     308    mpPendingSourceBitmap = 0;
     309
     310    unlock();
     311
     312    BYTE *pAddress = NULL;
     313    ULONG ulWidth = 0;
     314    ULONG ulHeight = 0;
     315    ULONG ulBitsPerPixel = 0;
     316    ULONG ulBytesPerLine = 0;
     317    ULONG ulPixelFormat = 0;
     318
     319    mpSourceBitmap.QueryBitmapInfo(pAddress,
     320                                   ulWidth,
     321                                   ulHeight,
     322                                   ulBitsPerPixel,
     323                                   ulBytesPerLine,
     324                                   ulPixelFormat);
     325
     326    UIResizeEvent e(FramebufferPixelFormat_Opaque, pAddress,
     327                    ulBitsPerPixel, ulBytesPerLine, ulWidth, ulHeight);
     328    resizeEvent(&e);
     329}
     330
     331STDMETHODIMP UIFrameBuffer::NotifyChange(ULONG aScreenId,
     332                                         ULONG aXOrigin,
     333                                         ULONG aYOrigin,
     334                                         ULONG aWidth,
     335                                         ULONG aHeight)
     336{
     337    LogRelFlow(("NotifyChange: %d %d,%d %dx%d\n",
     338                aScreenId, aXOrigin, aYOrigin, aWidth, aHeight));
     339
     340    /* Obtain the new screen bitmap. */
     341    lock();
     342
     343    /* Make sure frame-buffer is used: @todo still required? */
     344    if (m_fIsMarkedAsUnused)
     345    {
     346        LogRelFlow(("UIFrameBuffer::NotifyChange: Ignored!\n"));
     347        unlock();
     348        return E_FAIL;
     349    }
     350
     351    /* Save the new bitmap. */
     352    mpPendingSourceBitmap = 0;
     353    m_pMachineView->session().GetConsole().GetDisplay().QuerySourceBitmap(aScreenId, mpPendingSourceBitmap);
     354
     355    unlock();
     356
     357    /* Widget resize is NOT thread-safe and *probably* never will be,
     358     * We have to notify machine-view with the async-signal to perform resize operation. */
     359    LogRelFlow(("UIFrameBuffer::NotifyChange: Sending to async-handler...\n"));
     360    emit sigNotifyChange(aScreenId, aWidth, aHeight);
     361
     362    RTThreadYield();
     363
    284364    return S_OK;
    285365}
     
    606686            m_pMachineView, SLOT(sltHandleRequestResize(int, uchar*, int, int, int, int)),
    607687            Qt::QueuedConnection);
     688    connect(this, SIGNAL(sigNotifyChange(ulong, int, int)),
     689            m_pMachineView, SLOT(sltHandleNotifyChange(ulong, int, int)),
     690            Qt::QueuedConnection);
    608691    connect(this, SIGNAL(sigNotifyUpdate(int, int, int, int)),
    609692            m_pMachineView, SLOT(sltHandleNotifyUpdate(int, int, int, int)),
     
    621704    disconnect(this, SIGNAL(sigRequestResize(int, uchar*, int, int, int, int)),
    622705               m_pMachineView, SLOT(sltHandleRequestResize(int, uchar*, int, int, int, int)));
     706    disconnect(this, SIGNAL(sigNotifyChange(ulong, int, int)),
     707               m_pMachineView, SLOT(sltHandleNotifyChange(ulong, int, int)));
    623708    disconnect(this, SIGNAL(sigNotifyUpdate(int, int, int, int)),
    624709               m_pMachineView, SLOT(sltHandleNotifyUpdate(int, int, int, int)));
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h

    r51187 r51436  
    2828/* COM includes: */
    2929#include "CFramebuffer.h"
     30#include "CDisplaySourceBitmap.h"
    3031
    3132/* Other VBox includes: */
     
    9697                          int iBitsPerPixel, int iBytesPerLine,
    9798                          int iWidth, int iHeight);
     99    void sigNotifyChange(ulong uScreenId, int iWidth, int iHeight);
    98100    void sigNotifyUpdate(int iX, int iY, int iWidth, int iHeight);
    99101    void sigSetVisibleRegion(QRegion region);
     
    150152                              ULONG uWidth, ULONG uHeight,
    151153                              BOOL *pbFinished);
     154    STDMETHOD(NotifyChange)(ULONG aScreenId,
     155                            ULONG aXOrigin,
     156                            ULONG aYOrigin,
     157                            ULONG aWidth,
     158                            ULONG aHeight);
    152159
    153160    STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight);
     
    196203    virtual void paintEvent(QPaintEvent *pEvent) = 0;
    197204    virtual void applyVisibleRegion(const QRegion &region);
     205
     206    void notifyChange(ulong uScreenId);
    198207
    199208#ifdef VBOX_WITH_VIDEOHWACCEL
     
    230239    bool m_fIsMarkedAsUnused;
    231240    bool m_fIsAutoEnabled;
     241
     242    CDisplaySourceBitmap mpSourceBitmap;
     243    CDisplaySourceBitmap mpPendingSourceBitmap;
     244    bool mfUpdates;
    232245
    233246    /* To avoid a seamless flicker,
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp

    r51404 r51436  
    145145    else
    146146        popupCenter().forgetAboutWrongColorDepth(m_pMachineView->machineWindow());
     147    lock();
     148    mfUpdates = true;
     149    unlock();
    147150}
    148151
     
    161164    if (!m_pMachineView)
    162165        return;
     166       
     167    lock();
     168    if (!mfUpdates)
     169    {
     170       unlock();
     171       return;
     172    }
    163173
    164174    /* If the machine is NOT in 'running', 'paused' or 'saving' state,
     
    203213            break;
    204214    }
     215    unlock();
    205216}
    206217
     
    376387     * 2. or the machine is in the state which breaks link between
    377388     *    the framebuffer and the actual video-memory: */
    378     m_img = QImage(m_width, m_height, QImage::Format_RGB32);
    379     m_img.fill(0);
    380     m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
    381     m_bUsesGuestVRAM = false;
    382 }
    383 
     389    if (!mpSourceBitmap.isNull())
     390    {
     391        BYTE *pAddress = NULL;
     392        ULONG ulWidth = 0;
     393        ULONG ulHeight = 0;
     394        ULONG ulBitsPerPixel = 0;
     395        ULONG ulBytesPerLine = 0;
     396        ULONG ulPixelFormat = 0;
     397
     398        mpSourceBitmap.QueryBitmapInfo(pAddress,
     399                                       ulWidth,
     400                                       ulHeight,
     401                                       ulBitsPerPixel,
     402                                       ulBytesPerLine,
     403                                       ulPixelFormat);
     404
     405        m_img = QImage(pAddress, ulWidth, ulHeight, ulBytesPerLine, QImage::Format_RGB32);
     406        m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
     407        m_bUsesGuestVRAM = true;
     408    }
     409}
     410
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r51404 r51436  
    276276    }
    277277
    278     /* Report to the VM thread that we finished resizing: */
    279     session().GetConsole().GetDisplay().ResizeCompleted(screenId());
    280 
    281278    /* Emit a signal about guest was resized: */
    282279    emit resizeHintDone();
     
    288285                (unsigned long)m_uScreenId, iPixelFormat,
    289286                iBitsPerPixel, iBytesPerLine, iWidth, iHeight));
     287}
     288
     289void UIMachineView::sltHandleNotifyChange(ulong uScreenId, int iWidth, int iHeight)
     290{
     291    LogRelFlow(("UIMachineView::HandleNotifyChange: Screen=%d, Size=%dx%d.\n",
     292                (unsigned long)m_uScreenId, iWidth, iHeight));
     293
     294    // TODO: Move to appropriate place!
     295    /* Some situations require frame-buffer resize-events to be ignored at all,
     296     * leaving machine-window, machine-view and frame-buffer sizes preserved: */
     297    if (uisession()->isGuestResizeIgnored())
     298        return;
     299
     300    /* If machine-window is visible: */
     301    if (uisession()->isScreenVisible(m_uScreenId))
     302    {
     303        // TODO: Move to appropriate place!
     304        /* Adjust 'scale' mode for current machine-view size: */
     305        if (visualStateType() == UIVisualStateType_Scale)
     306            frameBuffer()->setScaledSize(size());
     307
     308        /* Perform frame-buffer mode-change: */
     309        frameBuffer()->notifyChange(uScreenId);
     310
     311        /* Scale-mode doesn't need this.. */
     312        if (visualStateType() != UIVisualStateType_Scale)
     313        {
     314            /* Adjust maximum-size restriction for machine-view: */
     315            setMaximumSize(sizeHint());
     316
     317            /* Disable the resize hint override hack: */
     318            m_sizeHintOverride = QSize(-1, -1);
     319
     320            /* Force machine-window update own layout: */
     321            QCoreApplication::sendPostedEvents(0, QEvent::LayoutRequest);
     322
     323            /* Update machine-view sliders: */
     324            updateSliders();
     325
     326            /* By some reason Win host forgets to update machine-window central-widget
     327             * after main-layout was updated, let's do it for all the hosts: */
     328            machineWindow()->centralWidget()->update();
     329
     330            /* Normalize machine-window geometry: */
     331            if (visualStateType() == UIVisualStateType_Normal)
     332                machineWindow()->normalizeGeometry(true /* adjust position */);
     333        }
     334
     335#ifdef Q_WS_MAC
     336        /* Update MacOS X dock icon size: */
     337        machineLogic()->updateDockIconSize(screenId(), iWidth, iHeight);
     338#endif /* Q_WS_MAC */
     339    }
     340
     341    /* Emit a signal about guest was resized: */
     342    emit resizeHintDone();
     343
     344    LogRelFlow(("UIMachineView::ResizeHandled: Screen=%d, Size=%dx%d.\n",
     345                (unsigned long)m_uScreenId, iWidth, iHeight));
    290346}
    291347
     
    354410                    /* Ask for full guest display update (it will also update
    355411                     * the viewport through IFramebuffer::NotifyUpdate): */
    356                     if (m_previousState == KMachineState_Paused ||
    357                         m_previousState == KMachineState_TeleportingPausedVM)
    358                     {
    359                         CDisplay dsp = session().GetConsole().GetDisplay();
    360                         dsp.InvalidateAndUpdate();
    361                     }
     412                    CDisplay dsp = session().GetConsole().GetDisplay();
     413                    dsp.InvalidateAndUpdate();
    362414                }
    363415            }
     
    497549        Assert(!display.isNull());
    498550        CFramebuffer fb(NULL);
    499         LONG XOrigin, YOrigin;
    500551        /* Check if the framebuffer is already assigned;
    501552         * in this case we do not need to re-assign it neither do we need to AddRef. */
    502         display.GetFramebuffer(m_uScreenId, fb, XOrigin, YOrigin);
     553        display.QueryFramebuffer(m_uScreenId, fb);
    503554        if (fb.raw() != m_pFrameBuffer) /* <-this will evaluate to true iff no framebuffer is yet assigned */
    504555        {
    505556            m_pFrameBuffer->AddRef();
    506557        }
    507         /* Always perform SetFramebuffer to ensure 3D gets notified: */
    508         display.SetFramebuffer(m_uScreenId, CFramebuffer(m_pFrameBuffer));
     558        /* Always perform AttachFramebuffer to ensure 3D gets notified: */
     559        if (!fb.isNull())
     560            display.DetachFramebuffer(m_uScreenId);
     561        display.AttachFramebuffer(m_uScreenId, CFramebuffer(m_pFrameBuffer));
    509562    }
    510563
     
    629682    /* Temporarily detach the framebuffer from IDisplay before detaching
    630683     * from view in order to respect the thread synchonisation logic (see UIFrameBuffer.h).
    631      * Note: VBOX_WITH_CROGL additionally requires us to call SetFramebuffer
     684     * Note: VBOX_WITH_CROGL additionally requires us to call DetachFramebuffer
    632685     * to ensure 3D gets notified of view being destroyed... */
    633686    CDisplay display = session().GetConsole().GetDisplay();
    634     display.SetFramebuffer(m_uScreenId, CFramebuffer(NULL));
     687    display.DetachFramebuffer(m_uScreenId);
    635688
    636689    /* Detach framebuffer from view: */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h

    r51187 r51436  
    9797                                int iBitsPerPixel, int iBytesPerLine,
    9898                                int iWidth, int iHeight);
     99
     100    /* Handler: Frame-buffer NotifyChange stuff: */
     101    virtual void sltHandleNotifyChange(ulong uScreenId, int iWidth, int iHeight);
    99102
    100103    /* Handler: Frame-buffer NotifyUpdate stuff: */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r51395 r51436  
    12301230            /* Detach framebuffer from Display: */
    12311231            CDisplay display = session().GetConsole().GetDisplay();
    1232             display.SetFramebuffer(i, CFramebuffer(NULL));
     1232            display.DetachFramebuffer(i);
    12331233            /* Release framebuffer reference: */
    12341234            pFb->Release();
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r51361 r51436  
    231231    ComPtr<IDisplay> pDisplay;
    232232    ComPtr<IFramebuffer> pFramebuffer;
    233     LONG xo, yo;
    234233
    235234    if (!g_pConsole)
     
    241240    CHECK_ERROR2_STMT(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), return);
    242241
    243     CHECK_ERROR2_STMT(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), return);
     242    CHECK_ERROR2_STMT(pDisplay, QueryFramebuffer(screenId, pFramebuffer.asOutParam()), return);
    244243
    245244    if (!pFramebuffer)
     
    11061105                    for (i=0; i<monitorCount; ++i)
    11071106                    {
    1108                         CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
     1107                        CHECK_ERROR_RET(pDisplay, QueryFramebuffer(i, pFramebuffer.asOutParam()), rc);
    11091108
    11101109                        if (!pFramebuffer)
     
    11181117                            CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
    11191118                            CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
     1119                            CHECK_ERROR_RET(pDisplay, GetScreenResolution(i, NULL, NULL, NULL, &xo, &yo), rc);
    11201120
    11211121                            rc = crVBoxServerMapScreen(i, xo, yo, w, h, winId);
     
    12131213                Assert(g_pConsole);
    12141214                CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
    1215                 CHECK_ERROR_RET(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), rc);
     1215                CHECK_ERROR_RET(pDisplay, QueryFramebuffer(screenId, pFramebuffer.asOutParam()), rc);
    12161216
    12171217                crServerVBoxCompositionSetEnableStateGlobal(GL_FALSE);
     
    12451245                            CHECK_ERROR_BREAK(pFramebuffer, COMGETTER(Width)(&w));
    12461246                            CHECK_ERROR_BREAK(pFramebuffer, COMGETTER(Height)(&h));
     1247                            CHECK_ERROR_BREAK(pDisplay, GetScreenResolution(screenId, NULL, NULL, NULL, &xo, &yo));
    12471248
    12481249                            rc = crVBoxServerMapScreen(screenId, xo, yo, w, h, winId);
  • trunk/src/VBox/Main/Makefile.kmk

    r51417 r51436  
    709709        src-client/ConsoleVRDPServer.cpp \
    710710        src-client/DisplayImpl.cpp \
     711        src-client/DisplaySourceBitmapImpl.cpp \
    711712        src-client/EmulatedUSBImpl.cpp \
    712713        src-client/GuestImpl.cpp \
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r51426 r51436  
    1515415154
    1515515155  <interface
     15156    name="IDisplaySourceBitmap" extends="$unknown" wsmap="suppress"
     15157    uuid="b00907f7-d85e-4dce-b1a6-16a2d91b0269"
     15158    >
     15159    <attribute name="screenId" type="unsigned long" readonly="yes"/>
     15160    <method name="queryBitmapInfo">
     15161      <desc>Information about the screen bitmap.</desc>
     15162      <param name="address" type="octet" mod="ptr" dir="out"/>
     15163      <param name="width" type="unsigned long" dir="out"/>
     15164      <param name="height" type="unsigned long" dir="out"/>
     15165      <param name="bitsPerPixel" type="unsigned long" dir="out"/>
     15166      <param name="bytesPerLine" type="unsigned long" dir="out"/>
     15167      <param name="pixelFormat" type="unsigned long" dir="out"/>
     15168    </method>
     15169
     15170  </interface>
     15171
     15172  <interface
    1515615173    name="IFramebuffer" extends="$unknown"
    15157     uuid="e3f122c0-adab-4fc9-a8dc-da112fb48428"
     15174    uuid="29e4a04d-03a7-4860-977b-a987c3e92c2b"
    1515815175    wsmap="managed"
    1515915176    >
     
    1526515282    </method>
    1526615283
     15284  <!--
    1526715285    <method name="requestResize" wsmap="suppress">
    1526815286      <desc>
     
    1529815316        available or not. If @a pixelFormat is <link
    1529915317        to="FramebufferPixelFormat_Opaque"/> then direct access to the guest
    15300         VRAM buffer is not available -- the @a VRAM, @a bitsPerPixel and
     15318        VRAM buffer is not available - the @a VRAM, @a bitsPerPixel and
    1530115319        @a bytesPerLine parameters must be ignored and the implementation must use
    1530215320        the indirect mode (where it provides its own buffer in one of the
     
    1538115399          <link to="IDisplay::resizeCompleted"/>.
    1538215400        </desc>
     15401      </param>
     15402    </method>
     15403  -->
     15404
     15405    <method name="notifyChange">
     15406      <desc>
     15407        Requests a size change.
     15408      </desc>
     15409      <param name="screenId" type="unsigned long" dir="in">
     15410        <desc>
     15411          Logical guest screen number.
     15412        </desc>
     15413      </param>
     15414      <param name="xOrigin" type="unsigned long" dir="in">
     15415        <desc>Location of the screen in the guest.</desc>
     15416      </param>
     15417      <param name="yOrigin" type="unsigned long" dir="in">
     15418        <desc>Location of the screen in the guest.</desc>
     15419      </param>
     15420      <param name="width" type="unsigned long" dir="in">
     15421        <desc>Width of the guest display, in pixels.</desc>
     15422      </param>
     15423      <param name="height" type="unsigned long" dir="in">
     15424        <desc>Height of the guest display, in pixels.</desc>
    1538315425      </param>
    1538415426    </method>
     
    1554215584  <interface
    1554315585    name="IDisplay" extends="$unknown"
    15544     uuid="480b372c-c0b5-4c23-9bd7-dcbb85b1594c"
     15586    uuid="efd0567f-8697-4b4c-965a-7f3672d1909e"
    1554515587    wsmap="managed"
    1554615588    >
     
    1555615598      the host computer or an RDP session's display on a remote computer.
    1555715599    </desc>
     15600
    1555815601    <method name="getScreenResolution">
    1555915602      <desc>Queries display width, height and color depth for given screen.</desc>
     
    1556615609    </method>
    1556715610
    15568     <method name="setFramebuffer">
    15569       <desc>
    15570         Sets the framebuffer for given screen.
     15611    <method name="attachFramebuffer">
     15612      <desc>
     15613        Sets the graphics updates target for a screen.
    1557115614      </desc>
    1557215615      <param name="screenId" type="unsigned long" dir="in"/>
     
    1557415617    </method>
    1557515618
    15576     <method name="getFramebuffer">
    15577       <desc>
    15578         Queries the framebuffer for given screen.
     15619    <method name="detachFramebuffer">
     15620      <desc>
     15621        Removes the graphics updates target for a screen.
     15622      </desc>
     15623      <param name="screenId" type="unsigned long" dir="in"/>
     15624    </method>
     15625
     15626    <method name="queryFramebuffer">
     15627      <desc>
     15628        Queries the graphics updates targets for a screen.
    1557915629      </desc>
    1558015630      <param name="screenId" type="unsigned long" dir="in"/>
    1558115631      <param name="framebuffer" type="IFramebuffer" dir="out"/>
    15582       <param name="xOrigin" type="long" dir="out"/>
    15583       <param name="yOrigin" type="long" dir="out"/>
    1558415632    </method>
    1558515633
     
    1581015858    </method>
    1581115859
     15860  <!--
    1581215861    <method name="resizeCompleted">
    1581315862      <desc>
     
    1582115870      <param name="screenId" type="unsigned long" dir="in"/>
    1582215871    </method>
     15872  -->
    1582315873
    1582415874    <method name="completeVHWACommand">
     
    1586815918      </param>
    1586915919    </method>
     15920
     15921    <method name="querySourceBitmap" wsmap="suppress">
     15922      <desc>
     15923         Obtains the guest screen bitmap parameters.
     15924      </desc>
     15925      <param name="screenId" type="unsigned long" dir="in"/>
     15926      <param name="displaySourceBitmap" type="IDisplaySourceBitmap" dir="out"/>
     15927    </method>
     15928
    1587015929  </interface>
    1587115930
  • trunk/src/VBox/Main/include/ConsoleVRDPServer.h

    r49120 r51436  
    197197    int m_mousey;
    198198
    199     IFramebuffer *maFramebuffers[SchemaDefs::MaxGuestMonitors];
     199    ComPtr<IDisplaySourceBitmap> maSourceBitmaps[SchemaDefs::MaxGuestMonitors];
    200200
    201201    ComPtr<IEventListener> mConsoleListener;
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r51141 r51436  
    3232#endif
    3333
     34#include "DisplaySourceBitmapWrap.h"
     35
    3436class Console;
    3537struct VIDEORECCONTEXT;
     
    4951
    5052    ComPtr<IFramebuffer> pFramebuffer;
     53    ComPtr<IDisplaySourceBitmap> pSourceBitmap;
    5154    bool fDisabled;
    5255
     
    219222    STDMETHOD(GetScreenResolution)(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ULONG *aBitsPerPixel, LONG *aXOrigin, LONG *aYOrigin);
    220223    STDMETHOD(SetFramebuffer)(ULONG aScreenId, IFramebuffer *aFramebuffer);
     224    STDMETHOD(AttachFramebuffer)(ULONG aScreenId,
     225                                 IFramebuffer *aFramebuffer);
     226    STDMETHOD(DetachFramebuffer)(ULONG aScreenId);
     227    STDMETHOD(QueryFramebuffer)(ULONG aScreenId,
     228                                IFramebuffer **aFramebuffer);
    221229    STDMETHOD(GetFramebuffer)(ULONG aScreenId, IFramebuffer **aFramebuffer, LONG *aXOrigin, LONG *aYOrigin);
    222230    STDMETHOD(SetVideoModeHint)(ULONG aDisplay, BOOL aEnabled, BOOL aChangeOrigin, LONG aOriginX, LONG aOriginY, ULONG aWidth, ULONG aHeight, ULONG aBitsPerPixel);
     
    232240
    233241    STDMETHOD(ViewportChanged)(ULONG aScreenId, ULONG x, ULONG y, ULONG width, ULONG height);
     242    STDMETHOD(QuerySourceBitmap)(ULONG aScreenId,
     243                                 IDisplaySourceBitmap **aDisplaySourceBitmap);
    234244
    235245    static const PDMDRVREG  DrvReg;
     
    237247private:
    238248
     249    HRESULT querySourceBitmap(ULONG aScreenId,
     250                              IDisplaySourceBitmap **ppDisplaySourceBitmap);
    239251    int updateDisplayData(void);
    240252
     
    423435                   uint8_t fLimitSize);
    424436
     437class ATL_NO_VTABLE DisplaySourceBitmap:
     438    public DisplaySourceBitmapWrap
     439{
     440public:
     441
     442    DECLARE_EMPTY_CTOR_DTOR(DisplaySourceBitmap)
     443
     444    HRESULT FinalConstruct();
     445    void FinalRelease();
     446
     447    /* Public initializer/uninitializer for internal purposes only. */
     448    HRESULT init(ComObjPtr<Display> pDisplay, unsigned uScreenId, DISPLAYFBINFO *pFBInfo);
     449    void uninit();
     450
     451    bool usesVRAM(void) { return m.pu8Allocated == NULL; }
     452
     453private:
     454    // wrapped IDisplaySourceBitmap properties
     455    virtual HRESULT getScreenId(ULONG *aScreenId);
     456
     457    // wrapped IDisplaySourceBitmap methods
     458    virtual HRESULT queryBitmapInfo(BYTE **aAddress,
     459                                    ULONG *aWidth,
     460                                    ULONG *aHeight,
     461                                    ULONG *aBitsPerPixel,
     462                                    ULONG *aBytesPerLine,
     463                                    ULONG *aPixelFormat);
     464
     465    int initSourceBitmap(unsigned aScreenId, DISPLAYFBINFO *pFBInfo);
     466
     467    struct Data
     468    {
     469        ComObjPtr<Display> pDisplay;
     470        unsigned uScreenId;
     471        DISPLAYFBINFO *pFBInfo;
     472
     473        uint8_t *pu8Allocated;
     474
     475        uint8_t *pu8Address;
     476        ULONG ulWidth;
     477        ULONG ulHeight;
     478        ULONG ulBitsPerPixel;
     479        ULONG ulBytesPerLine;
     480        ULONG ulPixelFormat;
     481    };
     482
     483    Data m;
     484};
     485
    425486#endif // ____H_DISPLAYIMPL
    426487/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r51419 r51436  
    34063406            InsertConfigInteger(pCfg, "VMSVGAEnabled", true);
    34073407#ifdef VBOX_WITH_VMSVGA3D
    3408             IFramebuffer *pFramebuffer = getDisplay()->getFramebuffer();
    3409             if (pFramebuffer)
     3408            IFramebuffer *pFramebuffer = NULL;
     3409            hrc = getDisplay()->QueryFramebuffer(0, &pFramebuffer);
     3410            if (SUCCEEDED(hrc) && pFramebuffer)
    34103411            {
    34113412                LONG64 winId = 0;
     
    34143415                hrc = pFramebuffer->COMGETTER(WinId)(&winId);
    34153416                InsertConfigInteger(pCfg, "HostWindowId", winId);
     3417                pFramebuffer->Release();
    34163418            }
    34173419            BOOL f3DEnabled;
     
    34383440        /* VESA height reduction */
    34393441        ULONG ulHeightReduction;
    3440         IFramebuffer *pFramebuffer = getDisplay()->getFramebuffer();
    3441         if (pFramebuffer)
     3442        IFramebuffer *pFramebuffer = NULL;
     3443        hrc = getDisplay()->QueryFramebuffer(0, &pFramebuffer);
     3444        if (SUCCEEDED(hrc) && pFramebuffer)
    34423445        {
    34433446            hrc = pFramebuffer->COMGETTER(HeightReduction)(&ulHeightReduction);             H();
     3447            pFramebuffer->Release();
     3448            pFramebuffer = NULL;
    34443449        }
    34453450        else
  • trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp

    r51092 r51436  
    10851085    bool fAvailable = false;
    10861086
    1087     IFramebuffer *pfb = NULL;
    1088     LONG xOrigin = 0;
    1089     LONG yOrigin = 0;
    1090 
    1091     server->mConsole->getDisplay()->GetFramebuffer(uScreenId, &pfb, &xOrigin, &yOrigin);
    1092 
    1093     if (pfb)
    1094     {
    1095         pfb->Lock ();
    1096 
    1097         /* Query framebuffer parameters. */
    1098         ULONG lineSize = 0;
    1099         pfb->COMGETTER(BytesPerLine)(&lineSize);
    1100 
    1101         ULONG bitsPerPixel = 0;
    1102         pfb->COMGETTER(BitsPerPixel)(&bitsPerPixel);
    1103 
    1104         BYTE *address = NULL;
    1105         pfb->COMGETTER(Address)(&address);
    1106 
    1107         ULONG height = 0;
    1108         pfb->COMGETTER(Height)(&height);
    1109 
    1110         ULONG width = 0;
    1111         pfb->COMGETTER(Width)(&width);
    1112 
    1113         /* Now fill the information as requested by the caller. */
    1114         pInfo->pu8Bits = address;
    1115         pInfo->xOrigin = xOrigin;
    1116         pInfo->yOrigin = yOrigin;
    1117         pInfo->cWidth = width;
    1118         pInfo->cHeight = height;
    1119         pInfo->cBitsPerPixel = bitsPerPixel;
    1120         pInfo->cbLine = lineSize;
    1121 
    1122         pfb->Unlock();
    1123 
    1124         fAvailable = true;
    1125     }
    1126 
    1127     if (server->maFramebuffers[uScreenId])
    1128     {
    1129         server->maFramebuffers[uScreenId]->Release();
    1130     }
    1131     server->maFramebuffers[uScreenId] = pfb;
     1087    /* Obtain the new screen bitmap. */
     1088    HRESULT hr = server->mConsole->getDisplay()->QuerySourceBitmap(uScreenId, server->maSourceBitmaps[uScreenId].asOutParam());
     1089    if (SUCCEEDED(hr))
     1090    {
     1091        LONG xOrigin = 0;
     1092        LONG yOrigin = 0;
     1093        BYTE *pAddress = NULL;
     1094        ULONG ulWidth = 0;
     1095        ULONG ulHeight = 0;
     1096        ULONG ulBitsPerPixel = 0;
     1097        ULONG ulBytesPerLine = 0;
     1098        ULONG ulPixelFormat = 0;
     1099
     1100        hr = server->maSourceBitmaps[uScreenId]->QueryBitmapInfo(&pAddress,
     1101                                                                 &ulWidth,
     1102                                                                 &ulHeight,
     1103                                                                 &ulBitsPerPixel,
     1104                                                                 &ulBytesPerLine,
     1105                                                                 &ulPixelFormat);
     1106
     1107        if (SUCCEEDED(hr))
     1108        {
     1109            hr = server->mConsole->getDisplay()->GetScreenResolution(uScreenId, NULL, NULL, NULL,
     1110                                                                     &xOrigin, &yOrigin);
     1111
     1112            if (SUCCEEDED(hr))
     1113            {
     1114                /* Now fill the information as requested by the caller. */
     1115                pInfo->pu8Bits = pAddress;
     1116                pInfo->xOrigin = xOrigin;
     1117                pInfo->yOrigin = yOrigin;
     1118                pInfo->cWidth = ulWidth;
     1119                pInfo->cHeight = ulHeight;
     1120                pInfo->cBitsPerPixel = ulBitsPerPixel;
     1121                pInfo->cbLine = ulBytesPerLine;
     1122
     1123                fAvailable = true;
     1124            }
     1125        }
     1126    }
    11321127
    11331128    return fAvailable;
     
    11361131DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackFramebufferLock(void *pvCallback, unsigned uScreenId)
    11371132{
    1138     ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback);
    1139 
    1140     if (server->maFramebuffers[uScreenId])
    1141     {
    1142         server->maFramebuffers[uScreenId]->Lock();
    1143     }
     1133    NOREF(pvCallback);
     1134    NOREF(uScreenId);
     1135    /* Do nothing */
    11441136}
    11451137
    11461138DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackFramebufferUnlock(void *pvCallback, unsigned uScreenId)
    11471139{
    1148     ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback);
    1149 
    1150     if (server->maFramebuffers[uScreenId])
    1151     {
    1152         server->maFramebuffers[uScreenId]->Unlock();
    1153     }
     1140    NOREF(pvCallback);
     1141    NOREF(uScreenId);
     1142    /* Do nothing */
    11541143}
    11551144
     
    14081397    m_InputSynch.fClientScrollLock = false;
    14091398
    1410     RT_ZERO(maFramebuffers);
    1411 
    14121399    {
    14131400        ComPtr<IEventSource> es;
     
    14671454
    14681455    unsigned i;
    1469     for (i = 0; i < RT_ELEMENTS(maFramebuffers); i++)
    1470     {
    1471         if (maFramebuffers[i])
    1472         {
    1473             maFramebuffers[i]->Release();
    1474             maFramebuffers[i] = NULL;
    1475         }
     1456    for (i = 0; i < RT_ELEMENTS(maSourceBitmaps); i++)
     1457    {
     1458        maSourceBitmaps[i].setNull();
    14761459    }
    14771460
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r51408 r51436  
    855855    Assert (pFramebuffer);
    856856
     857    NOREF(pixelFormat);
     858    NOREF(pvVRAM);
     859    NOREF(bpp);
     860    NOREF(cbLine);
     861
    857862    /* Call the framebuffer to try and set required pixelFormat. */
    858     BOOL finished = TRUE;
    859 
    860     pFramebuffer->RequestResize (uScreenId, pixelFormat, (BYTE *) pvVRAM,
    861                                  bpp, cbLine, w, h, &finished);
    862 
    863     if (!finished)
    864     {
    865         LogRelFlowFunc(("External framebuffer wants us to wait!\n"));
    866         return VINF_VGA_RESIZE_IN_PROGRESS;
    867     }
     863    HRESULT hr = pFramebuffer->NotifyChange(uScreenId, 0, 0, w, h); /* @todo origin */
     864
     865    Log(("pFramebuffer->NotifyChange hr %08x\n", hr));
    868866
    869867    return VINF_SUCCESS;
     
    939937
    940938    /* If there is no framebuffer, this call is not interesting. */
    941     if (   uScreenId >= mcMonitors
    942         || maFramebuffers[uScreenId].pFramebuffer.isNull())
     939    if (uScreenId >= mcMonitors)
    943940    {
    944941        return VINF_SUCCESS;
     
    953950        mLastHeight = h;
    954951        mLastFlags = flags;
     952
     953        DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId];
     954        pFBInfo->w = w;
     955        pFBInfo->h = h;
     956
     957        pFBInfo->u16BitsPerPixel = (uint16_t)bpp;
     958        pFBInfo->pu8FramebufferVRAM = (uint8_t *)pvVRAM;
     959        pFBInfo->u32LineSize = cbLine;
     960    }
     961
     962    if (maFramebuffers[uScreenId].pFramebuffer.isNull())
     963    {
     964        return VINF_SUCCESS;
    955965    }
    956966
     
    10011011    /* Framebuffer will be invalid during resize, make sure that it is not accessed. */
    10021012    if (uScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
    1003         mpDrv->pUpPort->pfnSetRenderVRAM (mpDrv->pUpPort, false);
     1013    {
     1014        mpDrv->pUpPort->pfnSetRenderVRAM(mpDrv->pUpPort, false);
     1015
     1016        mpDrv->IConnector.pu8Data    = NULL;
     1017        mpDrv->IConnector.cbScanline = 0;
     1018        mpDrv->IConnector.cBits      = 32; /* DevVGA does not work with cBits == 0. */
     1019        mpDrv->IConnector.cx         = 0;
     1020        mpDrv->IConnector.cy         = 0;
     1021    }
     1022
     1023    maFramebuffers[uScreenId].pSourceBitmap.setNull();
    10041024
    10051025    int rc = callFramebufferResize (maFramebuffers[uScreenId].pFramebuffer, uScreenId,
     
    10821102        if (uScreenId == VBOX_VIDEO_PRIMARY_SCREEN && !pFBInfo->pFramebuffer.isNull())
    10831103        {
    1084             /* Primary framebuffer has completed the resize. Update the connector data for VGA device. */
    1085             int rc2 = updateDisplayData();
    1086 
    1087             /* Check the framebuffer pixel format to setup the rendering in VGA device. */
    1088             BOOL usesGuestVRAM = FALSE;
    1089             pFBInfo->pFramebuffer->COMGETTER(UsesGuestVRAM) (&usesGuestVRAM);
    1090 
    1091             pFBInfo->fDefaultFormat = (usesGuestVRAM == FALSE);
    1092 
    1093             /* If the primary framebuffer is disabled, tell the VGA device to not to copy
    1094              * pixels from VRAM to the framebuffer.
    1095              */
    1096             if (pFBInfo->fDisabled || RT_FAILURE(rc2))
    1097                 mpDrv->pUpPort->pfnSetRenderVRAM (mpDrv->pUpPort, false);
    1098             else
    1099                 mpDrv->pUpPort->pfnSetRenderVRAM (mpDrv->pUpPort,
    1100                                                   pFBInfo->fDefaultFormat);
    1101 
    11021104            /* If the screen resize was because of disabling, tell framebuffer to repaint.
    11031105             * The framebuffer if now in default format so it will not use guest VRAM
     
    11091111        else if (!pFBInfo->pFramebuffer.isNull())
    11101112        {
    1111             BOOL usesGuestVRAM = FALSE;
    1112             pFBInfo->pFramebuffer->COMGETTER(UsesGuestVRAM) (&usesGuestVRAM);
    1113 
    1114             pFBInfo->fDefaultFormat = (usesGuestVRAM == FALSE);
    1115 
    11161113            /* If the screen resize was because of disabling, tell framebuffer to repaint.
    11171114             * The framebuffer if now in default format so it will not use guest VRAM
     
    23862383    if (aScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
    23872384    {
    2388         CHECK_CONSOLE_DRV(mpDrv);
    2389 
    2390         u32Width = mpDrv->IConnector.cx;
    2391         u32Height = mpDrv->IConnector.cy;
    2392         int rc = mpDrv->pUpPort->pfnQueryColorDepth(mpDrv->pUpPort, &u32BitsPerPixel);
    2393         AssertRC(rc);
     2385        if (mpDrv)
     2386        {
     2387            u32Width = mpDrv->IConnector.cx;
     2388            u32Height = mpDrv->IConnector.cy;
     2389            int rc = mpDrv->pUpPort->pfnQueryColorDepth(mpDrv->pUpPort, &u32BitsPerPixel);
     2390            AssertRC(rc);
     2391        }
    23942392    }
    23952393    else if (aScreenId < mcMonitors)
     
    24782476        ComAssertRCRet (vrc, E_FAIL);
    24792477    }
     2478
     2479    return S_OK;
     2480}
     2481
     2482STDMETHODIMP Display::AttachFramebuffer(ULONG aScreenId,
     2483                                        IFramebuffer *aFramebuffer)
     2484{
     2485    LogRelFlowFunc(("aScreenId = %d\n", aScreenId));
     2486
     2487    CheckComArgPointerValid(aFramebuffer);
     2488
     2489    AutoCaller autoCaller(this);
     2490    if (FAILED(autoCaller.rc()))
     2491        return autoCaller.rc();
     2492
     2493    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     2494
     2495    if (aScreenId >= mcMonitors)
     2496        return setError(E_INVALIDARG, tr("AttachFramebuffer: Invalid screen %d (total %d)"),
     2497                        aScreenId, mcMonitors);
     2498
     2499    DISPLAYFBINFO *pFBInfo = &maFramebuffers[aScreenId];
     2500    if (!pFBInfo->pFramebuffer.isNull())
     2501        return setError(E_FAIL, tr("AttachFramebuffer: Framebuffer already attached to %d"),
     2502                        aScreenId);
     2503
     2504    pFBInfo->pFramebuffer = aFramebuffer;
     2505
     2506    /* The driver might not have been constructed yet */
     2507    if (mpDrv)
     2508    {
     2509        /* Setup the new framebuffer, the resize will lead to an updateDisplayData call. */
     2510
     2511#if defined(VBOX_WITH_CROGL)
     2512        /* Release the lock, because SHCRGL_HOST_FN_SCREEN_CHANGED will read current framebuffer */
     2513        /* @todo investigate */
     2514        {
     2515            BOOL is3denabled;
     2516            mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
     2517
     2518            if (is3denabled)
     2519            {
     2520                alock.release();
     2521            }
     2522        }
     2523#endif
     2524
     2525        /* @todo generic code for all monitors. */
     2526        if (pFBInfo->fVBVAEnabled && pFBInfo->pu8FramebufferVRAM)
     2527        {
     2528            /* This display in VBVA mode. Resize it to the last guest resolution,
     2529             * if it has been reported.
     2530             */
     2531            handleDisplayResize(aScreenId, pFBInfo->u16BitsPerPixel,
     2532                                pFBInfo->pu8FramebufferVRAM,
     2533                                pFBInfo->u32LineSize,
     2534                                pFBInfo->w,
     2535                                pFBInfo->h,
     2536                                pFBInfo->flags);
     2537        }
     2538        else if (aScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
     2539        {
     2540            /* VGA device mode, only for the primary screen. */
     2541            handleDisplayResize(VBOX_VIDEO_PRIMARY_SCREEN, mLastBitsPerPixel,
     2542                                mLastAddress,
     2543                                mLastBytesPerLine,
     2544                                mLastWidth,
     2545                                mLastHeight,
     2546                                mLastFlags);
     2547        }
     2548    }
     2549
     2550    LogRelFlowFunc(("Attached to %d\n", aScreenId));
     2551    return S_OK;
     2552}
     2553
     2554STDMETHODIMP Display::DetachFramebuffer(ULONG aScreenId)
     2555{
     2556    LogRelFlowFunc(("aScreenId = %d\n", aScreenId));
     2557
     2558    AutoCaller autoCaller(this);
     2559    if (FAILED(autoCaller.rc()))
     2560        return autoCaller.rc();
     2561
     2562    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     2563
     2564    if (aScreenId >= mcMonitors)
     2565        return setError(E_INVALIDARG, tr("DetachFramebuffer: Invalid screen %d (total %d)"),
     2566                        aScreenId, mcMonitors);
     2567
     2568    DISPLAYFBINFO *pFBInfo = &maFramebuffers[aScreenId];
     2569
     2570    pFBInfo->pFramebuffer.setNull();
     2571
     2572    return S_OK;
     2573}
     2574
     2575STDMETHODIMP Display::QueryFramebuffer(ULONG aScreenId,
     2576                                       IFramebuffer **aFramebuffer)
     2577{
     2578    LogRelFlowFunc(("aScreenId = %d\n", aScreenId));
     2579
     2580    CheckComArgOutPointerValid(aFramebuffer);
     2581
     2582    AutoCaller autoCaller(this);
     2583    if (FAILED(autoCaller.rc()))
     2584        return autoCaller.rc();
     2585
     2586    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     2587
     2588    if (aScreenId >= mcMonitors)
     2589        return setError(E_INVALIDARG, tr("QueryFramebuffer: Invalid screen %d (total %d)"),
     2590                        aScreenId, mcMonitors);
     2591
     2592    DISPLAYFBINFO *pFBInfo = &maFramebuffers[aScreenId];
     2593
     2594    *aFramebuffer = pFBInfo->pFramebuffer;
     2595    if (!pFBInfo->pFramebuffer.isNull())
     2596        pFBInfo->pFramebuffer->AddRef();
    24802597
    24812598    return S_OK;
     
    32393356                    && !pFBInfo->fDisabled)
    32403357                {
    3241                     address = NULL;
    3242                     HRESULT hrc = pFBInfo->pFramebuffer->COMGETTER(Address) (&address);
    3243                     if (SUCCEEDED(hrc) && address != NULL)
     3358                    BYTE *pAddress = NULL;
     3359                    ULONG ulWidth = 0;
     3360                    ULONG ulHeight = 0;
     3361                    ULONG ulBitsPerPixel = 0;
     3362                    ULONG ulBytesPerLine = 0;
     3363                    ULONG ulPixelFormat = 0;
     3364
     3365                    HRESULT hrc = pFBInfo->pSourceBitmap->QueryBitmapInfo(&pAddress,
     3366                                                                          &ulWidth,
     3367                                                                          &ulHeight,
     3368                                                                          &ulBitsPerPixel,
     3369                                                                          &ulBytesPerLine,
     3370                                                                          &ulPixelFormat);
     3371                    if (SUCCEEDED(hrc))
    32443372                    {
    32453373                        pu8Src       = pFBInfo->pu8FramebufferVRAM;
     
    32523380
    32533381                        /* Default format is 32 bpp. */
    3254                         pu8Dst             = address;
     3382                        pu8Dst             = pAddress;
    32553383                        xDst                = xSrc;
    32563384                        yDst                = ySrc;
     
    33743502                 * When framebuffer uses VRAM directly, just notify it to update.
    33753503                 */
    3376                 if (pFBInfo->fDefaultFormat)
     3504                if (pFBInfo->fDefaultFormat && !pFBInfo->pSourceBitmap.isNull())
    33773505                {
    3378                     BYTE *address = NULL;
    3379                     ULONG uWidth = 0;
    3380                     ULONG uHeight = 0;
    3381                     pFBInfo->pFramebuffer->COMGETTER(Width) (&uWidth);
    3382                     pFBInfo->pFramebuffer->COMGETTER(Height) (&uHeight);
    3383                     HRESULT hrc = pFBInfo->pFramebuffer->COMGETTER(Address) (&address);
    3384                     if (SUCCEEDED(hrc) && address != NULL)
     3506                    BYTE *pAddress = NULL;
     3507                    ULONG ulWidth = 0;
     3508                    ULONG ulHeight = 0;
     3509                    ULONG ulBitsPerPixel = 0;
     3510                    ULONG ulBytesPerLine = 0;
     3511                    ULONG ulPixelFormat = 0;
     3512
     3513                    HRESULT hrc = pFBInfo->pSourceBitmap->QueryBitmapInfo(&pAddress,
     3514                                                                          &ulWidth,
     3515                                                                          &ulHeight,
     3516                                                                          &ulBitsPerPixel,
     3517                                                                          &ulBytesPerLine,
     3518                                                                          &ulPixelFormat);
     3519                    if (SUCCEEDED(hrc))
    33853520                    {
    33863521                        uint32_t width              = pFBInfo->w;
     
    33963531
    33973532                        /* Default format is 32 bpp. */
    3398                         uint8_t *pu8Dst             = address;
     3533                        uint8_t *pu8Dst             = pAddress;
    33993534                        int32_t xDst                = xSrc;
    34003535                        int32_t yDst                = ySrc;
     
    34083543                         * copyrect should not be called.
    34093544                         */
    3410                         if (uWidth == pFBInfo->w && uHeight == pFBInfo->h)
     3545                        if (ulWidth == pFBInfo->w && ulHeight == pFBInfo->h)
    34113546                        {
    34123547
     
    35493684}
    35503685
     3686STDMETHODIMP Display::QuerySourceBitmap(ULONG aScreenId,
     3687                                        IDisplaySourceBitmap **aDisplaySourceBitmap)
     3688{
     3689    LogRelFlowFunc(("aScreenId = %d\n", aScreenId));
     3690
     3691    AutoCaller autoCaller(this);
     3692    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     3693
     3694    Console::SafeVMPtr ptrVM(mParent);
     3695    if (!ptrVM.isOk())
     3696        return ptrVM.rc();
     3697
     3698    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3699
     3700    if (aScreenId >= mcMonitors)
     3701        return setError(E_INVALIDARG, tr("QuerySourceBitmap: Invalid screen %d (total %d)"),
     3702                        aScreenId, mcMonitors);
     3703
     3704    HRESULT hr = querySourceBitmap(aScreenId, aDisplaySourceBitmap);
     3705
     3706    alock.release();
     3707
     3708    LogRelFlowFunc(("%Rhrc\n", hr));
     3709    return hr;
     3710}
     3711
    35513712// private methods
    35523713/////////////////////////////////////////////////////////////////////////////
     3714
     3715HRESULT Display::querySourceBitmap(ULONG aScreenId,
     3716                                   IDisplaySourceBitmap **ppDisplaySourceBitmap)
     3717{
     3718    HRESULT hr = S_OK;
     3719
     3720    DISPLAYFBINFO *pFBInfo = &maFramebuffers[aScreenId];
     3721    if (pFBInfo->pSourceBitmap.isNull())
     3722    {
     3723        /* Create a new object. */
     3724        ComObjPtr<DisplaySourceBitmap> obj;
     3725        hr = obj.createObject();
     3726        if (SUCCEEDED(hr))
     3727        {
     3728            hr = obj->init(this, aScreenId, pFBInfo);
     3729        }
     3730
     3731        if (SUCCEEDED(hr))
     3732        {
     3733            pFBInfo->pSourceBitmap = obj;
     3734
     3735            /* Whether VRAM must be copied to the internal buffer. */
     3736            pFBInfo->fDefaultFormat = !obj->usesVRAM();
     3737
     3738            if (aScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
     3739            {
     3740                /* Start buffer updates. */
     3741                BYTE *pAddress = NULL;
     3742                ULONG ulWidth = 0;
     3743                ULONG ulHeight = 0;
     3744                ULONG ulBitsPerPixel = 0;
     3745                ULONG ulBytesPerLine = 0;
     3746                ULONG ulPixelFormat = 0;
     3747
     3748                obj->QueryBitmapInfo(&pAddress,
     3749                                     &ulWidth,
     3750                                     &ulHeight,
     3751                                     &ulBitsPerPixel,
     3752                                     &ulBytesPerLine,
     3753                                     &ulPixelFormat);
     3754
     3755                mpDrv->IConnector.pu8Data    = pAddress;
     3756                mpDrv->IConnector.cbScanline = ulBytesPerLine;
     3757                mpDrv->IConnector.cBits      = ulBitsPerPixel;
     3758                mpDrv->IConnector.cx         = ulWidth;
     3759                mpDrv->IConnector.cy         = ulHeight;
     3760
     3761                if (pFBInfo->fDefaultFormat)
     3762                    mpDrv->pUpPort->pfnSetRenderVRAM(mpDrv->pUpPort, true);
     3763            }
     3764
     3765            if (pFBInfo->fDefaultFormat)
     3766            {
     3767                /* @todo make sure that the bitmap contains the latest image? */
     3768            }
     3769        }
     3770    }
     3771
     3772    if (SUCCEEDED(hr))
     3773    {
     3774        pFBInfo->pSourceBitmap->AddRef();
     3775        *ppDisplaySourceBitmap = pFBInfo->pSourceBitmap;
     3776    }
     3777
     3778    return hr;
     3779}
    35533780
    35543781/**
     
    38484075    unsigned uScreenId;
    38494076
    3850     Log2(("DisplayRefreshCallback\n"));
    38514077    for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++)
    38524078    {
     
    38954121                if (!pFBInfo->pFramebuffer.isNull() && pFBInfo->u32ResizeStatus == ResizeStatus_Void)
    38964122                {
    3897                     Assert(pDrv->IConnector.pu8Data);
    38984123                    pDisplay->vbvaLock();
    38994124                    pDrv->pUpPort->pfnUpdateDisplay(pDrv->pUpPort);
     
    47424967            {
    47434968                /* Render VRAM content to the framebuffer. */
    4744                 BYTE *address = NULL;
    4745                 HRESULT hrc = pFBInfo->pFramebuffer->COMGETTER(Address) (&address);
    4746                 if (SUCCEEDED(hrc) && address != NULL)
     4969                BYTE *pAddress = NULL;
     4970                ULONG ulWidth = 0;
     4971                ULONG ulHeight = 0;
     4972                ULONG ulBitsPerPixel = 0;
     4973                ULONG ulBytesPerLine = 0;
     4974                ULONG ulPixelFormat = 0;
     4975
     4976                HRESULT hrc = pFBInfo->pSourceBitmap->QueryBitmapInfo(&pAddress,
     4977                                                                      &ulWidth,
     4978                                                                      &ulHeight,
     4979                                                                      &ulBitsPerPixel,
     4980                                                                      &ulBytesPerLine,
     4981                                                                      &ulPixelFormat);
     4982                if (SUCCEEDED(hrc))
    47474983                {
    47484984                    uint32_t width              = pCmd->w;
     
    47574993                    uint32_t u32SrcBitsPerPixel = pFBInfo->u16BitsPerPixel;
    47584994
    4759                     uint8_t *pu8Dst             = address;
     4995                    uint8_t *pu8Dst             = pAddress;
    47604996                    int32_t xDst                = xSrc;
    47614997                    int32_t yDst                = ySrc;
     
    52185454    pThis->pDisplay = pDisplay;
    52195455    pThis->pDisplay->mpDrv = pThis;
    5220     /*
    5221      * Update our display information according to the framebuffer
    5222      */
    5223     pDisplay->updateDisplayData();
     5456
     5457    /* Disable VRAM to a buffer copy initially. */
     5458    pThis->pUpPort->pfnSetRenderVRAM (pThis->pUpPort, false);
     5459    pThis->IConnector.cBits = 32; /* DevVGA does nothing otherwise. */
    52245460
    52255461    /*
  • trunk/src/VBox/Main/src-client/VMMDevInterface.cpp

    r51096 r51436  
    400400#endif
    401401    IFramebuffer *framebuffer = NULL;
    402     LONG xOrigin = 0;
    403     LONG yOrigin = 0;
    404     HRESULT hrc = pConsole->getDisplay()->GetFramebuffer(display, &framebuffer, &xOrigin, &yOrigin);
     402    HRESULT hrc = pConsole->getDisplay()->QueryFramebuffer(display, &framebuffer);
    405403    if (SUCCEEDED(hrc) && framebuffer)
    406404    {
     
    425423    if (!heightReduction)
    426424        return VERR_INVALID_PARAMETER;
    427     IFramebuffer *framebuffer = pConsole->getDisplay()->getFramebuffer();
    428     if (framebuffer)
     425    IFramebuffer *framebuffer = NULL;
     426    HRESULT hrc = pConsole->getDisplay()->QueryFramebuffer(0, &framebuffer);
     427    if (SUCCEEDED(hrc) && framebuffer)
     428    {
    429429        framebuffer->COMGETTER(HeightReduction)((ULONG*)heightReduction);
     430        framebuffer->Release();
     431    }
    430432    else
    431433        *heightReduction = 0;
Note: See TracChangeset for help on using the changeset viewer.

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