void CrBltLeave(PCR_BLITTER pBlitter) { if (!CrBltIsEntered(pBlitter)) { crWarning("CrBltLeave: blitter not entered"); return; } if (pBlitter->Flags.SupportsFBO) { pBlitter->pDispatch->BindFramebufferEXT(GL_FRAMEBUFFER, 0); pBlitter->pDispatch->DrawBuffer(GL_BACK); pBlitter->pDispatch->ReadBuffer(GL_BACK); } pBlitter->pDispatch->Flush(); if (pBlitter->CtxInfo.Base.id) { if (pBlitter->pRestoreCtxInfo != &pBlitter->CtxInfo) { pBlitter->pDispatch->MakeCurrent(pBlitter->pRestoreMural->Base.id, 0, pBlitter->pRestoreCtxInfo->Base.id); } else { pBlitter->pDispatch->MakeCurrent(0, 0, 0); } } pBlitter->pRestoreCtxInfo = NULL; }
VBOXBLITTERDECL(int) CrBltImgGetTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, GLenum enmFormat, CR_BLITTER_IMG *pDst) { if (!CrBltIsEntered(pBlitter)) { crWarning("CrBltImgGetTex: blitter not entered"); return VERR_INVALID_STATE; } int rc = crBltImgCreateForTex(pSrc, pDst, enmFormat); if (!RT_SUCCESS(rc)) { crWarning("crBltImgCreateForTex failed, rc %d", rc); return rc; } pBlitter->pDispatch->BindTexture(pSrc->target, pSrc->hwid); #ifdef DEBUG_misha { GLint width = 0, height = 0, depth = 0; pBlitter->pDispatch->GetTexLevelParameteriv(pSrc->target, 0, GL_TEXTURE_WIDTH, &width); pBlitter->pDispatch->GetTexLevelParameteriv(pSrc->target, 0, GL_TEXTURE_HEIGHT, &height); pBlitter->pDispatch->GetTexLevelParameteriv(pSrc->target, 0, GL_TEXTURE_DEPTH, &depth); Assert(width == pSrc->width); Assert(height == pSrc->height); // Assert(depth == pSrc->depth); } #endif pBlitter->pDispatch->GetTexImage(pSrc->target, 0, enmFormat, GL_UNSIGNED_BYTE, pDst->pvData); pBlitter->pDispatch->BindTexture(pSrc->target, 0); return VINF_SUCCESS; }
int CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural) { if (pMural) { if (!memcmp(&pBlitter->CurrentMural, pMural, sizeof (pBlitter->CurrentMural))) return VINF_SUCCESS; memcpy(&pBlitter->CurrentMural, pMural, sizeof (pBlitter->CurrentMural)); } else { if (!pBlitter->CurrentMural.Base.id) return VINF_SUCCESS; pBlitter->CurrentMural.Base.id = 0; } pBlitter->Flags.CurrentMuralChanged = 1; if (!CrBltIsEntered(pBlitter)) return VINF_SUCCESS; else if (!pBlitter->CtxInfo.Base.id) { crWarning("setting current mural for entered no-context blitter"); return VERR_INVALID_STATE; } pBlitter->pDispatch->Flush(); if (pMural) pBlitter->pDispatch->MakeCurrent(pMural->Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id); else pBlitter->pDispatch->MakeCurrent(0, 0, 0); return VINF_SUCCESS; }
VBOXBLITTERDECL(int) CrBltImgGetMural(PCR_BLITTER pBlitter, bool fBb, CR_BLITTER_IMG *pDst) { if (!CrBltIsEntered(pBlitter)) { crWarning("CrBltImgGetMural: blitter not entered"); return VERR_INVALID_STATE; } crWarning("NOT IMPLEMENTED"); return VERR_NOT_IMPLEMENTED; }
int CrBltEnter(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural) { if (!pBlitter->CurrentMural.Base.id && pBlitter->CtxInfo.Base.id) { crWarning("current mural not initialized!"); return VERR_INVALID_STATE; } if (CrBltIsEntered(pBlitter)) { crWarning("blitter is entered already!"); 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->Flush(); pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id); } else { if (pRestoreCtxInfo) { crWarning("pRestoreCtxInfo is not NULL for \"no-context\" blitter"); pRestoreCtxInfo = NULL; } } if (pRestoreCtxInfo) { pBlitter->pRestoreCtxInfo = pRestoreCtxInfo; pBlitter->pRestoreMural = pRestoreMural; } else { pBlitter->pRestoreCtxInfo = &pBlitter->CtxInfo; } if (pBlitter->Flags.Initialized) return VINF_SUCCESS; int rc = crBltInitOnMakeCurent(pBlitter); if (RT_SUCCESS(rc)) { pBlitter->Flags.Initialized = 1; return VINF_SUCCESS; } crWarning("crBltInitOnMakeCurent failed, rc %d", rc); CrBltLeave(pBlitter); return rc; }
void CrBltPresent(PCR_BLITTER pBlitter) { if (!CrBltIsEntered(pBlitter)) { crWarning("CrBltPresent: blitter not entered"); return; } if (pBlitter->CtxInfo.Base.visualBits & CR_DOUBLE_BIT) pBlitter->pDispatch->SwapBuffers(pBlitter->CurrentMural.Base.id, 0); else pBlitter->pDispatch->Flush(); }
VBOXBLITTERDECL(void) CrBltImgFree(PCR_BLITTER pBlitter, CR_BLITTER_IMG *pDst) { if (!CrBltIsEntered(pBlitter)) { crWarning("CrBltImgFree: blitter not entered"); return; } if (pDst->pvData) { RTMemFree(pDst->pvData); pDst->pvData = NULL; } }
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)) { crWarning("CrBltBlitTexMural: blitter not entered"); return; } RTRECTSIZE DstSize = {pBlitter->CurrentMural.width, pBlitter->CurrentMural.height}; pBlitter->pDispatch->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0); 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) { if (!CrBltIsEntered(pBlitter)) { crWarning("CrBltBlitTexTex: blitter not entered"); return; } RTRECTSIZE DstSize = {(uint32_t)pDst->width, (uint32_t)pDst->height}; pBlitter->pDispatch->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, pBlitter->idFBO); /* TODO: mag/min filters ? */ 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); crBltBlitTexBuf(pBlitter, pSrc, pSrcRect, GL_DRAW_FRAMEBUFFER, &DstSize, pDstRect, cRects, fFlags); pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pDst->target, 0, 0); }
VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural) { if (CrBltIsEntered(pBlitter)) { crWarning("CrBltBlitTexTex: blitter is entered"); return VERR_INVALID_STATE; } if (pBlitter->Flags.ShadersGloal || !CrGlslNeedsCleanup(&pBlitter->LocalGlslCache)) return VINF_SUCCESS; int rc = CrBltEnter(pBlitter, pRestoreCtxInfo, pRestoreMural); if (!RT_SUCCESS(rc)) { crWarning("CrBltEnter failed, rc %d", rc); return rc; } CrGlslCleanup(&pBlitter->LocalGlslCache); CrBltLeave(pBlitter); return VINF_SUCCESS; }