/* $Id: server_presenter.h $ */ /** @file * Presenter API definitions. */ /* * Copyright (C) 2014-2019 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * 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. */ #ifndef __SERVER_PRESENTER_H__ #define __SERVER_PRESENTER_H__ #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 #include #include #include "render/renderspu.h" #include #include #include #include #include class ICrFbDisplay { public: virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) = 0; virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) = 0; virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) = 0; virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) = 0; virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) = 0; virtual ~ICrFbDisplay() {} }; typedef struct CR_FRAMEBUFFER { VBOXVR_SCR_COMPOSITOR Compositor; struct VBVAINFOSCREEN ScreenInfo; void *pvVram; ICrFbDisplay *pDisplay; RTLISTNODE EntriesList; uint32_t cEntries; /* <- just for debugging */ uint32_t cUpdating; CRHTABLE SlotTable; } CR_FRAMEBUFFER; typedef union CR_FBENTRY_FLAGS { struct { uint32_t fCreateNotified : 1; uint32_t fInList : 1; uint32_t Reserved : 30; }; uint32_t Value; } CR_FBENTRY_FLAGS; typedef struct CR_FRAMEBUFFER_ENTRY { VBOXVR_SCR_COMPOSITOR_ENTRY Entry; RTLISTNODE Node; uint32_t cRefs; CR_FBENTRY_FLAGS Flags; CRHTABLE HTable; } CR_FRAMEBUFFER_ENTRY; typedef struct CR_FBTEX { CR_TEXDATA Tex; CRTextureObj *pTobj; } CR_FBTEX; class CrFbDisplayBase : public ICrFbDisplay { public: CrFbDisplayBase(); virtual bool isComposite(); class CrFbDisplayComposite* getContainer(); bool isInList(); bool isUpdating(); int setRegionsChanged(); int setFramebuffer(struct CR_FRAMEBUFFER *pFb); struct CR_FRAMEBUFFER* getFramebuffer(); virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb); virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb); virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry); virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb); virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb); virtual ~CrFbDisplayBase(); /*@todo: move to protected and switch from RTLISTNODE*/ RTLISTNODE mNode; class CrFbDisplayComposite* mpContainer; protected: virtual void onUpdateEnd(); virtual void ueRegions(); static DECLCALLBACK(bool) entriesCreateCb(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry, void *pvContext); static DECLCALLBACK(bool) entriesDestroyCb(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry, void *pvContext); int fbSynchAddAllEntries(); int fbCleanupRemoveAllEntries(); virtual int setFramebufferBegin(struct CR_FRAMEBUFFER *pFb); virtual void setFramebufferEnd(struct CR_FRAMEBUFFER *pFb); static DECLCALLBACK(void) slotEntryReleaseCB(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry, void *pvContext); virtual void slotRelease(); virtual int fbCleanup(); virtual int fbSync(); CRHTABLE_HANDLE slotGet(); private: typedef union CR_FBDISPBASE_FLAGS { struct { uint32_t fRegionsShanged : 1; uint32_t Reserved : 31; }; uint32_t u32Value; } CR_FBDISPBASE_FLAGS; struct CR_FRAMEBUFFER *mpFb; uint32_t mcUpdates; CRHTABLE_HANDLE mhSlot; CR_FBDISPBASE_FLAGS mFlags; }; class CrFbDisplayComposite : public CrFbDisplayBase { public: CrFbDisplayComposite(); virtual bool isComposite(); uint32_t getDisplayCount(); bool add(CrFbDisplayBase *pDisplay); bool remove(CrFbDisplayBase *pDisplay, bool fCleanupDisplay = true); CrFbDisplayBase* first(); CrFbDisplayBase* next(CrFbDisplayBase* pDisplay); virtual int setFramebuffer(struct CR_FRAMEBUFFER *pFb); virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb); virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb); virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry); virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb); virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb); virtual ~CrFbDisplayComposite(); void cleanup(bool fCleanupDisplays = true); private: RTLISTNODE mDisplays; uint32_t mcDisplays; }; class CrFbWindow { public: CrFbWindow(uint64_t parentId); bool IsCreated() const; bool IsVisivle() const; void Destroy(); int Reparent(uint64_t parentId); int SetVisible(bool fVisible); int SetSize(uint32_t width, uint32_t height, bool fForced=false); int SetPosition(int32_t x, int32_t y, bool fForced=false); int SetVisibleRegionsChanged(); int SetCompositor(const struct VBOXVR_SCR_COMPOSITOR * pCompositor); bool SetScaleFactor(GLdouble scaleFactorW, GLdouble scaleFactorH); bool GetScaleFactor(GLdouble *scaleFactorW, GLdouble *scaleFactorH); int UpdateBegin(); void UpdateEnd(); uint64_t GetParentId(); int Create(); ~CrFbWindow(); protected: void checkRegions(); bool isPresentNeeded(); bool checkInitedUpdating(); private: typedef union CR_FBWIN_FLAGS { struct { uint32_t fVisible : 1; uint32_t fDataPresented : 1; uint32_t fForcePresentOnReenable : 1; uint32_t fCompositoEntriesModified : 1; uint32_t Reserved : 28; }; uint32_t Value; } CR_FBWIN_FLAGS; GLint mSpuWindow; const struct VBOXVR_SCR_COMPOSITOR * mpCompositor; uint32_t mcUpdates; int32_t mxPos; int32_t myPos; uint32_t mWidth; uint32_t mHeight; CR_FBWIN_FLAGS mFlags; uint64_t mParentId; RTSEMRW scaleFactorLock; GLdouble mScaleFactorWStorage; GLdouble mScaleFactorHStorage; }; class CrFbDisplayWindow : public CrFbDisplayBase { public: CrFbDisplayWindow(const RTRECT *pViewportRect, uint64_t parentId); virtual ~CrFbDisplayWindow(); virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb); virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb); virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb); virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry); virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb); const RTRECT* getViewportRect(); virtual int setViewportRect(const RTRECT *pViewportRect); virtual CrFbWindow * windowDetach(bool fCleanup = true); virtual CrFbWindow * windowAttach(CrFbWindow * pNewWindow); virtual int reparent(uint64_t parentId); virtual bool isVisible(); int winVisibilityChanged(); CrFbWindow* getWindow(); protected: virtual void onUpdateEnd(); virtual void ueRegions(); virtual int screenChanged(); virtual int windowSetCompositor(bool fSet); virtual int windowCleanup(); virtual int fbCleanup(); bool isActive(); int windowDimensionsSync(bool fForceCleanup = false); virtual int windowSync(); virtual int fbSync(); virtual const struct RTRECT* getRect(); private: typedef union CR_FBDISPWINDOW_FLAGS { struct { uint32_t fNeVisible : 1; uint32_t fNeForce : 1; uint32_t Reserved : 30; }; uint32_t u32Value; } CR_FBDISPWINDOW_FLAGS; CrFbWindow *mpWindow; RTRECT mViewportRect; CR_FBDISPWINDOW_FLAGS mFlags; uint32_t mu32Screen; uint64_t mParentId; }; class CrFbDisplayWindowRootVr : public CrFbDisplayWindow { public: CrFbDisplayWindowRootVr(const RTRECT *pViewportRect, uint64_t parentId); virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry); virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int setViewportRect(const RTRECT *pViewportRect); protected: virtual int windowSetCompositor(bool fSet); virtual void ueRegions(); int compositorMarkUpdated(); virtual int screenChanged(); virtual const struct RTRECT* getRect(); virtual int fbCleanup(); virtual int fbSync(); VBOXVR_SCR_COMPOSITOR_ENTRY* entryAlloc(); void entryFree(VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry); int synchCompositorRegions(); virtual int synchCompositor(); virtual int clearCompositor(); void rootVrTranslateForPos(); static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) rootVrGetCEntry(const VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext); private: VBOXVR_SCR_COMPOSITOR mCompositor; }; class CrFbDisplayVrdp : public CrFbDisplayBase { public: CrFbDisplayVrdp(); virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry); virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb); virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb); protected: void syncPos(); virtual int fbCleanup(); virtual int fbSync(); void vrdpDestroy(HCR_FRAMEBUFFER_ENTRY hEntry); void vrdpGeometry(HCR_FRAMEBUFFER_ENTRY hEntry); int vrdpRegions(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); int vrdpFrame(HCR_FRAMEBUFFER_ENTRY hEntry); int vrdpRegionsAll(struct CR_FRAMEBUFFER *pFb); int vrdpSynchEntry(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry); int vrdpSyncEntryAll(struct CR_FRAMEBUFFER *pFb); int vrdpCreate(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry); private: RTPOINT mPos; }; typedef struct CR_FB_INFO { CrFbDisplayComposite *pDpComposite; uint32_t u32Id; VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aTargetMap); } CR_FB_INFO; typedef struct CR_FBDISPLAY_INFO { CrFbDisplayWindow *pDpWin; CrFbDisplayWindowRootVr *pDpWinRootVr; CrFbDisplayVrdp *pDpVrdp; CrFbWindow *pWindow; uint32_t u32DisplayMode; uint32_t u32Id; int32_t iFb; /* Cache scaling factor here before display output * initialized (i.e., guest not yet initiated first 3D call). * No synchronization stuff needed here because all the reads * and writes are done in context of 3D HGCM thread. */ double dInitialScaleFactorW; double dInitialScaleFactorH; } CR_FBDISPLAY_INFO; typedef struct CR_PRESENTER_GLOBALS { #ifndef VBOXVDBG_MEMCACHE_DISABLE RTMEMCACHE FbEntryLookasideList; RTMEMCACHE FbTexLookasideList; RTMEMCACHE CEntryLookasideList; #endif uint32_t u32DisplayMode; uint32_t u32DisabledDisplayMode; bool fEnabled; CRHashTable *pFbTexMap; CR_FBDISPLAY_INFO aDisplayInfos[CR_MAX_GUEST_MONITORS]; CR_FBMAP FramebufferInitMap; CR_FRAMEBUFFER aFramebuffers[CR_MAX_GUEST_MONITORS]; CR_FB_INFO aFbInfos[CR_MAX_GUEST_MONITORS]; bool fWindowsForceHidden; uint32_t cbTmpBuf; void *pvTmpBuf; uint32_t cbTmpBuf2; void *pvTmpBuf2; } CR_PRESENTER_GLOBALS; extern CR_PRESENTER_GLOBALS g_CrPresenter; HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry); #endif /* __SERVER_PRESENTER_H__ */