VirtualBox

Changeset 41319 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
May 15, 2012 6:09:25 PM (13 years ago)
Author:
vboxsync
Message:

wddm: hide displays when not used

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp

    r38565 r41319  
    21232123    D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
    21242124    const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
     2125
     2126#ifdef DEBUG_misha
     2127    if (pAllocation)
     2128    {
     2129        Assert(pAllocation->SurfDesc.VidPnSourceId == srcId);
     2130    }
     2131#endif
    21252132
    21262133    NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hDesiredVidPn,
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r41058 r41319  
    188188}
    189189
    190 NTSTATUS vboxWddmGhDisplayPostInfoScreen (PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation, POINT * pVScreenPos)
     190NTSTATUS vboxWddmGhDisplayPostInfoScreen(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation, POINT * pVScreenPos)
    191191{
    192192    NTSTATUS Status = vboxWddmGhDisplayPostInfoScreenBySDesc(pDevExt, &pAllocation->SurfDesc, pVScreenPos, VBVA_SCREEN_F_ACTIVE);
    193     Assert(Status == STATUS_SUCCESS);
     193    if (!NT_SUCCESS(Status))
     194        WARN(("vboxWddmGhDisplayPostInfoScreenBySDesc failed Status 0x%x", Status));
     195    return Status;
     196}
     197
     198NTSTATUS vboxWddmGhDisplayHideScreen(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     199{
     200    VBOXWDDM_SURFACE_DESC SurfDesc = {0};
     201    POINT VScreenPos = {0};
     202    SurfDesc.VidPnSourceId = VidPnTargetId;
     203    NTSTATUS Status = vboxWddmGhDisplayPostInfoScreenBySDesc(pDevExt, &SurfDesc, &VScreenPos, VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED);
     204    if (!NT_SUCCESS(Status))
     205        WARN(("vboxWddmGhDisplayPostInfoScreenBySDesc failed Status 0x%x", Status));
    194206    return Status;
    195207}
     
    44474459
    44484460        Assert(pAllocation);
     4461        Assert(pAllocation->SurfDesc.VidPnSourceId == pSetVidPnSourceAddress->VidPnSourceId);
     4462
    44494463        if (pAllocation)
    44504464        {
     
    45704584}
    45714585
     4586static DECLCALLBACK(BOOLEAN) vboxWddmVidPnCleanupTargetsForSrcEnum(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
     4587        CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, SIZE_T cTgtPaths, PVOID pContext)
     4588{
     4589    AssertRelease(VidPnTargetId < RT_ELEMENTS(pDevExt->aTargets));
     4590    PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[VidPnTargetId];
     4591    /* see comments in DxgkDdiCommitVidPn */
     4592    pTarget->HeightVisible = 0;
     4593    return TRUE;
     4594}
     4595
     4596
    45724597NTSTATUS
    45734598APIENTRY
     
    45804605
    45814606    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
     4607    uint32_t au32OldHeightVisible[VBOX_VIDEO_MAX_SCREENS];
     4608    NTSTATUS Status;
    45824609
    45834610    vboxVDbgBreakFv();
    45844611
    4585     const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
    4586     NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
    4587     Assert(Status == STATUS_SUCCESS);
    4588     if (Status == STATUS_SUCCESS)
    4589     {
     4612    /* we first store the current visible height for each target (monitor)
     4613     * and then we will zero up it for targets either for the given source
     4614     * (in case pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)
     4615     * or all targets otherwize.
     4616     * In the end we will match the old and new visible height for all targets to see if
     4617     * some of them become inactivated and hide them accordingly,
     4618     * or we will restore the old height values on failure */
     4619    for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     4620    {
     4621        PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
     4622        au32OldHeightVisible[i] = pTarget->HeightVisible;
     4623    }
     4624
     4625    do {
     4626        const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
     4627        Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
     4628        if (!NT_SUCCESS(Status))
     4629        {
     4630            WARN(("DxgkCbQueryVidPnInterface failed Status 0x%x", Status));
     4631            break;
     4632        }
     4633
    45904634#ifdef VBOXWDDM_DEBUG_VIDPN
    45914635        vboxVidPnDumpVidPn("\n>>>>COMMIT VidPN: >>>>", pDevExt, pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
    45924636#endif
     4637
    45934638        if (pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)
    45944639        {
     4640            /* there is not VidPn on driver start, check that */
     4641            if (pDevExt->u.primary.hCommittedVidPn)
     4642            {
     4643                D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
     4644                CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
     4645                const DXGK_VIDPN_INTERFACE* pOldVidPnInterface = NULL;
     4646                Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pDevExt->u.primary.hCommittedVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pOldVidPnInterface);
     4647                if (!NT_SUCCESS(Status))
     4648                {
     4649                    WARN(("DxgkCbQueryVidPnInterface for current VidPn failed Status 0x%x", Status));
     4650                    break;
     4651                }
     4652
     4653                Status = pOldVidPnInterface->pfnGetTopology(pDevExt->u.primary.hCommittedVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
     4654                if (!NT_SUCCESS(Status))
     4655                {
     4656                    WARN(("pfnGetTopology for current VidPn failed Status 0x%x", Status));
     4657                    break;
     4658                }
     4659
     4660                /* this will sero up visible height for all targets of the fiven source, see above comment */
     4661                Status = vboxVidPnEnumTargetsForSource(pDevExt, hVidPnTopology, pVidPnTopologyInterface,
     4662                                pCommitVidPnArg->AffectedVidPnSourceId,
     4663                                vboxWddmVidPnCleanupTargetsForSrcEnum, NULL);
     4664                if (Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY)
     4665                    Status = STATUS_SUCCESS;
     4666
     4667                if (!NT_SUCCESS(Status))
     4668                {
     4669                    WARN(("vboxVidPnEnumTargetsForSource for current VidPn failed Status 0x%x", Status));
     4670                    break;
     4671                }
     4672            }
     4673
    45954674            Status = vboxVidPnCommitSourceModeForSrcId(
    45964675                    pDevExt,
    45974676                    pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface,
    45984677                    pCommitVidPnArg->AffectedVidPnSourceId, (PVBOXWDDM_ALLOCATION)pCommitVidPnArg->hPrimaryAllocation);
    4599             Assert(Status == STATUS_SUCCESS);
    4600             if (Status != STATUS_SUCCESS)
    4601                 LOGREL(("vboxVidPnCommitSourceModeForSrcId failed Status(0x%x)", Status));
     4678            if (!NT_SUCCESS(Status))
     4679            {
     4680                WARN(("vboxVidPnCommitSourceModeForSrcId for current VidPn failed Status 0x%x", Status));
     4681                break;
     4682            }
    46024683        }
    46034684        else
    46044685        {
     4686            for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     4687            {
     4688                PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
     4689                /* see above comment */
     4690                pTarget->HeightVisible = 0;
     4691            }
     4692
    46054693            /* clear all current primaries */
    46064694            for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     
    46114699            D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
    46124700            const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
    4613             NTSTATUS Status = pVidPnInterface->pfnGetTopology(pCommitVidPnArg->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
    4614             Assert(Status == STATUS_SUCCESS);
    4615             if (Status == STATUS_SUCCESS)
    4616             {
    4617                 VBOXVIDPNCOMMIT CbContext = {0};
    4618                 CbContext.pDevExt = pDevExt;
    4619                 CbContext.pVidPnInterface = pVidPnInterface;
    4620                 CbContext.pCommitVidPnArg = pCommitVidPnArg;
    4621                 Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
    4622                             vboxVidPnCommitPathEnum, &CbContext);
    4623                 Assert(Status == STATUS_SUCCESS);
    4624                 if (Status == STATUS_SUCCESS)
    4625                 {
    4626                         Status = CbContext.Status;
    4627                         Assert(Status == STATUS_SUCCESS);
    4628                         if (Status != STATUS_SUCCESS)
    4629                             LOGREL(("vboxVidPnCommitPathEnum failed Status(0x%x)", Status));
    4630                 }
    4631                 else
    4632                     LOGREL(("vboxVidPnEnumPaths failed Status(0x%x)", Status));
    4633             }
    4634             else
    4635                 LOGREL(("pfnGetTopology failed Status(0x%x)", Status));
    4636         }
    4637 
    4638         if (Status == STATUS_SUCCESS)
    4639         {
    4640             pDevExt->u.primary.hCommittedVidPn = pCommitVidPnArg->hFunctionalVidPn;
    4641         }
    4642     }
    4643     else
    4644         LOGREL(("DxgkCbQueryVidPnInterface failed Status(0x%x)", Status));
    4645 
    4646     LOGF(("LEAVE, status(0x%x), context(0x%x)", Status, hAdapter));
    4647 
     4701            Status = pVidPnInterface->pfnGetTopology(pCommitVidPnArg->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
     4702            if (!NT_SUCCESS(Status))
     4703            {
     4704                WARN(("pfnGetTopology failed Status 0x%x", Status));
     4705                break;
     4706            }
     4707
     4708            VBOXVIDPNCOMMIT CbContext = {0};
     4709            CbContext.pDevExt = pDevExt;
     4710            CbContext.pVidPnInterface = pVidPnInterface;
     4711            CbContext.pCommitVidPnArg = pCommitVidPnArg;
     4712            Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
     4713                        vboxVidPnCommitPathEnum, &CbContext);
     4714            if (!NT_SUCCESS(Status))
     4715            {
     4716                WARN(("vboxVidPnEnumPaths failed Status 0x%x", Status));
     4717                break;
     4718            }
     4719
     4720            Status = CbContext.Status;
     4721            if (!NT_SUCCESS(Status))
     4722            {
     4723                WARN(("vboxVidPnCommitPathEnum failed Status 0x%x", Status));
     4724                break;
     4725            }
     4726        }
     4727
     4728        Assert(NT_SUCCESS(Status));
     4729        pDevExt->u.primary.hCommittedVidPn = pCommitVidPnArg->hFunctionalVidPn;
     4730
     4731        for (int i = 1; /* <- never try to hide a primary monitor */
     4732                i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     4733        {
     4734            PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
     4735            if (!pTarget->HeightVisible && !!au32OldHeightVisible[i])
     4736            {
     4737                /* the target was previously visible */
     4738                vboxWddmGhDisplayHideScreen(pDevExt, i);
     4739            }
     4740        }
     4741
     4742        LOGF(("LEAVE, SUCCESS status(0x%x), context(0x%x)", Status, hAdapter));
     4743
     4744        return Status;
     4745    } while (0);
     4746
     4747    AssertRelease(!NT_SUCCESS(Status));
     4748    /* failure branch restore original visible height values, see comments above */
     4749    for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     4750    {
     4751        PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
     4752        pTarget->HeightVisible = au32OldHeightVisible[i];
     4753    }
     4754
     4755    LOGF(("LEAVE, !!FAILURE!! status(0x%x), context(0x%x)", Status, hAdapter));
    46484756    return Status;
    46494757}
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