blitter.cpp revision 529e6bec97f5ef2e005c99c205c9624583ecb7f0
/* $Id$ */
/** @file
* Blitter API implementation
*/
/*
* Copyright (C) 2013-2015 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.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#ifdef IN_VMSVGA3D
# include "../include/cr_blitter.h"
# define WARN AssertMsgFailed
#else
# 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"
# include "cr_bmpscale.h"
#endif
static void crMClrFillMem(uint32_t *pu32Dst, int32_t cbDstPitch, uint32_t width, uint32_t height, uint32_t u32Color)
{
{
{
}
}
}
{
Assert(x >= 0);
Assert(y >= 0);
}
{
{
if (VBoxRectIsZero(&Intersection))
continue;
}
}
static void crMBltMem(const uint8_t *pu8Src, int32_t cbSrcPitch, uint8_t *pu8Dst, int32_t cbDstPitch, uint32_t width, uint32_t height)
{
{
pu8Src += cbSrcPitch;
pu8Dst += cbDstPitch;
}
}
void CrMBltImgRect(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, CR_BLITTER_IMG *pDst)
{
uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4;
crMBltMem(pu8Src, fSrcInvert ? -((int32_t)pSrc->pitch) : (int32_t)pSrc->pitch, pu8Dst, pDst->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
}
void CrMBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pPos, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pDst)
{
RestrictSrcRect.xLeft = 0;
RestrictSrcRect.yTop = 0;
RestrictDstRect.xLeft = 0;
RestrictDstRect.yTop = 0;
{
if (VBoxRectIsZero(&Intersection))
continue;
}
}
#ifndef IN_VMSVGA3D
void CrMBltImgRectScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pPos, bool fSrcInvert, const RTRECT *pCopyRect, float strX, float strY, CR_BLITTER_IMG *pDst)
{
if (VBoxRectIsZero(&UnscaledCopyRect))
{
WARN(("ups"));
return;
}
if (srcX < 0)
{
WARN(("ups"));
srcX = 0;
}
if (srcY < 0)
{
WARN(("ups"));
srcY = 0;
}
{
WARN(("ups"));
return;
}
{
WARN(("ups"));
return;
}
uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4;
}
void CrMBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTRECTSIZE *pSrcRectSize, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pDst)
{
RestrictDstRect.xLeft = 0;
RestrictDstRect.yTop = 0;
{
if (VBoxRectIsZero(&Intersection))
continue;
}
}
#endif /* !IN_VMSVGA3D */
/**
*
* @param pBlitter The blitter to initialize.
* @param pCtxBase Contains the blitter context info. Its value is
* treated differently depending on the fCreateNewCtx
* value.
* @param fCreateNewCtx If true, then @a pCtxBase must NOT be NULL. Its
* visualBits is used as a visual bits info for the new
* context, its id field is used to specified the
* shared context id to be used for blitter context.
* The id can be null to specify no shared context is
* needed
*
* If false and @a pCtxBase is NOT null AND its id
* field is NOT null, then specified the blitter
* context to be used blitter treats it as if it has
* default ogl state.
*
* Otherwise, the blitter works in a "no-context" mode,
* i.e. the� caller is responsible for making a proper
* context current before calling the blitter. Note
* proper context must be set before doing BltEnter,
* and ResoreContext info is ignored in that case. Also
* note that the blitter caches the current window
* info, and assumes the current context's values are
* preserved wrt that window before the calls, so if
* one uses different contexts for one blitter, the
* blitter current window values must be explicitly
* reset by doing CrBltMuralSetCurrentInfo(pBlitter,
* NULL).
* @param fForceDrawBlt If true this forces the blitter to always use
* glDrawXxx-based blits even if
* GL_EXT_framebuffer_blit. This is needed because
* BlitFramebufferEXT is often known to be buggy, and
* glDrawXxx-based blits appear to be more reliable.
* @param pShaders
* @param pDispatch
*/
{
{
crWarning("Default share context not initialized!");
return VERR_INVALID_PARAMETER;
}
if (!pCtxBase && fCreateNewCtx)
{
crWarning("pCtxBase is zero while fCreateNewCtx is set!");
return VERR_INVALID_PARAMETER;
}
if (pCtxBase)
if (fCreateNewCtx)
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
pBlitter->CtxInfo.Base.id = pDispatch->CreateContext("", pCtxBase->Base.visualBits, pCtxBase->Base.id);
#endif
{
crWarning("CreateContext failed!");
return VERR_GENERAL_FAILURE;
}
}
if (pShaders)
{
}
else
{
}
return VINF_SUCCESS;
}
{
if (CrBltIsEntered(pBlitter))
{
WARN(("CrBltBlitTexTex: blitter is entered"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
}
{
if (pMural)
{
return VINF_SUCCESS;
}
else
{
if (CrBltIsEntered(pBlitter))
{
WARN(("can not set null mural for entered bleater"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
if (!CrBltIsEntered(pBlitter))
return VINF_SUCCESS;
{
WARN(("setting current mural for entered no-context blitter"));
return VERR_INVALID_STATE;
}
WARN(("changing mural for entered blitter, is is somewhat expected?"));
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
pBlitter->pDispatch->MakeCurrent(pMural->Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
#endif
return VINF_SUCCESS;
}
#ifndef IN_VMSVGA3D
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);
{
if (CRBLT_F_INVERT_SRC_YCOORDS & fFlags)
{
}
else
{
}
if (CRBLT_F_INVERT_DST_YCOORDS & fFlags)
{
}
else
{
}
{
{
/* use srcY1 < srcY2 && dstY1 < dstY2 whenever possible to avoid GPU driver bugs */
}
}
{
{
/* use srcX1 < srcX2 && dstX1 < dstX2 whenever possible to avoid GPU driver bugs */
}
}
}
return VINF_SUCCESS;
}
/* GL_TRIANGLE_FAN */
DECLINLINE(GLfloat*) crBltVtRectTFNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height)
{
/* going ccw:
* 1. (left;top) 4. (right;top)
* | ^
* > |
* 2. (left;bottom) -> 3. (right;bottom) */
/* xLeft yTop */
/* xLeft yBottom */
/* xRight yBottom */
/* xRight yTop */
return &pBuff[8];
}
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)
{
/* xLeft yTop */
/* xLeft yBottom */
/* xRight yBottom */
/* xRight yTop */
return &pBuff[8];
}
{
/* triangle 1 */
/* triangle 2 */
return pIndex + 6;
}
/* Indexed GL_TRIANGLES */
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;
}
{
return cRects * 4;
}
{
return 6 * cRects;
}
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
/* debugging: ensure we calculate proper buffer size */
cbBuffer += 16;
#endif
else
{
}
}
}
#endif /* !IN_VMSVGA3D */
static void crBltCheckSetupViewport(PCR_BLITTER pBlitter, const RTRECTSIZE *pDstSize, bool fFBODraw)
{
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
fUpdateViewport = true;
}
if (fUpdateViewport)
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
}
}
#ifndef IN_VMSVGA3D
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:
{
break;
}
case GL_TEXTURE_RECTANGLE_ARB:
{
normalX = 1;
normalY = 1;
break;
}
default:
{
return VERR_INVALID_PARAMETER;
}
}
if (cRects == 1)
{
/* just optimization to draw a single rect with GL_TRIANGLE_FAN */
}
else
{
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;
}
{
{
}
else
crWarning("GL_EXT_framebuffer_object not supported, blitter can only blit to window");
else
crWarning("GL_ARB_pixel_buffer_object not supported");
/* BlitFramebuffer seems to be buggy on Intel,
* try always glDrawXxx for now */
{
}
else
{
// crWarning("GL_EXT_framebuffer_blit not supported, will use Draw functions for blitting, which might be less efficient");
}
/* defaults. but just in case */
return VINF_SUCCESS;
}
#endif /* !IN_VMSVGA3D */
{
{
WARN(("blitter not entered!"));
return;
}
return;
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
{
}
#endif
}
{
{
WARN(("current mural not initialized!"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
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)*/
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
#endif
}
return VINF_SUCCESS;
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
int rc = VINF_SUCCESS;
#else
#endif
if (RT_SUCCESS(rc))
{
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)
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
if (!(fFlags & CRBLT_F_NOALPHA))
else
{
if (!RT_SUCCESS(rc))
{
return;
}
/* since we use shaders, we need to use draw commands rather than framebuffer blits.
* force using draw-based blitting */
}
#endif
}
{
}
void CrBltBlitTexMural(PCR_BLITTER pBlitter, bool fBb, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
{
if (!CrBltIsEntered(pBlitter))
{
WARN(("CrBltBlitTexMural: blitter not entered"));
return;
}
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
crBltBlitTexBuf(pBlitter, pSrc, paSrcRects, fBb ? GL_BACK : GL_FRONT, &DstSize, paDstRects, cRects, fFlags);
}
#ifndef IN_VMSVGA3D
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)
{
if (!CrBltIsEntered(pBlitter))
{
WARN(("CrBltBlitTexTex: blitter not entered"));
return;
}
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);
}
{
if (!CrBltIsEntered(pBlitter))
{
WARN(("CrBltPresent: blitter not entered"));
return;
}
else
}
static int crBltImgInitBaseForTex(const VBOXVR_TEXTURE *pSrc, CR_BLITTER_IMG *pDst, GLenum enmFormat)
{
{
return VERR_NOT_IMPLEMENTED;
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
{
crWarning("RTMemAlloc failed");
return VERR_NO_MEMORY;
}
#ifdef DEBUG_misha
{
{
}
}
#endif
return VINF_SUCCESS;
}
VBOXBLITTERDECL(int) CrBltImgGetTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, GLenum enmFormat, CR_BLITTER_IMG *pDst)
{
if (!CrBltIsEntered(pBlitter))
{
WARN(("CrBltImgGetTex: blitter not entered"));
return VERR_INVALID_STATE;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
#ifdef DEBUG_misha
{
// Assert(depth == pSrc->depth);
}
#endif
return VINF_SUCCESS;
}
{
if (!CrBltIsEntered(pBlitter))
{
WARN(("CrBltImgGetMural: blitter not entered"));
return VERR_INVALID_STATE;
}
WARN(("NOT IMPLEMENTED"));
return VERR_NOT_IMPLEMENTED;
}
{
if (!CrBltIsEntered(pBlitter))
{
WARN(("CrBltImgFree: blitter not entered"));
return;
}
{
}
}
{
if (pCache->iGlVersion == 0)
{
if (pCache->iGlVersion <= 0)
{
}
}
return true;
/* @todo: we could also check for GL_ARB_shader_objects and GL_ARB_fragment_shader,
* but seems like chromium does not support properly gl*Object versions of shader functions used with those extensions */
return false;
}
#define CR_GLSL_STR_V_120 "#version 120\n"
#define CR_GLSL_STR_EXT_TR "#extension GL_ARB_texture_rectangle : enable\n"
#define CR_GLSL_STR_2D "2D"
#define CR_GLSL_STR_2DRECT "2DRect"
_ver \
_ext \
"void main()\n" \
"{\n" \
"vec2 srcCoord = vec2(gl_TexCoord[0]);\n" \
"gl_FragData[0].w = 1.0;\n" \
"}\n"
{
if (!CrGlslIsSupported(pCache))
{
crWarning("CrGlslIsSupported is false");
return NULL;
}
{
if (enmTexTarget == GL_TEXTURE_2D)
else if (enmTexTarget == GL_TEXTURE_RECTANGLE_ARB)
return NULL;
}
{
if (enmTexTarget == GL_TEXTURE_2D)
else if (enmTexTarget == GL_TEXTURE_RECTANGLE_ARB)
return NULL;
}
crError("crGlslGetFsStringNoAlpha: we should not be here!");
return NULL;
}
{
*puiProgram = 0;
if (!pStrFsShader)
{
crWarning("crGlslGetFsStringNoAlpha failed");
return VERR_NOT_SUPPORTED;
}
int rc = VINF_SUCCESS;
if (!uiShader)
{
crWarning("CreateShader failed");
return VERR_NOT_SUPPORTED;
}
#ifndef DEBUG_misha
if(!compiled)
#endif
{
if (!pBuf)
#ifdef DEBUG_misha
if (compiled)
else
#endif
{
goto end;
}
}
if (!uiProgram)
{
goto end;
}
#ifndef DEBUG_misha
if(!linked)
#endif
{
if (!pBuf)
#ifdef DEBUG_misha
if (linked)
else
#endif
{
goto end;
}
}
if (iUniform == -1)
{
crWarning("GetUniformLocation failed for sampler0");
}
else
{
}
*puiProgram = uiProgram;
/* avoid end finalizer from cleaning it */
uiProgram = 0;
end:
if (uiShader)
if (uiProgram)
if (pBuf)
return rc;
}
{
switch (enmTexTarget)
{
case GL_TEXTURE_2D:
return pCache->uNoAlpha2DProg;
case GL_TEXTURE_RECTANGLE_ARB:
return pCache->uNoAlpha2DRectProg;
default:
return 0;
}
}
{
switch (enmTexTarget)
{
case GL_TEXTURE_2D:
return &pCache->uNoAlpha2DProg;
case GL_TEXTURE_RECTANGLE_ARB:
return &pCache->uNoAlpha2DRectProg;
default:
return NULL;
}
}
{
if (!puiProgram)
return VERR_INVALID_PARAMETER;
if (*puiProgram)
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
}
{
if (!uiProg)
{
crWarning("request to use inexistent program!");
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (!uiProg)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
return VINF_SUCCESS;
}
#endif /* !IN_VMSVGA3D */
{
}
{
if (pCache->uNoAlpha2DProg)
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
pCache->uNoAlpha2DProg = 0;
}
if (pCache->uNoAlpha2DRectProg)
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
pCache->uNoAlpha2DRectProg = 0;
}
}
{
/* sanity */
}
#ifndef IN_VMSVGA3D
/*TdBlt*/
{
return;
return;
{
crWarning("PBO create failed");
return;
}
0, GL_STREAM_READ_ARB);
}
static uint32_t crTdBltTexCreate(PCR_BLITTER pBlitter, uint32_t width, uint32_t height, GLenum enmTarget)
{
if (!tex)
{
crWarning("Tex create failed");
return 0;
}
/*Restore gl state*/
return tex;
}
{
if (pTex->idInvertTex)
return VINF_SUCCESS;
pTex->idInvertTex = crTdBltTexCreate(pTex->pBlitter, pTex->Tex.width, pTex->Tex.height, pTex->Tex.target);
if (!pTex->idInvertTex)
{
crWarning("Invert Tex create failed");
return VERR_GENERAL_FAILURE;
}
return VINF_SUCCESS;
}
#endif /* !IN_VMSVGA3D */
{
}
{
{
return;
}
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
}
else
{
}
}
#ifndef IN_VMSVGA3D
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (pvData)
{
{
}
}
else
{
{
if (!pvData)
{
WARN(("Out of memory in crTdBltImgAcquire"));
return VERR_NO_MEMORY;
}
}
}
/*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
/*restore gl state*/
{
if (!pvData)
{
WARN(("Failed to MapBuffer in CrHlpGetTexImage"));
return VERR_GENERAL_FAILURE;
}
}
return VINF_SUCCESS;
}
#endif /* !IN_VMSVGA3D */
/* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataInvalidateNe or CrTdBltDataCleanup */
{
{
WARN(("tex not entered"));
return VERR_INVALID_STATE;
}
{
WARN(("Data NOT acquired"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (pTex->pScaledCache)
}
/* discard the texture data cached with previous CrTdBltDataAcquire.
* Must be called wit data released (CrTdBltDataRelease) */
{
{
WARN(("tex not entered"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
if (pTex->pScaledCache)
}
{
return VINF_SUCCESS;
bool fEntered = false;
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
fEntered = true;
}
if (fEntered)
return VINF_SUCCESS;
}
{
if (pTex->pScaledCache)
{
}
}
{
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
}
if (pTex->idInvertTex)
{
#ifdef IN_VMSVGA3D
/** @todo IN_VMSVGA3D */
#else
#endif
pTex->idInvertTex = 0;
}
}
/* does same as CrTdBltDataFree, and in addition cleans up */
{
{
WARN(("tex not entered"));
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
{
bool fEntered = false;
{
if (!RT_SUCCESS(rc))
{
WARN(("err"));
return rc;
}
fEntered = true;
}
if (fEntered)
return VINF_SUCCESS;
}
#ifndef IN_VMSVGA3D
/* 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, const CR_BLITTER_IMG**ppImg)
{
{
WARN(("tex not entered"));
return VERR_INVALID_STATE;
}
{
WARN(("Data acquired already"));
return VERR_INVALID_STATE;
}
if (pTex->Flags.DataValid && pTex->Img.enmFormat == enmFormat && !pTex->Flags.DataInverted == !fInverted)
{
return VINF_SUCCESS;
}
int rc;
if (fInverted)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
}
{
if (!RT_SUCCESS(rc))
{
return;
}
}
static int ctTdBltSdCreate(PCR_BLITTER pBlitter, uint32_t width, uint32_t height, GLenum enmTarget, PCR_TEXDATA *ppScaledCache)
{
*ppScaledCache = NULL;
if (!pScaledCache)
{
WARN(("RTMemAlloc failed"));
return VERR_NO_MEMORY;
}
{
WARN(("Tex create failed"));
return VERR_GENERAL_FAILURE;
}
return VINF_SUCCESS;
}
static int ctTdBltSdGet(PCR_TEXDATA pTex, uint32_t width, uint32_t height, PCR_TEXDATA *ppScaledCache)
{
*ppScaledCache = NULL;
if (!pTex->pScaledCache)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
else
{
if (cmp <= 0)
if (!cmp)
else if (cmp < 0) /* current cache is "less" than the requested */
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
else /* cmp > 0 */
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
}
#if 0
{
{
WARN(("Tex create failed"));
return VERR_GENERAL_FAILURE;
}
}
#endif
return VINF_SUCCESS;
}
static int ctTdBltSdGetUpdated(PCR_TEXDATA pTex, uint32_t width, uint32_t height, PCR_TEXDATA *ppScaledCache)
{
*ppScaledCache = NULL;
if (!RT_SUCCESS(rc))
{
return rc;
}
{
}
return VINF_SUCCESS;
}
VBOXBLITTERDECL(int) CrTdBltDataAcquireScaled(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, uint32_t width, uint32_t height, const CR_BLITTER_IMG**ppImg)
{
{
WARN(("tex not entered"));
return VERR_INVALID_STATE;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (pScaledCache != pTex)
return VINF_SUCCESS;
}
{
if (!pTex->pScaledCache)
return;
}
#endif /* !IN_VMSVGA3D */