VirtualBox

Changeset 53528 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 12, 2014 8:22:39 PM (10 years ago)
Author:
vboxsync
Message:

Devices/Graphics, Devices/PC/DevACPI, Main: add support for sending video mode hints through the VGA device.

Location:
trunk/src/VBox
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r53240 r53528  
    60626062    pThis->IPort.pfnSetViewPort         = vmsvgaPortSetViewPort;
    60636063#endif
     6064    pThis->IPort.pfnSendModeHint        = vbvaPortSendModeHint;
    60646065
    60656066#if defined(VBOX_WITH_HGSMI)
  • trunk/src/VBox/Devices/Graphics/DevVGA.h

    r53205 r53528  
    686686
    687687DECLCALLBACK(int) vgaUpdateDisplayAll(PVGASTATE pThis, bool fFailOnResize);
     688DECLCALLBACK(int) vbvaPortSendModeHint(PPDMIDISPLAYPORT pInterface, uint32_t cx,
     689                                       uint32_t cy, uint32_t cBPP,
     690                                       uint32_t cDisplay, uint32_t dx,
     691                                       uint32_t dy, uint32_t fEnabled,
     692                                       uint32_t fNotifyGuest);
    688693
    689694# ifdef VBOX_WITH_VDMA
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r53078 r53528  
    8383    VBVAMOUSESHAPEINFO mouseShapeInfo;
    8484    bool fPaused;
     85    VBVAMODEHINT aModeHints[VBOX_VIDEO_MAX_SCREENS];
    8586} VBVACONTEXT;
    8687
     
    495496        pVBVA->hostFlags.u32HostEvents = 0;
    496497        pVBVA->hostFlags.u32SupportedOrders = 0;
     498        pVGAState->fGuestCaps = 0;
     499        pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv, 0);
    497500
    498501        rc = pVGAState->pDrv->pfnVBVAEnable (pVGAState->pDrv, uScreenId, &pVBVA->hostFlags, false);
     
    15991602            AssertRCReturn(rc, rc);
    16001603#endif
     1604            rc = SSMR3PutU32 (pSSM, RT_ELEMENTS(pCtx->aModeHints));
     1605            AssertRCReturn(rc, rc);
     1606            rc = SSMR3PutU32 (pSSM, sizeof(VBVAMODEHINT));
     1607            AssertRCReturn(rc, rc);
     1608            for (unsigned i = 0; i < RT_ELEMENTS(pCtx->aModeHints); ++i)
     1609            {
     1610                rc = SSMR3PutMem (pSSM, pCtx->aModeHints[i],
     1611                                  sizeof(VBVAMODEHINT));
     1612                AssertRCReturn(rc, rc);
     1613            }
    16011614        }
    16021615    }
     
    21462159                pConf32->u32Value = 64*_1K;
    21472160            }
     2161            else if (pConf32->u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING)
     2162            {
     2163                pConf32->u32Value = VINF_SUCCESS;
     2164            }
    21482165            else
    21492166            {
     
    23972414            VBVACAPS *pCaps = (VBVACAPS*)pvBuffer;
    23982415            pVGAState->fGuestCaps = pCaps->fCaps;
     2416            pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv,
     2417                                                          pCaps->fCaps);
    23992418            pCaps->rc = VINF_SUCCESS;
    24002419        } break;
     
    24122431            pCfg->rc = VINF_SUCCESS;
    24132432        } break;
     2433
     2434        case VBVA_QUERY_MODE_HINTS:
     2435        {
     2436            if (cbBuffer < sizeof(VBVAQUERYMODEHINTS))
     2437            {
     2438                rc = VERR_INVALID_PARAMETER;
     2439                break;
     2440            }
     2441            VBVAQUERYMODEHINTS *pModeHintQuery = (VBVAQUERYMODEHINTS*)pvBuffer;
     2442            LogRelFlowFunc(("VBVA_QUERY_MODE_HINTS: cHintsQueried=%u, cbHintStructureGuest=%u\n",
     2443                            (unsigned)pModeHintQuery->cHintsQueried,
     2444                            (unsigned)pModeHintQuery->cbHintStructureGuest));
     2445            if (cbBuffer <   sizeof (VBVAQUERYMODEHINTS)
     2446                           +   (uint64_t)pModeHintQuery->cHintsQueried
     2447                             * pModeHintQuery->cbHintStructureGuest)
     2448            {
     2449                pModeHintQuery->rc = VERR_INVALID_PARAMETER;
     2450                break;
     2451            }
     2452            pModeHintQuery->rc = VINF_SUCCESS;
     2453            uint8_t *pbHint = (uint8_t *)pvBuffer + sizeof(VBVAQUERYMODEHINTS);
     2454            memset(pbHint, ~0, cbBuffer - sizeof(VBVAQUERYMODEHINTS));
     2455            unsigned iHint;
     2456            for (iHint = 0; iHint < pModeHintQuery->cHintsQueried && iHint < 64;
     2457                 ++iHint)
     2458            {
     2459                memcpy(pbHint, &pCtx->aModeHints[iHint],
     2460                       RT_MIN(pModeHintQuery->cbHintStructureGuest,
     2461                              sizeof(VBVAMODEHINT)));
     2462                pbHint += pModeHintQuery->cbHintStructureGuest;
     2463                Assert(pbHint - (uint8_t *)pvBuffer <= cbBuffer);
     2464            }
     2465        } break;
     2466
    24142467        default:
    24152468            Log(("Unsupported VBVA guest command %d!!!\n",
     
    25022555    }
    25032556
     2557    return rc;
     2558}
     2559
     2560static int vbvaSendModeHintWorker(PVGASTATE pThis, uint32_t cx, uint32_t cy,
     2561                                  uint32_t cBPP, uint32_t iDisplay, uint32_t dx,
     2562                                  uint32_t dy, uint32_t fEnabled,
     2563                                  uint32_t fNotifyGuest)
     2564{
     2565    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pThis->pHGSMI);
     2566    /** @note See Display::setVideoModeHint: "It is up to the guest to decide
     2567     *  whether the hint is valid. Therefore don't do any VRAM sanity checks
     2568     *  here! */
     2569    if (iDisplay > RT_MIN(pThis->cMonitors, RT_ELEMENTS(pCtx->aModeHints)))
     2570        return VERR_OUT_OF_RANGE;
     2571    pCtx->aModeHints[iDisplay].magic    = VBVAMODEHINT_MAGIC;
     2572    pCtx->aModeHints[iDisplay].cx       = cx;
     2573    pCtx->aModeHints[iDisplay].cy       = cy;
     2574    pCtx->aModeHints[iDisplay].cBPP     = cBPP;
     2575    pCtx->aModeHints[iDisplay].dx       = dx;
     2576    pCtx->aModeHints[iDisplay].dy       = dy;
     2577    pCtx->aModeHints[iDisplay].fEnabled = fEnabled;
     2578    if (fNotifyGuest && pThis->fGuestCaps & VBVACAPS_IRQ)
     2579        VBVARaiseIrq(pThis, HGSMIHOSTFLAGS_HOTPLUG);
     2580    return VINF_SUCCESS;
     2581}
     2582
     2583/** Converts a display port interface pointer to a vga state pointer. */
     2584#define IDISPLAYPORT_2_VGASTATE(pInterface) ( (PVGASTATE)((uintptr_t)pInterface - RT_OFFSETOF(VGASTATE, IPort)) )
     2585
     2586DECLCALLBACK(int) vbvaPortSendModeHint(PPDMIDISPLAYPORT pInterface, uint32_t cx,
     2587                                       uint32_t cy, uint32_t cBPP,
     2588                                       uint32_t iDisplay, uint32_t dx,
     2589                                       uint32_t dy, uint32_t fEnabled,
     2590                                       uint32_t fNotifyGuest)
     2591{
     2592    PVGASTATE pThis;
     2593    int rc;
     2594
     2595    pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
     2596    rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
     2597    AssertRC(rc);
     2598    rc = vbvaSendModeHintWorker(pThis, cx, cy, cBPP, iDisplay, dx, dy, fEnabled,
     2599                                fNotifyGuest);
     2600    PDMCritSectLeave(&pThis->CritSect);
    25042601    return rc;
    25052602}
     
    25352632             pCtx->cViews = pVGAState->cMonitors;
    25362633             pCtx->fPaused = true;
     2634             memset(pCtx->aModeHints, ~0, sizeof(*pCtx->aModeHints));
    25372635         }
    25382636     }
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r53083 r53528  
    854854
    855855/**
     856 * Send an ACPI monitor hot-plug event.
     857 *
     858 * @returns VBox status code
     859 * @param   pInterface      Pointer to the interface structure containing the
     860 *                          called function pointer.
     861 */
     862static DECLCALLBACK(int) acpiR3Port_MonitorHotPlugEvent(PPDMIACPIPORT pInterface)
     863{
     864    ACPIState *pThis = RT_FROM_MEMBER(pInterface, ACPIState, IACPIPort);
     865    DEVACPI_LOCK_R3(pThis);
     866
     867    apicR3UpdateGpe0(pThis, pThis->gpe0_sts | 0x4, pThis->gpe0_en);
     868
     869    DEVACPI_UNLOCK(pThis);
     870    return VINF_SUCCESS;
     871}
     872
     873/**
    856874 * Used by acpiR3PmTimer to re-arm the PM timer.
    857875 *
     
    29893007    pThis->IACPIPort.pfnGetGuestEnteredACPIMode = acpiR3Port_GetGuestEnteredACPIMode;
    29903008    pThis->IACPIPort.pfnGetCpuStatus            = acpiR3Port_GetCpuStatus;
     3009    pThis->IACPIPort.pfnMonitorHotPlugEvent     = acpiR3Port_MonitorHotPlugEvent;
    29913010
    29923011    /*
  • trunk/src/VBox/Devices/PC/vbox.dsl

    r53334 r53528  
    910910            }
    911911
     912            // Graphics device
     913            Device (GFX0)
     914            {
     915                Name (_ADR, 0x00020000)
     916
     917                Scope (\_GPE)
     918                {
     919                    // GPE bit 2 handler
     920                    // GPE.2 must be set and SCI raised when
     921                    // display information changes.
     922                    Method (_L02, 0, NotSerialized)
     923                    {
     924                            Notify (\_SB.PCI0.GFX0, 0x81)
     925                    }
     926                }
     927
     928                Method (_DOD, 0, NotSerialized)
     929                {
     930                    Return (Package()
     931                    {
     932                        0x80000100
     933                    })
     934                }
     935
     936                Device (VGA)
     937                {
     938                    Method (_ADR, 0, Serialized)
     939                    {
     940                        Return (0x0100)
     941                    }
     942                }
     943            }
     944
    912945            // HDA Audio card
    913946            Device (HDEF)
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r53442 r53528  
    250250    HRESULT i_onShowWindow(BOOL aCheck, BOOL *aCanShow, LONG64 *aWinId);
    251251    void i_onVRDEServerInfoChange();
     252    HRESULT i_sendACPIMonitorHotPlugEvent();
    252253
    253254    static const PDMDRVREG DrvStatusReg;
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r53053 r53528  
    148148                               uint32_t w, uint32_t h, uint16_t flags);
    149149    void i_handleDisplayUpdate(unsigned uScreenId, int x, int y, int w, int h);
     150    void i_handleUpdateVMMDevSupportsGraphics(bool fSupportsGraphics);
     151    void i_handleUpdateGuestVBVACapabilities(uint32_t fNewCapabilities);
    150152#ifdef VBOX_WITH_VIDEOHWACCEL
    151153    int  i_handleVHWACommandProcess(PVBOXVHWACMD pCommand);
     
    327329                                                              uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy,
    328330                                                              const void *pvShape);
     331    static DECLCALLBACK(void)  i_displayVBVAGuestCapabilityUpdate(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fCapabilities);
    329332#endif
    330333
     
    357360    unsigned mcMonitors;
    358361    DISPLAYFBINFO maFramebuffers[SchemaDefs::MaxGuestMonitors];
     362    /** Does the VMM device have the "supports graphics" capability set?
     363     *  Does not go into the saved state as it is refreshed on restore. */
     364    bool        mfVMMDevSupportsGraphics;
     365    /** Mirror of the current guest VBVA capabilities.
     366     *  Does not go into the saved state as it is refreshed on restore. */
     367    uint32_t    mfGuestVBVACapabilities;
    359368
    360369    bool mfSourceBitmapEnabled;
     
    426435    static int i_drawToScreenEMT(Display *pDisplay, ULONG aScreenId, BYTE *address, ULONG x, ULONG y, ULONG width, ULONG height);
    427436
     437    void i_updateGuestGraphicsFacility(void);
     438
    428439#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
    429440    int i_crOglWindowsShow(bool fShow);
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r53442 r53528  
    51845184
    51855185    fireVRDEServerInfoChangedEvent(mEventSource);
     5186}
     5187
     5188HRESULT Console::i_sendACPIMonitorHotPlugEvent()
     5189{
     5190    LogFlowThisFuncEnter();
     5191
     5192    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     5193
     5194    if (   mMachineState != MachineState_Running
     5195        && mMachineState != MachineState_Teleporting
     5196        && mMachineState != MachineState_LiveSnapshotting)
     5197        return i_setInvalidMachineStateError();
     5198
     5199    /* get the VM handle. */
     5200    SafeVMPtr ptrVM(this);
     5201    if (!ptrVM.isOk())
     5202        return ptrVM.rc();
     5203
     5204    // no need to release lock, as there are no cross-thread callbacks
     5205
     5206    /* get the acpi device interface and press the sleep button. */
     5207    PPDMIBASE pBase;
     5208    int vrc = PDMR3QueryDeviceLun(ptrVM.rawUVM(), "acpi", 0, 0, &pBase);
     5209    if (RT_SUCCESS(vrc))
     5210    {
     5211        Assert(pBase);
     5212        PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
     5213        if (pPort)
     5214            vrc = pPort->pfnMonitorHotPlugEvent(pPort);
     5215        else
     5216            vrc = VERR_PDM_MISSING_INTERFACE;
     5217    }
     5218
     5219    HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
     5220        setError(VBOX_E_PDM_ERROR,
     5221            tr("Sending monitor hot-plug event failed (%Rrc)"),
     5222            vrc);
     5223
     5224    LogFlowThisFunc(("rc=%Rhrc\n", rc));
     5225    LogFlowThisFuncLeave();
     5226    return rc;
    51865227}
    51875228
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r53201 r53528  
    2020#include "ConsoleImpl.h"
    2121#include "ConsoleVRDPServer.h"
     22#include "GuestImpl.h"
    2223#include "VMMDev.h"
    2324
     
    122123#ifdef VBOX_WITH_HGSMI
    123124    mu32UpdateVBVAFlags = 0;
     125    mfVMMDevSupportsGraphics = false;
     126    mfGuestVBVACapabilities = 0;
    124127#endif
    125128#ifdef VBOX_WITH_VPX
     
    10321035        mParent->i_consoleVRDPServer()->SendUpdateBitmap(uScreenId, x, y, w, h);
    10331036    }
     1037}
     1038
     1039void Display::i_updateGuestGraphicsFacility(void)
     1040{
     1041    Guest* pGuest = mParent->i_getGuest();
     1042    AssertPtrReturnVoid(pGuest);
     1043    /* The following is from GuestImpl.cpp. */
     1044    /** @todo A nit: The timestamp is wrong on saved state restore. Would be better
     1045     *  to move the graphics and seamless capability -> facility translation to
     1046     *  VMMDev so this could be saved.  */
     1047    RTTIMESPEC TimeSpecTS;
     1048    RTTimeNow(&TimeSpecTS);
     1049
     1050    if (   mfVMMDevSupportsGraphics
     1051        || (mfGuestVBVACapabilities & VBVACAPS_VIDEO_MODE_HINTS) != 0)
     1052        pGuest->i_setAdditionsStatus(VBoxGuestFacilityType_Graphics,
     1053                                     VBoxGuestFacilityStatus_Active,
     1054                                     0 /*fFlags*/, &TimeSpecTS);
     1055    else
     1056        pGuest->i_setAdditionsStatus(VBoxGuestFacilityType_Graphics,
     1057                                     VBoxGuestFacilityStatus_Inactive,
     1058                                     0 /*fFlags*/, &TimeSpecTS);
     1059}
     1060
     1061void Display::i_handleUpdateVMMDevSupportsGraphics(bool fSupportsGraphics)
     1062{
     1063    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1064    if (mfVMMDevSupportsGraphics == fSupportsGraphics)
     1065        return;
     1066    mfVMMDevSupportsGraphics = fSupportsGraphics;
     1067    i_updateGuestGraphicsFacility();
     1068    /* The VMMDev interface notifies the console. */
     1069}
     1070
     1071void Display::i_handleUpdateGuestVBVACapabilities(uint32_t fNewCapabilities)
     1072{
     1073    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1074    bool fNotify = (fNewCapabilities & VBVACAPS_VIDEO_MODE_HINTS) != 0;
     1075
     1076    mfGuestVBVACapabilities = fNewCapabilities;
     1077    if (!fNotify)
     1078        return;
     1079    i_updateGuestGraphicsFacility();
     1080    /* Tell the console about it */
     1081    mParent->i_onAdditionsStateChange();
    10341082}
    10351083
     
    16371685    alock.release();
    16381686
     1687    /* We always send the hint to the graphics card in case the guest enables
     1688     * support later.  For now we notify exactly when support is enabled. */
     1689    mpDrv->pUpPort->pfnSendModeHint(mpDrv->pUpPort, aWidth, aHeight,
     1690                                    aBitsPerPixel, aDisplay,
     1691                                    aChangeOrigin ? aOriginX : ~0,
     1692                                    aChangeOrigin ? aOriginY : ~0,
     1693                                    RT_BOOL(aEnabled),
     1694                                      mfGuestVBVACapabilities
     1695                                    & VBVACAPS_VIDEO_MODE_HINTS);
     1696    if (   mfGuestVBVACapabilities & VBVACAPS_VIDEO_MODE_HINTS
     1697        && !(mfGuestVBVACapabilities & VBVACAPS_IRQ))
     1698    {
     1699        HRESULT hrc = mParent->i_sendACPIMonitorHotPlugEvent();
     1700        if (FAILED(hrc))
     1701            return hrc;
     1702    }
     1703
     1704    /* We currently never suppress the VMMDev hint if the guest has requested
     1705     * it.  Specifically the video graphics driver may not be responsible for
     1706     * screen positioning in the guest virtual desktop, and the component
     1707     * responsible may want to get the hint from VMMDev. */
    16391708    VMMDev *pVMMDev = mParent->i_getVMMDev();
    16401709    if (pVMMDev)
     
    37813850    return VINF_SUCCESS;
    37823851}
     3852
     3853DECLCALLBACK(void) Display::i_displayVBVAGuestCapabilityUpdate(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fCapabilities)
     3854{
     3855    LogFlowFunc(("\n"));
     3856
     3857    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
     3858    Display *pThis = pDrv->pDisplay;
     3859
     3860    pThis->i_handleUpdateGuestVBVACapabilities(fCapabilities);
     3861}
    37833862#endif /* VBOX_WITH_HGSMI */
    37843863
     
    38813960    pThis->IConnector.pfnVBVAResize            = Display::i_displayVBVAResize;
    38823961    pThis->IConnector.pfnVBVAMousePointerShape = Display::i_displayVBVAMousePointerShape;
     3962    pThis->IConnector.pfnVBVAGuestCapabilityUpdate = Display::i_displayVBVAGuestCapabilityUpdate;
    38833963#endif
    38843964
  • trunk/src/VBox/Main/src-client/GuestImpl.cpp

    r52085 r53528  
    10831083                     0 /*fFlags*/, &TimeSpecTS);
    10841084    /** @todo Add VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING */
    1085     i_facilityUpdate(VBoxGuestFacilityType_Graphics,
    1086                      aCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
    1087                      0 /*fFlags*/, &TimeSpecTS);
    1088 }
    1089 
     1085}
     1086
  • trunk/src/VBox/Main/src-client/VMMDevInterface.cpp

    r52934 r53528  
    290290     */
    291291    pGuest->i_setSupportedFeatures(newCapabilities);
     292
     293    /*
     294     * Tell the Display, so that it can update the "supports graphics"
     295     * capability if the graphics card has not asserted it.
     296     */
     297    Display* pDisplay = pConsole->i_getDisplay();
     298    AssertPtrReturnVoid(pDisplay);
     299    pDisplay->i_handleUpdateVMMDevSupportsGraphics(newCapabilities
     300                                             & VMMDEV_GUEST_SUPPORTS_GRAPHICS);
    292301
    293302    /*
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