server_presenter.cpp revision 4252e037570a3c8d943552edb7858c9889aaca1d
/* $Id$ */
/** @file
* Presenter API
*/
/*
* Copyright (C) 2012-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "cr_spu.h"
#include "chromium.h"
#include "cr_error.h"
#include "cr_net.h"
#include "cr_rand.h"
#include "server_dispatch.h"
#include "server.h"
#include "cr_mem.h"
#include "cr_string.h"
#include <cr_vreg.h>
#include <cr_htable.h>
#ifdef DEBUG_misha
# define VBOXVDBG_MEMCACHE_DISABLE
#endif
#ifndef VBOXVDBG_MEMCACHE_DISABLE
# include <iprt/memcache.h>
#endif
#include "render/renderspu.h"
class ICrFbDisplay
{
public:
virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) = 0;
virtual ~ICrFbDisplay() {}
};
class CrFbDisplayComposite;
class CrFbDisplayBase;
class CrFbDisplayWindow;
class CrFbDisplayWindowRootVr;
class CrFbDisplayVrdp;
typedef struct CR_FRAMEBUFFER
{
struct VBVAINFOSCREEN ScreenInfo;
void *pvVram;
typedef struct CR_FBDISPLAY_INFO
{
typedef struct CR_PRESENTER_GLOBALS
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#endif
static CR_PRESENTER_GLOBALS g_CrPresenter;
/* FRAMEBUFFER */
{
}
{
}
HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry);
{
return &pFb->Compositor;
}
{
}
{
return &hFb->ScreenInfo;
}
{
{
}
return VINF_SUCCESS;
}
{
{
WARN(("invalid UpdateEnd call!"));
return;
}
{
}
}
{
}
{
{
WARN(("no update in progress"));
return VERR_INVALID_STATE;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
{
WARN(("update in progress"));
return;
}
}
{
}
{
{
WARN(("update in progress"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
return VINF_SUCCESS;
}
typedef union CR_FBENTRY_FLAGS
{
struct {
};
typedef struct CR_FRAMEBUFFER_ENTRY
{
typedef struct CR_FBTEX
{
} CR_FBTEX;
#define PCR_FRAMEBUFFER_FROM_COMPOSITOR(_pCompositor) ((CR_FRAMEBUFFER*)((uint8_t*)(_pCompositor) - RT_OFFSETOF(CR_FRAMEBUFFER, Compositor)))
#define PCR_FBENTRY_FROM_ENTRY(_pEntry) ((CR_FRAMEBUFFER_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_FRAMEBUFFER_ENTRY, Entry)))
#define CR_PMGR_MODE_WINDOW 0x1
/* CR_PMGR_MODE_WINDOW gets automatically set with it */
#define CR_PMGR_MODE_ROOTVR 0x2
#define CR_PMGR_MODE_VRDP 0x4
#define CR_PMGR_MODE_ALL 0x7
int CrPMgrInit()
{
int rc = VINF_SUCCESS;
if (g_CrPresenter.pFbTexMap)
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
0, /* size_t cbAlignment */
UINT32_MAX, /* uint32_t cMaxObjects */
NULL, /* PFNMEMCACHECTOR pfnCtor*/
NULL, /* PFNMEMCACHEDTOR pfnDtor*/
NULL, /* void *pvUser*/
0 /* uint32_t fFlags*/
);
if (RT_SUCCESS(rc))
{
0, /* size_t cbAlignment */
UINT32_MAX, /* uint32_t cMaxObjects */
NULL, /* PFNMEMCACHECTOR pfnCtor*/
NULL, /* PFNMEMCACHEDTOR pfnDtor*/
NULL, /* void *pvUser*/
0 /* uint32_t fFlags*/
);
if (RT_SUCCESS(rc))
{
0, /* size_t cbAlignment */
UINT32_MAX, /* uint32_t cMaxObjects */
NULL, /* PFNMEMCACHECTOR pfnCtor*/
NULL, /* PFNMEMCACHEDTOR pfnDtor*/
NULL, /* void *pvUser*/
0 /* uint32_t fFlags*/
);
if (RT_SUCCESS(rc))
{
#endif
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
else
#ifndef VBOXVDBG_MEMCACHE_DISABLE
}
else
}
else
}
else
#endif
}
else
{
WARN(("crAllocHashtable failed"));
rc = VERR_NO_MEMORY;
}
return rc;
}
void CrPMgrTerm()
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#endif
}
static CR_FBTEX* crFbTexAlloc()
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#else
#endif
}
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#else
#endif
}
static CR_FRAMEBUFFER_ENTRY* crFbEntryAlloc()
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#else
#endif
}
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#else
#endif
}
{
if (pTobj)
{
{
/* on the host side, we need to delete an ogl texture object here as well, which crStateDeleteTextureCallback will do
* in addition to calling crStateDeleteTextureObject to delete a state object */
}
}
}
void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased)
{
}
{
if (!pFbTex)
{
WARN(("crFbTexAlloc failed!"));
return NULL;
}
return pFbTex;
}
{
if (!pFbTex)
{
WARN(("crFbTexCreate failed!"));
return NULL;
}
}
{
if (pFbTex)
{
return pFbTex;
}
if (!pShared)
{
WARN(("pShared is null!"));
return NULL;
}
if (!pTobj)
{
WARN(("pTobj is null!"));
return NULL;
}
if (!hwid)
{
WARN(("hwId is null!"));
return NULL;
}
if (!pFbTex)
{
WARN(("crFbTexCreate failed!"));
return NULL;
}
return pFbTex;
}
{
{
}
}
{
}
{
}
{
if (!cRefs)
return cRefs;
}
static DECLCALLBACK(void) crFbEntryReleased(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry)
{
CR_FRAMEBUFFER_ENTRY *pFbReplacingEntry = pReplacingEntry ? PCR_FBENTRY_FROM_ENTRY(pReplacingEntry) : NULL;
if (pFbReplacingEntry)
{
/*replace operation implies the replaced entry gets auto-destroyed,
* while all its data gets moved to the *clean* replacing entry
* 1. ensure the replacing entry is cleaned up */
/* 2. mark the replaced entry is destroyed */
}
else
{
}
}
static CR_FRAMEBUFFER_ENTRY* crFbEntryCreate(CR_FRAMEBUFFER *pFb, CR_TEXDATA* pTex, const RTRECT *pRect, uint32_t fFlags)
{
if (!pEntry)
{
WARN(("crFbEntryAlloc failed!"));
return NULL;
}
return pEntry;
}
int CrFbEntryCreateForTexData(CR_FRAMEBUFFER *pFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry)
{
if (!pEntry)
{
WARN(("crFbEntryCreate failed"));
return VERR_NO_MEMORY;
}
return VINF_SUCCESS;
}
int CrFbEntryTexDataUpdate(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY pEntry, struct CR_TEXDATA *pTex)
{
{
WARN(("framebuffer not updating"));
return VERR_INVALID_STATE;
}
if (pTex)
{
}
return VINF_SUCCESS;
}
int CrFbEntryCreateForTexId(CR_FRAMEBUFFER *pFb, GLuint idTexture, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry)
{
if (!pFbTex)
{
WARN(("crFbTexAcquire failed"));
return VERR_INVALID_PARAMETER;
}
if (!RT_SUCCESS(rc))
{
}
/*always release the tex, the CrFbEntryCreateForTexData will do incref as necessary */
return rc;
}
{
}
{
}
{
{
WARN(("framebuffer not updating"));
return VERR_INVALID_STATE;
}
bool fChanged = false;
if (fChanged)
{
}
return VINF_SUCCESS;
}
int CrFbEntryRegionsAdd(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated)
{
{
WARN(("framebuffer not updating"));
return VERR_INVALID_STATE;
}
uint32_t fChangeFlags = 0;
bool fEntryWasInList;
if (hEntry)
{
}
else
{
fEntryWasInList = false;
}
int rc = CrVrScrCompositorEntryRegionsAdd(&pFb->Compositor, hEntry ? &hEntry->Entry : NULL, pPos, cRegions, paRegions, fPosRelated, &pReplacedScrEntry, &fChangeFlags);
if (RT_SUCCESS(rc))
{
{
if (!fEntryWasInList && pNewEntry)
{
{
}
}
}
else if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)
{
/* we have already processed that in a "release" callback */
}
else
{
}
}
else
return rc;
}
int CrFbEntryRegionsSet(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated)
{
{
WARN(("framebuffer not updating"));
return VERR_INVALID_STATE;
}
bool fChanged = 0;
bool fEntryWasInList;
if (hEntry)
{
}
else
{
fEntryWasInList = false;
}
int rc = CrVrScrCompositorEntryRegionsSet(&pFb->Compositor, pNewEntry, pPos, cRegions, paRegions, fPosRelated, &fChanged);
if (RT_SUCCESS(rc))
{
if (fChanged)
{
if (!fEntryWasInList && pNewEntry)
{
{
{
}
}
}
}
}
else
return rc;
}
{
}
HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry)
{
}
{
}
{
}
{
}
{
}
class CrFbDisplayBase : public ICrFbDisplay
{
public:
CrFbDisplayBase() :
mcUpdates(0),
{}
virtual bool isComposite()
{
return false;
}
class CrFbDisplayComposite* getContainer()
{
return mpContainer;
}
bool isInList()
{
return !!mpContainer;
}
bool isUpdating()
{
return !!mcUpdates;
}
{
if (mcUpdates)
{
WARN(("trying to set framebuffer while update is in progress"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (mpFb)
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
if (mpFb)
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
struct CR_FRAMEBUFFER* getFramebuffer()
{
return mpFb;
}
{
++mcUpdates;
return VINF_SUCCESS;
}
{
--mcUpdates;
}
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
}
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (!mcUpdates)
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
virtual ~CrFbDisplayBase();
/*@todo: move to protected and switch from RTLISTNODE*/
class CrFbDisplayComposite* mpContainer;
protected:
int fbSynchAddAllEntries()
{
const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
int rc = VINF_SUCCESS;
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
break;
}
}
return rc;
}
int fbCleanupRemoveAllEntries(bool fNotifyDestroy)
{
const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
int rc = VINF_SUCCESS;
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
break;
}
if (fNotifyDestroy)
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
break;
}
}
}
return rc;
}
{
return UpdateBegin(pFb);
}
{
}
virtual int fbCleanup()
{
if (mhSlot)
{
mhSlot = 0;
}
return VINF_SUCCESS;
}
virtual int fbSync()
{
return VINF_SUCCESS;
}
{
if (!mhSlot)
{
if (mpFb)
}
return mhSlot;
}
private:
struct CR_FRAMEBUFFER *mpFb;
};
class CrFbDisplayComposite : public CrFbDisplayBase
{
public:
mcDisplays(0)
{
}
virtual bool isComposite()
{
return true;
}
{
return mcDisplays;
}
{
{
WARN(("entry in list already"));
return false;
}
pDisplay->mpContainer = this;
++mcDisplays;
return true;
}
{
if (pDisplay->getContainer() != this)
{
WARN(("invalid entry container"));
return false;
}
if (fCleanupDisplay)
--mcDisplays;
return true;
}
{
}
{
if (pDisplay->getContainer() != this)
{
WARN(("invalid entry container"));
return NULL;
}
}
{
{
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
{
}
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
virtual ~CrFbDisplayComposite()
{
cleanup();
}
void cleanup(bool fCleanupDisplays = true)
{
{
}
}
private:
};
typedef union CR_FBWIN_FLAGS
{
struct {
};
class CrFbWindow
{
public:
mSpuWindow(0),
mcUpdates(0),
mxPos(0),
myPos(0),
mWidth(0),
mHeight(0),
{
}
bool IsCreated()
{
return !!mSpuWindow;
}
void Destroy()
{
if (!mSpuWindow)
return;
mSpuWindow = 0;
mFlags.fDataPresented = 0;
}
{
if (!checkInitedUpdating())
{
WARN(("err"));
return VERR_INVALID_STATE;
}
if (!parentId)
if (mSpuWindow)
{
}
return VINF_SUCCESS;
}
int SetVisible(bool fVisible)
{
if (!checkInitedUpdating())
{
WARN(("err"));
return VERR_INVALID_STATE;
}
{
if (mSpuWindow && mParentId)
}
return VINF_SUCCESS;
}
{
if (!checkInitedUpdating())
{
WARN(("err"));
return VERR_INVALID_STATE;
}
{
if (mSpuWindow)
}
return VINF_SUCCESS;
}
{
if (!checkInitedUpdating())
{
WARN(("err"));
return VERR_INVALID_STATE;
}
LOG(("CrWIN: Pos [%d ; %d]", x, y));
{
mxPos = x;
myPos = y;
if (mSpuWindow)
}
return VINF_SUCCESS;
}
int SetVisibleRegionsChanged()
{
if (!checkInitedUpdating())
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (!checkInitedUpdating())
{
WARN(("err"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
int UpdateBegin()
{
++mcUpdates;
if (mcUpdates > 1)
return VINF_SUCCESS;
// Assert(!mFlags.fCompositoEntriesModified);
if (mFlags.fDataPresented)
{
}
return VINF_SUCCESS;
}
void UpdateEnd()
{
--mcUpdates;
if (mcUpdates)
return;
checkRegions();
if (mSpuWindow)
{
bool fPresentNeeded = isPresentNeeded();
{
mFlags.fForcePresentOnReenable = false;
}
/* even if the above branch is entered due to mFlags.fForcePresentOnReenable,
* the backend should clean up the compositor as soon as presentation is performed */
}
else
{
}
}
{
return mParentId;
}
int Create()
{
if (mSpuWindow)
{
//WARN(("window already created"));
return VINF_ALREADY_INITIALIZED;
}
if (mSpuWindow < 0) {
WARN(("WindowCreate failed"));
return VERR_GENERAL_FAILURE;
}
checkRegions();
return VINF_SUCCESS;
}
~CrFbWindow()
{
Destroy();
}
protected:
void checkRegions()
{
if (!mSpuWindow)
return;
return;
if (mpCompositor)
{
if (!RT_SUCCESS(rc))
{
cRects = 0;
}
}
else
{
cRects = 0;
}
}
bool isPresentNeeded()
{
return mFlags.fVisible && mWidth && mHeight && mpCompositor && !CrVrScrCompositorIsEmpty(mpCompositor);
}
bool checkInitedUpdating()
{
if (!mcUpdates)
{
WARN(("not updating"));
return false;
}
return true;
}
private:
const struct VBOXVR_SCR_COMPOSITOR * mpCompositor;
};
class CrFbDisplayWindow : public CrFbDisplayBase
{
public:
{
}
virtual ~CrFbDisplayWindow()
{
if (mpWindow)
delete mpWindow;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return mpWindow->UpdateBegin();
}
{
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (mpWindow->GetParentId())
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (mpWindow->GetParentId())
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (mpWindow->GetParentId())
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return mpWindow->SetVisibleRegionsChanged();
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return mpWindow->SetVisibleRegionsChanged();
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return mpWindow->SetVisibleRegionsChanged();
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return screenChanged();
}
{
if (!isUpdating())
{
WARN(("not updating!"));
return VERR_INVALID_STATE;
}
{
int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop);
if (!RT_SUCCESS(rc))
{
WARN(("SetPosition failed"));
return rc;
}
}
return VINF_SUCCESS;
}
virtual CrFbWindow * windowDetach()
{
if (isUpdating())
{
WARN(("updating!"));
return NULL;
}
if (mpWindow)
{
}
return pWindow;
}
{
if (isUpdating())
{
WARN(("updating!"));
return NULL;
}
if (mpWindow)
windowDetach();
if (pNewWindow)
windowSync();
return mpWindow;
}
{
if (!isUpdating())
{
WARN(("not updating!"));
return VERR_INVALID_STATE;
}
if (!RT_SUCCESS(rc))
WARN(("window reparent failed"));
return rc;
}
protected:
virtual int screenChanged()
{
if (!isUpdating())
{
WARN(("not updating!"));
return VERR_INVALID_STATE;
}
int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop);
if (!RT_SUCCESS(rc))
{
return rc;
}
return mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop));
}
virtual int windowCleanup()
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return VINF_SUCCESS;
}
virtual int fbCleanup()
{
int rc = windowCleanup();
if (!RT_SUCCESS(rc))
{
WARN(("windowCleanup failed"));
return rc;
}
return CrFbDisplayBase::fbCleanup();
}
virtual int windowSync()
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
rc = mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop));
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return rc;
}
virtual int fbSync()
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return windowSync();
}
virtual const struct VBOXVR_SCR_COMPOSITOR* getCompositor()
{
return CrFbGetCompositor(getFramebuffer());
}
private:
};
class CrFbDisplayWindowRootVr : public CrFbDisplayWindow
{
public:
{
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
CrVrScrCompositorEntryInit(pMyEntry, CrVrScrCompositorEntryRectGet(pSrcEntry), CrVrScrCompositorEntryTexGet(pSrcEntry), NULL);
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet());
return VINF_SUCCESS;
}
virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hNewEntry, slotGet());
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet());
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet());
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
rc = synchCompositorRegions();
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
rc = synchCompositorData();
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return VINF_SUCCESS;
}
protected:
virtual int screenChanged()
{
if (!RT_SUCCESS(rc))
{
return rc;
}
rc = synchCompositorData();
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return VINF_SUCCESS;
}
virtual int fbCleanup()
{
int rc = clearCompositor();
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return CrFbDisplayWindow::fbCleanup();
}
virtual int fbSync()
{
int rc = synchCompositor();
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return CrFbDisplayWindow::fbSync();
}
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#else
#endif
}
{
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#else
#endif
}
int synchCompositorRegions()
{
int rc;
/* ensure the rootvr compositor does not hold any data,
* i.e. cleanup all rootvr entries data */
rc = CrVrScrCompositorIntersectedList(CrFbGetCompositor(getFramebuffer()), &cr_server.RootVr, &mCompositor, rootVrGetCEntry, this, NULL);
if (!RT_SUCCESS(rc))
{
return rc;
}
return getWindow()->SetVisibleRegionsChanged();
}
int synchCompositorData()
{
int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL);
if (!RT_SUCCESS(rc))
{
return rc;
}
rc = synchCompositorRegions();
if (!RT_SUCCESS(rc))
{
return rc;
}
return rc;
}
virtual int synchCompositor()
{
int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL);
if (!RT_SUCCESS(rc))
{
return rc;
}
rc = fbSynchAddAllEntries();
if (!RT_SUCCESS(rc))
{
return rc;
}
rc = synchCompositorRegions();
if (!RT_SUCCESS(rc))
{
return rc;
}
return rc;
}
virtual int clearCompositor()
{
return fbCleanupRemoveAllEntries(true);
}
void rootVrTranslateForPos()
{
}
static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) rootVrGetCEntry(const VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext)
{
VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, pThis->slotGet());
CrVrScrCompositorEntryRectSet(&pThis->mCompositor, pMyEntry, CrVrScrCompositorEntryRectGet(pEntry));
return pMyEntry;
}
private:
};
class CrFbDisplayVrdp : public CrFbDisplayBase
{
public:
{
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return vrdpRegionsAll(pFb);
}
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
syncPos();
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return vrdpRegionsAll(pFb);
}
protected:
void syncPos()
{
}
virtual int fbCleanup()
{
int rc = fbCleanupRemoveAllEntries(true);
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return CrFbDisplayBase::fbCleanup();
}
virtual int fbSync()
{
syncPos();
int rc = fbSynchAddAllEntries();
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
return CrFbDisplayBase::fbSync();
}
protected:
{
}
{
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
const CR_BLITTER_IMG *pImg;
int rc = CrTdBltDataAcquire(pTex, GL_BGRA, !!(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS), &pImg);
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
{
}
return VINF_SUCCESS;
}
{
}
{
const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
return VINF_SUCCESS;
}
{
void *pVrdp;
/* Query supported formats. */
if (!pachFormats)
{
WARN(("crAlloc failed"));
return VERR_NO_MEMORY;
}
0 /* H3DOR_PROP_FORMATS */, // @todo from a header
if (RT_SUCCESS(rc))
{
{
&pVrdp,
"H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header
if (pVrdp)
{
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
else
}
else
{
WARN(("CRORBegin failed"));
}
}
}
else
return rc;
}
private:
};
{
if (mpContainer)
mpContainer->remove(this);
}
#if 0
{
}
{
{
crDbgDumpRect(i, &paRects[i]);
}
}
{
int rc;
int cDisplays = 0, i;
for (i = 0; i < cr_server.screenCount; ++i)
{
++cDisplays;
}
if (!cDisplays)
return VINF_SUCCESS;
for (i = 0; i < cr_server.screenCount; ++i)
{
}
for (i = 0; i < cr_server.screenCount; ++i)
{
{
}
}
return VINF_SUCCESS;
}
{
}
#endif
{
if (idScreen >= CR_MAX_GUEST_MONITORS)
{
return NULL;
}
{
}
else
}
{
if (idScreen >= CR_MAX_GUEST_MONITORS)
{
return NULL;
}
{
return NULL;
}
else
if(CrFbIsEnabled(hFb))
return hFb;
return NULL;
}
{
for (;i < cr_server.screenCount; ++i)
{
if (hFb)
return hFb;
}
return NULL;
}
{
// if (!hFb)
// WARN(("no enabled framebuffer found"));
return hFb;
}
{
}
{
if (CR_PMGR_MODE_ROOTVR & u32Mode)
return u32Mode;
}
{
if (idScreen >= CR_MAX_GUEST_MONITORS)
{
return NULL;
}
{
if (CrFbIsUpdating(hFb))
{
WARN(("trying to update viewport while framebuffer is being updated"));
return VERR_INVALID_STATE;
}
if (RT_SUCCESS(rc))
{
}
else
}
return VINF_SUCCESS;
}
{
if (idScreen >= CR_MAX_GUEST_MONITORS)
{
return VERR_INVALID_PARAMETER;
}
{
if (CrFbIsUpdating(hFb))
{
WARN(("trying to update viewport while framebuffer is being updated"));
return VERR_INVALID_STATE;
}
if (RT_SUCCESS(rc))
{
}
else
}
return VINF_SUCCESS;
}
{
if (!u32ModeRemove && !u32ModeAdd)
return VINF_SUCCESS;
if (!pInfo->pDpComposite)
{
}
if (u32ModeRemove & CR_PMGR_MODE_ROOTVR)
{
delete pInfo->pDpWinRootVr;
if (!(u32ModeRemove & CR_PMGR_MODE_WINDOW))
{
/* ensure the window is re-created */
}
}
else if (u32ModeRemove & CR_PMGR_MODE_WINDOW)
{
}
if (u32ModeRemove & CR_PMGR_MODE_VRDP)
{
if (pInfo->pDpComposite)
else
}
if (u32ModeAdd & CR_PMGR_MODE_ROOTVR)
{
if (!pOldWin)
pInfo->pDpWinRootVr = new CrFbDisplayWindowRootVr(pOldWin, &cr_server.screenVieport[idScreen].Rect);
}
else if (u32ModeAdd & CR_PMGR_MODE_WINDOW)
{
if (!pOldWin)
}
if (u32ModeAdd & CR_PMGR_MODE_VRDP)
{
}
{
}
else
{
}
if (pOldWin)
delete pOldWin;
return VINF_SUCCESS;
}
{
if (fEnable)
{
u32ModeRemove = 0;
}
else
{
u32ModeAdd = 0;
}
hFb;
{
}
return VINF_SUCCESS;
}
int CrPMgrModeVrdp(bool fEnable)
{
}
int CrPMgrModeRootVr(bool fEnable)
{
}
int CrPMgrRootVrUpdate()
{
hFb;
{
if (RT_SUCCESS(rc))
{
}
else
}
return VINF_SUCCESS;
}
/*helper function that calls CrFbUpdateBegin for all enabled framebuffers */
int CrPMgrHlpGlblUpdateBegin()
{
hFb;
{
if (!RT_SUCCESS(rc))
{
{
}
return rc;
}
}
return VINF_SUCCESS;
}
/*helper function that calls CrFbUpdateEnd for all framebuffers being updated */
void CrPMgrHlpGlblUpdateEnd()
{
{
if (CrFbIsUpdating(hFb))
}
}
/*client should notify the manager about the framebuffer resize via this function */
{
int rc = VINF_SUCCESS;
if (CrFbIsEnabled(hFb))
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
else
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
return VINF_SUCCESS;
}
{
#if 0
#endif
if (u32)
{
}
return rc;
}
{
const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
{
++u32;
}
{
{
}
}
return VINF_SUCCESS;
}
{
int rc;
int cDisplays = 0, i;
for (i = 0; i < cr_server.screenCount; ++i)
{
if (CrPMgrFbGetEnabled(i))
++cDisplays;
}
if (!cDisplays)
return VINF_SUCCESS;
for (i = 0; i < cr_server.screenCount; ++i)
{
if (hFb)
{
}
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
WARN(("CrFbEntryCreateForTexId Failed"));
return rc;
}
if (cRects)
{
}
if (pRects)
return VINF_SUCCESS;
}
{
if (!u32)
return VINF_SUCCESS;
{
}
return VINF_SUCCESS;
}
{
int rc;
int cDisplays, screenCount, i;
if (!cDisplays)
return VINF_SUCCESS;
{
for (i = 0; i < cr_server.screenCount; ++i)
{
}
}
for (i = 0; i < cDisplays; ++i)
{
int iScreen;
if (!RT_SUCCESS(rc))
{
return rc;
}
void *pvVRAM;
{
}
else
{
}
if (!RT_SUCCESS(rc))
{
return rc;
}
}
return VINF_SUCCESS;
}
crServerDispatchVBoxTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, const GLint *pRects)
{
if (idScreen >= CR_MAX_GUEST_MONITORS)
{
WARN(("Invalid guest screen"));
return;
}
if (!hFb)
{
WARN(("request to present on disabled framebuffer, ignore"));
return;
}
int rc;
if (texture)
{
rc = CrFbEntryCreateForTexId(hFb, texture, (cfg & CR_PRESENT_FLAG_TEX_NONINVERT_YCOORD) ? 0 : CRBLT_F_INVERT_SRC_YCOORDS, &hEntry);
if (!RT_SUCCESS(rc))
{
WARN(("CrFbEntryCreateForTexId Failed"));
return;
}
#if 0
if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS))
{
}
#endif
}
else
if (RT_SUCCESS(rc))
{
if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS))
{
}
else
{
}
}
else
{
WARN(("CrFbUpdateBegin Failed"));
}
if (hEntry)
}