summaryrefslogtreecommitdiffstats
path: root/src/VBox/GuestHost/OpenGL/include/cr_blitter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/include/cr_blitter.h')
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_blitter.h377
1 files changed, 377 insertions, 0 deletions
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_blitter.h b/src/VBox/GuestHost/OpenGL/include/cr_blitter.h
new file mode 100644
index 00000000..86332992
--- /dev/null
+++ b/src/VBox/GuestHost/OpenGL/include/cr_blitter.h
@@ -0,0 +1,377 @@
+/* $Id: cr_blitter.h $ */
+/** @file
+ * Blitter API.
+ */
+
+/*
+ * Copyright (C) 2013-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 ___cr_blitter_h
+#define ___cr_blitter_h
+
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/string.h>
+#include "cr_vreg.h"
+#ifdef IN_VMSVGA3D
+# include <iprt/assert.h>
+typedef struct TODO_VMSVGA3D_DISPATCH_TABLE SPUDispatchTable;
+# include <OpenGL/OpenGL.h>
+#else
+# include "cr_spu.h"
+#endif
+
+/** @todo r=bird: VBOXBLITTERDECL makes no sense. */
+#ifndef IN_RING0
+# define VBOXBLITTERDECL(_type) DECLEXPORT(_type)
+#else
+# define VBOXBLITTERDECL(_type) RTDECL(_type)
+#endif
+
+RT_C_DECLS_BEGIN
+typedef struct CR_BLITTER_IMG
+{
+ void *pvData;
+ GLuint cbData;
+ GLenum enmFormat;
+ GLuint width, height;
+ GLuint bpp;
+ GLuint pitch;
+} CR_BLITTER_IMG;
+typedef CR_BLITTER_IMG *PCR_BLITTER_IMG;
+typedef CR_BLITTER_IMG const *PCCR_BLITTER_IMG;
+
+VBOXBLITTERDECL(void) CrMClrFillImgRect(PCR_BLITTER_IMG pDst, PCRTRECT pCopyRect, uint32_t u32Color);
+VBOXBLITTERDECL(void) CrMClrFillImg(PCR_BLITTER_IMG pImg, uint32_t cRects, PCRTRECT pRects, uint32_t u32Color);
+VBOXBLITTERDECL(void) CrMBltImgRect(PCCR_BLITTER_IMG pSrc, PCRTPOINT pSrcDataPoint, bool fSrcInvert, PCRTRECT pCopyRect,
+ PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrMBltImg(PCCR_BLITTER_IMG pSrc, PCRTPOINT pPos, uint32_t cRects, PCRTRECT pRects, PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrMBltImgRectScaled(PCCR_BLITTER_IMG pSrc, PCRTPOINT pPos, bool fSrcInvert, PCRTRECT pCopyRect,
+ float strX, float strY, PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrMBltImgScaled(PCCR_BLITTER_IMG pSrc, PCRTRECTSIZE pSrcRectSize, PCRTRECT pDstRect, uint32_t cRects,
+ PCRTRECT pRects, PCR_BLITTER_IMG pDst);
+
+/*
+ * GLSL Cache
+ */
+typedef struct CR_GLSL_CACHE
+{
+ int iGlVersion;
+ GLuint uNoAlpha2DProg;
+ GLuint uNoAlpha2DRectProg;
+ SPUDispatchTable *pDispatch;
+} CR_GLSL_CACHE;
+typedef CR_GLSL_CACHE *PCR_GLSL_CACHE;
+typedef CR_GLSL_CACHE const *PCCR_GLSL_CACHE;
+
+DECLINLINE(void) CrGlslInit(PCR_GLSL_CACHE pCache, SPUDispatchTable *pDispatch)
+{
+ RT_ZERO(*pCache);
+ pCache->pDispatch = pDispatch;
+}
+
+DECLINLINE(bool) CrGlslIsInited(PCCR_GLSL_CACHE pCache)
+{
+ return !!pCache->pDispatch;
+}
+
+/* clients should set proper context before calling these funcs */
+VBOXBLITTERDECL(bool) CrGlslIsSupported(PCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(int) CrGlslProgGenAllNoAlpha(PCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(int) CrGlslProgGenNoAlpha(PCR_GLSL_CACHE pCache, GLenum enmTexTarget);
+VBOXBLITTERDECL(int) CrGlslProgUseGenNoAlpha(PCR_GLSL_CACHE pCache, GLenum enmTexTarget);
+VBOXBLITTERDECL(int) CrGlslProgUseNoAlpha(PCCR_GLSL_CACHE pCache, GLenum enmTexTarget);
+VBOXBLITTERDECL(void) CrGlslProgClear(PCCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(bool) CrGlslNeedsCleanup(PCCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(void) CrGlslCleanup(PCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(void) CrGlslTerm(PCR_GLSL_CACHE pCache);
+
+/*
+ * BLITTER
+ */
+typedef struct CR_BLITTER_BUFFER
+{
+ GLuint cbBuffer;
+ GLvoid *pvBuffer;
+} CR_BLITTER_BUFFER;
+typedef CR_BLITTER_BUFFER *PCR_BLITTER_BUFFER;
+typedef CR_BLITTER_BUFFER const *PCCR_BLITTER_BUFFER;
+
+typedef union CR_BLITTER_FLAGS
+{
+ struct
+ {
+ uint32_t Initialized : 1;
+ uint32_t CtxCreated : 1;
+ uint32_t SupportsFBO : 1;
+ uint32_t SupportsPBO : 1;
+ uint32_t CurrentMuralChanged : 1;
+ uint32_t LastWasFBODraw : 1;
+ uint32_t ForceDrawBlit : 1;
+ uint32_t ShadersGloal : 1;
+ uint32_t Reserved : 24;
+ };
+ uint32_t Value;
+} CR_BLITTER_FLAGS;
+
+struct CR_BLITTER;
+
+typedef DECLCALLBACK(int) FNCRBLT_BLITTER(struct CR_BLITTER *pBlitter, PCVBOXVR_TEXTURE pSrc, PCRTRECT paSrcRect,
+ PCRTRECTSIZE pDstSize, PCRTRECT paDstRect, uint32_t cRects, uint32_t fFlags);
+typedef FNCRBLT_BLITTER *PFNCRBLT_BLITTER;
+
+typedef struct CR_BLITTER_SPUITEM
+{
+ int id;
+ GLint visualBits;
+} CR_BLITTER_SPUITEM, *PCR_BLITTER_SPUITEM;
+
+typedef struct CR_BLITTER_CONTEXT
+{
+ CR_BLITTER_SPUITEM Base;
+} CR_BLITTER_CONTEXT;
+typedef CR_BLITTER_CONTEXT *PCR_BLITTER_CONTEXT;
+typedef CR_BLITTER_CONTEXT const *PCCR_BLITTER_CONTEXT;
+
+typedef struct CR_BLITTER_WINDOW
+{
+ CR_BLITTER_SPUITEM Base;
+ GLuint width, height;
+} CR_BLITTER_WINDOW;
+typedef CR_BLITTER_WINDOW *PCR_BLITTER_WINDOW;
+typedef CR_BLITTER_WINDOW const *PCCR_BLITTER_WINDOW;
+
+typedef struct CR_BLITTER
+{
+ GLuint idFBO;
+ CR_BLITTER_FLAGS Flags;
+ uint32_t cEnters;
+ PFNCRBLT_BLITTER pfnBlt;
+ CR_BLITTER_BUFFER Verticies;
+ CR_BLITTER_BUFFER Indicies;
+ RTRECTSIZE CurrentSetSize;
+ CR_BLITTER_WINDOW CurrentMural;
+ CR_BLITTER_CONTEXT CtxInfo;
+ int32_t i32MakeCurrentUserData;
+ SPUDispatchTable *pDispatch;
+ PCCR_GLSL_CACHE pGlslCache;
+ CR_GLSL_CACHE LocalGlslCache;
+} CR_BLITTER;
+typedef CR_BLITTER *PCR_BLITTER;
+typedef CR_BLITTER const *PCCR_BLITTER;
+
+DECLINLINE(GLboolean) CrBltIsInitialized(PCR_BLITTER pBlitter)
+{
+ return !!pBlitter->pDispatch;
+}
+
+VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, PCCR_BLITTER_CONTEXT pCtxBase, bool fCreateNewCtx,
+ bool fForceDrawBlt, PCCR_GLSL_CACHE pShaders, SPUDispatchTable *pDispatch);
+
+VBOXBLITTERDECL(void) CrBltTerm(PCR_BLITTER pBlitter);
+
+VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter);
+
+DECLINLINE(GLboolean) CrBltSupportsTexTex(PCR_BLITTER pBlitter)
+{
+ return pBlitter->Flags.SupportsFBO;
+}
+
+DECLINLINE(GLboolean) CrBltIsEntered(PCR_BLITTER pBlitter)
+{
+ return !!pBlitter->cEnters;
+}
+
+DECLINLINE(GLint) CrBltGetVisBits(PCR_BLITTER pBlitter)
+{
+ return pBlitter->CtxInfo.Base.visualBits;
+}
+
+
+DECLINLINE(GLboolean) CrBltIsEverEntered(PCR_BLITTER pBlitter)
+{
+ return !!pBlitter->Flags.Initialized;
+}
+
+DECLINLINE(void) CrBltSetMakeCurrentUserData(PCR_BLITTER pBlitter, int32_t i32MakeCurrentUserData)
+{
+ pBlitter->i32MakeCurrentUserData = i32MakeCurrentUserData;
+}
+
+VBOXBLITTERDECL(int) CrBltMuralSetCurrentInfo(PCR_BLITTER pBlitter, PCCR_BLITTER_WINDOW pMural);
+
+DECLINLINE(PCCR_BLITTER_WINDOW) CrBltMuralGetCurrentInfo(PCR_BLITTER pBlitter)
+{
+ return &pBlitter->CurrentMural;
+}
+
+VBOXBLITTERDECL(void) CrBltCheckUpdateViewport(PCR_BLITTER pBlitter);
+
+VBOXBLITTERDECL(void) CrBltLeave(PCR_BLITTER pBlitter);
+VBOXBLITTERDECL(int) CrBltEnter(PCR_BLITTER pBlitter);
+VBOXBLITTERDECL(void) CrBltBlitTexMural(PCR_BLITTER pBlitter, bool fBb, PCVBOXVR_TEXTURE pSrc, PCRTRECT paSrcRects,
+ PCRTRECT paDstRects, uint32_t cRects, uint32_t fFlags);
+VBOXBLITTERDECL(void) CrBltBlitTexTex(PCR_BLITTER pBlitter, PCVBOXVR_TEXTURE pSrc, PCRTRECT pSrcRect, PCVBOXVR_TEXTURE pDst,
+ PCRTRECT pDstRect, uint32_t cRects, uint32_t fFlags);
+VBOXBLITTERDECL(int) CrBltImgGetTex(PCR_BLITTER pBlitter, PCVBOXVR_TEXTURE pSrc, GLenum enmFormat, PCR_BLITTER_IMG pDst);
+
+VBOXBLITTERDECL(int) CrBltImgGetMural(PCR_BLITTER pBlitter, bool fBb, PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrBltImgFree(PCR_BLITTER pBlitter, PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrBltPresent(PCR_BLITTER pBlitter);
+/* */
+struct CR_TEXDATA;
+
+typedef DECLCALLBACK(void) FNCRTEXDATA_RELEASED(struct CR_TEXDATA *pTexture);
+typedef FNCRTEXDATA_RELEASED *PFNCRTEXDATA_RELEASED;
+
+typedef union CR_TEXDATA_FLAGS
+{
+ struct
+ {
+ uint32_t DataValid : 1;
+ uint32_t DataAcquired : 1;
+ uint32_t DataInverted : 1;
+ uint32_t Entered : 1;
+ uint32_t Reserved : 28;
+ };
+ uint32_t Value;
+} CR_TEXDATA_FLAGS;
+
+
+typedef struct CR_TEXDATA
+{
+ VBOXVR_TEXTURE Tex;
+ volatile uint32_t cRefs;
+ /* fields specific to texture data download */
+ uint32_t idInvertTex;
+ uint32_t idPBO;
+ CR_TEXDATA_FLAGS Flags;
+ PCR_BLITTER pBlitter;
+ CR_BLITTER_IMG Img;
+ /*dtor*/
+ PFNCRTEXDATA_RELEASED pfnTextureReleased;
+ struct CR_TEXDATA *pScaledCache;
+} CR_TEXDATA;
+typedef CR_TEXDATA *PCR_TEXDATA;
+typedef CR_TEXDATA const *PCCR_TEXDATA;
+
+DECLINLINE(void) CrTdInit(PCR_TEXDATA pTex, PCVBOXVR_TEXTURE pVrTex, PCR_BLITTER pBlitter, PFNCRTEXDATA_RELEASED pfnTextureReleased)
+{
+ memset(pTex, 0, sizeof (*pTex));
+ pTex->Tex = *pVrTex;
+ pTex->cRefs = 1;
+ pTex->pBlitter = pBlitter;
+ pTex->pfnTextureReleased = pfnTextureReleased;
+}
+
+DECLINLINE(PCVBOXVR_TEXTURE) CrTdTexGet(PCCR_TEXDATA pTex)
+{
+ return &pTex->Tex;
+}
+
+DECLINLINE(PCR_BLITTER) CrTdBlitterGet(PCR_TEXDATA pTex)
+{
+ return pTex->pBlitter;
+}
+
+DECLINLINE(int) CrTdBltEnter(PCR_TEXDATA pTex)
+{
+ int rc;
+ if (pTex->Flags.Entered)
+ return VERR_INVALID_STATE;
+ rc = CrBltEnter(pTex->pBlitter);
+#ifdef IN_VMSVGA3D
+ AssertRCReturn(rc, rc);
+#else
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("CrBltEnter failed rc %d", rc));
+ return rc;
+ }
+#endif
+ pTex->Flags.Entered = 1;
+ return VINF_SUCCESS;
+}
+
+DECLINLINE(bool) CrTdBltIsEntered(PCR_TEXDATA pTex)
+{
+ return pTex->Flags.Entered;
+}
+
+DECLINLINE(void) CrTdBltLeave(PCR_TEXDATA pTex)
+{
+#ifdef IN_VMSVGA3D
+ AssertReturnVoid(pTex->Flags.Entered);
+#else
+ if (!pTex->Flags.Entered)
+ {
+ WARN(("invalid Blt Leave"));
+ return;
+ }
+#endif
+
+ CrBltLeave(pTex->pBlitter);
+
+ pTex->Flags.Entered = 0;
+}
+
+/* the CrTdBltXxx calls are done with the entered blitter */
+/** Acquire the texture data, returns the cached data in case it is cached.
+ * The data remains cached in the CR_TEXDATA object until it is discarded with
+ * CrTdBltDataFree or CrTdBltDataCleanup. */
+VBOXBLITTERDECL(int) CrTdBltDataAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, PCCR_BLITTER_IMG *ppImg);
+
+VBOXBLITTERDECL(int) CrTdBltDataAcquireScaled(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted,
+ uint32_t width, uint32_t height, PCCR_BLITTER_IMG *ppImg);
+
+VBOXBLITTERDECL(int) CrTdBltDataReleaseScaled(PCR_TEXDATA pTex, PCCR_BLITTER_IMG pImg);
+
+VBOXBLITTERDECL(void) CrTdBltScaleCacheMoveTo(PCR_TEXDATA pTex, PCR_TEXDATA pDstTex);
+
+/** Release the texture data, the data remains cached in the CR_TEXDATA object
+ * until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup. */
+VBOXBLITTERDECL(int) CrTdBltDataRelease(PCR_TEXDATA pTex);
+/** Discard the texture data cached with previous CrTdBltDataAcquire.
+ * Must be called wit data released (CrTdBltDataRelease). */
+VBOXBLITTERDECL(int) CrTdBltDataFree(PCR_TEXDATA pTex);
+VBOXBLITTERDECL(int) CrTdBltDataFreeNe(PCR_TEXDATA pTex);
+VBOXBLITTERDECL(void) CrTdBltDataInvalidateNe(PCR_TEXDATA pTex);
+/** Does same as CrTdBltDataFree, and in addition cleans up.
+ * This is kind of a texture destructor, which clients should call on texture object destruction,
+ * e.g. from the PFNCRTEXDATA_RELEASED callback. */
+VBOXBLITTERDECL(int) CrTdBltDataCleanup(PCR_TEXDATA pTex);
+
+VBOXBLITTERDECL(int) CrTdBltDataCleanupNe(PCR_TEXDATA pTex);
+
+DECLINLINE(uint32_t) CrTdAddRef(PCR_TEXDATA pTex)
+{
+ return ASMAtomicIncU32(&pTex->cRefs);
+}
+
+DECLINLINE(uint32_t) CrTdRelease(PCR_TEXDATA pTex)
+{
+ uint32_t cRefs = ASMAtomicDecU32(&pTex->cRefs);
+ if (!cRefs)
+ {
+ if (pTex->pfnTextureReleased)
+ pTex->pfnTextureReleased(pTex);
+ else
+ CrTdBltDataCleanupNe(pTex);
+ }
+
+ return cRefs;
+}
+
+RT_C_DECLS_END
+
+#endif
+