VirtualBox

Changeset 49420 in vbox for trunk/src


Ignore:
Timestamp:
Nov 8, 2013 3:54:02 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
90501
Message:

forward-port and adopt VHWA fixes

Location:
trunk/src/VBox
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp

    r37423 r49420  
    6767                if(pBody->u.out.ErrInfo)
    6868                {
     69                    WARN(("pBody->u.out.ErrInfo = %#x", pBody->u.out.ErrInfo));
    6970                    lpCanCreateSurface->ddRVal = DDERR_GENERIC;
    7071                }
    7172                else
    7273                {
    73                     WARN(("pBody->u.out.ErrInfo = %#x", pBody->u.out.ErrInfo));
    7474                    lpCanCreateSurface->ddRVal = DD_OK;
    7575                }
     
    275275                pBody->u.in.hSurf = pDesc->hHostHandle;
    276276
    277                 /* we're not interested in completion, just send the command */
    278                 VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
     277                VBoxDispVHWACommandSubmit(pDev, pCmd);
     278
     279                VBoxDispVHWACommandRelease(pDev, pCmd);
    279280
    280281                VBoxDispVHWASurfDescFree(pDesc);
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r48468 r49420  
    49654965    if (pThis->cMilliesRefreshInterval)
    49664966        TMTimerSetMillies(pTimer, pThis->cMilliesRefreshInterval);
     4967
     4968#ifdef VBOX_WITH_VIDEOHWACCEL
     4969    vbvaTimerCb(pThis);
     4970#endif
     4971
    49674972}
    49684973
  • trunk/src/VBox/Devices/Graphics/DevVGA.h

    r45808 r49420  
    6464#endif /* VBOX_WITH_HGSMI */
    6565#include "DevVGASavedState.h"
     66
     67# include <iprt/list.h>
    6668
    6769#define MSR_COLOR_EMULATION 0x01
     
    196198#endif
    197199
     200#ifdef VBOX_WITH_VIDEOHWACCEL
     201#define VBOX_VHWA_MAX_PENDING_COMMANDS 1000
     202
     203typedef struct _VBOX_VHWA_PENDINGCMD
     204{
     205    RTLISTNODE Node;
     206    PVBOXVHWACMD pCommand;
     207} VBOX_VHWA_PENDINGCMD;
     208#endif
     209
    198210typedef struct VGAState {
    199211#ifndef VBOX
     
    420432#  endif
    421433# endif /* VBOX_WITH_HGSMI */
     434
     435    struct {
     436        uint32_t cPending;
     437        uint32_t Padding1;
     438        union
     439        {
     440            RTLISTNODE PendingList;
     441            /* make sure the structure sized cross different contexts correctly */
     442            struct
     443            {
     444                R3PTRTYPE(void *) dummy1;
     445                R3PTRTYPE(void *) dummy2;
     446            } dummy;
     447        };
     448    } pendingVhwaCommands;
    422449#endif /* VBOX */
    423450} VGAState;
     
    496523int vbvaVHWAReset (PVGASTATE pVGAState);
    497524
     525void vbvaTimerCb(PVGASTATE pVGAState);
     526
    498527int vboxVBVASaveStatePrep (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
    499528int vboxVBVASaveStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r49366 r49420  
    767767static VBOXVHWACMD* vbvaVHWAHHCommandCreate (PVGASTATE pVGAState, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay, VBOXVHWACMD_LENGTH cbCmd)
    768768{
    769     VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAlloc(cbCmd + VBOXVHWACMD_HEADSIZE());
     769    VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAllocZ(cbCmd + VBOXVHWACMD_HEADSIZE());
    770770    Assert(pHdr);
    771771    if (pHdr)
     
    789789}
    790790
    791 static unsigned vbvaVHWAHandleCommand (PVGASTATE pVGAState, VBVACONTEXT *pCtx, PVBOXVHWACMD pCmd)
    792 {
     791static void vbvaVHWACommandComplete(PVGASTATE pVGAState, PVBOXVHWACMD pCommand, bool fAsyncCommand)
     792{
     793    if (fAsyncCommand)
     794    {
     795        Assert(pCommand->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH);
     796        vbvaVHWACommandCompleteAsynch(&pVGAState->IVBVACallbacks, pCommand);
     797    }
     798    else
     799    {
     800        Log(("VGA Command <<< Sync rc %d %#p, %d\n", pCommand->rc, pCommand, pCommand->enmCmd));
     801        pCommand->Flags &= (~VBOXVHWACMD_FLAG_HG_ASYNCH);
     802    }
     803
     804}
     805
     806static void vbvaVHWACommandCompleteAllPending(PVGASTATE pVGAState, int rc)
     807{
     808    if (!pVGAState->pendingVhwaCommands.cPending)
     809        return;
     810
     811    VBOX_VHWA_PENDINGCMD *pIter, *pNext;
     812    RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
     813    {
     814        pIter->pCommand->rc = rc;
     815        vbvaVHWACommandComplete(pVGAState, pIter->pCommand, true);
     816
     817        /* the command is submitted/processed, remove from the pend list */
     818        RTListNodeRemove(&pIter->Node);
     819        --pVGAState->pendingVhwaCommands.cPending;
     820        RTMemFree(pIter);
     821    }
     822}
     823
     824static void vbvaVHWACommandCClearAllPending(PVGASTATE pVGAState)
     825{
     826    if (!pVGAState->pendingVhwaCommands.cPending)
     827        return;
     828
     829    VBOX_VHWA_PENDINGCMD *pIter, *pNext;
     830    RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
     831    {
     832        RTListNodeRemove(&pIter->Node);
     833        --pVGAState->pendingVhwaCommands.cPending;
     834        RTMemFree(pIter);
     835    }
     836}
     837
     838static void vbvaVHWACommandPend(PVGASTATE pVGAState, PVBOXVHWACMD pCommand)
     839{
     840    int rc = VERR_BUFFER_OVERFLOW;
     841
     842    if (pVGAState->pendingVhwaCommands.cPending < VBOX_VHWA_MAX_PENDING_COMMANDS)
     843    {
     844        VBOX_VHWA_PENDINGCMD *pPend = (VBOX_VHWA_PENDINGCMD*)RTMemAlloc(sizeof (*pPend));
     845        if (pPend)
     846        {
     847            pCommand->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH;
     848            pPend->pCommand = pCommand;
     849            RTListAppend(&pVGAState->pendingVhwaCommands.PendingList, &pPend->Node);
     850            ++pVGAState->pendingVhwaCommands.cPending;
     851            return;
     852        }
     853        else
     854            rc = VERR_NO_MEMORY;
     855    }
     856    else
     857    {
     858        LogRel(("Pending command count has reached its threshold, completing them all.."));
     859    }
     860
     861    vbvaVHWACommandCompleteAllPending(pVGAState, rc);
     862
     863    pCommand->rc = rc;
     864
     865    vbvaVHWACommandComplete(pVGAState, pCommand, false);
     866}
     867
     868static bool vbvaVHWACommandCanPend(PVBOXVHWACMD pCommand)
     869{
     870    switch (pCommand->enmCmd)
     871    {
     872        case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
     873        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN:
     874        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND:
     875        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEPERFORM:
     876        case VBOXVHWACMD_TYPE_HH_SAVESTATE_LOADPERFORM:
     877            return false;
     878        default:
     879            return true;
     880    }
     881}
     882
     883static int vbvaVHWACommandSavePending(PVGASTATE pVGAState, PSSMHANDLE pSSM)
     884{
     885    int rc = SSMR3PutU32(pSSM, pVGAState->pendingVhwaCommands.cPending);
     886    AssertRCReturn(rc, rc);
     887    VBOX_VHWA_PENDINGCMD *pIter;
     888    RTListForEach(&pVGAState->pendingVhwaCommands.PendingList, pIter, VBOX_VHWA_PENDINGCMD, Node)
     889    {
     890        rc = SSMR3PutU32(pSSM, (uint32_t)(((uint8_t*)pIter->pCommand) - ((uint8_t*)pVGAState->vram_ptrR3)));
     891        AssertRCReturn(rc, rc);
     892    }
     893    return rc;
     894}
     895
     896static int vbvaVHWACommandLoadPending(PVGASTATE pVGAState, PSSMHANDLE pSSM, uint32_t u32Version)
     897{
     898    if (u32Version < VGA_SAVEDSTATE_VERSION_WITH_PENDVHWA)
     899        return VINF_SUCCESS;
     900
     901    int rc;
     902    uint32_t u32;
     903    rc = SSMR3GetU32(pSSM, &u32);
     904    AssertRCReturn(rc, rc);
     905    for (uint32_t i = 0; i < u32; ++i)
     906    {
     907        uint32_t off32;
     908        rc = SSMR3GetU32(pSSM, &off32);
     909        AssertRCReturn(rc, rc);
     910        PVBOXVHWACMD pCommand = (PVBOXVHWACMD)(((uint8_t*)pVGAState->vram_ptrR3) + off32);
     911        vbvaVHWACommandPend(pVGAState, pCommand);
     912    }
     913    return rc;
     914}
     915
     916
     917static bool vbvaVHWACommandSubmit(PVGASTATE pVGAState, PVBOXVHWACMD pCommand, bool fAsyncCommand)
     918{
     919    unsigned id = (unsigned)pCommand->iDisplay;
     920    int rc = VINF_SUCCESS;
     921    bool fPend = false;
     922
    793923    if (pVGAState->pDrv->pfnVHWACommandProcess)
    794         pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCmd);
    795 #ifdef DEBUG_misha
     924    {
     925        Log(("VGA Command >>> %#p, %d\n", pCommand, pCommand->enmCmd));
     926        int rc = pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCommand);
     927        if (rc == VINF_CALLBACK_RETURN)
     928        {
     929            Log(("VGA Command --- Going Async %#p, %d\n", pCommand, pCommand->enmCmd));
     930            return true; /* command will be completed asynchronously, return right away */
     931        }
     932        else if (rc == VERR_INVALID_STATE)
     933        {
     934            Log(("VGA Command --- Trying Pend %#p, %d\n", pCommand, pCommand->enmCmd));
     935            fPend = vbvaVHWACommandCanPend(pCommand);
     936            if (!fPend)
     937            {
     938                Log(("VGA Command --- Can NOT Pend %#p, %d\n", pCommand, pCommand->enmCmd));
     939                pCommand->rc = rc;
     940            }
     941            else
     942                Log(("VGA Command --- Can Pend %#p, %d\n", pCommand, pCommand->enmCmd));
     943        }
     944        else
     945        {
     946            Log(("VGA Command --- Going Complete Sync rc %d %#p, %d\n", rc, pCommand, pCommand->enmCmd));
     947            pCommand->rc = rc;
     948        }
     949
     950        /* the command was completed, take a special care about it (seee below) */
     951    }
    796952    else
     953    {
    797954        AssertFailed();
    798 #endif
    799     return 0;
     955        pCommand->rc = VERR_INVALID_STATE;
     956    }
     957
     958    if (fPend)
     959        return false;
     960
     961    vbvaVHWACommandComplete(pVGAState, pCommand, fAsyncCommand);
     962
     963    return true;
     964}
     965
     966static bool vbvaVHWACheckPendingCommands(PVGASTATE pVGAState)
     967{
     968    if (!pVGAState->pendingVhwaCommands.cPending)
     969        return true;
     970
     971    VBOX_VHWA_PENDINGCMD *pIter, *pNext;
     972    RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
     973    {
     974        if (!vbvaVHWACommandSubmit(pVGAState, pIter->pCommand, true))
     975            return false; /* the command should be pended still */
     976
     977        /* the command is submitted/processed, remove from the pend list */
     978        RTListNodeRemove(&pIter->Node);
     979        --pVGAState->pendingVhwaCommands.cPending;
     980        RTMemFree(pIter);
     981    }
     982
     983    return true;
     984}
     985
     986void vbvaTimerCb(PVGASTATE pVGAState)
     987{
     988    vbvaVHWACheckPendingCommands(pVGAState);
     989}
     990static void vbvaVHWAHandleCommand(PVGASTATE pVGAState, PVBOXVHWACMD pCmd)
     991{
     992    if (vbvaVHWACheckPendingCommands(pVGAState))
     993    {
     994        if (vbvaVHWACommandSubmit(pVGAState, pCmd, false))
     995            return;
     996    }
     997
     998    vbvaVHWACommandPend(pVGAState, pCmd);
    800999}
    8011000
     
    8151014        vbvaVHWAHHCommandRetain (pCmd);
    8161015        VBOXVHWA_HH_CALLBACK_SET(pCmd, vbvaVHWAHHCommandSetEventCallback, (void*)hComplEvent);
    817         vbvaVHWAHandleCommand(pVGAState, NULL, pCmd);
     1016        vbvaVHWAHandleCommand(pVGAState, pCmd);
    8181017        if((ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags)  & VBOXVHWACMD_FLAG_HG_ASYNCH) != 0)
    8191018        {
     
    8371036int vbvaVHWAConstruct (PVGASTATE pVGAState)
    8381037{
     1038    pVGAState->pendingVhwaCommands.cPending = 0;
     1039    RTListInit(&pVGAState->pendingVhwaCommands.PendingList);
    8391040    VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_CONSTRUCT, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT));
    8401041    Assert(pCmd);
     
    8901091int vbvaVHWAReset (PVGASTATE pVGAState)
    8911092{
     1093    vbvaVHWACommandCClearAllPending(pVGAState);
     1094
    8921095    /* ensure we have all pending cmds processed and h->g cmds disabled */
    8931096    VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_RESET, 0, 0);
     
    10091212{
    10101213    int rc;
     1214    Log(("VGA Command <<< Async rc %d %#p, %d\n", pCmd->rc, pCmd, pCmd->enmCmd));
     1215
    10111216    if((pCmd->Flags & VBOXVHWACMD_FLAG_HH_CMD) == 0)
    10121217    {
     
    13941599                if (RT_SUCCESS(rc))
    13951600                {
     1601                    rc = vbvaVHWACommandSavePending(pVGAState, pSSM);
     1602                    AssertRCReturn(rc, rc);
     1603
    13961604                    vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND, 0);
    13971605                    vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVASaveStateEndPreCb, NULL, &VhwaData);
     
    15881796                    vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVALoadStatePerformPreCb, vboxVBVALoadStatePerformPostCb, &VhwaData);
    15891797                    rc = VhwaData.rc;
    1590                     AssertRC(rc);
    15911798                    vbvaVHWAHHCommandRelease(pCmd);
     1799                    AssertRCReturn(rc, rc);
     1800
     1801                    rc = vbvaVHWACommandLoadPending(pVGAState, pSSM, u32Version);
     1802                    AssertRCReturn(rc, rc);
    15921803                }
    15931804                else
     
    19732184        case VBVA_VHWA_CMD:
    19742185        {
    1975             rc = vbvaVHWAHandleCommand (pVGAState, pCtx, (PVBOXVHWACMD)pvBuffer);
     2186            if (cbBuffer < sizeof (VBOXVHWACMD))
     2187            {
     2188                rc = VERR_INVALID_PARAMETER;
     2189                break;
     2190            }
     2191            vbvaVHWAHandleCommand(pVGAState, (PVBOXVHWACMD)pvBuffer);
     2192            rc = VINF_SUCCESS;
     2193            break;
    19762194        } break;
    19772195#endif
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp

    r47510 r49420  
    4343#include <iprt/asm.h>
    4444#include <iprt/semaphore.h>
     45#include <iprt/memcache.h>
     46
    4547#include <VBox/VBoxGL2D.h>
    4648#include <VBox/err.h>
     
    6769
    6870#define VBOXQGL_STATE_NAMEBASE "QGLVHWAData"
    69 #define VBOXQGL_STATE_VERSION           3
    70 #define VBOXQGL_STATE_VERSION_PIPESAVED 3
     71#define VBOXQGL_STATE_VERSION_PIPESAVED    3
     72#define VBOXQGL_STATE_VERSION              3
    7173
    7274#ifdef DEBUG
     
    175177static bool g_bVBoxVHWASupported = false;
    176178
     179class VBoxVHWAEntriesCache
     180{
     181public:
     182    VBoxVHWAEntriesCache()
     183    {
     184        int rc = RTMemCacheCreate(&mVBoxCmdEntryCache, sizeof (VBoxVHWACommandElement),
     185                                    0, /* size_t cbAlignment */
     186                                    UINT32_MAX, /* uint32_t cMaxObjects */
     187                                    NULL, /* PFNMEMCACHECTOR pfnCtor*/
     188                                    NULL, /* PFNMEMCACHEDTOR pfnDtor*/
     189                                    NULL, /* void *pvUser*/
     190                                    0 /* uint32_t fFlags*/
     191                                    );
     192        AssertRC(rc);
     193    }
     194
     195    ~VBoxVHWAEntriesCache()
     196    {
     197        RTMemCacheDestroy(mVBoxCmdEntryCache);
     198    }
     199
     200    VBoxVHWACommandElement * alloc()
     201    {
     202        return (VBoxVHWACommandElement*)RTMemCacheAlloc(mVBoxCmdEntryCache);
     203    }
     204
     205    void free(VBoxVHWACommandElement * pEl)
     206    {
     207        RTMemCacheFree(mVBoxCmdEntryCache, pEl);
     208    }
     209
     210private:
     211    RTMEMCACHE mVBoxCmdEntryCache;
     212};
     213
     214static VBoxVHWAEntriesCache g_VBoxCmdEntriesCache;
     215
    177216static struct VBOXVHWACMD * vhwaHHCmdCreate(VBOXVHWACMD_TYPE type, size_t size)
    178217{
     
    211250public:
    212251    VBoxVHWACommandProcessEvent ()
    213         : QEvent ((QEvent::Type) VHWACommandProcessType)
     252        : QEvent ((QEvent::Type) VHWACommandProcessType),
     253          fProcessed(false)
    214254    {
    215255#ifdef DEBUG_misha
     
    217257#endif
    218258    }
     259
     260    void setProcessed()
     261    {
     262        fProcessed = true;
     263    }
     264
     265    ~VBoxVHWACommandProcessEvent()
     266    {
     267        if (!fProcessed)
     268        {
     269            AssertMsgFailed(("VHWA command beinf destroyed unproceessed!"));
     270            LogRel(("VHWA command being destroyed unproceessed!"));
     271        }
    219272#ifdef DEBUG_misha
    220     ~VBoxVHWACommandProcessEvent()
    221     {
    222273        g_EventCounter.dec();
    223     }
    224 
     274#endif
     275    }
     276#ifdef DEBUG_misha
    225277    static uint32_t cPending() { return g_EventCounter.refs(); }
     278#endif
     279
    226280private:
     281    bool fProcessed;
     282#ifdef DEBUG_misha
    227283    static VBoxVHWARefCounter g_EventCounter;
    228284#endif
     
    41764232int VBoxQGLOverlay::reset()
    41774233{
    4178     VBoxVHWACommandElement * pHead, * pTail;
    4179     mCmdPipe.reset(&pHead, &pTail);
    4180     if(pHead)
    4181     {
    4182         CDisplay display = mpSession->GetConsole().GetDisplay();
    4183         Assert (!display.isNull());
    4184 
    4185         /* complete aborted commands */
    4186         for(VBoxVHWACommandElement * pCur = pHead; pCur; pCur = pCur->mpNext)
    4187         {
    4188             switch(pCur->type())
    4189             {
    4190 #ifdef VBOX_WITH_VIDEOHWACCEL
    4191             case VBOXVHWA_PIPECMD_VHWA:
    4192                 {
    4193                     struct VBOXVHWACMD * pCmd = pCur->vhwaCmd();
    4194                     pCmd->rc = VERR_INVALID_STATE;
    4195                     display.CompleteVHWACommand((BYTE*)pCmd);
    4196                 }
    4197                 break;
    4198             case VBOXVHWA_PIPECMD_FUNC:
    4199                 /* should not happen, don't handle this for now */
    4200                 Assert(0);
    4201                 break;
    4202 #endif
    4203             case VBOXVHWA_PIPECMD_PAINT:
    4204                 break;
    4205             default:
    4206                 /* should not happen, don't handle this for now */
    4207                 Assert(0);
    4208                 break;
    4209             }
    4210         }
    4211 
    4212         VBoxVHWACommandElement *pTest = mCmdPipe.detachCmdList(NULL, pHead, pTail);
    4213         Assert(!pTest);
    4214         NOREF(pTest);
    4215     }
     4234    CDisplay display = mpSession->GetConsole().GetDisplay();
     4235    Assert (!display.isNull());
     4236
     4237    mCmdPipe.reset(&display);
    42164238
    42174239    resetGl();
     
    42374259            VBOXVHWACMD *pCmd = (*sIt);
    42384260            VBOXVHWA_HH_CALLBACK_SET(pCmd, vbvaVHWAHHCommandFreeCmd, pCmd);
    4239             mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd, 0);
     4261            mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
    42404262        }
    42414263    }
     
    42454267int VBoxQGLOverlay::onVHWACommand(struct VBOXVHWACMD * pCmd)
    42464268{
    4247     uint32_t flags = 0;
     4269    Log(("VHWA Command >>> %#p, %d\n", pCmd, pCmd->enmCmd));
    42484270    switch(pCmd->enmCmd)
    42494271    {
     
    42514273        case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
    42524274        case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
    4253             flags |= VBOXVHWACMDPIPEC_COMPLETEEVENT;
    42544275            break;
     4276        case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
     4277        {
     4278            VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);
     4279            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
     4280            pCmd->rc = vhwaConstruct(pBody);
     4281            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
     4282            return VINF_SUCCESS;
     4283        }
    42554284        case VBOXVHWACMD_TYPE_HH_RESET:
    42564285        {
     
    42594288            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
    42604289            pCmd->rc = reset();
     4290            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
    42614291            return VINF_SUCCESS;
    42624292        }
     
    42644294            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
    42654295            pCmd->rc = VINF_SUCCESS;
     4296            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
    42664297            return VINF_SUCCESS;
    42674298        case VBOXVHWACMD_TYPE_HH_DISABLE:
    42684299            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
    42694300            pCmd->rc = VINF_SUCCESS;
     4301            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
    42704302            return VINF_SUCCESS;
    42714303        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN:
     
    42734305            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
    42744306            pCmd->rc = VINF_SUCCESS;
     4307            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
    42754308            return VINF_SUCCESS;
    42764309        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND:
     
    42784311            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
    42794312            pCmd->rc = VINF_SUCCESS;
     4313            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
    42804314            return VINF_SUCCESS;
    42814315        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEPERFORM:
     
    42904324            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
    42914325            pCmd->rc = rc;
     4326            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
    42924327            return VINF_SUCCESS;
    42934328        }
     
    42964331            VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM *pLoad = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM);
    42974332            PSSMHANDLE pSSM = pLoad->pSSM;
    4298             uint32_t u32Version;
     4333            uint32_t u32Version = 0;
    42994334            int rc = SSMR3GetU32(pSSM, &u32Version); Assert(RT_SUCCESS(rc) || rc == VERR_SSM_LOADED_TOO_MUCH);
    43004335            if (RT_SUCCESS(rc))
     
    43024337                rc = vhwaLoadExec(pSSM, u32Version); AssertRC(rc);
    43034338            }
    4304             else if (rc == VERR_SSM_LOADED_TOO_MUCH)
     4339            else
    43054340            {
    4306                 rc = VINF_SUCCESS;
     4341                /* sanity */
     4342                u32Version = 0;
     4343
     4344                if (rc == VERR_SSM_LOADED_TOO_MUCH)
     4345                    rc = VINF_SUCCESS;
    43074346            }
    43084347            pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
    43094348            pCmd->rc = rc;
     4349            Log(("VHWA Command <<< Sync %#p, %d\n", pCmd, pCmd->enmCmd));
    43104350            return VINF_SUCCESS;
     4351        }
     4352        case VBOXVHWACMD_TYPE_QUERY_INFO1:
     4353        {
     4354            VBOXVHWACMD_QUERYINFO1 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
     4355            Assert(pBody->u.in.guestVersion.maj == VBOXVHWA_VERSION_MAJ);
     4356            Assert(pBody->u.in.guestVersion.min == VBOXVHWA_VERSION_MIN);
     4357            Assert(pBody->u.in.guestVersion.bld == VBOXVHWA_VERSION_BLD);
     4358            Assert(pBody->u.in.guestVersion.reserved == VBOXVHWA_VERSION_RSV);
     4359            /* do NOT break!! make it proceed asynchronously */
    43114360        }
    43124361        default:
    43134362            break;
    43144363    }
     4364
     4365    Log(("VHWA Command --- Going Async %#p, %d\n", pCmd, pCmd->enmCmd));
    43154366    /* indicate that we process and complete the command asynchronously */
    43164367    pCmd->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH;
    43174368
    4318     mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd, flags);
    4319     return VINF_SUCCESS;
     4369    mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
     4370    return VINF_CALLBACK_RETURN;
    43204371
    43214372}
     
    43234374void VBoxQGLOverlay::onVHWACommandEvent(QEvent * pEvent)
    43244375{
    4325     Q_UNUSED(pEvent);
     4376    VBoxVHWACommandProcessEvent *pVhwaEvent = (VBoxVHWACommandProcessEvent*)pEvent;
     4377    /* sanity actually */
     4378    pVhwaEvent->setProcessed();
     4379
    43264380    Assert(!mProcessingCommands);
    43274381    mProcessingCommands = true;
    43284382    Assert(!mGlCurrent);
    43294383    mGlCurrent = false; /* just a fall-back */
    4330     bool bFirstCmd = true;
    4331     VBoxVHWACommandElement *pLast;
    4332     VBoxVHWACommandElement * pFirst = mCmdPipe.detachCmdList(&pLast, NULL, NULL);
    4333     while(pFirst) /* pFirst can be zero right after reset when all pending commands are flushed,
    4334                    * while events for those commands may still come along */
    4335     {
    4336         VBoxVHWACommandElement * pLastProcessed = processCmdList(pFirst, bFirstCmd);
    4337 
    4338         if (pLastProcessed == pLast)
    4339         {
    4340             pFirst = mCmdPipe.detachCmdList(&pLast, pFirst, pLastProcessed);
    4341             bFirstCmd = false;
    4342         }
    4343         else
    4344         {
    4345             mCmdPipe.putBack(pLastProcessed->mpNext, pLast, pFirst, pLastProcessed);
    4346             break;
    4347         }
     4384    VBoxVHWACommandElement *pCmd = mCmdPipe.getCmd();
     4385    if (pCmd)
     4386    {
     4387        processCmd(pCmd);
     4388        mCmdPipe.doneCmd();
    43484389    }
    43494390
    43504391    mProcessingCommands = false;
    43514392    repaint();
    4352 //    vboxOpExit();
    43534393    mGlCurrent = false;
    43544394}
     
    43574397                         ULONG aW, ULONG aH)
    43584398{
    4359 #if 1
     4399    /* we do not to miss notify updates, because we have to update bg textures for it,
     4400     * so no not check for m_fIsMarkedAsUnused here,
     4401     * mOverlay will store the required info for us */
    43604402    QRect r(aX, aY, aW, aH);
    4361     mCmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r, 0);
     4403    mCmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r);
    43624404    return true;
    4363 #else
    4364     /* We're not on the GUI thread and update() isn't thread safe in
    4365      * Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is),
    4366      * on Linux (didn't check Qt 4.x there) and probably on other
    4367      * non-DOS platforms, so post the event instead. */
    4368     QApplication::postEvent (mView,
    4369                              new VBoxRepaintEvent (aX, aY, aW, aH));
    4370 
    4371     return S_OK;
    4372 #endif
    43734405}
    43744406
     
    43784410    mContentsTopLeft = topLeft;
    43794411
    4380     if(mGlOn)
    4381     {
     4412    if (mGlOn)
     4413    {
     4414        Assert(mOverlayImage.hasSurfaces());
    43824415        Assert(!mGlCurrent);
    43834416        Assert(!mNeedOverlayRepaint);
     
    43864419        /* need to ensure we're in sync */
    43874420        mNeedOverlayRepaint = vboxSynchGl();
    4388     }
    4389 
    4390     if(!mOnResizeCmdList.empty())
     4421
     4422        if (!mOverlayImage.hasSurfaces())
     4423        {
     4424            Assert(0);
     4425            vboxSetGlOn(false);
     4426        }
     4427    }
     4428    else
     4429        Assert(!mOverlayImage.hasSurfaces());
     4430
     4431    if (!mOnResizeCmdList.empty())
    43914432    {
    43924433        for (VHWACommandList::const_iterator it = mOnResizeCmdList.begin();
     
    44294470    CDisplay display = mpSession->GetConsole().GetDisplay();
    44304471    Assert (!display.isNull());
     4472
     4473    Log(("VHWA Command <<< Async %#p, %d\n", cmd, ((VBOXVHWACMD *)cmd)->enmCmd));
    44314474
    44324475    display.CompleteVHWACommand((BYTE*)cmd);
     
    45904633        {
    45914634            VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
     4635            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    45924636            initGl();
    45934637            makeCurrent();
    45944638            pCmd->rc = mOverlayImage.vhwaSurfaceCanCreate(pBody);
     4639            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    45954640        } break;
    45964641        case VBOXVHWACMD_TYPE_SURF_CREATE:
    45974642        {
    45984643            VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
     4644            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    45994645            initGl();
    46004646            makeCurrent();
     
    46154661                mNeedOverlayRepaint = true;
    46164662            }
     4663
     4664            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46174665        } break;
    46184666        case VBOXVHWACMD_TYPE_SURF_DESTROY:
    46194667        {
    46204668            VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
     4669            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46214670            initGl();
    46224671            makeCurrent();
     
    46364685                mNeedOverlayRepaint = true;
    46374686            }
     4687            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46384688        } break;
    46394689        case VBOXVHWACMD_TYPE_SURF_LOCK:
    46404690        {
    46414691            VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
     4692            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46424693            initGl();
    46434694            makeCurrent();
    46444695            pCmd->rc = mOverlayImage.vhwaSurfaceLock(pBody);
     4696            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46454697        } break;
    46464698        case VBOXVHWACMD_TYPE_SURF_UNLOCK:
    46474699        {
    46484700            VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
     4701            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46494702            initGl();
    46504703            makeCurrent();
    46514704            pCmd->rc = vhwaSurfaceUnlock(pBody);
     4705            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46524706            /* mNeedOverlayRepaint is set inside the vhwaSurfaceUnlock */
    46534707        } break;
     
    46554709        {
    46564710            VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
     4711            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46574712            initGl();
    46584713            makeCurrent();
    46594714            pCmd->rc = mOverlayImage.vhwaSurfaceBlt(pBody);
    46604715            mNeedOverlayRepaint = true;
     4716            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46614717        } break;
    46624718        case VBOXVHWACMD_TYPE_SURF_FLIP:
    46634719        {
    46644720            VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
     4721            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46654722            initGl();
    46664723            makeCurrent();
    46674724            pCmd->rc = mOverlayImage.vhwaSurfaceFlip(pBody);
    46684725            mNeedOverlayRepaint = true;
     4726            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46694727        } break;
    46704728        case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
    46714729        {
    46724730            VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
     4731            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46734732            initGl();
    46744733            makeCurrent();
     
    46814740            vboxDoCheckUpdateViewport();
    46824741            mNeedOverlayRepaint = true;
     4742            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46834743        } break;
    46844744        case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
    46854745        {
    46864746            VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
     4747            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46874748            initGl();
    46884749            makeCurrent();
     
    46954756            vboxDoCheckUpdateViewport();
    46964757            mNeedOverlayRepaint = true;
     4758            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    46974759        } break;
    46984760#ifdef VBOX_WITH_WDDM
     
    47004762        {
    47014763            VBOXVHWACMD_SURF_COLORFILL * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORFILL);
     4764            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47024765            initGl();
    47034766            makeCurrent();
    47044767            pCmd->rc = mOverlayImage.vhwaSurfaceColorFill(pBody);
    47054768            mNeedOverlayRepaint = true;
     4769            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47064770        } break;
    47074771#endif
     
    47094773        {
    47104774            VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
     4775            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47114776            initGl();
    47124777            makeCurrent();
     
    47154780            vboxDoCheckUpdateViewport();
    47164781            mNeedOverlayRepaint = true;
     4782            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47174783        } break;
    47184784        case VBOXVHWACMD_TYPE_QUERY_INFO1:
    47194785        {
    47204786            VBOXVHWACMD_QUERYINFO1 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
     4787            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47214788            initGl();
    47224789            makeCurrent();
    47234790            pCmd->rc = mOverlayImage.vhwaQueryInfo1(pBody);
     4791            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47244792        } break;
    47254793        case VBOXVHWACMD_TYPE_QUERY_INFO2:
    47264794        {
    47274795            VBOXVHWACMD_QUERYINFO2 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
     4796            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47284797            initGl();
    47294798            makeCurrent();
    47304799            pCmd->rc = mOverlayImage.vhwaQueryInfo2(pBody);
     4800            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47314801        } break;
    47324802        case VBOXVHWACMD_TYPE_ENABLE:
     4803            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47334804            initGl();
     4805            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47344806        case VBOXVHWACMD_TYPE_DISABLE:
    47354807            pCmd->rc = VINF_SUCCESS;
     
    47384810        {
    47394811            VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);
     4812            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47404813            pCmd->rc = vhwaConstruct(pBody);
     4814            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47414815        } break;
    47424816#ifdef VBOX_WITH_WDDM
     
    47444818        {
    47454819            VBOXVHWACMD_SURF_GETINFO * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_GETINFO);
     4820            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47464821            pCmd->rc = mOverlayImage.vhwaSurfaceGetInfo(pBody);
     4822            Assert(!mGlOn == !mOverlayImage.hasSurfaces());
    47474823        } break;
    47484824#endif
     
    48504926}
    48514927
    4852 VBoxVHWACommandElement * VBoxQGLOverlay::processCmdList(VBoxVHWACommandElement * pCmd, bool bFirst)
    4853 {
    4854     VBoxVHWACommandElement * pCur;
    4855     do
    4856     {
    4857         pCur = pCmd;
    4858         switch(pCmd->type())
    4859         {
     4928void VBoxQGLOverlay::processCmd(VBoxVHWACommandElement * pCmd)
     4929{
     4930    switch(pCmd->type())
     4931    {
    48604932        case VBOXVHWA_PIPECMD_PAINT:
    48614933            addMainDirtyRect(pCmd->rect());
     
    48744946        default:
    48754947            Assert(0);
    4876         }
    4877 
    4878         pCmd = pCmd->mpNext;
    4879         if (!pCmd)
    4880             break;
    4881 
    4882         if (!bFirst)
    4883         {
    4884             if (pCmd->isNewEvent())
    4885                 break;
    4886         }
    4887         else
    4888         {
    4889             Assert(pCur->isNewEvent());
    4890             bFirst = false;
    4891         }
    4892     } while(1);
    4893 
    4894     return pCur;
    4895 }
    4896 
     4948    }
     4949}
    48974950
    48984951VBoxVHWACommandElementProcessor::VBoxVHWACommandElementProcessor(QObject *pNotifyObject) :
    48994952    m_pNotifyObject(pNotifyObject),
    4900     mbNewEvent (false),
    4901     mbProcessingList (false),
    4902     mcDisabled (0)
     4953    mpCurCmd(NULL),
     4954    mbResetting(false),
     4955    mcDisabled(0)
    49034956{
    49044957    int rc = RTCritSectInit(&mCritSect);
    49054958    AssertRC(rc);
    49064959
    4907     for(int i = RT_ELEMENTS(mElementsBuffer) - 1; i >= 0; i--)
    4908     {
    4909         mFreeElements.push(&mElementsBuffer[i]);
    4910     }
     4960    RTListInit(&mCommandList);
    49114961}
    49124962
     
    49144964{
    49154965    Assert(!m_NotifyObjectRefs.refs());
    4916     Assert(m_CmdPipe.isEmpty());
     4966    RTListIsEmpty(&mCommandList);
     4967
    49174968    RTCritSectDelete(&mCritSect);
    49184969}
    49194970
    4920 bool VBoxVHWACommandElementProcessor::completeCurrentEvent()
    4921 {
    4922     bool bActive = true;
    4923     RTCritSectEnter(&mCritSect);
    4924     mbNewEvent = true;
    4925     if (!m_pNotifyObject)
    4926         bActive = false;
    4927     RTCritSectLeave(&mCritSect);
    4928     return bActive;
    4929 }
    4930 
    4931 void VBoxVHWACommandElementProcessor::postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData, uint32_t flags)
     4971void VBoxVHWACommandElementProcessor::postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
    49324972{
    49334973    QObject *pNotifyObject = NULL;
     4974
     4975    Log(("VHWA post %d %#p\n", aType, pvData));
     4976
    49344977    /* 1. lock*/
    49354978    RTCritSectEnter(&mCritSect);
    4936     VBoxVHWACommandElement * pCmd = mFreeElements.pop();
     4979
     4980    VBoxVHWACommandElement * pCmd = g_VBoxCmdEntriesCache.alloc();
    49374981    if(!pCmd)
    49384982    {
     
    49474991    pCmd->setData(aType, pvData);
    49484992
    4949     if((flags & VBOXVHWACMDPIPEC_NEWEVENT) != 0)
    4950         mbNewEvent = true;
    4951 
    49524993    /* 2. if can add to current*/
    4953     if(mbNewEvent || (!mbProcessingList && m_CmdPipe.isEmpty()))
    4954     {
    4955         pCmd->setNewEvent(true);
    4956         mbNewEvent = false;
    4957         if (m_pNotifyObject)
    4958         {
    4959             m_NotifyObjectRefs.inc(); /* ensure the parent does not get destroyed while we are using it */
    4960             pNotifyObject = m_pNotifyObject;
    4961 #ifdef DEBUG_misha
    4962             checkConsistence();
    4963 #endif
    4964         }
    4965     }
    4966     else
    4967     {
    4968         pCmd->setNewEvent(false);
    4969 #ifdef DEBUG_misha
    4970         if (m_pNotifyObject)
    4971             checkConsistence();
    4972 #endif
    4973     }
    4974 
    4975     m_CmdPipe.put(pCmd);
    4976 #ifdef DEBUG_misha
    49774994    if (m_pNotifyObject)
    49784995    {
    4979         checkConsistence(1);
    4980     }
    4981 #endif
    4982 
    4983     if((flags & VBOXVHWACMDPIPEC_COMPLETEEVENT) != 0)
    4984         mbNewEvent = true;
     4996        m_NotifyObjectRefs.inc(); /* ensure the parent does not get destroyed while we are using it */
     4997        pNotifyObject = m_pNotifyObject;
     4998    }
     4999
     5000    RTListAppend(&mCommandList, &pCmd->ListNode);
    49855001
    49865002    RTCritSectLeave(&mCritSect);
     
    49945010}
    49955011
    4996 #ifdef DEBUG_misha
    4997 void VBoxVHWACommandElementProcessor::checkConsistence(uint32_t cEvents2Submit, const VBoxVHWACommandElementPipe *pPipe)
    4998 {
    4999     const VBoxVHWACommandElement *pLast;
    5000     const VBoxVHWACommandElement *pFirst = pPipe ? pPipe->contentsRo(&pLast) : m_CmdPipe.contentsRo(&pLast);
    5001     uint32_t cEvents = 0;
    5002 
    5003     for (const VBoxVHWACommandElement * pCur = pFirst; pCur; pCur = pCur->mpNext)
    5004     {
    5005         if (pCur->isNewEvent())
    5006         {
    5007             ++cEvents;
    5008             Assert(cEvents <= VBoxVHWACommandProcessEvent::cPending() + cEvents2Submit);
    5009         }
    5010     }
    5011 //    Assert(cEvents == VBoxVHWACommandProcessEvent::cPending());
    5012 }
    5013 #endif
    5014 
    5015 void VBoxVHWACommandElementProcessor::putBack(class VBoxVHWACommandElement * pFirst2Put, VBoxVHWACommandElement * pLast2Put,
    5016         class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free)
    5017 {
    5018     RTCritSectEnter(&mCritSect);
    5019     if (pFirst2Free)
    5020         mFreeElements.pusha(pFirst2Free, pLast2Free);
    5021     m_CmdPipe.prepend(pFirst2Put, pLast2Put);
    5022     mbProcessingList = false;
    5023     Assert(pFirst2Put->isNewEvent());
    5024 #ifdef DEBUG_misha
    5025     Assert(VBoxVHWACommandProcessEvent::cPending());
    5026     const VBoxVHWACommandElement *pLast;
    5027     const VBoxVHWACommandElement *pFirst = m_CmdPipe.contentsRo(&pLast);
    5028     Assert(pFirst);
    5029     Assert(pLast);
    5030     Assert(pFirst == pFirst2Put);
    5031     checkConsistence();
    5032 #endif
    5033     RTCritSectLeave(&mCritSect);
    5034 }
    5035 
    50365012void VBoxVHWACommandElementProcessor::setNotifyObject(QObject *pNotifyObject)
    50375013{
    50385014    int cEventsNeeded = 0;
    5039     const VBoxVHWACommandElement * pFirst;
    50405015    RTCritSectEnter(&mCritSect);
    50415016    if (m_pNotifyObject == pNotifyObject)
     
    50645039        m_pNotifyObject = pNotifyObject;
    50655040
    5066         pFirst = m_CmdPipe.contentsRo(NULL);
    5067         for (; pFirst; pFirst = pFirst->mpNext)
    5068         {
    5069             if (pFirst->isNewEvent())
    5070                 ++cEventsNeeded;
     5041        VBoxVHWACommandElement *pCur;
     5042        RTListForEach(&mCommandList, pCur, VBoxVHWACommandElement, ListNode)
     5043        {
     5044            ++cEventsNeeded;
    50715045        }
    50725046
     
    50795053        Assert(!m_pNotifyObject);
    50805054    }
    5081 
    5082 #ifdef DEBUG_misha
    5083     checkConsistence(cEventsNeeded);
    5084 #endif
    50855055
    50865056    RTCritSectLeave(&mCritSect);
     
    50995069}
    51005070
    5101 VBoxVHWACommandElement * VBoxVHWACommandElementProcessor::detachCmdList(VBoxVHWACommandElement **ppLast,
    5102         VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free)
    5103 {
    5104     VBoxVHWACommandElement * pList = NULL;
    5105     QObject * pNotifyObject = NULL;
     5071void VBoxVHWACommandElementProcessor::doneCmd()
     5072{
     5073    VBoxVHWACommandElement * pEl;
    51065074    RTCritSectEnter(&mCritSect);
    5107     if (pFirst2Free)
    5108     {
    5109         mFreeElements.pusha(pFirst2Free, pLast2Free);
    5110     }
    5111 
    5112 #ifdef DEBUG_misha
    5113     checkConsistence();
    5114 #endif
    5115 
    5116     if (!mcDisabled)
    5117     {
    5118         pList = m_CmdPipe.detachList(ppLast);
    5119 
    5120         if (pList)
    5121         {
    5122             /* assume the caller atomically calls detachCmdList to free the elements obtained now those and reset the state */
    5123             mbProcessingList = true;
    5124             RTCritSectLeave(&mCritSect);
    5125             return pList;
    5126         }
    5127         else
    5128         {
    5129             mbProcessingList = false;
    5130         }
    5131     }
    5132     else
    5133     {
    5134         Assert(!mbProcessingList);
    5135         if (!m_CmdPipe.isEmpty())
     5075    pEl = mpCurCmd;
     5076    Assert(mpCurCmd);
     5077    mpCurCmd = NULL;
     5078    RTCritSectLeave(&mCritSect);
     5079
     5080    if (pEl)
     5081        g_VBoxCmdEntriesCache.free(pEl);
     5082}
     5083
     5084VBoxVHWACommandElement * VBoxVHWACommandElementProcessor::getCmd()
     5085{
     5086    VBoxVHWACommandElement * pEl = NULL;
     5087    RTCritSectEnter(&mCritSect);
     5088
     5089    Assert(!mpCurCmd);
     5090
     5091    if (mbResetting)
     5092    {
     5093        RTCritSectEnter(&mCritSect);
     5094        return NULL;
     5095    }
     5096
     5097    if (mcDisabled)
     5098    {
     5099        QObject * pNotifyObject = NULL;
     5100
     5101        if (!RTListIsEmpty(&mCommandList))
    51365102        {
    51375103            Assert(m_pNotifyObject);
     
    51405106                m_NotifyObjectRefs.inc(); /* ensure the parent does not get destroyed while we are using it */
    51415107                pNotifyObject = m_pNotifyObject;
    5142 #ifdef DEBUG_misha
    5143                 checkConsistence();
    5144 #endif
    51455108            }
    51465109        }
     5110
     5111        RTCritSectLeave(&mCritSect);
     5112
     5113        if (pNotifyObject)
     5114        {
     5115            VBoxVHWACommandProcessEvent *pCurrentEvent = new VBoxVHWACommandProcessEvent();
     5116            QApplication::postEvent(pNotifyObject, pCurrentEvent);
     5117            m_NotifyObjectRefs.dec();
     5118        }
     5119        return NULL;
     5120    }
     5121
     5122    pEl = RTListGetFirst(&mCommandList, VBoxVHWACommandElement, ListNode);
     5123    if (pEl)
     5124    {
     5125        RTListNodeRemove(&pEl->ListNode);
     5126        mpCurCmd = pEl;
    51475127    }
    51485128
    51495129    RTCritSectLeave(&mCritSect);
    51505130
    5151     if (pNotifyObject)
    5152     {
    5153         VBoxVHWACommandProcessEvent *pCurrentEvent = new VBoxVHWACommandProcessEvent();
    5154         QApplication::postEvent(pNotifyObject, pCurrentEvent);
    5155         m_NotifyObjectRefs.dec();
    5156     }
    5157     return NULL;
     5131    return pEl;
    51585132}
    51595133
    51605134/* it is currently assumed no one sends any new commands while reset is in progress */
    5161 void VBoxVHWACommandElementProcessor::reset(VBoxVHWACommandElement ** ppHead, VBoxVHWACommandElement ** ppTail)
    5162 {
    5163     VBoxVHWACommandElementPipe pipe;
     5135void VBoxVHWACommandElementProcessor::reset(CDisplay *pDisplay)
     5136{
     5137    VBoxVHWACommandElement *pCur, *pNext;
     5138
    51645139    RTCritSectEnter(&mCritSect);
    51655140
    5166     pipe.setFrom(&m_CmdPipe);
    5167 
    5168     if(mbProcessingList)
     5141    mbResetting = true;
     5142
     5143    if(mpCurCmd)
    51695144    {
    51705145        for(;;)
     
    51745149            RTCritSectEnter(&mCritSect);
    51755150            /* it is assumed no one sends any new commands while reset is in progress */
    5176             if(!mbProcessingList)
     5151            if(!mpCurCmd)
    51775152            {
    51785153                break;
     
    51815156    }
    51825157
    5183     Assert(!mbProcessingList);
    5184 
    5185     pipe.prependFrom(&m_CmdPipe);
    5186 
    5187     if(!pipe.isEmpty())
    5188         mbProcessingList = true;
    5189 
    51905158    RTCritSectLeave(&mCritSect);
    51915159
    5192     *ppHead = pipe.detachList(ppTail);
     5160    RTListForEachSafe(&mCommandList, pCur, pNext, VBoxVHWACommandElement, ListNode)
     5161    {
     5162        switch(pCur->type())
     5163        {
     5164#ifdef VBOX_WITH_VIDEOHWACCEL
     5165        case VBOXVHWA_PIPECMD_VHWA:
     5166            {
     5167                struct VBOXVHWACMD * pCmd = pCur->vhwaCmd();
     5168                pCmd->rc = VERR_INVALID_STATE;
     5169                Log(("VHWA Command <<< Async RESET %#p, %d\n", pCmd, pCmd->enmCmd));
     5170                pDisplay->CompleteVHWACommand((BYTE*)pCmd);
     5171            }
     5172            break;
     5173        case VBOXVHWA_PIPECMD_FUNC:
     5174            /* should not happen, don't handle this for now */
     5175            Assert(0);
     5176            break;
     5177#endif
     5178        case VBOXVHWA_PIPECMD_PAINT:
     5179            break;
     5180        default:
     5181            /* should not happen, don't handle this for now */
     5182            Assert(0);
     5183            break;
     5184        }
     5185
     5186        RTListNodeRemove(&pCur->ListNode);
     5187        g_VBoxCmdEntriesCache.free(pCur);
     5188    }
    51935189}
    51945190
     
    52355231                            {
    52365232                                QRect r = QRect(x, y, w, h);
    5237                                 postCmd(VBOXVHWA_PIPECMD_PAINT, &r, 0);
     5233                                postCmd(VBOXVHWA_PIPECMD_PAINT, &r);
    52385234                            }
    52395235                            break;
     
    52485244                            if (RT_SUCCESS(rc))
    52495245                            {
    5250                                 postCmd(VBOXVHWA_PIPECMD_VHWA, (VBOXVHWACMD*)(((uint8_t*)pvVRAM) + offCmd), 0);
     5246                                postCmd(VBOXVHWA_PIPECMD_VHWA, (VBOXVHWACMD*)(((uint8_t*)pvVRAM) + offCmd));
    52515247                            }
    52525248                            break;
     
    52815277    rc = SSMR3PutU32(pSSM, VBOXVHWACOMMANDELEMENTLISTBEGIN_MAGIC);         AssertRC(rc);
    52825278    rc = SSMR3PutU32(pSSM, m_NotifyObjectRefs.refs());         AssertRC(rc);
    5283     rc = SSMR3PutBool(pSSM, mbNewEvent);         AssertRC(rc);
    5284 
    5285     const VBoxVHWACommandElement * pCur = m_CmdPipe.contentsRo(NULL);
    5286     for (;pCur; pCur = pCur->mpNext)
     5279    rc = SSMR3PutBool(pSSM, true);         AssertRC(rc);
     5280
     5281    VBoxVHWACommandElement *pCur;
     5282    RTListForEach(&mCommandList, pCur, VBoxVHWACommandElement, ListNode)
    52875283    {
    52885284        rc = SSMR3PutU32(pSSM, pCur->type());         AssertRC(rc);
     
    52955291                rc = SSMR3PutS32(pSSM, pCur->rect().width());         AssertRC(rc);
    52965292                rc = SSMR3PutS32(pSSM, pCur->rect().height());         AssertRC(rc);
    5297                 rc = SSMR3PutBool(pSSM, pCur->isNewEvent());         AssertRC(rc);
     5293                rc = SSMR3PutBool(pSSM, true);         AssertRC(rc);
    52985294                break;
    52995295            case VBOXVHWA_PIPECMD_VHWA:
    53005296            {
    53015297                rc = SSMR3PutU32(pSSM, (uint32_t)((uintptr_t)((uint8_t*)pCur->vhwaCmd() - (uint8_t*)pvVRAM)));         AssertRC(rc);
    5302                 rc = SSMR3PutBool(pSSM, pCur->isNewEvent());         AssertRC(rc);
     5298                rc = SSMR3PutBool(pSSM, true);         AssertRC(rc);
    53035299                break;
    53045300            }
     
    53165312    RTCritSectEnter(&mCritSect);
    53175313
    5318     if(mbProcessingList)
     5314    if(mpCurCmd)
    53195315    {
    53205316        for(;;)
     
    53245320            RTCritSectEnter(&mCritSect);
    53255321            /* it is assumed no one sends any new commands while reset is in progress */
    5326             if(!mbProcessingList)
     5322            if(!mpCurCmd)
    53275323            {
    53285324                break;
     
    53315327    }
    53325328
    5333     Assert(!mbProcessingList);
     5329    Assert(!mpCurCmd);
    53345330}
    53355331
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h

    r44528 r49420  
    3636#include "COMEnums.h"
    3737
     38#include "CDisplay.h"
     39
    3840/* Other VBox includes: */
    3941#include <iprt/assert.h>
     
    4143#include <iprt/asm.h>
    4244#include <iprt/err.h>
     45#include <iprt/list.h>
    4346#include <VBox/VBoxGL2D.h>
    4447#ifdef VBOXVHWA_PROFILE_FPS
    4548# include <iprt/stream.h>
    4649#endif /* VBOXVHWA_PROFILE_FPS */
     50
     51#ifndef S_FALSE
     52# define S_FALSE ((HRESULT)1L)
     53#endif
    4754
    4855#ifdef DEBUG_misha
     
    11891196{
    11901197public:
    1191     VBoxVHWACommandElement() :
    1192         bNewEvent(false)
    1193     {}
    1194 
    11951198    void setVHWACmd(struct VBOXVHWACMD * pCmd)
    11961199    {
     
    12301233    }
    12311234
    1232     void setNewEvent(bool bNew) {bNewEvent = bNew;}
    1233     bool isNewEvent() const { return bNewEvent; }
    1234 
    12351235    VBOXVHWA_PIPECMD_TYPE type() const {return mType;}
    12361236    const QRect & rect() const {return mRect;}
     
    12381238    const VBOXVHWAFUNCCALLBACKINFO & func() const {return u.mFuncCallback; }
    12391239
    1240     VBoxVHWACommandElement * mpNext;
     1240    RTLISTNODE ListNode;
    12411241private:
    12421242    VBOXVHWA_PIPECMD_TYPE mType;
     
    12471247    }u;
    12481248    QRect                 mRect;
    1249     bool bNewEvent;
    1250 };
    1251 
    1252 class VBoxVHWACommandElementPipe
    1253 {
    1254 public:
    1255     VBoxVHWACommandElementPipe() :
    1256         mpFirst(NULL),
    1257         mpLast(NULL)
    1258     {}
    1259 
    1260     void put(VBoxVHWACommandElement *pCmd)
    1261     {
    1262         if (mpLast)
    1263         {
    1264             Assert(mpFirst);
    1265             mpLast->mpNext = pCmd;
    1266             mpLast = pCmd;
    1267         }
    1268         else
    1269         {
    1270             Assert(!mpFirst);
    1271             mpFirst = pCmd;
    1272             mpLast = pCmd;
    1273         }
    1274         pCmd->mpNext= NULL;
    1275 
    1276     }
    1277 
    1278     void setFrom(VBoxVHWACommandElementPipe *pOther)
    1279     {
    1280         mpFirst = pOther->detachList(&mpLast);
    1281     }
    1282 
    1283     void set(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
    1284     {
    1285         mpFirst = pFirst;
    1286         mpLast = pLast;
    1287         if (mpLast)
    1288             mpLast->mpNext = NULL;
    1289     }
    1290 
    1291     void prepend(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
    1292     {
    1293         if (!mpFirst)
    1294             set(pFirst, pLast);
    1295         else if (pLast)
    1296         {
    1297             pLast->mpNext = mpFirst;
    1298             mpFirst = pFirst;
    1299         }
    1300     }
    1301 
    1302     void prependFrom(VBoxVHWACommandElementPipe *pOther)
    1303     {
    1304         VBoxVHWACommandElement *pFirst;
    1305         VBoxVHWACommandElement *pLast;
    1306         pFirst = pOther->detachList(&pLast);
    1307         prepend(pFirst, pLast);
    1308     }
    1309 
    1310     void append(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
    1311     {
    1312         if (!mpLast)
    1313             set(pFirst, pLast);
    1314         else if (pLast)
    1315         {
    1316             mpLast->mpNext = pFirst;
    1317             mpLast = pLast;
    1318             pLast->mpNext = NULL;
    1319         }
    1320     }
    1321 
    1322     VBoxVHWACommandElement * detachList(VBoxVHWACommandElement **ppLast)
    1323     {
    1324         if (mpLast)
    1325         {
    1326             VBoxVHWACommandElement * pHead = mpFirst;
    1327             if (ppLast)
    1328                 *ppLast = mpLast;
    1329             mpFirst = NULL;
    1330             mpLast = NULL;
    1331             return pHead;
    1332         }
    1333         if (ppLast)
    1334             *ppLast = NULL;
    1335         return NULL;
    1336     }
    1337 
    1338 
    1339 
    1340     const VBoxVHWACommandElement * contentsRo (const VBoxVHWACommandElement **ppLast) const
    1341     {
    1342         if (ppLast)
    1343             *ppLast = mpLast;
    1344         return mpFirst;
    1345     }
    1346 
    1347     bool isEmpty() const { return !mpLast; }
    1348 
    1349 private:
    1350     VBoxVHWACommandElement *mpFirst;
    1351     VBoxVHWACommandElement *mpLast;
    1352 };
    1353 
    1354 class VBoxVHWACommandElementStack
    1355 {
    1356 public:
    1357     VBoxVHWACommandElementStack() :
    1358         mpFirst(NULL) {}
    1359 
    1360     void push(VBoxVHWACommandElement *pCmd)
    1361     {
    1362         pCmd->mpNext = mpFirst;
    1363         mpFirst = pCmd;
    1364     }
    1365 
    1366     void pusha(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
    1367     {
    1368         pLast->mpNext = mpFirst;
    1369         mpFirst = pFirst;
    1370     }
    1371 
    1372     VBoxVHWACommandElement * pop()
    1373     {
    1374         if(mpFirst)
    1375         {
    1376             VBoxVHWACommandElement * ret = mpFirst;
    1377             mpFirst = ret->mpNext;
    1378             return ret;
    1379         }
    1380         return NULL;
    1381     }
    1382 private:
    1383     VBoxVHWACommandElement *mpFirst;
    13841249};
    13851250
     
    14251290};
    14261291
    1427 #define VBOXVHWACMDPIPEC_NEWEVENT      0x00000001
    1428 #define VBOXVHWACMDPIPEC_COMPLETEEVENT 0x00000002
    14291292class VBoxVHWACommandElementProcessor
    14301293{
     
    14321295    VBoxVHWACommandElementProcessor(QObject *pNotifyObject);
    14331296    ~VBoxVHWACommandElementProcessor();
    1434     void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData, uint32_t flags);
    1435     bool completeCurrentEvent();
    1436     class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement ** ppLast,
    1437             class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
    1438     void putBack(class VBoxVHWACommandElement * pFirst2Put, VBoxVHWACommandElement * pLast2Put,
    1439             class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
    1440     void reset(class VBoxVHWACommandElement ** ppHead, class VBoxVHWACommandElement ** ppTail);
     1297    void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData);
     1298    VBoxVHWACommandElement *getCmd();
     1299    void doneCmd();
     1300    void reset(CDisplay *pDisplay);
    14411301    void setNotifyObject(QObject *pNotifyObject);
    14421302    int loadExec (struct SSMHANDLE * pSSM, uint32_t u32Version, void *pvVRAM);
     
    14461306    void lock();
    14471307    void unlock();
    1448 #ifdef DEBUG_misha
    1449     void checkConsistence(uint32_t cEvents2Submit = 0, const VBoxVHWACommandElementPipe *pPipe = NULL);
    1450 #endif
    14511308private:
    14521309    RTCRITSECT mCritSect;
    1453     VBoxVHWACommandElementPipe m_CmdPipe;
     1310    RTLISTNODE mCommandList;
    14541311    QObject *m_pNotifyObject;
    14551312    VBoxVHWARefCounter m_NotifyObjectRefs;
    1456     bool mbNewEvent;
    1457     bool mbProcessingList;
     1313    VBoxVHWACommandElement *mpCurCmd;
     1314    bool mbResetting;
    14581315    uint32_t mcDisabled;
    1459     VBoxVHWACommandElementStack mFreeElements;
    1460     VBoxVHWACommandElement mElementsBuffer[2048];
    14611316};
    14621317
     
    18191674                             ULONG aW, ULONG aH);
    18201675
    1821     /**
    1822      * to be called on RequestResize framebuffer call
    1823      * @return true if the request was processed & should not be forwarded to the framebuffer
    1824      * false - otherwise */
    1825     bool onRequestResize (ULONG aScreenId, ULONG uPixelFormat,
    1826                           BYTE * pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine,
    1827                           ULONG uWidth, ULONG uHeight,
    1828                           HRESULT *pResult,
    1829                           BOOL * pbFinished)
    1830     {
    1831         Q_UNUSED(aScreenId);
    1832         Q_UNUSED(uPixelFormat);
    1833         Q_UNUSED(pVRAM);
    1834         Q_UNUSED(uBitsPerPixel);
    1835         Q_UNUSED(uBytesPerLine);
    1836         Q_UNUSED(uWidth);
    1837         Q_UNUSED(uHeight);
    1838         Q_UNUSED(pbFinished);
    1839 
    1840         if (mCmdPipe.completeCurrentEvent())
    1841             return false;
    1842 
    1843         /* TODO: more graceful resize handling */
    1844         *pResult = E_FAIL;
    1845 
    1846         return true;
     1676    void onNotifyUpdateIgnore (ULONG aX, ULONG aY,
     1677                             ULONG aW, ULONG aH)
     1678    {
     1679        /* @todo: we actually should not miss notify updates, since we need to update the texture on it */
    18471680    }
    18481681
     
    19221755    void addMainDirtyRect (const QRect & aRect);
    19231756    void vboxCheckUpdateOverlay (const QRect & rect);
    1924     VBoxVHWACommandElement * processCmdList (VBoxVHWACommandElement * pCmd, bool bFirst);
     1757    void processCmd (VBoxVHWACommandElement * pCmd);
    19251758
    19261759    int vhwaConstruct (struct VBOXVHWACMD_HH_CONSTRUCT *pCmd);
     
    19801813    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand)
    19811814    {
    1982         return mOverlay.onVHWACommand ((struct VBOXVHWACMD*)pCommand);
     1815        int rc;
     1816        T::lock();
     1817        /* Make sure frame-buffer is used: */
     1818        if (m_fIsMarkedAsUnused)
     1819        {
     1820            LogRel2(("ProcessVHWACommand: Postponed!\n"));
     1821            /* Unlock access to frame-buffer: */
     1822            T::unlock();
     1823            /* tell client to pend ProcessVHWACommand */
     1824            return E_ACCESSDENIED;
     1825        }
     1826        rc = mOverlay.onVHWACommand ((struct VBOXVHWACMD*)pCommand);
     1827        T::unlock();
     1828        if (rc == VINF_CALLBACK_RETURN)
     1829            return S_OK;
     1830        else if (RT_SUCCESS(rc))
     1831            return S_FALSE;
     1832        else if (rc == VERR_INVALID_STATE)
     1833            return E_ACCESSDENIED;
     1834        return E_FAIL;
    19831835    }
    19841836
     
    19871839        mOverlay.onVHWACommandEvent (pEvent);
    19881840    }
    1989 
    1990     STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
    1991                               BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
    1992                               ULONG aWidth, ULONG aHeight,
    1993                               BOOL *aFinished)
    1994    {
    1995         HRESULT result;
    1996         if (mOverlay.onRequestResize (aScreenId, aPixelFormat,
    1997                 aVRAM, aBitsPerPixel, aBytesPerLine,
    1998                 aWidth, aHeight,
    1999                 &result,
    2000                 aFinished))
    2001         {
    2002             return result;
    2003         }
    2004         return T::RequestResize (aScreenId, aPixelFormat,
    2005                 aVRAM, aBitsPerPixel, aBytesPerLine,
    2006                 aWidth, aHeight,
    2007                 aFinished);
    2008    }
    20091841
    20101842    STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
    20111843                             ULONG aW, ULONG aH)
    20121844    {
    2013         if (mOverlay.onNotifyUpdate (aX, aY, aW, aH))
    2014             return S_OK;
    2015         return T::NotifyUpdate (aX, aY, aW, aH);
    2016     }
    2017 
    2018     STDMETHOD(VideoModeSupported) (ULONG uWidth, ULONG uHeight, ULONG uBPP,
    2019                                        BOOL *pbSupported)
    2020     {
    2021         /* TODO: tmp workaround: the lock should be moved to the calling code??
    2022          * otherwise we may end up calling a null View */
    2023         /* Todo: can we call VideoModeSupported with the lock held?
    2024          * if not we can introduce a ref counting for the mpView usage
    2025          * to ensure it stays alive till we need it*/
    2026         HRESULT hr = T::Lock();
    2027         HRESULT retHr = S_OK;
    2028         Assert(hr == S_OK);
    2029         if (SUCCEEDED(hr))
    2030         {
    2031             if (mpView)
    2032                 retHr = T::VideoModeSupported(uWidth, uHeight, uBPP, pbSupported);
    2033             hr = T::Unlock();
    2034             Assert(hr == S_OK);
    2035         }
    2036         return retHr;
     1845        HRESULT hr = S_OK;
     1846        T::lock();
     1847        /* Make sure frame-buffer is used: */
     1848        if (m_fIsMarkedAsUnused)
     1849        {
     1850            LogRel2(("NotifyUpdate: Ignored!\n"));
     1851            mOverlay.onNotifyUpdateIgnore (aX, aY, aW, aH);
     1852            /* Unlock access to frame-buffer: */
     1853            T::unlock();
     1854            /*can we actually ignore the notify update?*/
     1855            /* Ignore NotifyUpdate: */
     1856            return E_FAIL;
     1857        }
     1858
     1859        if (!mOverlay.onNotifyUpdate (aX, aY, aW, aH))
     1860            hr = T::NotifyUpdate (aX, aY, aW, aH);
     1861        T::unlock();
     1862        return hr;
    20371863    }
    20381864
     
    20591885    {
    20601886        /* lock to ensure we do not collide with the EMT thread passing commands to us */
    2061         HRESULT hr = T::Lock();
    2062         Assert(hr == S_OK);
    2063         if (SUCCEEDED(hr))
    2064         {
    2065             T::setView(pView);
    2066             mpView = pView;
    2067             mOverlay.updateAttachment(pView ? pView->viewport() : NULL, pView);
    2068             hr = T::Unlock();
    2069             Assert(hr == S_OK);
    2070         }
    2071     }
     1887        T::lock();
     1888        T::setView(pView);
     1889        mpView = pView;
     1890        mOverlay.updateAttachment(pView ? pView->viewport() : NULL, pView);
     1891        T::unlock();
     1892    }
     1893
    20721894private:
    20731895    VBoxQGLOverlay mOverlay;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r49401 r49420  
    619619    QApplication::sendPostedEvents(this, QEvent::MetaCall);
    620620
     621#ifdef VBOX_WITH_VIDEOHWACCEL
     622    if (m_fAccelerate2DVideo)
     623        QApplication::sendPostedEvents(this, VHWACommandProcessType);
     624#endif /* VBOX_WITH_VIDEOHWACCEL */
     625
    621626    /* Temporarily detach the framebuffer from IDisplay before detaching
    622627     * from view in order to respect the thread synchonisation logic (see UIFrameBuffer.h).
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r48955 r49420  
    147147    void handleDisplayUpdate(unsigned uScreenId, int x, int y, int w, int h);
    148148#ifdef VBOX_WITH_VIDEOHWACCEL
    149     void handleVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand);
     149    int handleVHWACommandProcess(PVBOXVHWACMD pCommand);
    150150#endif
    151151#ifdef VBOX_WITH_CRHGSMI
     
    225225
    226226#ifdef VBOX_WITH_VIDEOHWACCEL
    227     static DECLCALLBACK(void)  displayVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand);
     227    static DECLCALLBACK(int)  displayVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand);
    228228#endif
    229229
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r49311 r49420  
    38103810#ifdef VBOX_WITH_VIDEOHWACCEL
    38113811
    3812 void Display::handleVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand)
     3812#ifndef S_FALSE
     3813# define S_FALSE ((HRESULT)1L)
     3814#endif
     3815
     3816int Display::handleVHWACommandProcess(PVBOXVHWACMD pCommand)
    38133817{
    38143818    unsigned id = (unsigned)pCommand->iDisplay;
    38153819    int rc = VINF_SUCCESS;
    3816     if (id < mcMonitors)
    3817     {
    3818         IFramebuffer *pFramebuffer = maFramebuffers[id].pFramebuffer;
    3819 #ifdef DEBUG_misha
    3820         Assert (pFramebuffer);
    3821 #endif
    3822 
    3823         if (pFramebuffer != NULL)
    3824         {
    3825             HRESULT hr = pFramebuffer->ProcessVHWACommand((BYTE*)pCommand);
    3826             if (FAILED(hr))
    3827             {
    3828                 rc = (hr == E_NOTIMPL) ? VERR_NOT_IMPLEMENTED : VERR_GENERAL_FAILURE;
    3829             }
    3830         }
    3831         else
    3832         {
    3833             rc = VERR_NOT_IMPLEMENTED;
    3834         }
    3835     }
    3836     else
    3837     {
    3838         rc = VERR_INVALID_PARAMETER;
    3839     }
    3840 
    3841     if (RT_FAILURE(rc))
    3842     {
    3843         /* tell the guest the command is complete */
    3844         pCommand->Flags &= (~VBOXVHWACMD_FLAG_HG_ASYNCH);
    3845         pCommand->rc = rc;
    3846     }
    3847 }
    3848 
    3849 DECLCALLBACK(void) Display::displayVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand)
     3820    if (id >= mcMonitors)
     3821        return VERR_INVALID_PARAMETER;
     3822
     3823    ComPtr<IFramebuffer> pFramebuffer;
     3824    AutoReadLock arlock(this COMMA_LOCKVAL_SRC_POS);
     3825    pFramebuffer = maFramebuffers[id].pFramebuffer;
     3826    arlock.release();
     3827
     3828    if (pFramebuffer == NULL)
     3829        return VERR_INVALID_STATE; /* notify we can not handle request atm */
     3830
     3831    HRESULT hr = pFramebuffer->ProcessVHWACommand((BYTE*)pCommand);
     3832    if (hr == S_FALSE)
     3833        return VINF_SUCCESS;
     3834    else if (SUCCEEDED(hr))
     3835        return VINF_CALLBACK_RETURN;
     3836    else if (hr == E_ACCESSDENIED)
     3837        return VERR_INVALID_STATE; /* notify we can not handle request atm */
     3838    else if (hr == E_NOTIMPL)
     3839        return VERR_NOT_IMPLEMENTED;
     3840    return VERR_GENERAL_FAILURE;
     3841}
     3842
     3843DECLCALLBACK(int) Display::displayVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand)
    38503844{
    38513845    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
    38523846
    3853     pDrv->pDisplay->handleVHWACommandProcess(pInterface, pCommand);
     3847    return pDrv->pDisplay->handleVHWACommandProcess(pCommand);
    38543848}
    38553849#endif
Note: See TracChangeset for help on using the changeset viewer.

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