VirtualBox

Changeset 39981 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 3, 2012 12:13:33 PM (13 years ago)
Author:
vboxsync
Message:

wddm/3d: visible regions fixes for WPF apps

Location:
trunk/src/VBox/Additions
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h

    r39537 r39981  
    3030#include <VBox/VBoxVideo.h>
    3131#include "../../../../include/VBoxDisplay.h"
     32#include "../VBoxVideoTools.h"
    3233#include <VBox/VBoxUhgsmi.h>
    3334
     
    222223} VBOXWDDM_OVERLAY_DESC, *PVBOXWDDM_OVERLAY_DESC;
    223224
    224 /* the dirty rect info is valid */
    225 #define VBOXWDDM_DIRTYREGION_F_VALID      0x00000001
    226 #define VBOXWDDM_DIRTYREGION_F_RECT_VALID 0x00000002
    227 
    228 typedef struct VBOXWDDM_DIRTYREGION
    229 {
    230     uint32_t fFlags; /* <-- see VBOXWDDM_DIRTYREGION_F_xxx flags above */
    231     RECT Rect;
    232 } VBOXWDDM_DIRTYREGION, *PVBOXWDDM_DIRTYREGION;
    233 
    234225typedef struct VBOXWDDM_OVERLAY_INFO
    235226{
     
    280271             * if set - VBOXWDDM_RECTS_INFO::aRects[0] contains view rectangle */
    281272            UINT bSetViewRect : 1;
    282             /* sets visible regions */
    283             UINT bSetVisibleRects : 1;
     273            /* adds visible regions */
     274            UINT bAddVisibleRects : 1;
    284275            /* adds hidden regions */
    285276            UINT bAddHiddenRects : 1;
     
    739730}
    740731
    741 DECLINLINE(void) vboxWddmRectUnite(RECT *pR, const RECT *pR2Unite)
    742 {
    743     pR->left = RT_MIN(pR->left, pR2Unite->left);
    744     pR->top = RT_MIN(pR->top, pR2Unite->top);
    745     pR->right = RT_MAX(pR->right, pR2Unite->right);
    746     pR->bottom = RT_MAX(pR->bottom, pR2Unite->bottom);
    747 }
    748 
    749 DECLINLINE(bool) vboxWddmRectIntersection(const RECT *a, const RECT *b, RECT *rect)
    750 {
    751     Assert(a);
    752     Assert(b);
    753     Assert(rect);
    754     rect->left = RT_MAX(a->left, b->left);
    755     rect->right = RT_MIN(a->right, b->right);
    756     rect->top = RT_MAX(a->top, b->top);
    757     rect->bottom = RT_MIN(a->bottom, b->bottom);
    758     return (rect->right>rect->left) && (rect->bottom>rect->top);
    759 }
    760 
    761 DECLINLINE(bool) vboxWddmRectIsEqual(const RECT *pRect1, const RECT *pRect2)
    762 {
    763     Assert(pRect1);
    764     Assert(pRect2);
    765     if (pRect1->left != pRect2->left)
    766         return false;
    767     if (pRect1->top != pRect2->top)
    768         return false;
    769     if (pRect1->right != pRect2->right)
    770         return false;
    771     if (pRect1->bottom != pRect2->bottom)
    772         return false;
    773     return true;
    774 }
    775 
    776 DECLINLINE(bool) vboxWddmRectIsCoveres(const RECT *pRect, const RECT *pCovered)
    777 {
    778     Assert(pRect);
    779     Assert(pCovered);
    780     if (pRect->left > pCovered->left)
    781         return false;
    782     if (pRect->top > pCovered->top)
    783         return false;
    784     if (pRect->right < pCovered->right)
    785         return false;
    786     if (pRect->bottom < pCovered->bottom)
    787         return false;
    788     return true;
    789 }
    790 
    791 DECLINLINE(bool) vboxWddmRectIsEmpty(const RECT * pRect)
    792 {
    793     return pRect->left == pRect->right-1 && pRect->top == pRect->bottom-1;
    794 }
    795 
    796 DECLINLINE(bool) vboxWddmRectIsIntersect(const RECT * pRect1, const RECT * pRect2)
    797 {
    798     return !((pRect1->left < pRect2->left && pRect1->right < pRect2->left)
    799             || (pRect2->left < pRect1->left && pRect2->right < pRect1->left)
    800             || (pRect1->top < pRect2->top && pRect1->bottom < pRect2->top)
    801             || (pRect2->top < pRect1->top && pRect2->bottom < pRect1->top));
    802 }
    803 
    804 DECLINLINE(void) vboxWddmRectUnited(RECT * pDst, const RECT * pRect1, const RECT * pRect2)
    805 {
    806     pDst->left = RT_MIN(pRect1->left, pRect2->left);
    807     pDst->top = RT_MIN(pRect1->top, pRect2->top);
    808     pDst->right = RT_MAX(pRect1->right, pRect2->right);
    809     pDst->bottom = RT_MAX(pRect1->bottom, pRect2->bottom);
    810 }
    811 
    812 DECLINLINE(void) vboxWddmRectTranslate(RECT * pRect, int x, int y)
    813 {
    814     pRect->left   += x;
    815     pRect->top    += y;
    816     pRect->right  += x;
    817     pRect->bottom += y;
    818 }
    819 
    820 DECLINLINE(void) vboxWddmRectMove(RECT * pRect, int x, int y)
    821 {
    822     LONG w = pRect->right - pRect->left;
    823     LONG h = pRect->bottom - pRect->top;
    824     pRect->left   = x;
    825     pRect->top    = y;
    826     pRect->right  = w + x;
    827     pRect->bottom = h + y;
    828 }
    829 
    830 DECLINLINE(void) vboxWddmRectTranslated(RECT *pDst, const RECT * pRect, int x, int y)
    831 {
    832     *pDst = *pRect;
    833     vboxWddmRectTranslate(pDst, x, y);
    834 }
    835 
    836 DECLINLINE(void) vboxWddmRectMoved(RECT *pDst, const RECT * pRect, int x, int y)
    837 {
    838     *pDst = *pRect;
    839     vboxWddmRectMove(pDst, x, y);
    840 }
    841 
    842 DECLINLINE(void) vboxWddmDirtyRegionAddRect(PVBOXWDDM_DIRTYREGION pInfo, const RECT *pRect)
    843 {
    844     if (!(pInfo->fFlags & VBOXWDDM_DIRTYREGION_F_VALID))
    845     {
    846         pInfo->fFlags = VBOXWDDM_DIRTYREGION_F_VALID;
    847         if (pRect)
    848         {
    849             pInfo->fFlags |= VBOXWDDM_DIRTYREGION_F_RECT_VALID;
    850             pInfo->Rect = *pRect;
    851         }
    852     }
    853     else if (!!(pInfo->fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID))
    854     {
    855         if (pRect)
    856             vboxWddmRectUnite(&pInfo->Rect, pRect);
    857         else
    858             pInfo->fFlags &= ~VBOXWDDM_DIRTYREGION_F_RECT_VALID;
    859     }
    860 }
    861 
    862 DECLINLINE(void) vboxWddmDirtyRegionUnite(PVBOXWDDM_DIRTYREGION pInfo, const PVBOXWDDM_DIRTYREGION pInfo2)
    863 {
    864     if (pInfo2->fFlags & VBOXWDDM_DIRTYREGION_F_VALID)
    865     {
    866         if (pInfo2->fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID)
    867             vboxWddmDirtyRegionAddRect(pInfo, &pInfo2->Rect);
    868         else
    869             vboxWddmDirtyRegionAddRect(pInfo, NULL);
    870     }
    871 }
    872 
    873 DECLINLINE(void) vboxWddmDirtyRegionClear(PVBOXWDDM_DIRTYREGION pInfo)
    874 {
    875     pInfo->fFlags = 0;
    876 }
    877 
    878732#define VBOXWDDM_ARRAY_MAXELEMENTSU32(_t) ((uint32_t)((UINT32_MAX) / sizeof (_t)))
    879733#define VBOXWDDM_TRAILARRAY_MAXELEMENTSU32(_t, _af) ((uint32_t)(((~(0UL)) - (uint32_t)RT_OFFSETOF(_t, _af[0])) / RT_SIZEOFMEMB(_t, _af[0])))
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp

    r36867 r39981  
    5656            vboxVDbgPrint(("\n>>>\n"));
    5757            HWND hWnd = Regions.hWnd;
    58             if (Regions.pRegions->fFlags.bSetVisibleRects)
     58            if (Regions.pRegions->fFlags.bAddVisibleRects)
    5959            {
    6060                uint32_t iVisibleRects = 0;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h

    r38982 r39981  
    9999   VBOXWDDM_GLOBAL_POINTER_INFO PointerInfo;
    100100
    101    VBOXSHGSMILIST CtlList;
    102    VBOXSHGSMILIST DmaCmdList;
     101   VBOXVTLIST CtlList;
     102   VBOXVTLIST DmaCmdList;
    103103#ifdef VBOX_WITH_VIDEOHWACCEL
    104    VBOXSHGSMILIST VhwaCmdList;
     104   VBOXVTLIST VhwaCmdList;
    105105#endif
    106106   BOOL bNotifyDxDpc;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp

    r39533 r39981  
    181181}
    182182
    183 PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainCreate()
     183PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainCreate(UINT w, UINT h)
    184184{
    185185    PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmMemAllocZero(sizeof (VBOXWDDM_SWAPCHAIN));
     
    190190        pSwapchain->enmState = VBOXWDDM_OBJSTATE_TYPE_INITIALIZED;
    191191        pSwapchain->cRefs = 1;
     192        /* init to some invalid value so that the pos get submitted */
     193        pSwapchain->Pos.x = pSwapchain->Pos.y = VBOXWDDM_INVALID_COORD;
     194        pSwapchain->width = w;
     195        pSwapchain->height = h;
     196        VBoxWddmVrListInit(&pSwapchain->VisibleRegions);
    192197    }
    193198    return pSwapchain;
     
    220225    if (!cRefs)
    221226    {
     227        VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
    222228        vboxWddmMemFree(pSwapchain);
    223229    }
     
    342348    RemoveEntryList(&pSwapchain->DevExtListEntry);
    343349    pSwapchain->hSwapchainKm = NULL;
    344     if (pSwapchain->pLastReportedRects)
    345     {
    346         vboxVideoCmCmdRelease(pSwapchain->pLastReportedRects);
    347         pSwapchain->pLastReportedRects = NULL;
    348     }
     350    VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
    349351    vboxWddmSwapchainRelease(pSwapchain);
    350352}
     
    471473        else if (pSwapchainInfo->SwapchainInfo.cAllocs)
    472474        {
    473             pSwapchain = vboxWddmSwapchainCreate();
     475            pSwapchain = vboxWddmSwapchainCreate(apAlloc[0]->SurfDesc.width, apAlloc[0]->SurfDesc.height);
    474476            if (!pSwapchain)
    475477            {
     
    490492        /* do not zero up the view rect since it may still be valid */
    491493//        memset(&pSwapchain->ViewRect, 0, sizeof (pSwapchain->ViewRect));
    492         if (pSwapchain->pLastReportedRects)
    493         {
    494             vboxVideoCmCmdRelease(pSwapchain->pLastReportedRects);
    495             pSwapchain->pLastReportedRects = NULL;
    496         }
     494        /* @todo: do we really need to zero this up here ? */
     495        VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
    497496
    498497        vboxWddmSwapchainAllocRemoveAll(pDevExt, pSwapchain);
     
    16431642}
    16441643#endif
     1644
     1645
     1646/* visible rects */
     1647typedef struct VBOXWDDMVR_REG
     1648{
     1649    LIST_ENTRY ListEntry;
     1650    RECT Rect;
     1651} VBOXWDDMVR_REG, *PVBOXWDDMVR_REG;
     1652
     1653#define PVBOXWDDMVR_REG_FROM_ENTRY(_pEntry) ((PVBOXWDDMVR_REG)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXWDDMVR_REG, ListEntry)))
     1654
     1655static LOOKASIDE_LIST_EX g_VBoxWddmVrLookasideList;
     1656
     1657static PVBOXWDDMVR_REG vboxWddmVrRegCreate()
     1658{
     1659    PVBOXWDDMVR_REG pReg = (PVBOXWDDMVR_REG)ExAllocateFromLookasideListEx(&g_VBoxWddmVrLookasideList);
     1660    if (!pReg)
     1661    {
     1662        WARN(("ExAllocateFromLookasideListEx failed!"));
     1663    }
     1664    return pReg;
     1665}
     1666
     1667static void vboxWddmVrRegTerm(PVBOXWDDMVR_REG pReg)
     1668{
     1669    ExFreeToLookasideListEx(&g_VBoxWddmVrLookasideList, pReg);
     1670}
     1671
     1672void VBoxWddmVrListClear(PVBOXWDDMVR_LIST pList)
     1673{
     1674    PLIST_ENTRY pNext;
     1675    for (PLIST_ENTRY pEntry = pList->ListHead.Flink; pEntry != &pList->ListHead; pEntry = pNext)
     1676    {
     1677        pNext = pEntry->Flink;
     1678        PVBOXWDDMVR_REG pReg = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry);
     1679        vboxWddmVrRegTerm(pReg);
     1680    }
     1681    VBoxWddmVrListInit(pList);
     1682}
     1683
     1684#define VBOXWDDMVR_MEMTAG 'vDBV'
     1685
     1686NTSTATUS VBoxWddmVrInit()
     1687{
     1688    NTSTATUS Status = ExInitializeLookasideListEx(&g_VBoxWddmVrLookasideList,
     1689                            NULL, /* PALLOCATE_FUNCTION_EX Allocate */
     1690                            NULL, /* PFREE_FUNCTION_EX Free */
     1691                            NonPagedPool,
     1692                            EX_LOOKASIDE_LIST_EX_FLAGS_FAIL_NO_RAISE, /* ULONG Flags */
     1693                            sizeof (VBOXWDDMVR_REG),
     1694                            VBOXWDDMVR_MEMTAG,
     1695                            0 /* USHORT Depth - reserved, must be null */
     1696                            );
     1697    if (!NT_SUCCESS(Status))
     1698    {
     1699        WARN(("ExInitializeLookasideListEx failed, Status (0x%x)", Status));
     1700        return Status;
     1701    }
     1702    return STATUS_SUCCESS;
     1703}
     1704
     1705void VBoxWddmVrTerm()
     1706{
     1707    ExDeleteLookasideListEx(&g_VBoxWddmVrLookasideList);
     1708}
     1709
     1710typedef DECLCALLBACK(int) FNVBOXWDDMVR_CB_COMPARATOR(const PVBOXWDDMVR_REG pReg1, const PVBOXWDDMVR_REG pReg2);
     1711typedef FNVBOXWDDMVR_CB_COMPARATOR *PFNVBOXWDDMVR_CB_COMPARATOR;
     1712
     1713static DECLCALLBACK(int) vboxWddmVrRegNonintersectedComparator(const RECT* pRect1, const RECT* pRect2)
     1714{
     1715    Assert(!vboxWddmRectIsIntersect(pRect1, pRect2));
     1716    if (pRect1->top != pRect2->top)
     1717        return pRect1->top - pRect2->top;
     1718    return pRect1->left - pRect2->left;
     1719}
     1720
     1721#ifdef DEBUG_misha
     1722static void vboxWddmVrDbgListDoVerify(PVBOXWDDMVR_LIST pList)
     1723{
     1724    PLIST_ENTRY pEntry1 = pList->ListHead.Flink;
     1725
     1726    for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink)
     1727    {
     1728        PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
     1729        for (PLIST_ENTRY pEntry2 = pEntry1->Flink; pEntry2 != &pList->ListHead; pEntry2 = pEntry2->Flink)
     1730        {
     1731            PVBOXWDDMVR_REG pReg2 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry2);
     1732            Assert(vboxWddmVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0);
     1733        }
     1734    }
     1735}
     1736
     1737#define vboxWddmVrDbgListVerify vboxWddmVrDbgListDoVerify
     1738#else
     1739#define vboxWddmVrDbgListVerify(_p) do {} while (0)
     1740#endif
     1741
     1742static NTSTATUS vboxWddmVrListUniteIntersection(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_LIST pIntersection);
     1743
     1744#define VBOXWDDMVR_INVALID_COORD (~0UL)
     1745
     1746DECLINLINE(void) vboxWddmVrListRegAdd(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_REG pReg, PLIST_ENTRY pPlace, BOOLEAN fAfter)
     1747{
     1748    if (fAfter)
     1749        InsertHeadList(pPlace, &pReg->ListEntry);
     1750    else
     1751        InsertTailList(pPlace, &pReg->ListEntry);
     1752    ++pList->cEntries;
     1753    vboxWddmVrDbgListVerify(pList);
     1754}
     1755
     1756DECLINLINE(void) vboxWddmVrListRegRemove(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_REG pReg)
     1757{
     1758    RemoveEntryList(&pReg->ListEntry);
     1759    --pList->cEntries;
     1760}
     1761
     1762static void vboxWddmVrListRegAddOrder(PVBOXWDDMVR_LIST pList, PLIST_ENTRY pMemberEntry, PVBOXWDDMVR_REG pReg)
     1763{
     1764    do
     1765    {
     1766        if (pMemberEntry != &pList->ListHead)
     1767        {
     1768            PVBOXWDDMVR_REG pMemberReg = PVBOXWDDMVR_REG_FROM_ENTRY(pMemberEntry);
     1769            if (vboxWddmVrRegNonintersectedComparator(&pMemberReg->Rect, &pReg->Rect) < 0)
     1770            {
     1771                pMemberEntry = pMemberEntry->Flink;
     1772                continue;
     1773            }
     1774        }
     1775        vboxWddmVrListRegAdd(pList, pReg, pMemberEntry, FALSE);
     1776        break;
     1777    } while (1);
     1778}
     1779
     1780static void vboxWddmVrListAddNonintersected(PVBOXWDDMVR_LIST pList1, PVBOXWDDMVR_LIST pList2)
     1781{
     1782    PLIST_ENTRY pEntry1 = pList1->ListHead.Flink;
     1783
     1784    for (PLIST_ENTRY pEntry2 = pList2->ListHead.Flink; pEntry2 != &pList2->ListHead; pEntry2 = pList2->ListHead.Flink)
     1785    {
     1786        PVBOXWDDMVR_REG pReg2 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry2);
     1787        do {
     1788            if (pEntry1 != &pList1->ListHead)
     1789            {
     1790                PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
     1791                if (vboxWddmVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0)
     1792                {
     1793                    pEntry1 = pEntry1->Flink;
     1794                    continue;
     1795                }
     1796            }
     1797            vboxWddmVrListRegRemove(pList2, pReg2);
     1798            vboxWddmVrListRegAdd(pList1, pReg2, pEntry1, FALSE);
     1799            break;
     1800        } while (1);
     1801    }
     1802
     1803    Assert(VBoxWddmVrListIsEmpty(pList2));
     1804}
     1805
     1806static NTSTATUS vboxWddmVrListRegIntersectSubstNoJoin(PVBOXWDDMVR_LIST pList1, PVBOXWDDMVR_REG pReg1, const RECT * pRect2)
     1807{
     1808    UINT topLim = VBOXWDDMVR_INVALID_COORD;
     1809    UINT bottomLim = VBOXWDDMVR_INVALID_COORD;
     1810    LIST_ENTRY List;
     1811    PVBOXWDDMVR_REG pBottomReg = NULL;
     1812#ifdef DEBUG_misha
     1813    RECT tmpRect = pReg1->Rect;
     1814    vboxWddmVrDbgListVerify(pList1);
     1815#endif
     1816
     1817    InitializeListHead(&List);
     1818
     1819    Assert(vboxWddmRectIsIntersect(&pReg1->Rect, pRect2));
     1820
     1821    if (pReg1->Rect.top < pRect2->top)
     1822    {
     1823        Assert(pRect2->top < pReg1->Rect.bottom);
     1824        PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
     1825        pRegResult->Rect.top = pReg1->Rect.top;
     1826        pRegResult->Rect.left = pReg1->Rect.left;
     1827        pRegResult->Rect.bottom = pRect2->top;
     1828        pRegResult->Rect.right = pReg1->Rect.right;
     1829        topLim = pRect2->top;
     1830        InsertTailList(&List, &pRegResult->ListEntry);
     1831    }
     1832
     1833    if (pReg1->Rect.bottom > pRect2->bottom)
     1834    {
     1835        Assert(pRect2->bottom > pReg1->Rect.top);
     1836        PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
     1837        pRegResult->Rect.top = pRect2->bottom;
     1838        pRegResult->Rect.left = pReg1->Rect.left;
     1839        pRegResult->Rect.bottom = pReg1->Rect.bottom;
     1840        pRegResult->Rect.right = pReg1->Rect.right;
     1841        bottomLim = pRect2->bottom;
     1842        pBottomReg = pRegResult;
     1843    }
     1844
     1845    if (pReg1->Rect.left < pRect2->left)
     1846    {
     1847        Assert(pRect2->left < pReg1->Rect.right);
     1848        PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
     1849        pRegResult->Rect.top = topLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.top : topLim;
     1850        pRegResult->Rect.left = pReg1->Rect.left;
     1851        pRegResult->Rect.bottom = bottomLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.bottom : bottomLim;
     1852        pRegResult->Rect.right = pRect2->left;
     1853        InsertTailList(&List, &pRegResult->ListEntry);
     1854    }
     1855
     1856    if (pReg1->Rect.right > pRect2->right)
     1857    {
     1858        Assert(pRect2->right > pReg1->Rect.left);
     1859        PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
     1860        pRegResult->Rect.top = topLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.top : topLim;
     1861        pRegResult->Rect.left = pRect2->right;
     1862        pRegResult->Rect.bottom = bottomLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.bottom : bottomLim;
     1863        pRegResult->Rect.right = pReg1->Rect.right;
     1864        InsertTailList(&List, &pRegResult->ListEntry);
     1865    }
     1866
     1867    if (pBottomReg)
     1868        InsertTailList(&List, &pBottomReg->ListEntry);
     1869
     1870    PLIST_ENTRY pMemberEntry = pReg1->ListEntry.Flink;
     1871    vboxWddmVrListRegRemove(pList1, pReg1);
     1872    vboxWddmVrRegTerm(pReg1);
     1873
     1874    if (IsListEmpty(&List))
     1875        return STATUS_SUCCESS; /* the region is covered by the pRect2 */
     1876
     1877    PLIST_ENTRY pEntry = List.Flink, pNext;
     1878    for (; pEntry != &List; pEntry = pNext)
     1879    {
     1880        pNext = pEntry->Flink;
     1881        PVBOXWDDMVR_REG pReg = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry);
     1882
     1883        vboxWddmVrListRegAddOrder(pList1, pMemberEntry, pReg);
     1884        pMemberEntry = pEntry->Flink; /* the following elements should go after the given pEntry since they are ordered already */
     1885    }
     1886    return STATUS_SUCCESS;
     1887}
     1888
     1889typedef DECLCALLBACK(PLIST_ENTRY) FNVBOXWDDMVR_CB_INTERSECTED_VISITOR(PVBOXWDDMVR_LIST pList1, PVBOXWDDMVR_REG pReg1, const RECT * pRect2, void *pvContext, PLIST_ENTRY *ppNext);
     1890typedef FNVBOXWDDMVR_CB_INTERSECTED_VISITOR *PFNVBOXWDDMVR_CB_INTERSECTED_VISITOR;
     1891
     1892static void vboxWddmVrListVisitIntersected(PVBOXWDDMVR_LIST pList1, UINT cRects, const RECT *aRects, BOOLEAN fRectsNonintersectedOrdered, PFNVBOXWDDMVR_CB_INTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
     1893{
     1894    PLIST_ENTRY pEntry1 = pList1->ListHead.Flink;
     1895    PLIST_ENTRY pNext1;
     1896    UINT iFirst2 = 0;
     1897
     1898    for (; pEntry1 != &pList1->ListHead; pEntry1 = pNext1)
     1899    {
     1900        pNext1 = pEntry1->Flink;
     1901        PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
     1902        for (UINT i = iFirst2; i < cRects; ++i)
     1903        {
     1904            const RECT *pRect2 = &aRects[i];
     1905            if (pReg1->Rect.bottom <= pRect2->top)
     1906            {
     1907                if (fRectsNonintersectedOrdered)
     1908                    break; /* the forthcomming rects won't intersect as well since they have at least not bigget top */
     1909                else
     1910                    continue; /* no assumptions, just continue */
     1911            }
     1912            else if (pRect2->bottom <= pReg1->Rect.top)
     1913            {
     1914                if (fRectsNonintersectedOrdered)
     1915                {
     1916                    iFirst2 = i + 1; /* the previous rects including this one have top < pRect2->bottom,
     1917                                      * while the forhtcoming pRegs will have top >= pReg1->Rect.top
     1918                                      * so we can start with the next rect next time */
     1919                }
     1920                continue;
     1921            }
     1922            /* y coords intersect */
     1923            else if (pReg1->Rect.right <= pRect2->left)
     1924                continue;
     1925            else if (pRect2->right <= pReg1->Rect.left)
     1926                continue;
     1927            /* x coords intersect */
     1928
     1929            /* the visitor can modify the list 1, apply necessary adjustments after it */
     1930            PLIST_ENTRY pEntry1 = pfnVisitor (pList1, pReg1, pRect2, pvVisitor, &pNext1);
     1931            if (pEntry1 == &pList1->ListHead)
     1932                break;
     1933        }
     1934    }
     1935}
     1936
     1937
     1938static void vboxWddmVrListJoinRectsHV(PVBOXWDDMVR_LIST pList, BOOLEAN fHorizontal)
     1939{
     1940    PLIST_ENTRY pNext1, pNext2;
     1941
     1942    for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pNext1)
     1943    {
     1944        PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
     1945        pNext1 = pEntry1->Flink;
     1946        for (PLIST_ENTRY pEntry2 = pEntry1->Flink; pEntry2 != &pList->ListHead; pEntry2 = pNext2)
     1947        {
     1948            PVBOXWDDMVR_REG pReg2 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry2);
     1949            pNext2 = pEntry2->Flink;
     1950            if (fHorizontal)
     1951            {
     1952                if (pReg1->Rect.top == pReg2->Rect.top)
     1953                {
     1954                    if (pReg1->Rect.right == pReg2->Rect.left)
     1955                    {
     1956                        /* join rectangles */
     1957                        vboxWddmVrListRegRemove(pList, pReg2);
     1958                        if (pReg1->Rect.bottom > pReg2->Rect.bottom)
     1959                        {
     1960                            LONG oldRight1 = pReg1->Rect.right;
     1961                            LONG oldBottom1 = pReg1->Rect.bottom;
     1962                            pReg1->Rect.right = pReg2->Rect.right;
     1963                            pReg1->Rect.bottom = pReg2->Rect.bottom;
     1964
     1965                            vboxWddmVrDbgListVerify(pList);
     1966
     1967                            pReg2->Rect.left = pReg1->Rect.left;
     1968                            pReg2->Rect.top = pReg1->Rect.bottom;
     1969                            pReg2->Rect.right = oldRight1;
     1970                            pReg2->Rect.bottom = oldBottom1;
     1971                            vboxWddmVrListRegAddOrder(pList, pReg1->ListEntry.Flink, pReg2);
     1972                            /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
     1973                             * and thus can match one of the previous rects */
     1974                            pNext1 = pList->ListHead.Flink;
     1975                            break;
     1976                        }
     1977                        else if (pReg1->Rect.bottom < pReg2->Rect.bottom)
     1978                        {
     1979                            pReg1->Rect.right = pReg2->Rect.right;
     1980                            vboxWddmVrDbgListVerify(pList);
     1981                            pReg2->Rect.top = pReg1->Rect.bottom;
     1982                            vboxWddmVrListRegAddOrder(pList, pReg1->ListEntry.Flink, pReg2);
     1983                            /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
     1984                             * and thus can match one of the previous rects */
     1985                            pNext1 = pList->ListHead.Flink;
     1986                            break;
     1987                        }
     1988                        else
     1989                        {
     1990                            pReg1->Rect.right = pReg2->Rect.right;
     1991                            vboxWddmVrDbgListVerify(pList);
     1992                            /* reset the pNext1 since it could be the pReg2 being destroyed */
     1993                            pNext1 = pEntry1->Flink;
     1994                            /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
     1995                            vboxWddmVrRegTerm(pReg2);
     1996                        }
     1997                    }
     1998                    continue;
     1999                }
     2000                else if (pReg1->Rect.bottom == pReg2->Rect.bottom)
     2001                {
     2002                    Assert(pReg1->Rect.top < pReg2->Rect.top); /* <- since pReg1 > pReg2 && pReg1->Rect.top != pReg2->Rect.top*/
     2003                    if (pReg1->Rect.right == pReg2->Rect.left)
     2004                    {
     2005                        /* join rectangles */
     2006                        vboxWddmVrListRegRemove(pList, pReg2);
     2007
     2008                        pReg1->Rect.bottom = pReg2->Rect.top;
     2009                        vboxWddmVrDbgListVerify(pList);
     2010                        pReg2->Rect.left = pReg1->Rect.left;
     2011
     2012                        vboxWddmVrListRegAddOrder(pList, pReg2->ListEntry.Flink, pReg2);
     2013
     2014                        /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
     2015                         * and thus can match one of the previous rects */
     2016                        pNext1 = pList->ListHead.Flink;
     2017                        break;
     2018                    }
     2019                    else if (pReg1->Rect.left == pReg2->Rect.right)
     2020                    {
     2021                        /* join rectangles */
     2022                        vboxWddmVrListRegRemove(pList, pReg2);
     2023
     2024                        pReg1->Rect.bottom = pReg2->Rect.top;
     2025                        vboxWddmVrDbgListVerify(pList);
     2026                        pReg2->Rect.right = pReg1->Rect.right;
     2027
     2028                        vboxWddmVrListRegAddOrder(pList, pReg2->ListEntry.Flink, pReg2);
     2029
     2030                        /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
     2031                         * and thus can match one of the previous rects */
     2032                        pNext1 = pList->ListHead.Flink;
     2033                        break;
     2034                    }
     2035                    continue;
     2036                }
     2037            }
     2038            else
     2039            {
     2040                if (pReg1->Rect.bottom == pReg2->Rect.top)
     2041                {
     2042                    if (pReg1->Rect.left == pReg2->Rect.left)
     2043                    {
     2044                        if (pReg1->Rect.right == pReg2->Rect.right)
     2045                        {
     2046                            /* join rects */
     2047                            vboxWddmVrListRegRemove(pList, pReg2);
     2048
     2049                            pReg1->Rect.bottom = pReg2->Rect.bottom;
     2050                            vboxWddmVrDbgListVerify(pList);
     2051
     2052                            /* reset the pNext1 since it could be the pReg2 being destroyed */
     2053                            pNext1 = pEntry1->Flink;
     2054                            /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
     2055                            vboxWddmVrRegTerm(pReg2);
     2056                            continue;
     2057                        }
     2058                        /* no more to be done for for pReg1 */
     2059                        break;
     2060                    }
     2061                    else if (pReg1->Rect.right > pReg2->Rect.left)
     2062                    {
     2063                        /* no more to be done for for pReg1 */
     2064                        break;
     2065                    }
     2066
     2067                    continue;
     2068                }
     2069                else if (pReg1->Rect.bottom < pReg2->Rect.top)
     2070                {
     2071                    /* no more to be done for for pReg1 */
     2072                    break;
     2073                }
     2074            }
     2075        }
     2076    }
     2077}
     2078
     2079static void vboxWddmVrListJoinRects(PVBOXWDDMVR_LIST pList)
     2080{
     2081    vboxWddmVrListJoinRectsHV(pList, TRUE);
     2082    vboxWddmVrListJoinRectsHV(pList, FALSE);
     2083}
     2084
     2085typedef struct VBOXWDDMVR_CBDATA_SUBST
     2086{
     2087    NTSTATUS Status;
     2088    BOOLEAN fChanged;
     2089} VBOXWDDMVR_CBDATA_SUBST, *PVBOXWDDMVR_CBDATA_SUBST;
     2090
     2091static DECLCALLBACK(PLIST_ENTRY) vboxWddmVrListSubstNoJoinCb(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_REG pReg1, const RECT *pRect2, void *pvContext, PLIST_ENTRY *ppNext)
     2092{
     2093    PVBOXWDDMVR_CBDATA_SUBST pData = (PVBOXWDDMVR_CBDATA_SUBST)pvContext;
     2094    /* store the prev to get the new Flink out of it*/
     2095    PLIST_ENTRY pPrev = pReg1->ListEntry.Blink;
     2096    pData->fChanged = TRUE;
     2097
     2098    Assert(vboxWddmRectIsIntersect(&pReg1->Rect, pRect2));
     2099
     2100    /* NOTE: the pReg1 will be invalid after the vboxWddmVrListRegIntersectSubstNoJoin call!!! */
     2101    NTSTATUS Status = vboxWddmVrListRegIntersectSubstNoJoin(pList, pReg1, pRect2);
     2102    if (NT_SUCCESS(Status))
     2103    {
     2104        *ppNext = pPrev->Flink;
     2105        return &pList->ListHead;
     2106    }
     2107    WARN(("vboxWddmVrListRegIntersectSubstNoJoin failed!"));
     2108    Assert(!NT_SUCCESS(Status));
     2109    pData->Status = Status;
     2110    *ppNext = &pList->ListHead;
     2111    return &pList->ListHead;
     2112}
     2113
     2114static NTSTATUS vboxWddmVrListSubstNoJoin(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN fRectsNonintersectedOrdered, BOOLEAN *pfChanged)
     2115{
     2116    if (VBoxWddmVrListIsEmpty(pList))
     2117        return STATUS_SUCCESS;
     2118
     2119    VBOXWDDMVR_CBDATA_SUBST Data;
     2120    Data.Status = STATUS_SUCCESS;
     2121    Data.fChanged = FALSE;
     2122
     2123    *pfChanged = FALSE;
     2124
     2125    vboxWddmVrListVisitIntersected(pList, cRects, aRects, fRectsNonintersectedOrdered, vboxWddmVrListSubstNoJoinCb, &Data);
     2126    if (!NT_SUCCESS(Data.Status))
     2127    {
     2128        WARN(("vboxWddmVrListVisitIntersected failed!"));
     2129        return Data.Status;
     2130    }
     2131
     2132    *pfChanged = Data.fChanged;
     2133    return STATUS_SUCCESS;
     2134}
     2135
     2136#if 0
     2137static const PRECT vboxWddmVrRectsOrder(UINT cRects, const PRECT aRects)
     2138{
     2139#ifdef DEBUG
     2140    {
     2141        for (UINT i = 0; i < cRects; ++i)
     2142        {
     2143            RECT *pRectI = &aRects[i];
     2144            for (UINT j = i + 1; j < cRects; ++j)
     2145            {
     2146                RECT *pRectJ = &aRects[j];
     2147                Assert(!vboxWddmRectIsIntersect(pRectI, pRectJ));
     2148            }
     2149        }
     2150    }
     2151#endif
     2152
     2153    RECT * pRects = (RECT *)aRects;
     2154    /* check if rects are ordered already */
     2155    for (UINT i = 0; i < cRects - 1; ++i)
     2156    {
     2157        RECT *pRect1 = &pRects[i];
     2158        RECT *pRect2 = &pRects[i+1];
     2159        if (vboxWddmVrRegNonintersectedComparator(pRect1, pRect2) < 0)
     2160            continue;
     2161
     2162        WARN(("rects are unoreded!"));
     2163
     2164        if (pRects == aRects)
     2165        {
     2166            pRects = (RECT *)vboxWddmMemAlloc(sizeof (RECT) * cRects);
     2167            if (!pRects)
     2168            {
     2169                WARN(("vboxWddmMemAlloc failed!"));
     2170                return NULL;
     2171            }
     2172
     2173            memcpy(pRects, aRects, sizeof (RECT) * cRects);
     2174        }
     2175
     2176        Assert(pRects != aRects);
     2177
     2178        int j = (int)i - 1;
     2179        do {
     2180            RECT Tmp = *pRect1;
     2181            *pRect1 = *pRect2;
     2182            *pRect2 = Tmp;
     2183
     2184            if (j < 0)
     2185                break;
     2186
     2187            if (vboxWddmVrRegNonintersectedComparator(pRect1, pRect1-1) > 0)
     2188                break;
     2189
     2190            pRect2 = pRect1--;
     2191            --j;
     2192        } while (1);
     2193    }
     2194
     2195    return pRects;
     2196}
     2197#endif
     2198
     2199void VBoxWddmVrListTranslate(PVBOXWDDMVR_LIST pList, LONG x, LONG y)
     2200{
     2201    for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink)
     2202    {
     2203        PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
     2204        vboxWddmRectTranslate(&pReg1->Rect, x, y);
     2205    }
     2206}
     2207
     2208NTSTATUS VBoxWddmVrListRectsSubst(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged)
     2209{
     2210#if 0
     2211    const PRECT pRects = vboxWddmVrRectsOrder(cRects, aRects);
     2212    if (!pRects)
     2213    {
     2214        WARN(("vboxWddmVrRectsOrder failed!"));
     2215        return STATUS_NO_MEMORY;
     2216    }
     2217#endif
     2218
     2219    NTSTATUS Status = vboxWddmVrListSubstNoJoin(pList, cRects, aRects,
     2220            FALSE, /* rects can be of any type, i.e. can intersect and can NOT be ordered */
     2221            pfChanged);
     2222    if (!NT_SUCCESS(Status))
     2223    {
     2224        WARN(("vboxWddmVrListSubstNoJoin failed!"));
     2225        goto done;
     2226    }
     2227
     2228    if (!*pfChanged)
     2229        goto done;
     2230
     2231    vboxWddmVrListJoinRects(pList);
     2232
     2233done:
     2234#if 0
     2235    if (pRects != aRects)
     2236        vboxWddmMemFree(pRects);
     2237#endif
     2238    return Status;
     2239}
     2240
     2241NTSTATUS VBoxWddmVrListRectsAdd(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged)
     2242{
     2243    UINT cCovered = 0;
     2244
     2245#if 0
     2246#ifdef DEBUG
     2247    {
     2248        for (UINT i = 0; i < cRects; ++i)
     2249        {
     2250            RECT *pRectI = &aRects[i];
     2251            for (UINT j = i + 1; j < cRects; ++j)
     2252            {
     2253                RECT *pRectJ = &aRects[j];
     2254                Assert(!vboxWddmRectIsIntersect(pRectI, pRectJ));
     2255            }
     2256        }
     2257    }
     2258#endif
     2259#endif
     2260
     2261    /* early sort out the case when there are no new rects */
     2262    for (UINT i = 0; i < cRects; ++i)
     2263    {
     2264        for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink)
     2265        {
     2266            PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
     2267            if (vboxWddmRectIsCoveres(&pReg1->Rect, &aRects[i]))
     2268            {
     2269                cCovered++;
     2270                break;
     2271            }
     2272        }
     2273    }
     2274
     2275    if (cCovered == cRects)
     2276    {
     2277        *pfChanged = FALSE;
     2278        return STATUS_SUCCESS;
     2279    }
     2280
     2281    /* rects are not covered, need to go the slow way */
     2282
     2283    VBOXWDDMVR_LIST DiffList;
     2284    VBoxWddmVrListInit(&DiffList);
     2285    PRECT pListRects = NULL;
     2286    UINT cAllocatedRects = 0;
     2287    BOOLEAN fNeedRectreate = TRUE;
     2288    BOOLEAN fChanged = FALSE;
     2289    NTSTATUS Status = STATUS_SUCCESS;
     2290
     2291    for (UINT i = 0; i < cRects; ++i)
     2292    {
     2293        PVBOXWDDMVR_REG pReg = vboxWddmVrRegCreate();
     2294        if (!pReg)
     2295        {
     2296            WARN(("vboxWddmVrRegCreate failed!"));
     2297            Status = STATUS_NO_MEMORY;
     2298            break;
     2299        }
     2300        pReg->Rect = aRects[i];
     2301
     2302        UINT cListRects = VBoxWddmVrListRectsCount(pList);
     2303        if (!cListRects)
     2304        {
     2305            vboxWddmVrListRegAdd(pList, pReg, &pList->ListHead, FALSE);
     2306            fChanged = TRUE;
     2307            continue;
     2308        }
     2309        else
     2310        {
     2311            Assert(VBoxWddmVrListIsEmpty(&DiffList));
     2312            vboxWddmVrListRegAdd(&DiffList, pReg, &DiffList.ListHead, FALSE);
     2313        }
     2314
     2315        if (cAllocatedRects < cListRects)
     2316        {
     2317            cAllocatedRects = cListRects + cRects;
     2318            Assert(fNeedRectreate);
     2319            if (pListRects)
     2320                vboxWddmMemFree(pListRects);
     2321            pListRects = (PRECT)vboxWddmMemAlloc(sizeof (RECT) * cAllocatedRects);
     2322            if (!pListRects)
     2323            {
     2324                WARN(("vboxWddmMemAllocZero failed!"));
     2325                Status = STATUS_NO_MEMORY;
     2326                break;
     2327            }
     2328        }
     2329
     2330
     2331        if (fNeedRectreate)
     2332        {
     2333            Status = VBoxWddmVrListRectsGet(pList, cListRects, pListRects);
     2334            Assert(Status == STATUS_SUCCESS);
     2335            fNeedRectreate = FALSE;
     2336        }
     2337
     2338        BOOLEAN fDummyChanged = FALSE;
     2339        Status = vboxWddmVrListSubstNoJoin(&DiffList, cListRects, pListRects, TRUE, &fDummyChanged);
     2340        if (!NT_SUCCESS(Status))
     2341        {
     2342            WARN(("vboxWddmVrListSubstNoJoin failed!"));
     2343            Status = STATUS_NO_MEMORY;
     2344            break;
     2345        }
     2346
     2347        if (!VBoxWddmVrListIsEmpty(&DiffList))
     2348        {
     2349            vboxWddmVrListAddNonintersected(pList, &DiffList);
     2350            fNeedRectreate = TRUE;
     2351            fChanged = TRUE;
     2352        }
     2353
     2354        Assert(VBoxWddmVrListIsEmpty(&DiffList));
     2355    }
     2356
     2357    if (pListRects)
     2358        vboxWddmMemFree(pListRects);
     2359
     2360    Assert(VBoxWddmVrListIsEmpty(&DiffList) || Status != STATUS_SUCCESS);
     2361    VBoxWddmVrListClear(&DiffList);
     2362
     2363    if (fChanged)
     2364        vboxWddmVrListJoinRects(pList);
     2365
     2366    *pfChanged = fChanged;
     2367
     2368    return STATUS_SUCCESS;
     2369}
     2370
     2371NTSTATUS VBoxWddmVrListRectsGet(PVBOXWDDMVR_LIST pList, UINT cRects, PRECT aRects)
     2372{
     2373    if (cRects < VBoxWddmVrListRectsCount(pList))
     2374        return STATUS_BUFFER_TOO_SMALL;
     2375
     2376    UINT i = 0;
     2377    for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink, ++i)
     2378    {
     2379        PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
     2380        aRects[i] = pReg1->Rect;
     2381    }
     2382    return STATUS_SUCCESS;
     2383}
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h

    r39160 r39981  
    1919#ifndef ___VBoxMPMisc_h__
    2020#define ___VBoxMPMisc_h__
     21
     22#include "../../common/VBoxVideoTools.h"
    2123
    2224DECLINLINE(void) vboxVideoLeDetach(LIST_ENTRY *pList, LIST_ENTRY *pDstList)
     
    162164#endif
    163165
     166/* visible rects */
     167typedef struct VBOXWDDMVR_LIST
     168{
     169    LIST_ENTRY ListHead;
     170    UINT cEntries;
     171} VBOXWDDMVR_LIST, *PVBOXWDDMVR_LIST;
     172
     173DECLINLINE(UINT) VBoxWddmVrListRectsCount(PVBOXWDDMVR_LIST pList)
     174{
     175    return pList->cEntries;
     176}
     177
     178DECLINLINE(BOOLEAN) VBoxWddmVrListIsEmpty(PVBOXWDDMVR_LIST pList)
     179{
     180    return !VBoxWddmVrListRectsCount(pList);
     181}
     182
     183DECLINLINE(void) VBoxWddmVrListInit(PVBOXWDDMVR_LIST pList)
     184{
     185    InitializeListHead(&pList->ListHead);
     186    pList->cEntries = 0;
     187}
     188
     189void VBoxWddmVrListClear(PVBOXWDDMVR_LIST pList);
     190
     191void VBoxWddmVrListTranslate(PVBOXWDDMVR_LIST pList, LONG x, LONG y);
     192
     193NTSTATUS VBoxWddmVrListRectsAdd(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged);
     194NTSTATUS VBoxWddmVrListRectsSubst(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged);
     195NTSTATUS VBoxWddmVrListRectsGet(PVBOXWDDMVR_LIST pList, UINT cRects, PRECT aRects);
     196
     197NTSTATUS VBoxWddmVrInit();
     198void VBoxWddmVrTerm();
     199
    164200#endif /* #ifndef ___VBoxMPMisc_h__ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.cpp

    r36867 r39981  
    183183//}
    184184
    185 #define VBOXSHGSMI_CMD2LISTENTRY(_pCmd) ((PVBOXSHGSMILIST_ENTRY)&(_pCmd)->pvNext)
     185#define VBOXSHGSMI_CMD2LISTENTRY(_pCmd) ((PVBOXVTLIST_ENTRY)&(_pCmd)->pvNext)
    186186#define VBOXSHGSMI_LISTENTRY2CMD(_pEntry) ( (PVBOXSHGSMIHEADER)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXSHGSMIHEADER, pvNext)) )
    187187
    188 int VBoxSHGSMICommandProcessCompletion (struct _HGSMIHEAP * pHeap, VBOXSHGSMIHEADER* pCur, bool bIrq, PVBOXSHGSMILIST pPostProcessList)
     188int VBoxSHGSMICommandProcessCompletion (struct _HGSMIHEAP * pHeap, VBOXSHGSMIHEADER* pCur, bool bIrq, PVBOXVTLIST pPostProcessList)
    189189{
    190190    int rc = VINF_SUCCESS;
     
    222222        }
    223223        else
    224             vboxSHGSMIListPut(pPostProcessList, VBOXSHGSMI_CMD2LISTENTRY(pCur), VBOXSHGSMI_CMD2LISTENTRY(pCur));
     224            vboxVtListPut(pPostProcessList, VBOXSHGSMI_CMD2LISTENTRY(pCur), VBOXSHGSMI_CMD2LISTENTRY(pCur));
    225225    } while (0);
    226226
     
    229229}
    230230
    231 int VBoxSHGSMICommandPostprocessCompletion (struct _HGSMIHEAP * pHeap, PVBOXSHGSMILIST pPostProcessList)
    232 {
    233     PVBOXSHGSMILIST_ENTRY pNext, pCur;
     231int VBoxSHGSMICommandPostprocessCompletion (struct _HGSMIHEAP * pHeap, PVBOXVTLIST pPostProcessList)
     232{
     233    PVBOXVTLIST_ENTRY pNext, pCur;
    234234    for (pCur = pPostProcessList->pFirst; pCur; pCur = pNext)
    235235    {
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.h

    r36867 r39981  
    2222#include <iprt/cdefs.h>
    2323#include <VBox/VBoxVideo.h>
     24#include "../../common/VBoxVideoTools.h"
    2425
    2526typedef DECLCALLBACK(void) FNVBOXSHGSMICMDCOMPLETION(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext);
     
    2930                                        PFNVBOXSHGSMICMDCOMPLETION *ppfnCompletion, void **ppvCompletion);
    3031typedef FNVBOXSHGSMICMDCOMPLETION_IRQ *PFNVBOXSHGSMICMDCOMPLETION_IRQ;
    31 
    32 typedef struct VBOXSHGSMILIST_ENTRY
    33 {
    34     struct VBOXSHGSMILIST_ENTRY *pNext;
    35 } VBOXSHGSMILIST_ENTRY, *PVBOXSHGSMILIST_ENTRY;
    36 
    37 typedef struct VBOXSHGSMILIST
    38 {
    39     PVBOXSHGSMILIST_ENTRY pFirst;
    40     PVBOXSHGSMILIST_ENTRY pLast;
    41 } VBOXSHGSMILIST, *PVBOXSHGSMILIST;
    42 
    43 DECLINLINE(bool) vboxSHGSMIListIsEmpty(PVBOXSHGSMILIST pList)
    44 {
    45     return !pList->pFirst;
    46 }
    47 
    48 DECLINLINE(void) vboxSHGSMIListInit(PVBOXSHGSMILIST pList)
    49 {
    50     pList->pFirst = pList->pLast = NULL;
    51 }
    52 
    53 DECLINLINE(void) vboxSHGSMIListPut(PVBOXSHGSMILIST pList, PVBOXSHGSMILIST_ENTRY pFirst, PVBOXSHGSMILIST_ENTRY pLast)
    54 {
    55     Assert(pFirst);
    56     Assert(pLast);
    57     pLast->pNext = NULL;
    58     if (pList->pLast)
    59     {
    60         Assert(pList->pFirst);
    61         pList->pLast->pNext = pFirst;
    62         pList->pLast = pLast;
    63     }
    64     else
    65     {
    66         Assert(!pList->pFirst);
    67         pList->pFirst = pFirst;
    68         pList->pLast = pLast;
    69     }
    70 }
    71 
    72 DECLINLINE(void) vboxSHGSMIListCat(PVBOXSHGSMILIST pList1, PVBOXSHGSMILIST pList2)
    73 {
    74     vboxSHGSMIListPut(pList1, pList2->pFirst, pList2->pLast);
    75     pList2->pFirst = pList2->pLast = NULL;
    76 }
    77 
    78 DECLINLINE(void) vboxSHGSMIListDetach(PVBOXSHGSMILIST pList, PVBOXSHGSMILIST_ENTRY *ppFirst, PVBOXSHGSMILIST_ENTRY *ppLast)
    79 {
    80     *ppFirst = pList->pFirst;
    81     if (ppLast)
    82         *ppLast = pList->pLast;
    83     pList->pFirst = NULL;
    84     pList->pLast = NULL;
    85 }
    86 
    87 DECLINLINE(void) vboxSHGSMIListDetach2List(PVBOXSHGSMILIST pList, PVBOXSHGSMILIST pDstList)
    88 {
    89     vboxSHGSMIListDetach(pList, &pDstList->pFirst, &pDstList->pLast);
    90 }
    91 
    92 DECLINLINE(void) vboxSHGSMIListDetachEntries(PVBOXSHGSMILIST pList, PVBOXSHGSMILIST_ENTRY pBeforeDetach, PVBOXSHGSMILIST_ENTRY pLast2Detach)
    93 {
    94     if (pBeforeDetach)
    95     {
    96         pBeforeDetach->pNext = pLast2Detach->pNext;
    97         if (!pBeforeDetach->pNext)
    98             pList->pLast = pBeforeDetach;
    99     }
    100     else
    101     {
    102         pList->pFirst = pLast2Detach->pNext;
    103         if (!pList->pFirst)
    104             pList->pLast = NULL;
    105     }
    106     pLast2Detach->pNext = NULL;
    107 }
    10832
    10933
     
    12549void* VBoxSHGSMICommandAlloc(struct _HGSMIHEAP * pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo);
    12650void VBoxSHGSMICommandFree(struct _HGSMIHEAP * pHeap, void *pvBuffer);
    127 int VBoxSHGSMICommandProcessCompletion(struct _HGSMIHEAP * pHeap, VBOXSHGSMIHEADER* pCmd, bool bIrq, PVBOXSHGSMILIST pPostProcessList);
    128 int VBoxSHGSMICommandPostprocessCompletion(struct _HGSMIHEAP * pHeap, PVBOXSHGSMILIST pPostProcessList);
     51int VBoxSHGSMICommandProcessCompletion(struct _HGSMIHEAP * pHeap, VBOXSHGSMIHEADER* pCmd, bool bIrq, PVBOXVTLIST pPostProcessList);
     52int VBoxSHGSMICommandPostprocessCompletion(struct _HGSMIHEAP * pHeap, PVBOXVTLIST pPostProcessList);
    12953
    13054#endif /* #ifndef ___VBoxMPShgsmi_h___ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h

    r38982 r39981  
    195195    VBOXWDDM_OBJSTATE_TYPE_TERMINATED
    196196} VBOXWDDM_OBJSTATE_TYPE;
     197
     198#define VBOXWDDM_INVALID_COORD ((LONG)((~0UL) >> 1))
     199
    197200typedef struct VBOXWDDM_SWAPCHAIN
    198201{
     
    200203    LIST_ENTRY AllocList;
    201204    struct VBOXWDDM_CONTEXT *pContext;
    202     RECT ViewRect;
    203205    VBOXWDDM_OBJSTATE_TYPE enmState;
    204206    volatile uint32_t cRefs;
    205207    VBOXDISP_UMHANDLE hSwapchainUm;
    206208    VBOXDISP_KMHANDLE hSwapchainKm;
    207     PVBOXVIDEOCM_CMD_RECTS_INTERNAL pLastReportedRects;
     209    POINT Pos;
     210    UINT width;
     211    UINT height;
     212    VBOXWDDMVR_LIST VisibleRegions;
    208213}VBOXWDDM_SWAPCHAIN, *PVBOXWDDM_SWAPCHAIN;
    209214
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp

    r39245 r39981  
    382382 * @param pDevExt
    383383 */
    384 static NTSTATUS vboxVdmaGgDirtyRectsProcess(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain, VBOXVDMAPIPE_RECTS *pContextRects)
     384static NTSTATUS vboxVdmaGgDirtyRectsProcess(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain, RECT *pSrcRect, VBOXVDMAPIPE_RECTS *pContextRects)
    385385{
    386386    PVBOXWDDM_RECTS_INFO pRects = &pContextRects->UpdateRects;
     
    388388    PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = NULL;
    389389    uint32_t cbCmdInternal = VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pRects->cRects);
     390    BOOLEAN fCurChanged = FALSE, fCurRectChanged = FALSE;
     391    POINT CurPos;
    390392    Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
     393
    391394    ExAcquireFastMutex(&pDevExt->ContextMutex);
     395
     396    if (pSwapchain)
     397    {
     398        CurPos.x = pContextRects->ContextRect.left - pSrcRect->left;
     399        CurPos.y = pContextRects->ContextRect.top - pSrcRect->top;
     400
     401        if (CurPos.x != pSwapchain->Pos.x || CurPos.y != pSwapchain->Pos.y)
     402        {
     403#if 0
     404            if (pSwapchain->Pos.x != VBOXWDDM_INVALID_COORD)
     405                VBoxWddmVrListTranslate(&pSwapchain->VisibleRegions, pSwapchain->Pos.x - CurPos.x, pSwapchain->Pos.y - CurPos.y);
     406            else
     407#endif
     408                VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
     409            fCurRectChanged = TRUE;
     410            pSwapchain->Pos = CurPos;
     411        }
     412
     413        Status = VBoxWddmVrListRectsAdd(&pSwapchain->VisibleRegions, pRects->cRects, pRects->aRects, &fCurChanged);
     414        if (!NT_SUCCESS(Status))
     415        {
     416            WARN(("VBoxWddmVrListRectsAdd failed!"));
     417            goto done;
     418        }
     419
     420
     421        /* visible rects of different windows do not intersect,
     422         * so if the given window visible rects did not increase, others have not changed either */
     423        if (!fCurChanged && !fCurRectChanged)
     424            goto done;
     425    }
     426
     427    /* before posting the add visible rects diff, we need to first hide rects for other windows */
     428
    392429    for (PLIST_ENTRY pCur = pDevExt->SwapchainList3D.Flink; pCur != &pDevExt->SwapchainList3D; pCur = pCur->Flink)
    393430    {
     
    395432        {
    396433            PVBOXWDDM_SWAPCHAIN pCurSwapchain = VBOXWDDMENTRY_2_SWAPCHAIN(pCur);
     434            BOOLEAN fChanged = FALSE;
     435
     436            Status = VBoxWddmVrListRectsSubst(&pCurSwapchain->VisibleRegions, pRects->cRects, pRects->aRects, &fChanged);
     437            if (!NT_SUCCESS(Status))
     438            {
     439                WARN(("vboxWddmVrListRectsAdd failed!"));
     440                goto done;
     441            }
     442
     443            if (!fChanged)
     444                continue;
     445
    397446            if (!pCmdInternal)
    398447            {
    399448                pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pCurSwapchain->pContext->CmContext, cbCmdInternal);
    400                 Assert(pCmdInternal);
    401449                if (!pCmdInternal)
    402450                {
     451                    WARN(("vboxVideoCmCmdCreate failed!"));
    403452                    Status = STATUS_NO_MEMORY;
    404                     break;
     453                    goto done;
    405454                }
    406455            }
     
    410459            }
    411460
    412             vboxVdmaDirtyRectsCalcIntersection(&pCurSwapchain->ViewRect, pRects, &pCmdInternal->Cmd.RectsInfo);
    413             if (pCmdInternal->Cmd.RectsInfo.cRects)
     461            pCmdInternal->Cmd.fFlags.Value = 0;
     462            pCmdInternal->Cmd.fFlags.bAddHiddenRects = 1;
     463            memcpy(&pCmdInternal->Cmd.RectsInfo, pRects, RT_OFFSETOF(VBOXWDDM_RECTS_INFO, aRects[pRects->cRects]));
     464
     465            pCmdInternal->hSwapchainUm = pCurSwapchain->hSwapchainUm;
     466
     467            vboxVideoCmCmdSubmit(pCmdInternal, VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pCmdInternal->Cmd.RectsInfo.cRects));
     468            pCmdInternal = NULL;
     469        }
     470    }
     471
     472    if (!pSwapchain)
     473        goto done;
     474
     475    RECT *pVisRects;
     476
     477    if (fCurRectChanged && fCurChanged)
     478    {
     479        cbCmdInternal = VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pRects->cRects + 1);
     480        if (pCmdInternal)
     481            vboxVideoCmCmdRelease(pCmdInternal);
     482        pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmdInternal);
     483        pCmdInternal->Cmd.fFlags.Value = 0;
     484        pCmdInternal->Cmd.fFlags.bSetViewRect = 1;
     485        pCmdInternal->Cmd.fFlags.bAddVisibleRects = 1;
     486        pCmdInternal->Cmd.RectsInfo.cRects = pRects->cRects + 1;
     487        pCmdInternal->Cmd.RectsInfo.aRects[0].left = CurPos.x;
     488        pCmdInternal->Cmd.RectsInfo.aRects[0].top = CurPos.y;
     489        pCmdInternal->Cmd.RectsInfo.aRects[0].right = CurPos.x + pSwapchain->width;
     490        pCmdInternal->Cmd.RectsInfo.aRects[0].bottom = CurPos.y + pSwapchain->height;
     491        pVisRects = &pCmdInternal->Cmd.RectsInfo.aRects[1];
     492    }
     493    else
     494    {
     495        if (!pCmdInternal)
     496        {
     497            Assert(pContext == pSwapchain->pContext);
     498            pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmdInternal);
     499            if (!pCmdInternal)
    414500            {
    415                 bool bSend = false;
    416                 pCmdInternal->Cmd.fFlags.Value = 0;
    417                 pCmdInternal->Cmd.fFlags.bAddHiddenRects = 1;
    418                 if (pCurSwapchain->pLastReportedRects)
    419                 {
    420                     if (pCurSwapchain->pLastReportedRects->Cmd.fFlags.bSetVisibleRects)
    421                     {
    422                         RECT *paPrevRects;
    423                         uint32_t cPrevRects;
    424                         if (pCurSwapchain->pLastReportedRects->Cmd.fFlags.bSetViewRect)
    425                         {
    426                             paPrevRects = &pCurSwapchain->pLastReportedRects->Cmd.RectsInfo.aRects[1];
    427                             cPrevRects = pCurSwapchain->pLastReportedRects->Cmd.RectsInfo.cRects - 1;
    428                         }
    429                         else
    430                         {
    431                             paPrevRects = &pCurSwapchain->pLastReportedRects->Cmd.RectsInfo.aRects[0];
    432                             cPrevRects = pCurSwapchain->pLastReportedRects->Cmd.RectsInfo.cRects;
    433                         }
    434 
    435                         if (vboxVdmaDirtyRectsHasIntersections(paPrevRects, cPrevRects,
    436                                 pCmdInternal->Cmd.RectsInfo.aRects, pCmdInternal->Cmd.RectsInfo.cRects))
    437                         {
    438                             bSend = true;
    439                         }
    440                     }
    441                     else
    442                     {
    443                         Assert(pCurSwapchain->pLastReportedRects->Cmd.fFlags.bAddHiddenRects);
    444                         if (!vboxVdmaDirtyRectsIsCover(pCurSwapchain->pLastReportedRects->Cmd.RectsInfo.aRects,
    445                                 pCurSwapchain->pLastReportedRects->Cmd.RectsInfo.cRects,
    446                                 pCmdInternal->Cmd.RectsInfo.aRects, pCmdInternal->Cmd.RectsInfo.cRects))
    447                         {
    448                             bSend = true;
    449                         }
    450                     }
    451                 }
    452                 else
    453                     bSend = true;
    454 
    455                 if (bSend)
    456                 {
    457                     if (pCurSwapchain->pLastReportedRects)
    458                         vboxVideoCmCmdRelease(pCurSwapchain->pLastReportedRects);
    459 
    460                     pCmdInternal->hSwapchainUm = pCurSwapchain->hSwapchainUm;
    461 
    462                     vboxVideoCmCmdRetain(pCmdInternal);
    463                     pCurSwapchain->pLastReportedRects = pCmdInternal;
    464                     vboxVideoCmCmdSubmit(pCmdInternal, VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pCmdInternal->Cmd.RectsInfo.cRects));
    465                     pCmdInternal = NULL;
    466                 }
     501                WARN(("vboxVideoCmCmdCreate failed!"));
     502                Status = STATUS_NO_MEMORY;
     503                goto done;
    467504            }
    468505        }
    469506        else
    470507        {
    471             RECT * pContextRect = &pContextRects->ContextRect;
    472             bool bRectShanged = (pSwapchain->ViewRect.left != pContextRect->left
    473                     || pSwapchain->ViewRect.top != pContextRect->top
    474                     || pSwapchain->ViewRect.right != pContextRect->right
    475                     || pSwapchain->ViewRect.bottom != pContextRect->bottom);
    476             PVBOXVIDEOCM_CMD_RECTS_INTERNAL pDrCmdInternal;
    477 
    478             bool bSend = false;
    479 
    480             if (bRectShanged)
    481             {
    482                 uint32_t cbDrCmdInternal = VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pRects->cRects + 1);
    483                 pDrCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pContext->CmContext, cbDrCmdInternal);
    484                 Assert(pDrCmdInternal);
    485                 if (!pDrCmdInternal)
    486                 {
    487                     Status = STATUS_NO_MEMORY;
    488                     break;
    489                 }
    490                 pDrCmdInternal->Cmd.fFlags.Value = 0;
    491                 pDrCmdInternal->Cmd.RectsInfo.cRects = pRects->cRects + 1;
    492                 pDrCmdInternal->Cmd.fFlags.bSetViewRect = 1;
    493                 pDrCmdInternal->Cmd.RectsInfo.aRects[0] = *pContextRect;
    494                 pSwapchain->ViewRect = *pContextRect;
    495                 memcpy(&pDrCmdInternal->Cmd.RectsInfo.aRects[1], pRects->aRects, sizeof (RECT) * pRects->cRects);
    496                 bSend = true;
    497             }
    498             else
    499             {
    500                 if (pCmdInternal)
    501                 {
    502                     pDrCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdReinitForContext(pCmdInternal, &pContext->CmContext);
    503                     pCmdInternal = NULL;
    504                 }
    505                 else
    506                 {
    507                     pDrCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmdInternal);
    508                     Assert(pDrCmdInternal);
    509                     if (!pDrCmdInternal)
    510                     {
    511                         Status = STATUS_NO_MEMORY;
    512                         break;
    513                     }
    514                 }
    515                 pDrCmdInternal->Cmd.fFlags.Value = 0;
    516                 pDrCmdInternal->Cmd.RectsInfo.cRects = pRects->cRects;
    517                 memcpy(&pDrCmdInternal->Cmd.RectsInfo.aRects[0], pRects->aRects, sizeof (RECT) * pRects->cRects);
    518 
    519                 if (pSwapchain->pLastReportedRects)
    520                 {
    521                     if (pSwapchain->pLastReportedRects->Cmd.fFlags.bSetVisibleRects)
    522                     {
    523                         RECT *paRects;
    524                         uint32_t cRects;
    525                         if (pSwapchain->pLastReportedRects->Cmd.fFlags.bSetViewRect)
    526                         {
    527                             paRects = &pSwapchain->pLastReportedRects->Cmd.RectsInfo.aRects[1];
    528                             cRects = pSwapchain->pLastReportedRects->Cmd.RectsInfo.cRects - 1;
    529                         }
    530                         else
    531                         {
    532                             paRects = &pSwapchain->pLastReportedRects->Cmd.RectsInfo.aRects[0];
    533                             cRects = pSwapchain->pLastReportedRects->Cmd.RectsInfo.cRects;
    534                         }
    535                         bSend = (pDrCmdInternal->Cmd.RectsInfo.cRects != cRects)
    536                                 || memcmp(paRects, pDrCmdInternal->Cmd.RectsInfo.aRects, cRects * sizeof (RECT));
    537                     }
    538                     else
    539                     {
    540                         Assert(pSwapchain->pLastReportedRects->Cmd.fFlags.bAddHiddenRects);
    541                         bSend = true;
    542                     }
    543                 }
    544                 else
    545                     bSend = true;
    546 
    547             }
    548 
    549             Assert(pRects->cRects);
    550             if (bSend)
    551             {
    552                 if (pSwapchain->pLastReportedRects)
    553                     vboxVideoCmCmdRelease(pSwapchain->pLastReportedRects);
    554 
    555                 pDrCmdInternal->Cmd.fFlags.bSetVisibleRects = 1;
    556                 pDrCmdInternal->hSwapchainUm = pSwapchain->hSwapchainUm;
    557 
    558                 vboxVideoCmCmdRetain(pDrCmdInternal);
    559                 pSwapchain->pLastReportedRects = pDrCmdInternal;
    560                 vboxVideoCmCmdSubmit(pDrCmdInternal, VBOXVIDEOCM_SUBMITSIZE_DEFAULT);
    561             }
    562             else
    563             {
    564                 if (!pCmdInternal)
    565                     pCmdInternal = pDrCmdInternal;
    566                 else
    567                     vboxVideoCmCmdRelease(pDrCmdInternal);
    568             }
    569         }
    570     }
     508            pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdReinitForContext(pCmdInternal, &pContext->CmContext);
     509        }
     510
     511        pCmdInternal->Cmd.fFlags.Value = 0;
     512        pCmdInternal->Cmd.fFlags.bAddVisibleRects = 1;
     513        pCmdInternal->Cmd.RectsInfo.cRects = pRects->cRects;
     514        pVisRects = &pCmdInternal->Cmd.RectsInfo.aRects[0];
     515    }
     516
     517    pCmdInternal->hSwapchainUm = pSwapchain->hSwapchainUm;
     518
     519    if (pRects->cRects)
     520        memcpy(pVisRects, pRects->aRects, sizeof (RECT) * pRects->cRects);
     521
     522    vboxVideoCmCmdSubmit(pCmdInternal, VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pCmdInternal->Cmd.RectsInfo.cRects));
     523    pCmdInternal = NULL;
     524
     525done:
    571526    ExReleaseFastMutex(&pDevExt->ContextMutex);
    572 
    573527
    574528    if (pCmdInternal)
     
    973927                                    if (pos.x || pos.y)
    974928                                    {
     929                                        /* note: do NOT trans;ate the src rect since it is used for screen pos calculation */
    975930                                        vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, pos.x, pos.y);
    976931                                    }
    977932
    978                                     Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, NULL, &pBlt->Blt.DstRects);
     933                                    Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, NULL, &pBlt->Blt.SrcRect, &pBlt->Blt.DstRects);
    979934                                    Assert(Status == STATUS_SUCCESS);
    980935                                }
     
    993948                                        if (pos.x || pos.y)
    994949                                        {
     950                                            /* note: do NOT trans;ate the src rect since it is used for screen pos calculation */
    995951                                            vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, pos.x, pos.y);
    996952                                        }
     
    1000956                                        if (pSwapchain)
    1001957                                        {
    1002                                             Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &pBlt->Blt.DstRects);
     958                                            Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &pBlt->Blt.SrcRect, &pBlt->Blt.DstRects);
    1003959                                            Assert(Status == STATUS_SUCCESS);
    1004960                                            vboxWddmSwapchainRelease(pSwapchain);
     
    1037993                {
    1038994                    POINT pos = pSource->VScreenPos;
     995                    RECT SrcRect;
    1039996                    VBOXVDMAPIPE_RECTS Rects;
     997                    SrcRect.left = 0;
     998                    SrcRect.top = 0;
     999                    SrcRect.right = pAlloc->SurfDesc.width;
     1000                    SrcRect.bottom = pAlloc->SurfDesc.height;
    10401001                    Rects.ContextRect.left = pos.x;
    10411002                    Rects.ContextRect.top = pos.y;
     
    10441005                    Rects.UpdateRects.cRects = 1;
    10451006                    Rects.UpdateRects.aRects[0] = Rects.ContextRect;
    1046                     Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &Rects);
     1007                    Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &SrcRect, &Rects);
    10471008                    Assert(Status == STATUS_SUCCESS);
    10481009                    vboxWddmSwapchainRelease(pSwapchain);
     
    11041065                            Assert(Status == STATUS_SUCCESS);
    11051066                        } break;
     1067#if 0
    11061068                        case VBOXVDMAPIPE_CMD_TYPE_RECTSINFO:
    11071069                        {
     
    11121074                            break;
    11131075                        }
     1076#endif
    11141077                        case VBOXVDMAPIPE_CMD_TYPE_FINISH:
    11151078                        {
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.cpp

    r36867 r39981  
    189189}
    190190
    191 void vboxVhwaCompletionListProcess(PVBOXMP_DEVEXT pDevExt, VBOXSHGSMILIST *pList)
    192 {
    193     PVBOXSHGSMILIST_ENTRY pNext, pCur;
     191void vboxVhwaCompletionListProcess(PVBOXMP_DEVEXT pDevExt, VBOXVTLIST *pList)
     192{
     193    PVBOXVTLIST_ENTRY pNext, pCur;
    194194    for (pCur = pList->pFirst; pCur; pCur = pNext)
    195195    {
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.h

    r36867 r39981  
    4141void vboxVhwaCommandSubmitAsynchByEvent(PVBOXMP_DEVEXT pDevExt, VBOXVHWACMD* pCmd, RTSEMEVENT hEvent);
    4242
    43 #define VBOXVHWA_CMD2LISTENTRY(_pCmd) ((PVBOXSHGSMILIST_ENTRY)&(_pCmd)->u.pNext)
     43#define VBOXVHWA_CMD2LISTENTRY(_pCmd) ((PVBOXVTLIST_ENTRY)&(_pCmd)->u.pNext)
    4444#define VBOXVHWA_LISTENTRY2CMD(_pEntry) ( (VBOXVHWACMD*)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXVHWACMD, u.pNext)) )
    4545
    46 DECLINLINE(void) vboxVhwaPutList(VBOXSHGSMILIST *pList, VBOXVHWACMD* pCmd)
     46DECLINLINE(void) vboxVhwaPutList(VBOXVTLIST *pList, VBOXVHWACMD* pCmd)
    4747{
    48     vboxSHGSMIListPut(pList, VBOXVHWA_CMD2LISTENTRY(pCmd), VBOXVHWA_CMD2LISTENTRY(pCmd));
     48    vboxVtListPut(pList, VBOXVHWA_CMD2LISTENTRY(pCmd), VBOXVHWA_CMD2LISTENTRY(pCmd));
    4949}
    5050
    51 void vboxVhwaCompletionListProcess(PVBOXMP_DEVEXT pDevExt, VBOXSHGSMILIST *pList);
     51void vboxVhwaCompletionListProcess(PVBOXMP_DEVEXT pDevExt, VBOXVTLIST *pList);
    5252#endif
    5353
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r39526 r39981  
    11441144    if (VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags) /* If HGSMI is enabled at all. */
    11451145    {
    1146         VBOXSHGSMILIST CtlList;
     1146        VBOXVTLIST CtlList;
    11471147#ifdef VBOX_WITH_VDMA
    1148         VBOXSHGSMILIST DmaCmdList;
    1149 #endif
    1150         vboxSHGSMIListInit(&CtlList);
     1148        VBOXVTLIST DmaCmdList;
     1149#endif
     1150        vboxVtListInit(&CtlList);
    11511151#ifdef VBOX_WITH_VDMA
    1152         vboxSHGSMIListInit(&DmaCmdList);
     1152        vboxVtListInit(&DmaCmdList);
    11531153#endif
    11541154
    11551155#ifdef VBOX_WITH_VIDEOHWACCEL
    1156         VBOXSHGSMILIST VhwaCmdList;
    1157         vboxSHGSMIListInit(&VhwaCmdList);
     1156        VBOXVTLIST VhwaCmdList;
     1157        vboxVtListInit(&VhwaCmdList);
    11581158#endif
    11591159
     
    11701170                {
    11711171                    VBOXWDDM_HGSMICMD_TYPE enmType = vboxWddmHgsmiGetCmdTypeFromOffset(pDevExt, offCmd);
    1172                     PVBOXSHGSMILIST pList;
     1172                    PVBOXVTLIST pList;
    11731173                    HGSMIHEAP * pHeap = NULL;
    11741174                    switch (enmType)
     
    12311231        } while (1);
    12321232
    1233         if (!vboxSHGSMIListIsEmpty(&CtlList))
    1234         {
    1235             vboxSHGSMIListCat(&pDevExt->CtlList, &CtlList);
     1233        if (!vboxVtListIsEmpty(&CtlList))
     1234        {
     1235            vboxVtListCat(&pDevExt->CtlList, &CtlList);
    12361236            bNeedDpc = TRUE;
    12371237        }
    12381238#ifdef VBOX_WITH_VDMA
    1239         if (!vboxSHGSMIListIsEmpty(&DmaCmdList))
    1240         {
    1241             vboxSHGSMIListCat(&pDevExt->DmaCmdList, &DmaCmdList);
     1239        if (!vboxVtListIsEmpty(&DmaCmdList))
     1240        {
     1241            vboxVtListCat(&pDevExt->DmaCmdList, &DmaCmdList);
    12421242            bNeedDpc = TRUE;
    12431243        }
    12441244#endif
    1245         if (!vboxSHGSMIListIsEmpty(&VhwaCmdList))
    1246         {
    1247             vboxSHGSMIListCat(&pDevExt->VhwaCmdList, &VhwaCmdList);
     1245        if (!vboxVtListIsEmpty(&VhwaCmdList))
     1246        {
     1247            vboxVtListCat(&pDevExt->VhwaCmdList, &VhwaCmdList);
    12481248            bNeedDpc = TRUE;
    12491249        }
     
    12851285typedef struct VBOXWDDM_DPCDATA
    12861286{
    1287     VBOXSHGSMILIST CtlList;
     1287    VBOXVTLIST CtlList;
    12881288#ifdef VBOX_WITH_VDMA
    1289     VBOXSHGSMILIST DmaCmdList;
     1289    VBOXVTLIST DmaCmdList;
    12901290#endif
    12911291#ifdef VBOX_WITH_VIDEOHWACCEL
    1292     VBOXSHGSMILIST VhwaCmdList;
     1292    VBOXVTLIST VhwaCmdList;
    12931293#endif
    12941294    LIST_ENTRY CompletedDdiCmdQueue;
     
    13061306    PVBOXWDDM_GETDPCDATA_CONTEXT pdc = (PVBOXWDDM_GETDPCDATA_CONTEXT)Context;
    13071307
    1308     vboxSHGSMIListDetach2List(&pdc->pDevExt->CtlList, &pdc->data.CtlList);
     1308    vboxVtListDetach2List(&pdc->pDevExt->CtlList, &pdc->data.CtlList);
    13091309#ifdef VBOX_WITH_VDMA
    1310     vboxSHGSMIListDetach2List(&pdc->pDevExt->DmaCmdList, &pdc->data.DmaCmdList);
     1310    vboxVtListDetach2List(&pdc->pDevExt->DmaCmdList, &pdc->data.DmaCmdList);
    13111311#endif
    13121312#ifdef VBOX_WITH_VIDEOHWACCEL
    1313     vboxSHGSMIListDetach2List(&pdc->pDevExt->VhwaCmdList, &pdc->data.VhwaCmdList);
     1313    vboxVtListDetach2List(&pdc->pDevExt->VhwaCmdList, &pdc->data.VhwaCmdList);
    13141314#endif
    13151315    vboxVdmaDdiCmdGetCompletedListIsr(pdc->pDevExt, &pdc->data.CompletedDdiCmdQueue);
     
    13471347        pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
    13481348
    1349     if (!vboxSHGSMIListIsEmpty(&context.data.CtlList))
     1349    if (!vboxVtListIsEmpty(&context.data.CtlList))
    13501350    {
    13511351        int rc = VBoxSHGSMICommandPostprocessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, &context.data.CtlList);
     
    13531353    }
    13541354#ifdef VBOX_WITH_VDMA
    1355     if (!vboxSHGSMIListIsEmpty(&context.data.DmaCmdList))
     1355    if (!vboxVtListIsEmpty(&context.data.DmaCmdList))
    13561356    {
    13571357        int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.Vdma.CmdHeap, &context.data.DmaCmdList);
     
    13601360#endif
    13611361#ifdef VBOX_WITH_VIDEOHWACCEL
    1362     if (!vboxSHGSMIListIsEmpty(&context.data.VhwaCmdList))
     1362    if (!vboxVtListIsEmpty(&context.data.VhwaCmdList))
    13631363    {
    13641364        vboxVhwaCompletionListProcess(pDevExt, &context.data.VhwaCmdList);
     
    15131513
    15141514    vboxVDbgBreakFv();
     1515
     1516    VBoxWddmVrTerm();
    15151517
    15161518    PRTLOGGER pLogger = RTLogRelSetDefaultInstance(NULL);
     
    57775779    LOGREL(("Built %s %s", __DATE__, __TIME__));
    57785780
     5781    NTSTATUS Status = VBoxWddmVrInit();
     5782    if (!NT_SUCCESS(Status))
     5783    {
     5784        WARN(("VBoxWddmVrInit failed!"));
     5785        return Status;
     5786    }
     5787
    57795788    DRIVER_INITIALIZATION_DATA DriverInitializationData = {'\0'};
    57805789
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h

    r38739 r39981  
    2727#include "common/VBoxMPUtils.h"
    2828#include "common/VBoxMPDevExt.h"
     29#include "../../common/VBoxVideoTools.h"
    2930
    3031//#define VBOXWDDM_DEBUG_VIDPN
  • trunk/src/VBox/Additions/common/crOpenGL/load.c

    r39631 r39981  
    855855    }
    856856
    857     if (pRegions->pRegions->fFlags.bSetVisibleRects || pRegions->pRegions->fFlags.bSetViewRect)
     857    if (pRegions->pRegions->fFlags.bAddVisibleRects || pRegions->pRegions->fFlags.bSetViewRect)
    858858    {
    859859        /* ensure data integrity */
     
    897897        }
    898898
    899         if (pRegions->pRegions->fFlags.bSetVisibleRects)
     899        if (pRegions->pRegions->fFlags.bAddVisibleRects)
    900900        {
    901901            hNewRgn = stubMakeRegionFromRects(pRegions->pRegions, pRegions->pRegions->fFlags.bSetViewRect ? 1 : 0);
     
    915915    if (hNewRgn!=INVALID_HANDLE_VALUE)
    916916    {
    917         if (pRegions->pRegions->fFlags.bSetVisibleRects)
     917        if (pRegions->pRegions->fFlags.bAddVisibleRects)
    918918        {
    919919            HRGN hEmptyRgn = CreateRectRgn(0, 0, 0, 0);
     
    955955        else
    956956        {
    957             if (pRegions->pRegions->fFlags.bSetVisibleRects)
     957            if (pRegions->pRegions->fFlags.bAddVisibleRects)
    958958            {
    959959                pWindow->hVisibleRegion = hNewRgn;
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