VirtualBox

Ignore:
Timestamp:
Mar 10, 2009 10:14:15 AM (16 years ago)
Author:
vboxsync
Message:

HGSMI for the graphics device: the windows guest display driver prototype code.

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Display
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/Makefile.kmk

    r12446 r17610  
    5656        $(VBOX_LIB_IPRT_GUEST_R0)
    5757
     58ifdef VBOX_WITH_HGSMI
     59VBoxDisp_LIBS         += \
     60        $(VBOX_PATH_ADDITIONS_LIB)/HGSMIGuestR0Lib$(VBOX_SUFF_LIB)
     61endif
     62
    5863include $(KBUILD_PATH)/subfooter.kmk
    5964
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/dd.c

    r16615 r17610  
    798798        DISPDBG((0, "%d,%d %dx%d\n", pDev->ddLock.rArea.left, pDev->ddLock.rArea.top, pDev->ddLock.rArea.right - pDev->ddLock.rArea.left, pDev->ddLock.rArea.bottom - pDev->ddLock.rArea.top));
    799799       
     800#ifndef VBOX_WITH_HGSMI
    800801        if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
    801802        {
     
    819820            vboxHwBufferEndUpdate (pDev);
    820821        }
     822#else
     823        if (pDev->bHGSMISupported && vboxHwBufferBeginUpdate (pDev))
     824        {
     825            vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
     826
     827            if (  pDev->pVBVA->u32HostEvents
     828                & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
     829            {
     830                vrdpReset (pDev);
     831
     832                pDev->pVBVA->u32HostEvents &=
     833                          ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
     834            }
     835
     836            if (pDev->pVBVA->u32HostEvents
     837                & VBVA_F_MODE_VRDP)
     838            {
     839                vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
     840            }
     841
     842            vboxHwBufferEndUpdate (pDev);
     843        }
     844#endif /* VBOX_WITH_HGSMI */
     845
    821846        pDev->ddLock.bLocked = FALSE;
    822847    }
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h

    r16615 r17610  
    129129    FLONG   flHooks;
    130130   
     131#ifndef VBOX_WITH_HGSMI
    131132    VBVAENABLERESULT vbva;
    132133    uint32_t         u32VRDPResetFlag;
     134#endif /* !VBOX_WITH_HGSMI */
    133135    BOOL             fHwBufferOverflow;
    134136    VBVARECORD       *pRecord;
     
    138140    SSB aSSB[4];                // LIFO type stack for saved screen areas.
    139141
     142#ifndef VBOX_WITH_HGSMI
    140143    VBOXDISPLAYINFO *pInfo;
    141144    BOOLEAN bVBoxVideoSupported;
     145#endif /* !VBOX_WITH_HGSMI */
    142146    ULONG iDevice;
    143147    VRAMLAYOUT layout;
     
    155159    } ddLock;
    156160#endif /* VBOX_WITH_DDRAW */
     161
     162#ifdef VBOX_WITH_HGSMI
     163    BOOLEAN bHGSMISupported;
     164    HGSMIHEAP hgsmiDisplayHeap;
     165    VBVABUFFER *pVBVA; /* Pointer to the pjScreen + layout->offVBVABuffer. NULL if VBVA is not enabled. */
     166#endif /* VBOX_WITH_HGSMI */
    157167};
    158168
     
    166176#endif
    167177
     178#ifndef VBOX_WITH_HGSMI
    168179/* The global semaphore handle for all driver instances. */
    169180extern HSEMAPHORE ghsemHwBuffer;
     181#endif /* !VBOX_WITH_HGSMI */
    170182
    171183extern BOOL  g_bOnNT40;
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/drv.c

    r13836 r17610  
    105105}
    106106
     107#ifndef VBOX_WITH_HGSMI
    107108#define VBVA_OPERATION(__psoDest, __fn, __a) do {                     \
    108109    if (bIsScreenSurface(__psoDest))                                  \
     
    133134    }                                                                 \
    134135} while (0)
     136#else
     137#define VBVA_OPERATION(__psoDest, __fn, __a) do {                      \
     138    if (bIsScreenSurface(__psoDest))                                   \
     139    {                                                                  \
     140        PPDEV ppdev = (PPDEV)__psoDest->dhpdev;                        \
     141                                                                       \
     142        if (ppdev->bHGSMISupported && vboxHwBufferBeginUpdate (ppdev)) \
     143        {                                                              \
     144            vbva##__fn __a;                                            \
     145                                                                       \
     146            if (  ppdev->pVBVA->u32HostEvents                           \
     147                & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)            \
     148            {                                                          \
     149                vrdpReset (ppdev);                                     \
     150                                                                       \
     151                ppdev->pVBVA->u32HostEvents &=                          \
     152                          ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;   \
     153            }                                                          \
     154                                                                       \
     155            if (ppdev->pVBVA->u32HostEvents                             \
     156                & VBVA_F_MODE_VRDP)                                    \
     157            {                                                          \
     158                vrdp##__fn __a;                                        \
     159            }                                                          \
     160                                                                       \
     161            vboxHwBufferEndUpdate (ppdev);                             \
     162        }                                                              \
     163    }                                                                  \
     164} while (0)
     165#endif /* VBOX_WITH_HGSMI */
    135166
    136167//#undef VBVA_OPERATION
     
    324355        PPDEV ppdev = (PPDEV)psoDest->dhpdev;
    325356
     357#ifndef VBOX_WITH_HGSMI
    326358        VBVAMEMORY *pVbvaMemory = ppdev->vbva.pVbvaMemory;
    327359
     
    330362        if (   pVbvaMemory
    331363            && (pVbvaMemory->fu32ModeFlags & VBVA_F_MODE_ENABLED))
     364#else
     365        DISPDBG((1, "offscreen->screen\n"));
     366
     367        if (   ppdev->pVBVA
     368            && (ppdev->pVBVA->u32HostEvents & VBVA_F_MODE_ENABLED))
     369#endif /* VBOX_WITH_HGSMI */
    332370        {
    333371            if (   (psoSrc->fjBitmap & BMF_DONTCACHE) != 0
     
    706744        PPDEV ppdev = (PPDEV)psoTarget->dhpdev;
    707745
     746#ifndef VBOX_WITH_HGSMI
    708747        if (   ppdev->vbva.pVbvaMemory
    709748            && (ppdev->vbva.pVbvaMemory->fu32ModeFlags & VBVA_F_MODE_ENABLED))
     
    724763            }
    725764        }
     765#else
     766        if (   ppdev->pVBVA
     767            && (ppdev->pVBVA->u32HostEvents & VBVA_F_MODE_ENABLED))
     768        {
     769            if (ppdev->pVBVA->u32HostEvents
     770                & VBVA_F_MODE_VRDP_RESET)
     771            {
     772                vrdpReset (ppdev);
     773
     774                ppdev->pVBVA->u32HostEvents &=
     775                    ~VBVA_F_MODE_VRDP_RESET;
     776            }
     777
     778            if (ppdev->pVBVA->u32HostEvents
     779                & VBVA_F_MODE_VRDP)
     780            {
     781                bRc = vrdpRealizeBrush (pbo, psoTarget, psoPattern, psoMask, pxlo, iHatch);
     782            }
     783        }
     784#endif /* VBOX_WITH_HGSMI */
    726785    }
    727786
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c

    r16615 r17610  
    130130        ULONG ret = 0;
    131131
     132#ifndef VBOX_WITH_HGSMI
    132133        if (ppdev && ppdev->pInfo && vboxHwBufferBeginUpdate (ppdev))
    133134        {
     
    142143        else
    143144            DISPDBG((0, "VBOXESC_ISVRDPACTIVE -> 0\n"));
     145#else
     146        if (ppdev && ppdev->pVBVA)
     147        {
     148            if (ppdev->pVBVA->u32HostEvents & VBVA_F_MODE_VRDP)
     149            {
     150                ret = 1;
     151            }
     152            DISPDBG((0, "VBOXESC_ISVRDPACTIVE -> %d (%x)\n", ret, ppdev->pVBVA->u32HostEvents));
     153        }
     154        else
     155            DISPDBG((0, "VBOXESC_ISVRDPACTIVE -> 0\n"));
     156#endif  /* VBOX_WITH_HGSMI */
    144157        return ret;
    145158    }
     
    274287    {   INDEX_DrvStrokePath,            (PFN) DrvStrokePath         },  // 14 0xe
    275288    {   INDEX_DrvFillPath,              (PFN) DrvFillPath           },  // 15 0xf
     289//    {   INDEX_DrvStrokeAndFillPath,     (PFN) DrvStrokeAndFillPath  },        // 16 0x10
    276290    {   INDEX_DrvPaint,                 (PFN) DrvPaint              },  // 17 0x11
    277291    {   INDEX_DrvBitBlt,                (PFN) DrvBitBlt             },  // 18 0x12
     
    316330#define HOOKS_BMF32BPP gflHooks
    317331
     332#ifndef VBOX_WITH_HGSMI
    318333HSEMAPHORE ghsemHwBuffer = 0;
     334#endif /* !VBOX_WITH_HGSMI */
    319335
    320336/******************************Public*Routine******************************\
     
    336352    // Set up hook flags to intercept all functions which can generate VRDP orders
    337353    gflHooks = HOOK_BITBLT | HOOK_TEXTOUT | HOOK_FILLPATH |
    338                HOOK_COPYBITS | HOOK_STROKEPATH | HOOK_LINETO |
     354               HOOK_COPYBITS | HOOK_STROKEPATH | HOOK_LINETO | /* HOOK_STROKEANDFILLPATH | */
    339355#ifdef VBOX_NEW_SURFACE_CODE
    340356               HOOK_PAINT | HOOK_STRETCHBLT | HOOK_SYNCHRONIZE;
     
    367383            DDI_DRIVER_VERSION_NT4;
    368384
     385#ifndef VBOX_WITH_HGSMI
    369386    if (!ghsemHwBuffer)
    370387    {
    371388        ghsemHwBuffer = EngCreateSemaphore ();
    372389    }
     390#endif /* !VBOX_WITH_HGSMI */
    373391
    374392    return(TRUE);
     
    387405    DISPDBG((0, "VBoxDisp::DrvDisableDriver called.\n"));
    388406
     407#ifndef VBOX_WITH_HGSMI
    389408    if (ghsemHwBuffer)
    390409    {
     
    392411        ghsemHwBuffer = NULL;
    393412    }
     413#endif /* !VBOX_WITH_HGSMI */
    394414
    395415    return;
     
    11281148        case DN_DEVICE_ORIGIN:
    11291149            ppdev->ptlDevOrg = *(PPOINTL)pvData;
     1150#ifndef VBOX_WITH_HGSMI
    11301151            DISPDBG((3, "DN_DEVICE_ORIGIN: %d, %d (PSO = %p, pInfo = %p)\n", ppdev->ptlDevOrg.x,
    11311152                     ppdev->ptlDevOrg.y, pso, ppdev->pInfo));
     
    11361157                VBoxProcessDisplayInfo(ppdev);
    11371158            }
     1159#else
     1160            DISPDBG((3, "DN_DEVICE_ORIGIN: %d, %d (PSO = %p)\n", ppdev->ptlDevOrg.x,
     1161                     ppdev->ptlDevOrg.y, pso));
     1162            if (ppdev->bHGSMISupported)
     1163            {
     1164                VBoxProcessDisplayInfo(ppdev);
     1165            }
     1166#endif /* VBOX_WITH_HGSMI */
    11381167            break;
    11391168        case DN_DRAWING_BEGIN:
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c

    r16710 r17610  
    3030
    3131#include "driver.h"
     32
     33#ifdef VBOX_WITH_HGSMI
     34#include <iprt/asm.h>
     35#include <VBox/HGSMI/HGSMI.h>
     36#include <VBox/HGSMI/HGSMIChSetup.h>
     37
     38#define VBE_DISPI_IOPORT_INDEX          0x01CE
     39#define VBE_DISPI_IOPORT_DATA           0x01CF
     40#define VBE_DISPI_INDEX_VBVA_GUEST      0xc
     41#endif
    3242
    3343#define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | FF_DONTCARE,L"System"}
     
    6171    DWORD returnedDataLength;
    6272
     73    ULONG iDevice;
     74    uint32_t u32DisplayInfoSize;
     75
     76#ifndef VBOX_WITH_HGSMI
    6377    QUERYDISPLAYINFORESULT DispInfo;
    6478    RtlZeroMemory(&DispInfo, sizeof (DispInfo));
     
    7185                                                     sizeof(DispInfo),
    7286                                                     &returnedDataLength);
    73 
    7487    if (ppdev->bVBoxVideoSupported)
    7588    {
    76         ppdev->iDevice = DispInfo.iDevice;
     89        iDevice = DispInfo.iDevice;
     90        u32DisplayInfoSize = DispInfo.u32DisplayInfoSize;
     91    }
     92#else
     93    QUERYHGSMIRESULT info;
     94    RtlZeroMemory(&info, sizeof (info));
     95
     96    ppdev->bHGSMISupported = !EngDeviceIoControl(ppdev->hDriver,
     97                                                 IOCTL_VIDEO_QUERY_HGSMI_INFO,
     98                                                 NULL,
     99                                                 0,
     100                                                 &info,
     101                                                 sizeof(info),
     102                                                 &returnedDataLength);
     103    if (ppdev->bHGSMISupported)
     104    {
     105        iDevice = info.iDevice;
     106        u32DisplayInfoSize = 4096; /* In HGSMI mode the display driver decides about the size. */
     107    }
     108#endif /* VBOX_WITH_HGSMI */
     109
     110#ifndef VBOX_WITH_HGSMI
     111    if (ppdev->bVBoxVideoSupported)
     112    {
     113#else
     114    if (ppdev->bHGSMISupported)
     115    {
     116#endif /* VBOX_WITH_HGSMI */
     117        ppdev->iDevice = iDevice;
    77118   
    78119        ppdev->layout.cbVRAM = pMemoryInformation->VideoRamLength;
     
    83124        cbAvailable = ppdev->layout.cbVRAM - ppdev->layout.cbFrameBuffer;
    84125       
    85         if (cbAvailable <= DispInfo.u32DisplayInfoSize)
    86         {
     126        if (cbAvailable <= u32DisplayInfoSize)
     127        {
     128#ifndef VBOX_WITH_HGSMI
    87129            ppdev->bVBoxVideoSupported = FALSE;
     130#else
     131            ppdev->bHGSMISupported = FALSE;
     132#endif /* VBOX_WITH_HGSMI */
    88133        }
    89134        else
    90135        {
    91             ppdev->layout.offDisplayInformation = ppdev->layout.cbVRAM - DispInfo.u32DisplayInfoSize;
    92             ppdev->layout.cbDisplayInformation  = DispInfo.u32DisplayInfoSize;
     136            ppdev->layout.offDisplayInformation = ppdev->layout.cbVRAM - u32DisplayInfoSize;
     137            ppdev->layout.cbDisplayInformation  = u32DisplayInfoSize;
    93138           
    94139            cbAvailable -= ppdev->layout.cbDisplayInformation;
     
    107152            if (ppdev->layout.cbVBVABuffer >= cbAvailable)
    108153            {
     154#ifndef VBOX_WITH_HGSMI
    109155                ppdev->bVBoxVideoSupported = FALSE;
     156#else
     157                ppdev->bHGSMISupported = FALSE;
     158#endif /* VBOX_WITH_HGSMI */
    110159            }
    111160            else
     
    122171    }
    123172   
     173#ifndef VBOX_WITH_HGSMI
    124174    if (!ppdev->bVBoxVideoSupported)
     175#else
     176    if (!ppdev->bHGSMISupported)
     177#endif /* VBOX_WITH_HGSMI */
    125178    {
    126179        ppdev->iDevice = 0;
     
    141194        ppdev->layout.cbDisplayInformation  = 0;
    142195    }
     196#ifdef VBOX_WITH_HGSMI
     197    else
     198    {
     199        /* Setup HGSMI heap in the display information area. The area has some space reserved for
     200         * HGSMI event flags in the beginning.
     201         */
     202        int rc = HGSMIHeapSetup (&ppdev->hgsmiDisplayHeap,
     203                                 (uint8_t *)ppdev->pjScreen + ppdev->layout.offDisplayInformation + sizeof (HGSMIHOSTFLAGS),
     204                                 ppdev->layout.cbDisplayInformation - sizeof (HGSMIHOSTFLAGS),
     205                                 ppdev->layout.offDisplayInformation + sizeof (HGSMIHOSTFLAGS));
     206
     207        if (RT_FAILURE (rc))
     208        {
     209            DISPDBG((0, "VBoxDISP::vboxInitVBoxVideo: HGSMIHeapSetup failed rc = %d\n",
     210                     rc));
     211
     212            ppdev->bHGSMISupported = FALSE;
     213        }
     214        else
     215        {
     216            /* Inform the host about the HGSMIHOSTEVENTS location. */
     217            void *p = HGSMIHeapAlloc (&ppdev->hgsmiDisplayHeap,
     218                                      sizeof (HGSMI_BUFFER_LOCATION),
     219                                      HGSMI_CH_HGSMI,
     220                                      HGSMI_CC_HOST_FLAGS_LOCATION);
     221
     222            if (!p)
     223            {
     224                DISPDBG((0, "VBoxDISP::vboxInitVBoxVideo: HGSMIHeapAlloc failed\n"));
     225                rc = VERR_NO_MEMORY;
     226            }
     227            else
     228            {
     229                HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&ppdev->hgsmiDisplayHeap,
     230                                                               p);
     231
     232                ((HGSMI_BUFFER_LOCATION *)p)->offLocation = ppdev->layout.offDisplayInformation;
     233                ((HGSMI_BUFFER_LOCATION *)p)->cbLocation = sizeof (HGSMIHOSTFLAGS);
     234
     235                /* Submit the buffer to the host. */
     236                ASMOutU16 (VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBVA_GUEST);
     237                ASMOutU32 (VBE_DISPI_IOPORT_DATA, offBuffer);
     238
     239                HGSMIHeapFree (&ppdev->hgsmiDisplayHeap, p);
     240            }
     241        }
     242    }
     243#endif /* VBOX_WITH_HGSMI */
    143244
    144245    DISPDBG((0, "vboxInitVBoxVideo:\n"
     
    164265}
    165266
     267
     268#ifndef VBOX_WITH_HGSMI
    166269/* Setup display information after remapping. */
    167270static void vboxSetupDisplayInfo (PPDEV ppdev, VIDEO_MEMORY_INFORMATION *pMemoryInformation)
     
    219322    }
    220323}
     324#else
     325static void vboxUpdateDisplayInfo (PPDEV ppdev)
     326{
     327    if (ppdev->bHGSMISupported)
     328    {
     329        /* Inform the host about this display layout. */
     330        DISPDBG((1, "Update: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     331        VBoxProcessDisplayInfo(ppdev);
     332    }
     333}
     334#endif /* VBOX_WITH_HGSMI */
    221335
    222336
     
    346460        vboxInitVBoxVideo (ppdev, &videoMemoryInformation);
    347461
     462#ifndef VBOX_WITH_HGSMI
    348463        if (ppdev->bVBoxVideoSupported)
    349464        {
     
    351466            vboxSetupDisplayInfo (ppdev, &videoMemoryInformation);
    352467        }
     468#endif /* !VBOX_WITH_HGSMI */
    353469    }
    354470
     
    360476        || ppdev->ulBitCount == 32)
    361477    {
     478#ifndef VBOX_WITH_HGSMI
    362479        if (ppdev->pInfo) /* Do not use VBVA on old hosts. */
    363480        {
     
    365482            vboxVbvaEnable (ppdev);
    366483        }
     484#else
     485        if (ppdev->bHGSMISupported)
     486        {
     487            /* Enable VBVA for this video mode. */
     488            vboxVbvaEnable (ppdev);
     489        }
     490#endif /* VBOX_WITH_HGSMI */
    367491    }
    368492
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c

    r8155 r17610  
    4343static BOOL vboxHwBufferWrite (PPDEV ppdev, const void *p, uint32_t cb);
    4444
     45#ifndef VBOX_WITH_HGSMI
    4546/*
    4647 * Public hardware buffer methods.
     
    336337                       &returnedDataLength);
    337338}
     339
     340#else /* VBOX_WITH_HGSMI */
     341
     342/*
     343 * Public hardware buffer methods.
     344 */
     345BOOL vboxVbvaEnable (PPDEV ppdev)
     346{
     347    BOOL bRc = FALSE;
     348
     349    DISPDBG((1, "VBoxDisp::vboxVbvaEnable called\n"));
     350   
     351    if (ppdev->bHGSMISupported)
     352    {
     353        VBVABUFFER *pVBVA = (VBVABUFFER *)((uint8_t *)ppdev->pjScreen + ppdev->layout.offVBVABuffer);
     354       
     355        pVBVA->u32HostEvents = 0;
     356        pVBVA->u32SupportedOrders = 0;
     357        pVBVA->off32Data;
     358        pVBVA->off32Free;
     359        RtlZeroMemory (pVBVA->aRecords, sizeof (pVBVA->aRecords));
     360        pVBVA->indexRecordFirst;
     361        pVBVA->indexRecordFree;
     362        pVBVA->cbPartialWriteThreshold;
     363        pVBVA->cbData      = ppdev->layout.cbVBVABuffer - sizeof (VBVABUFFER) + sizeof (pVBVA->au8Data);
     364
     365        ppdev->fHwBufferOverflow = FALSE;
     366        ppdev->pRecord           = NULL;
     367        ppdev->pVBVA             = pVBVA;
     368       
     369#if 0
     370        /* @todo inform host that VBVA mode has been entered. */
     371        bRC = vboxVBVAInformHost (ppdev);
     372#else
     373        /* All have been initialized. */
     374        bRc = TRUE;
     375#endif
     376    }
     377
     378    if (!bRc)
     379    {
     380        vboxVbvaDisable (ppdev);
     381    }
     382
     383    return bRc;
     384}
     385
     386void vboxVbvaDisable (PPDEV ppdev)
     387{
     388    DISPDBG((1, "VBoxDisp::vbvaDisable called.\n"));
     389
     390    ppdev->fHwBufferOverflow = FALSE;
     391    ppdev->pRecord           = NULL;
     392    ppdev->pVBVA             = NULL;
     393
     394    return;
     395}
     396
     397BOOL vboxHwBufferBeginUpdate (PPDEV ppdev)
     398{
     399    BOOL bRc = FALSE;
     400
     401    DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate called flags = 0x%08X\n",
     402             ppdev->pVBVA? ppdev->pVBVA->u32HostEvents: -1));
     403
     404    if (   ppdev->pVBVA
     405        && (ppdev->pVBVA->u32HostEvents & VBVA_F_MODE_ENABLED))
     406    {
     407        uint32_t indexRecordNext;
     408
     409        VBVA_ASSERT (!ppdev->fHwBufferOverflow);
     410        VBVA_ASSERT (ppdev->pRecord == NULL);
     411
     412        indexRecordNext = (ppdev->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS;
     413
     414        if (indexRecordNext == ppdev->pVBVA->indexRecordFirst)
     415        {
     416            /* All slots in the records queue are used. */
     417            vboxHwBufferFlush (ppdev);
     418        }
     419
     420        if (indexRecordNext == ppdev->pVBVA->indexRecordFirst)
     421        {
     422            /* Even after flush there is no place. Fail the request. */
     423            DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate no space in the queue of records!!! first %d, last %d\n",
     424                     ppdev->pVBVA->indexRecordFirst, ppdev->pVBVA->indexRecordFree));
     425        }
     426        else
     427        {
     428            /* Initialize the record. */
     429            VBVARECORD *pRecord = &ppdev->pVBVA->aRecords[ppdev->pVBVA->indexRecordFree];
     430
     431            pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;
     432
     433            ppdev->pVBVA->indexRecordFree = indexRecordNext;
     434
     435            DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate indexRecordNext = %d\n", indexRecordNext));
     436
     437            /* Remember which record we are using. */
     438            ppdev->pRecord = pRecord;
     439
     440            bRc = TRUE;
     441        }
     442    }
     443
     444    return bRc;
     445}
     446
     447void vboxHwBufferEndUpdate (PPDEV ppdev)
     448{
     449    VBVARECORD *pRecord;
     450
     451    DISPDBG((1, "VBoxDisp::vboxHwBufferEndUpdate called\n"));
     452
     453    VBVA_ASSERT(ppdev->pVBVA);
     454
     455    pRecord = ppdev->pRecord;
     456    VBVA_ASSERT (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
     457
     458    /* Mark the record completed. */
     459    pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;
     460
     461    ppdev->fHwBufferOverflow = FALSE;
     462    ppdev->pRecord = NULL;
     463
     464    return;
     465}
     466
     467/*
     468 * Private operations.
     469 */
     470static uint32_t vboxHwBufferAvail (const VBVABUFFER *pVBVA)
     471{
     472    int32_t i32Diff = pVBVA->off32Data - pVBVA->off32Free;
     473
     474    return i32Diff > 0? i32Diff: pVBVA->cbData + i32Diff;
     475}
     476
     477static void vboxHwBufferFlush (PPDEV ppdev)
     478{
     479    VBVA_ASSERT (ppdev->pVBVA);
     480
     481#if 0
     482    /* @todo issue the flush command */
     483    void *p = HGSMIHeapAlloc (&ppdev->hgsmiDisplayHeap,
     484                              sizeof (VBVA_FLUSH),
     485                              HGSMI_CH_VBVA,
     486                              HGSMI_CC_VBVA_FLUSH);
     487........
     488    if (!p)
     489    {
     490        DISPDBG((0, "VBoxDISP::vboxInitVBoxVideo: HGSMIHeapAlloc failed\n"));
     491        rc = VERR_NO_MEMORY;
     492    }
     493    else
     494    {
     495        HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&ppdev->hgsmiDisplayHeap,
     496                                                       p);
     497
     498        ((HGSMI_BUFFER_LOCATION *)p)->offLocation = ppdev->layout.offDisplayInformation;
     499        ((HGSMI_BUFFER_LOCATION *)p)->cbLocation = sizeof (HGSMIHOSTFLAGS);
     500
     501        /* Submit the buffer to the host. */
     502        ASMOutU16 (VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBVA_GUEST);
     503        ASMOutU32 (VBE_DISPI_IOPORT_DATA, offBuffer);
     504
     505        HGSMIHeapFree (&ppdev->hgsmiDisplayHeap, p);
     506    }
     507#endif
     508
     509    return;
     510}
     511
     512static void vboxHwBufferPlaceDataAt (PPDEV ppdev, const void *p, uint32_t cb, uint32_t offset)
     513{
     514    VBVABUFFER *pVBVA = ppdev->pVBVA;
     515    uint32_t u32BytesTillBoundary = pVBVA->cbData - offset;
     516    uint8_t  *dst                 = &pVBVA->au8Data[offset];
     517    int32_t i32Diff               = cb - u32BytesTillBoundary;
     518
     519    if (i32Diff <= 0)
     520    {
     521        /* Chunk will not cross buffer boundary. */
     522        memcpy (dst, p, cb);
     523    }
     524    else
     525    {
     526        /* Chunk crosses buffer boundary. */
     527        memcpy (dst, p, u32BytesTillBoundary);
     528        memcpy (&pVBVA->au8Data[0], (uint8_t *)p + u32BytesTillBoundary, i32Diff);
     529    }
     530
     531    return;
     532}
     533
     534static BOOL vboxHwBufferWrite (PPDEV ppdev, const void *p, uint32_t cb)
     535{
     536    VBVARECORD *pRecord;
     537    uint32_t cbHwBufferAvail;
     538
     539    uint32_t cbWritten = 0;
     540
     541    VBVABUFFER *pVBVA = ppdev->pVBVA;
     542    VBVA_ASSERT(pVBVA);
     543
     544    if (!pVBVA || ppdev->fHwBufferOverflow)
     545    {
     546        return FALSE;
     547    }
     548
     549    VBVA_ASSERT (pVBVA->indexRecordFirst != pVBVA->indexRecordFree);
     550
     551    pRecord = ppdev->pRecord;
     552    VBVA_ASSERT (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
     553
     554    DISPDBG((1, "VW %d\n", cb));
     555
     556    cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
     557
     558    while (cb > 0)
     559    {
     560        uint32_t cbChunk = cb;
     561
     562        DISPDBG((1, "VBoxDisp::vboxHwBufferWrite pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n",
     563                    pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten));
     564
     565        if (cbChunk >= cbHwBufferAvail)
     566        {
     567            DISPDBG((1, "VBoxDisp::vboxHwBufferWrite 1) avail %d, chunk %d\n", cbHwBufferAvail, cbChunk));
     568
     569            vboxHwBufferFlush (ppdev);
     570
     571            cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
     572
     573            if (cbChunk >= cbHwBufferAvail)
     574            {
     575                DISPDBG((1, "VBoxDisp::vboxHwBufferWrite: no place for %d bytes. Only %d bytes available after flush. Going to partial writes.\n",
     576                            cb, cbHwBufferAvail));
     577
     578                if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold)
     579                {
     580                    DISPDBG((1, "VBoxDisp::vboxHwBufferWrite: Buffer overflow!!!\n"));
     581                    ppdev->fHwBufferOverflow = TRUE;
     582                    VBVA_ASSERT(FALSE);
     583                    return FALSE;
     584                }
     585
     586                cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold;
     587            }
     588        }
     589
     590        VBVA_ASSERT(cbChunk <= cb);
     591        VBVA_ASSERT(cbChunk <= vboxHwBufferAvail (pVBVA));
     592
     593        vboxHwBufferPlaceDataAt (ppdev, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free);
     594
     595        pVBVA->off32Free   = (pVBVA->off32Free + cbChunk) % pVBVA->cbData;
     596        pRecord->cbRecord += cbChunk;
     597        cbHwBufferAvail -= cbChunk;
     598
     599        cb        -= cbChunk;
     600        cbWritten += cbChunk;
     601    }
     602
     603    return TRUE;
     604}
     605
     606/*
     607 * Public writer to the hardware buffer.
     608 */
     609BOOL vboxWrite (PPDEV ppdev, const void *pv, uint32_t cb)
     610{
     611    return vboxHwBufferWrite (ppdev, pv, cb);
     612}
     613
     614BOOL vboxOrderSupported (PPDEV ppdev, unsigned code)
     615{
     616    VBVABUFFER *pVBVA = ppdev->pVBVA;
     617
     618    if (!pVBVA)
     619    {
     620        return FALSE;
     621    }
     622
     623    if (pVBVA->u32SupportedOrders & (1 << code))
     624    {
     625        return TRUE;
     626    }
     627
     628    return FALSE;
     629}
     630
     631void VBoxProcessDisplayInfo(PPDEV ppdev)
     632{
     633#if 0
     634    DWORD returnedDataLength;
     635
     636    DISPDBG((1, "Process: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     637
     638    EngDeviceIoControl(ppdev->hDriver,
     639                       IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY,
     640                       NULL,
     641                       0,
     642                       NULL,
     643                       0,
     644                       &returnedDataLength);
     645#endif
     646}
     647#endif /* VBOX_WITH_HGSMI */
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