diff options
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/include/cr_server.h')
| -rw-r--r-- | src/VBox/GuestHost/OpenGL/include/cr_server.h | 287 |
1 files changed, 261 insertions, 26 deletions
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_server.h b/src/VBox/GuestHost/OpenGL/include/cr_server.h index 027354a2..b215d4cb 100644 --- a/src/VBox/GuestHost/OpenGL/include/cr_server.h +++ b/src/VBox/GuestHost/OpenGL/include/cr_server.h @@ -12,19 +12,28 @@ #include "cr_hash.h" #include "cr_protocol.h" #include "cr_glstate.h" +#include "cr_vreg.h" +#include "cr_blitter.h" #include "spu_dispatch_table.h" +#include "cr_dump.h" #include "state/cr_currentpointers.h" #include <iprt/types.h> #include <iprt/err.h> #include <iprt/string.h> +#include <iprt/list.h> +#include <iprt/thread.h> +#include <iprt/critsect.h> +#include <iprt/semaphore.h> +#include <iprt/memcache.h> #include <VBox/vmm/ssm.h> -#ifdef VBOX_WITH_CRHGSMI -# include <VBox/VBoxVideo.h> -#endif +#include <VBox/VBoxVideo.h> +#include <VBox/Hardware/VBoxVideoVBE.h> +#include <VBox/VBoxVideo3D.h> +#include <VBox/VBoxVideoHost3D.h> #ifdef __cplusplus extern "C" { @@ -34,7 +43,7 @@ extern "C" { #define CR_MAX_CLIENTS 64 /*@todo must match MaxGuestMonitors from SchemaDefs.h*/ -#define CR_MAX_GUEST_MONITORS 8 +#define CR_MAX_GUEST_MONITORS VBOX_VIDEO_MAX_SCREENS typedef DECLCALLBACKPTR(void, PFNCRSERVERPRESENTFBO) (void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h); @@ -54,7 +63,7 @@ typedef struct { DECLR3CALLBACKMEMBER(void, CRORGeometry, (void *pvInstance, int32_t x, int32_t y, uint32_t w, uint32_t h)); DECLR3CALLBACKMEMBER(void, CRORVisibleRegion, (void *pvInstance, - uint32_t cRects, RTRECT *paRects)); + uint32_t cRects, const RTRECT *paRects)); DECLR3CALLBACKMEMBER(void, CRORFrame, (void *pvInstance, void *pvData, uint32_t cbData)); DECLR3CALLBACKMEMBER(void, CROREnd, (void *pvInstance)); @@ -75,6 +84,140 @@ typedef struct { struct BucketingInfo; +typedef struct { + char *pszDpyName; + GLint visualBits; + int32_t externalID; +} CRCreateInfo_t; + +typedef struct { + char *pszDpyName; + int32_t externalID; + GLint requestedVisualBits; + GLint realVisualBits; +} CRCreateInfoEx_t; + +/* VRAM->RAM worker thread */ + +typedef enum +{ + CR_SERVER_RPW_STATE_UNINITIALIZED = 0, + CR_SERVER_RPW_STATE_INITIALIZING, + CR_SERVER_RPW_STATE_INITIALIZED, + CR_SERVER_RPW_STATE_UNINITIALIZING, +} CR_SERVER_RPW_STATE; + +/* worker control command */ +typedef enum +{ + CR_SERVER_RPW_CTL_TYPE_UNDEFINED = 0, + CR_SERVER_RPW_CTL_TYPE_WAIT_COMPLETE, + CR_SERVER_RPW_CTL_TYPE_TERM +} CR_SERVER_RPW_CTL_TYPE; + +struct CR_SERVER_RPW_ENTRY; + +typedef struct CR_SERVER_RPW_CTL { + CR_SERVER_RPW_CTL_TYPE enmType; + int rc; + RTSEMEVENT hCompleteEvent; + /* valid for *_WAIT_COMPLETE and *_CANCEL */ + struct CR_SERVER_RPW_ENTRY *pEntry; +} CR_SERVER_RPW_CTL; + + +struct CR_SERVER_RPW_ENTRY; + +typedef DECLCALLBACKPTR(void, PFNCR_SERVER_RPW_DATA) (const struct CR_SERVER_RPW_ENTRY* pEntry, void *pvEntryTexData); + +typedef DECLCALLBACKPTR(void, PFNCRSERVERNOTIFYEVENT) (int32_t screenId, uint32_t uEvent, void*pvData); + +typedef struct CR_SERVER_RPW_ENTRY +{ + RTRECTSIZE Size; + /* We have to use 4 textures here. + * + * 1. iDrawTex - the texture clients can draw to and then submit it for contents acquisition via crServerRpwEntrySubmit + * 2. iSubmittedTex - the texture submitted to the worker for processing and, whose processing has not start yet, + * i.e. it is being in the queue and can be safely removed/replaced [from] there + * 3. iWorkerTex - the texture being prepared & passed by the worker to the GPU (stage 1 of a worker contents acquisition process) + * 4. iGpuTex - the texture passed/processed to/by the GPU, whose data is then acquired by the server (stage 2 of a worker contents acquisition process) + * + * - There can be valid distinct iGpuTex, iWorkerTex, iSubmittedTex and iDrawTex present simultaneously. + * - Either or both of iSubmittedTex and iFreeTex are always valid + * + * Detail: + * + * - iSubmittedTex and iFreeTex modifications are performed under CR_SERVER_RPW::CritSect lock. + * + * - iDrawTex can only be changed by client side (i.e. the crServerRpwEntrySubmit caller), this is why client thread can access it w/o a lock + * - iSubmittedTex and iFreeTex can be modified by both client and worker, so lock is always required + * + * - iDrawTex can be accessed by client code only + * - iWorkerTex and iGpuTex can be accessed by worker code only + * - iSubmittedTex and iFreeTex can be accessed under CR_SERVER_RPW::CritSect lock only + * - either or both of iSubmittedTex and iFreeTex are always valid (see below for more explanation), + * this is why client can easily determine the new iDrawTex value on Submit, i.e. : + * + * (if initial iSubmittedTex was valid) + * --------------- + * | ^ + * > | + * Submit-> iDrawTex -> iSubmittedTex + * ^ + * | (if initial iSubmittedTex was NOT valid) + * iFreeTex + * + * - The worker can invalidate the iSubmittedTex (i.e. do iSubmittedTex -> iWorkerTex) only after it is done + * with the last iWorkerTex -> iGpuTex transformation freeing the previously used iGpuTex to iFreeTex. + * + * - A simplified worker iXxxTex transformation logic is: + * 1. iFreeTex is initially valid + * 2. iSubmittedTex -> iWorkerTex; + * 3. submit iWorkerTex acquire request to the GPU + * 4. complete current iGpuTex + * 5. iGpuTex -> iFreeTex + * 6. iWorkerTex -> iGpuTex + * 7. goto 1 + * + * */ + int8_t iTexDraw; + int8_t iTexSubmitted; + int8_t iTexWorker; + int8_t iTexGpu; + int8_t iCurPBO; + GLuint aidWorkerTexs[4]; + GLuint aidPBOs[2]; + RTLISTNODE WorkEntry; + RTLISTNODE WorkerWorkEntry; + RTLISTNODE GpuSubmittedEntry; + PFNCR_SERVER_RPW_DATA pfnData; +} CR_SERVER_RPW_ENTRY; + +typedef struct CR_SERVER_RPW { + RTLISTNODE WorkList; + RTCRITSECT CritSect; + RTSEMEVENT hSubmitEvent; + /* only one outstanding command is supported, + * and ctl requests must be cynchronized, hold it right here */ + CR_SERVER_RPW_CTL Ctl; + int ctxId; + GLint ctxVisBits; + RTTHREAD hThread; +} CR_SERVER_RPW; +/* */ + +/* FRAMEBUFFER */ +typedef struct CR_FRAMEBUFFER *HCR_FRAMEBUFFER; +typedef struct CR_FRAMEBUFFER_ENTRY *HCR_FRAMEBUFFER_ENTRY; +/* */ + +typedef struct CR_FBDATA +{ + HCR_FRAMEBUFFER hFb; + HCR_FRAMEBUFFER_ENTRY hFbEntry; + CR_TEXDATA* apTexDatas[2]; +} CR_FBDATA; /** * Mural info */ @@ -88,30 +231,55 @@ typedef struct { int screenId; GLboolean bVisible; /*guest window is visible*/ - GLboolean bUseFBO; /*redirect to FBO instead of real host window*/ + GLubyte u8Unused; /*redirect to FBO instead of real host window*/ GLboolean bFbDraw; /*GL_FRONT buffer is drawn to directly*/ + GLboolean fIsDummyRefference; GLint cVisibleRects; /*count of visible rects*/ GLint *pVisibleRects; /*visible rects left, top, right, bottom*/ GLboolean bReceivedRects; /*indicates if guest did any updates for visible regions*/ - GLuint idFBO, idColorTex, idDepthStencilRB; + GLuint cBuffers; + GLuint iBbBuffer; + GLuint aidFBOs[2]; + GLuint aidColorTexs[2]; + + void *pvReserved; + + CRCreateInfoEx_t CreateInfo; + + /* to avoid saved state breakage we need to keep RT_OFFSETOF(CRMuralInfo, CreateInfo) intact + * this is why we place some FBO stuff to the tail + * @todo: once we need to increment a saved state version, we could refactor this structure */ + GLint iCurDrawBuffer; + GLint iCurReadBuffer; + + GLuint idDepthStencilRB; GLuint fboWidth, fboHeight; - GLuint idPBO; - void *pvOutputRedirectInstance; -} CRMuralInfo; + GLboolean fHasParentWindow; -typedef struct { - char *pszDpyName; - GLint visualBits; - int32_t externalID; -} CRCreateInfo_t; + GLboolean fRedirected; + GLboolean fForcePresentState; + GLboolean fOrPresentOnReenable; + + GLboolean fIsVisible; + + CR_TEXDATA aTexs[2]; + uint32_t cUsedFBDatas; + CR_FBDATA *apUsedFBDatas[CR_MAX_GUEST_MONITORS]; + CR_FBDATA aFBDatas[CR_MAX_GUEST_MONITORS]; + + /* bitfield representing contexts the mural has been ever current with + * we just reuse CR_STATE_SHAREDOBJ_USAGE_XXX API here for simplicity */ + CRbitvalue ctxUsage[CR_MAX_BITARRAY]; +} CRMuralInfo; typedef struct { CRContext *pContext; int SpuContext; - CRCreateInfo_t CreateInfo; + CRCreateInfoEx_t CreateInfo; + CRMuralInfo * currentMural; } CRContextInfo; /** @@ -168,10 +336,15 @@ typedef struct { } CRScreenInfo; typedef struct { - int32_t x, y; - uint32_t w, h; + RTRECT Rect; } CRScreenViewportInfo; +/* BFB (BlitFramebuffer Blitter) flags + * so far only CR_SERVER_BFB_ON_ALWAIS is supported and is alwais used if any flag is set */ +#define CR_SERVER_BFB_DISABLED 0 +#define CR_SERVER_BFB_ON_INVERTED_BLIT 1 +#define CR_SERVER_BFB_ON_STRAIGHT_BLIT 2 +#define CR_SERVER_BFB_ON_ALWAIS (CR_SERVER_BFB_ON_INVERTED_BLIT | CR_SERVER_BFB_ON_STRAIGHT_BLIT) typedef struct { unsigned short tcpip_port; @@ -194,14 +367,12 @@ typedef struct { CRContextInfo *currentCtxInfo; GLint currentWindow; GLint currentNativeWindow; + CRMuralInfo *currentMural; CRHashTable *muralTable; /**< hash table where all murals are stored */ - CRHashTable *pWindowCreateInfoTable; /**< hash table with windows creation info */ int client_spu_id; - CRServerFreeIDsPool_t idsPool; - int mtu; int buffer_size; char protocol[1024]; @@ -221,6 +392,23 @@ typedef struct { CRHashTable *programTable; /**< for vertex programs */ GLuint currentProgram; + /* visBits -> dummy mural association */ + CRHashTable *dummyMuralTable; + + GLboolean fRootVrOn; + VBOXVR_LIST RootVr; + /* we need to translate Root Vr to each window coords, this one cpecifies the current translation point + * note that since window attributes modifications is performed in HGCM thread only and thus is serialized, + * we deal with the global RootVr data directly */ + RTPOINT RootVrCurPoint; + + /* blitter so far used for working around host drivers BlitFramebuffer bugs + * by implementing */ + uint32_t fBlitterMode; + CR_BLITTER Blitter; + + CR_SERVER_RPW RpwWorker; + /** configuration options */ /*@{*/ int useL2; @@ -276,14 +464,38 @@ typedef struct { GLuint currentSerialNo; PFNCRSERVERPRESENTFBO pfnPresentFBO; - GLboolean bForceOffscreenRendering; /*Force server to render 3d data offscreen - *using callback above to update vbox framebuffers*/ + + GLuint fVisualBitsDefault; GLboolean bUsePBOForReadback; /*Use PBO's for data readback*/ - GLboolean bUseOutputRedirect; /* Whether the output redirect was set. */ CROutputRedirect outputRedirect; GLboolean bUseMultipleContexts; + + GLboolean bWindowsInitiallyHidden; + + /* OR-ed CR_VBOX_CAP_XXX cap values + * describing VBox Chromium functionality caps visible to guest + * Currently can have only CR_VBOX_CAP_TEX_PRESENT cap to notify + * that the TexPresent mechanism is available and enabled */ + uint32_t u32Caps; + + PFNCRSERVERNOTIFYEVENT pfnNotifyEventCB; + + SPUDispatchTable TmpCtxDispatch; + + VBOXCRCMD_SVRENABLE_INFO CrCmdClientInfo; + +#ifdef VBOX_WITH_CRSERVER_DUMPER + CR_RECORDER Recorder; + CR_BLITTER RecorderBlitter; + CR_DBGPRINT_DUMPER DbgPrintDumper; + CR_HTML_DUMPER HtmlDumper; + CR_DUMPER *pDumper; +#endif + + int RcToGuest; + int RcToGuestOnce; } CRServer; @@ -301,16 +513,31 @@ extern DECLEXPORT(void) crVBoxServerRemoveClient(uint32_t u32ClientID); extern DECLEXPORT(int32_t) crVBoxServerClientWrite(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t cbBuffer); extern DECLEXPORT(int32_t) crVBoxServerClientRead(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t *pcbBuffer); extern DECLEXPORT(int32_t) crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor); +extern DECLEXPORT(int32_t) crVBoxServerClientGetCaps(uint32_t u32ClientID, uint32_t *pu32Caps); extern DECLEXPORT(int32_t) crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid); extern DECLEXPORT(int32_t) crVBoxServerSaveState(PSSMHANDLE pSSM); extern DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version); +typedef struct +{ + CR_BLITTER_IMG Img; + uint32_t u32Screen; + uint32_t fDataAllocated; +} CR_SCREENSHOT; + +extern DECLEXPORT(int) crServerVBoxWindowsShow(bool fShow); +extern DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, uint32_t height, uint32_t pitch, void *pvBuffer, CR_SCREENSHOT *pScreenshot); +extern DECLEXPORT(void) crServerVBoxScreenshotRelease(CR_SCREENSHOT *pScreenshot); + +extern DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable); extern DECLEXPORT(int32_t) crVBoxServerSetScreenCount(int sCount); extern DECLEXPORT(int32_t) crVBoxServerUnmapScreen(int sIndex); extern DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID); - -extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, GLint *pRects); +extern DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable); +struct VBVAINFOSCREEN; +extern DECLEXPORT(int) crVBoxServerNotifyResize(const struct VBVAINFOSCREEN *pScreen, void *pvVRAM); +extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, const RTRECT *pRects); extern DECLEXPORT(void) crVBoxServerSetPresentFBOCB(PFNCRSERVERPRESENTFBO pfnPresentFBO); @@ -320,6 +547,8 @@ extern DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect extern DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h); +extern DECLEXPORT(void) crServerVBoxSetNotifyEventCB(PFNCRSERVERNOTIFYEVENT pfnCb); + #ifdef VBOX_WITH_CRHGSMI /* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place. * @@ -336,8 +565,14 @@ extern DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, * */ extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd); extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t cbCtl); + #endif +extern DECLEXPORT(int32_t) crVBoxServerHgcmEnable(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd); +extern DECLEXPORT(int32_t) crVBoxServerHgcmDisable(); + +extern int crVBoxServerHostCtl(VBOXCRCMDCTL *pCtl, uint32_t cbCtl); + #ifdef __cplusplus } #endif |
