blitter.cpp revision 8d1da51eb6665874aa82bf03668e03d1a0d63223
* available from http://www.virtualbox.org. This file is free software;
#include "cr_blitter.h"
#include "cr_spu.h"
#include "chromium.h"
#include "cr_error.h"
#include "cr_net.h"
#include "cr_rand.h"
#include "cr_mem.h"
#include "cr_string.h"
/* @param pCtxBase - contains the blitter context info. Its value is treated differently depending on the fCreateNewCtx value
* @param fCreateNewCtx - if true - the pCtxBase must NOT be NULL. its visualBits is used as a visual bits info for the new context,
* Also note that blitter caches the current window info, and assumes the current context's values are preserved
* the blitter current window values must be explicitly reset by doing CrBltMuralSetCurrent(pBlitter, NULL)
* @param fForceDrawBlt - if true - forces the blitter to always use glDrawXxx-based blits even if GL_EXT_framebuffer_blit.
* This is needed because BlitFramebufferEXT is known to be often buggy, and glDrawXxx-based blits appear to be more reliable
VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, bool fForceDrawBlt, const CR_GLSL_CACHE *pShaders, SPUDispatchTable *pDispatch)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (pCtxBase)
if (fCreateNewCtx)
pBlitter->CtxInfo.Base.id = pDispatch->CreateContext("", pCtxBase->Base.visualBits, pCtxBase->Base.id);
return VERR_GENERAL_FAILURE;
if (pShaders)
return VINF_SUCCESS;
VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural)
return VERR_INVALID_STATE;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
if (pMural)
return VINF_SUCCESS;
return VERR_INVALID_STATE;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_INVALID_STATE;
pBlitter->pDispatch->MakeCurrent(pMural->Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
return VINF_SUCCESS;
static DECLCALLBACK(int) crBltBlitTexBufImplFbo(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
pBlitter->pDispatch->FramebufferTexture2DEXT(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pSrc->target, pSrc->hwid, 0);
return VINF_SUCCESS;
DECLINLINE(GLfloat*) crBltVtRectTFNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height)
DECLINLINE(GLfloat*) crBltVtRectsTFNormalized(const RTRECT *paRects, uint32_t cRects, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height)
return pBuff;
DECLINLINE(GLint*) crBltVtRectTF(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLint* pBuff, uint32_t height)
DECLINLINE(GLfloat*) crBltVtRectITNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height)
return ret;
DECLINLINE(GLint*) crBltVtRectIT(RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLint* pBuff, GLubyte **ppIndex, GLubyte *piBase, uint32_t height)
if (ppIndex)
return ret;
static GLfloat* crBltVtRectsITNormalized(const RTRECT *paRects, uint32_t cRects, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, GLubyte **ppIndex, GLubyte *piBase, uint32_t height)
uint32_t i;
for (i = 0; i < cRects; ++i)
if (ppIndex)
for (i = 0; i < cRects; ++i)
return pBuff;
#ifndef DEBUG_misha
static void crBltCheckSetupViewport(PCR_BLITTER pBlitter, const RTRECTSIZE *pDstSize, bool fFBODraw)
fUpdateViewport = true;
if (fUpdateViewport)
static DECLCALLBACK(int) crBltBlitTexBufImplDraw2D(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
return VERR_INVALID_PARAMETER;
pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * 2 * sizeof (*pVerticies) + cIndicies * sizeof (*pIndicies));
pTexCoords = crBltVtRectsITNormalized(paDstRect, cRects, 1, 1, pVerticies, &pIndicies, &iIdxBase, dstHeight);
return VINF_SUCCESS;
// crWarning("GL_EXT_framebuffer_blit not supported, will use Draw functions for blitting, which might be less efficient");
return VINF_SUCCESS;
pBlitter->pDispatch->MakeCurrent(pBlitter->pRestoreMural->Base.id, 0, pBlitter->pRestoreCtxInfo->Base.id);
int CrBltEnter(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural)
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;
if (pBlitter->CurrentMural.Base.id) /* <- pBlitter->CurrentMural.Base.id can be null if the blitter is in a "no-context" mode (see comments to BltInit for detail)*/
if (pRestoreCtxInfo)
pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
if (pRestoreCtxInfo)
if (pRestoreCtxInfo)
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
static void crBltBlitTexBuf(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, GLenum enmDstBuff, const RTRECTSIZE *pDstSize, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
void CrBltBlitTexMural(PCR_BLITTER pBlitter, bool fBb, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
crBltBlitTexBuf(pBlitter, pSrc, paSrcRects, fBb ? GL_BACK : GL_FRONT, &DstSize, paDstRects, cRects, fFlags);
void CrBltBlitTexTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *pSrcRect, const VBOXVR_TEXTURE *pDst, const RTRECT *pDstRect, uint32_t cRects, uint32_t fFlags)
pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pDst->target, pDst->hwid, 0);
// pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
// pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pDst->target, 0, 0);
return VERR_NOT_IMPLEMENTED;
return VERR_NO_MEMORY;
#ifdef DEBUG_misha
return VINF_SUCCESS;
VBOXBLITTERDECL(int) CrBltImgGetTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, GLenum enmFormat, CR_BLITTER_IMG *pDst)
return VERR_INVALID_STATE;
return rc;
#ifdef DEBUG_misha
return VINF_SUCCESS;
return VERR_INVALID_STATE;
return VERR_NOT_IMPLEMENTED;
* but seems like chromium does not support properly gl*Object versions of shader functions used with those extensions */
_ver \
_ext \
return NULL;
return NULL;
return NULL;
return NULL;
*puiProgram = 0;
if (!pStrFsShader)
return VERR_NOT_SUPPORTED;
if (!uiShader)
return VERR_NOT_SUPPORTED;
#ifdef DEBUG_misha
if(!compiled)
if (!pBuf)
#ifdef DEBUG_misha
if (compiled)
Assert(0);
goto end;
if (!uiProgram)
goto end;
#ifdef DEBUG_misha
if(!linked)
if (!pBuf)
#ifdef DEBUG_misha
if (linked)
Assert(0);
goto end;
uiProgram = 0;
end:
if (uiShader)
if (uiProgram)
if (pBuf)
return rc;
switch (enmTexTarget)
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
switch (enmTexTarget)
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
return NULL;
if (!puiProgram)
return VERR_INVALID_PARAMETER;
if (*puiProgram)
return VINF_SUCCESS;
return rc;
return rc;
return VINF_SUCCESS;
if (!uiProg)
return VERR_INVALID_STATE;
return VINF_SUCCESS;
if (!uiProg)
return rc;
return VINF_SUCCESS;