compositor.cpp revision a0bf15018685abecfef7c843595aadc6ad969d20
/* $Id$ */
/** @file
* Compositor impl
*/
/*
* Copyright (C) 2013 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.
*/
#include <cr_compositor.h>
{
{
return VINF_SUCCESS;
}
if (pCompositor->cRectsBuffer)
{
}
else
{
}
if (pCompositor->paSrcRects)
{
if (pCompositor->paDstRects)
{
pCompositor->paDstUnstretchedRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paDstUnstretchedRects) * cRects);
{
return VINF_SUCCESS;
}
}
else
{
WARN(("RTMemAlloc failed!"));
}
}
else
{
WARN(("RTMemAlloc failed!"));
}
pCompositor->cRectsBuffer = 0;
return VERR_NO_MEMORY;
}
{
}
static DECLCALLBACK(bool) crVrScrCompositorRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
{
return true;
}
typedef struct VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER
{
static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
{
{
}
else
{
{
pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstUnstretchedRects[i].xLeft - pEntry->Rect.xLeft));
pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstUnstretchedRects[i].yTop - pEntry->Rect.yTop));
pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstUnstretchedRects[i].xRight - pEntry->Rect.xLeft));
pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstUnstretchedRects[i].yBottom - pEntry->Rect.yTop));
}
}
#ifndef IN_RING0
{
{
{
pEntry->paDstRects[i].xLeft = (int32_t)(pEntry->paDstUnstretchedRects[i].xLeft * pCompositor->StretchX);
pEntry->paDstRects[i].xRight = (int32_t)(pEntry->paDstUnstretchedRects[i].xRight * pCompositor->StretchX);
}
{
pEntry->paDstRects[i].yTop = (int32_t)(pEntry->paDstUnstretchedRects[i].yTop * pCompositor->StretchY);
pEntry->paDstRects[i].yBottom = (int32_t)(pEntry->paDstUnstretchedRects[i].yBottom * pCompositor->StretchY);
}
}
}
else
#endif
{
memcpy(pEntry->paDstRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paDstUnstretchedRects));
}
#if 0//ndef IN_RING0
{
/* filter out zero rectangles*/
{
continue;
{
}
++iNew;
}
if (cDiff)
{
}
}
#endif
return true;
}
{
return VINF_SUCCESS;
if (!cRects)
{
pCompositor->cRects = 0;
return VINF_SUCCESS;
}
if (!RT_SUCCESS(rc))
return rc;
return VINF_SUCCESS;
}
static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangedFlags)
{
uint32_t fChangedFlags = 0;
int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, pEntry ? &pEntry->Ce : NULL, cRegions, paRegions, &pReplacedEntry, &fChangedFlags);
if (!RT_SUCCESS(rc))
{
return rc;
}
VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacedEntry);
{
}
else if (fChangedFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)
{
}
{
}
{
}
if (pfChangedFlags)
if (ppReplacedScrEntry)
return VINF_SUCCESS;
}
static int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
{
bool fChanged;
int rc = VBoxVrCompositorEntryRegionsSet(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
if (!RT_SUCCESS(rc))
{
return rc;
}
if (fChanged)
{
{
}
}
if (pfChanged)
return VINF_SUCCESS;
}
static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, bool *pfChanged)
{
if (pfChanged)
*pfChanged = false;
{
{
int rc = VBoxVrCompositorEntryRegionsTranslate(&pCompositor->Compositor, &pEntry->Ce, pPos->x - pEntry->Rect.xLeft, pPos->y - pEntry->Rect.yTop, pfChanged);
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (pfChanged)
*pfChanged = true;
}
return VINF_SUCCESS;
}
static int crVrScrCompositorEntryEnsureRegionsBounds(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, bool *pfChanged)
{
bool fChanged = false;
if (pfChanged)
*pfChanged = false;
if (!RT_SUCCESS(rc))
if (pfChanged)
return rc;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangeFlags)
{
int rc;
uint32_t fChangeFlags = 0;
bool fPosChanged = false;
if (pPos)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (fPosRelated)
{
if (!pEntry)
{
WARN(("Entry is expected to be specified for pos-related regions"));
return VERR_INVALID_PARAMETER;
}
{
if (!paTranslatedRects)
{
WARN(("RTMemAlloc failed"));
return VERR_NO_MEMORY;
}
{
}
}
}
rc = crVrScrCompositorEntryRegionsAdd(pCompositor, pEntry, cRegions, paRegions, ppReplacedScrEntry, &fChangeFlags);
if (!RT_SUCCESS(rc))
{
goto done;
}
{
bool fAdjusted = false;
if (!RT_SUCCESS(rc))
{
goto done;
}
if (fAdjusted)
{
{
}
else
{
fChangeFlags = 0;
}
}
}
fPosChanged = false;
else if (ppReplacedScrEntry)
if (pfChangeFlags)
{
if (fPosChanged)
{
/* means entry was in list and was moved, so regions changed */
*pfChangeFlags = VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
}
else
}
done:
if (paTranslatedRects)
return rc;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect)
{
{
return VINF_SUCCESS;
}
bool fChanged = false;
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryTexAssign(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, CR_TEXDATA *pTex)
{
return VINF_SUCCESS;
if (pTex)
return VINF_SUCCESS;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, bool *pfChanged)
{
/* @todo: the fChanged sate calculation is really rough now, this is enough for now though */
bool fChanged = false, fPosChanged = false;
if (!RT_SUCCESS(rc))
{
return rc;
}
if (pPos)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (fPosRelated)
{
if (!pEntry)
{
WARN(("Entry is expected to be specified for pos-related regions"));
return VERR_INVALID_PARAMETER;
}
{
if (!paTranslatedRects)
{
WARN(("RTMemAlloc failed"));
return VERR_NO_MEMORY;
}
{
}
}
}
if (!RT_SUCCESS(rc))
{
return rc;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (pfChanged)
return VINF_SUCCESS;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
{
bool fChanged = false;
int rc = VBoxVrCompositorEntryListIntersect(&pCompositor->Compositor, &pEntry->Ce, pList2, &fChanged);
if (!RT_SUCCESS(rc))
{
return rc;
}
if (fChanged)
{
}
if (pfChanged)
return VINF_SUCCESS;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
{
bool fChanged = false;
int rc = VBoxVrCompositorEntryRegionsIntersect(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
if (!RT_SUCCESS(rc))
{
return rc;
}
if (fChanged)
if (pfChanged)
return VINF_SUCCESS;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
{
int rc = VINF_SUCCESS;
bool fChanged = false;
{
bool fTmpChanged = false;
if (RT_SUCCESS(tmpRc))
{
fChanged |= fTmpChanged;
}
else
{
}
}
if (pfChanged)
return rc;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
{
int rc = VINF_SUCCESS;
bool fChanged = false;
{
bool fTmpChanged = false;
int tmpRc = CrVrScrCompositorEntryRegionsIntersect(pCompositor, pEntry, cRegions, paRegions, &fTmpChanged);
if (RT_SUCCESS(tmpRc))
{
fChanged |= fTmpChanged;
}
else
{
}
}
if (pfChanged)
return rc;
}
VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
/* regions are valid until the next CrVrScrCompositor call */
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
{
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (ppaSrcRegions)
if (ppaDstRegions)
return VINF_SUCCESS;
}
VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
{
}
VBOXVREGDECL(void) CrVrScrCompositorEntryFlagsSet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t fFlags)
{
return;
}
{
}
static void crVrScrCompositorEntryDataCopy(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pToEntry)
{
}
VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return VINF_SUCCESS;
return VINF_SUCCESS;
}
VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry)
{
return false;
return true;
}
static DECLCALLBACK(void) crVrScrCompositorEntryReleasedCB(const struct VBOXVR_COMPOSITOR *pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
{
if (pReplacingEntry)
{
PVBOXVR_SCR_COMPOSITOR_ENTRY pCReplacingEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacingEntry);
}
if (pCEntry->pfnEntryReleased)
{
PVBOXVR_SCR_COMPOSITOR_ENTRY pCReplacingEntry = pReplacingEntry ? VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacingEntry) : NULL;
}
}
VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, const RTRECT *pRect, bool *pfChanged)
{
{
if (pfChanged)
*pfChanged = false;
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
return VINF_SUCCESS;
}
{
if (pRect)
#ifndef IN_RING0
#endif
}
VBOXVREGDECL(void) CrVrScrCompositorRegionsClear(PVBOXVR_SCR_COMPOSITOR pCompositor, bool *pfChanged)
{
/* set changed flag first, while entries are in the list and we have them */
}
{
if (pCompositor->paDstRects)
{
}
if (pCompositor->paSrcRects)
{
}
{
}
pCompositor->cRects = 0;
pCompositor->cRectsBuffer = 0;
}
VBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged)
{
{
}
}
#ifndef IN_RING0
VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY)
{
return;
}
#endif
/* regions are valid until the next CrVrScrCompositor call */
VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (ppaSrcRegions)
if (ppaDstRegions)
return VINF_SUCCESS;
}
typedef struct VBOXVR_SCR_COMPOSITOR_VISITOR_CB
{
void *pvVisitor;
static DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
{
}
VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor)
{
}
VBOXVREGDECL(int) CrVrScrCompositorClone(const VBOXVR_SCR_COMPOSITOR *pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor)
{
/* for simplicity just copy from one to another */
const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
int rc = VINF_SUCCESS;
{
/* get source rects, that will be non-stretched and entry pos - pased */
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!pDstEntry)
{
WARN(("pfnEntryFor failed"));
return VERR_INVALID_STATE;
}
rc = CrVrScrCompositorEntryRegionsSet(pDstCompositor, pDstEntry, NULL, cRects, pRects, false, NULL);
if (!RT_SUCCESS(rc))
{
return rc;
}
}
return rc;
}
VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, bool *pfChanged)
{
int rc = VINF_SUCCESS;
bool fChanged = false;
{
bool fCurChanged = false;
if (!RT_SUCCESS(rc))
{
break;
}
fChanged |= fCurChanged;
}
if (pfChanged)
return rc;
}
VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}