server_presenter.cpp revision c58f1213e628a545081c70e26c6b67a841cff880
/* $Id$ */
/** @file
* Presenter API
*/
/*
* 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_spu.h"
#include "chromium.h"
#include "cr_error.h"
#include "cr_net.h"
#include "cr_rand.h"
#include "server_dispatch.h"
#include "server.h"
#include "cr_mem.h"
#include "cr_string.h"
#include <cr_vreg.h>
#define CR_DISPLAY_RECTS_UNDEFINED UINT32_MAX
#define CR_PRESENTER_ENTRY_FROM_ENTRY(_p) ((PCR_PRESENTER_ENTRY)(((uint8_t*)(_p)) - RT_OFFSETOF(CR_PRESENTER_ENTRY, Ce)))
#define CR_PRESENTER_FROM_COMPOSITOR(_p) ((PCR_PRESENTER)(((uint8_t*)(_p)) - RT_OFFSETOF(CR_PRESENTER, Compositor)))
{
{
return VINF_SUCCESS;
}
if (pPresenter->cRectsBuffer)
{
}
if (pPresenter->paSrcRects)
{
if (pPresenter->paDstRects)
{
return VINF_SUCCESS;
}
else
{
crWarning("RTMemAlloc failed!");
}
}
else
{
crWarning("RTMemAlloc failed!");
}
pPresenter->cRectsBuffer = 0;
return VERR_NO_MEMORY;
}
{
}
static DECLCALLBACK(bool) crPtRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
{
return true;
}
typedef struct CR_PRESENTOR_RECTS_ASSIGNER
{
static DECLCALLBACK(bool) crPtRectsAssignerCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
{
if (pPresenter->StretchX >= 1. && pPresenter->StretchY >= 1. /* <- stretching can not zero some rects */
{
}
else
{
{
pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstRects[i].xLeft - pEntry->Pos.x) * pPresenter->StretchX);
pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstRects[i].yTop - pEntry->Pos.y) * pPresenter->StretchY);
pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstRects[i].xRight - pEntry->Pos.x) * pPresenter->StretchX);
pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstRects[i].yBottom - pEntry->Pos.y) * pPresenter->StretchY);
}
{
/* filter out zero rectangles*/
{
continue;
{
}
++iNew;
}
if (cDiff)
{
}
}
}
return true;
}
{
return VINF_SUCCESS;
if (!cRects)
{
pPresenter->cRects = 0;
return VINF_SUCCESS;
}
if (!RT_SUCCESS(rc))
return rc;
return VINF_SUCCESS;
}
DECLCALLBACK(int) CrPtCbDrawEntrySingle(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter, bool *pfAllEntriesDrawn)
{
if (pfAllEntriesDrawn)
*pfAllEntriesDrawn = false;
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
rc = pPresenter->pfnDrawTexture(pPresenter, pBlitter, &pEntry->Texture, pEntry->paSrcRects, pEntry->paDstRects, pEntry->cRects);
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
static DECLCALLBACK(bool) crPtDrawEntryAllCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
{
bool fAllEntriesDrawn;
if (!RT_SUCCESS(rc))
{
}
return !fAllEntriesDrawn;
}
DECLCALLBACK(int) CrPtCbDrawEntryAll(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter, bool *pfAllEntriesDrawn)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (pfAllEntriesDrawn)
*pfAllEntriesDrawn = true;
return VINF_SUCCESS;
}
static int crPtEntryRegionsAdd(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
{
uint32_t fChangedFlags = 0;
int rc = VBoxVrCompositorEntryRegionsAdd(&pPresenter->Compositor, &pEntry->Ce, cRegions, paRegions, &fChangedFlags);
if (!RT_SUCCESS(rc))
{
return rc;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (pfChanged)
*pfChanged = !!fChangedFlags;
return VINF_SUCCESS;
}
static int crPtEntryRegionsSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
{
bool fChanged;
int rc = VBoxVrCompositorEntryRegionsSet(&pPresenter->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
if (!RT_SUCCESS(rc))
{
return rc;
}
if (fChanged)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
}
if (pfChanged)
return VINF_SUCCESS;
}
static void crPtEntryPositionSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos)
{
{
{
}
}
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
static DECLCALLBACK(bool) crPtPresentCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
{
bool fAllDrawn = false;
if (!RT_SUCCESS(rc))
{
}
return !fAllDrawn;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
int CrPtEntryRegionsAdd(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
int CrPtEntryRegionsSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
int CrPtInit(PCR_PRESENTER pPresenter, PFNCRDISPLAY_REGIONS_CHANGED pfnRegionsChanged, PFNCRDISPLAY_DRAW_ENTRY pfnDrawEntry, PFNCRDISPLAY_DRAW_TEXTURE pfnDrawTexture)
{
return VINF_SUCCESS;
}
{
if (pPresenter->paDstRects)
if (pPresenter->paSrcRects)
}
{
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
/* DISPLAY */
#define CR_DISPLAY_FROM_PRESENTER(_p) ((PCR_DISPLAY)(((uint8_t*)(_p)) - RT_OFFSETOF(CR_DISPLAY, Presenter)))
{
if (!RT_SUCCESS(rc))
{
return rc;
}
cr_server.head_spu->dispatch_table.WindowVisibleRegion(pDisplay->Mural.spuWindow, cRegions, (GLint*)paRegions);
{
/* @todo the code assumes that RTRECT == four GLInts. */
}
return VINF_SUCCESS;
}
static DECLCALLBACK(int) crDpCbDrawTextureWindow(struct CR_PRESENTER *pPresenter, PCR_BLITTER pBlitter,
{
return VINF_SUCCESS;
}
{
int rc = CrPtInit(&pDisplay->Presenter, crDpCbRegionsChanged, CrPtCbDrawEntryAll, crDpCbDrawTextureWindow);
if (RT_SUCCESS(rc))
{
{
return VINF_SUCCESS;
// crServerMuralTerm(&pDisplay->Mural);
}
else
{
crWarning("crServerMuralInit failed!");
}
}
return rc;
}
{
}
{
/* try to enter to make sure the blitter is initialized completely and to make sure we actually can do that */
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
else
{
}
return rc;
}
{
}
{
}
int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
{
}
int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
{
}
{
}
{
}
{
}
{
if (pMap->pTextureMap)
return VINF_SUCCESS;
crWarning("crAllocHashtable failed!");
return VERR_NO_MEMORY;
}
{
}
PCR_DISPLAY_ENTRY CrDemEntryGetCreate(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, CRContextInfo *pCtxInfo)
{
if (pEntry)
return pEntry;
if (!pContext)
{
crWarning("pContext is null!");
return NULL;
}
if (!pTobj)
{
crWarning("pTobj is null!");
return NULL;
}
if (!hwId)
{
crWarning("hwId is null!");
return NULL;
}
if (!pEntry)
{
crWarning("crAlloc failed allocating CR_DISPLAY_ENTRY");
return NULL;
}
return pEntry;
}
{
#ifdef DEBUG
{
if (!pEntry)
{
crWarning("request to delete inexistent entry");
return;
}
}
#endif
}
#define CR_PRESENT_SCREEN_MASK 0xffff
#define CR_PRESENT_FLAGS_OFFSET 16
{
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
else
}
else
return rc;
}
{
if (cr_server.fFBOModeBlitterInited > 0)
return &cr_server.FBOModeBlitter;
{
if (RT_SUCCESS(rc))
{
return &cr_server.FBOModeBlitter;
}
}
return NULL;
}
static int8_t crServerCheckInitDisplayBlitter()
{
return cr_server.fPresentBlitterInited;
crDebug("Display Functionality is requested");
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
return 1;
}
else
{
}
}
else
{
}
}
else
{
}
return -1;
}
static bool crServerDisplayIsSupported()
{
return crServerCheckInitDisplayBlitter() > 0;
}
{
return NULL;
}
{
if (idScreen >= CR_MAX_GUEST_MONITORS)
{
return NULL;
}
if (crServerCheckInitDisplayBlitter() > 0)
{
/* the display (screen id == 0) can be initialized while doing crServerCheckInitDisplayBlitter,
* so re-check the bit map */
if (RT_SUCCESS(rc))
{
}
else
{
}
}
else
{
crWarning("crServerCheckInitDisplayBlitter said \"UNSUPPORTED\"");
}
return NULL;
}
{
if (idPBO)
{
if (pCurCtx)
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
else
}
else
{
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
}
}
{
if (idPBO)
{
}
else
{
{
}
if (!pvData)
{
crWarning("Out of memory in CrHlpGetTexImage");
return NULL;
}
}
/*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvData);
/*restore gl state*/
if (pCurCtx)
{
}
else
{
}
if (idPBO)
{
if (!pvData)
{
crWarning("Failed to MapBuffer in CrHlpGetTexImage");
return NULL;
}
}
return pvData;
}
crServerDispatchTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, GLint *pRects)
{
if (!pDisplay)
{
crWarning("crServerDisplayGet Failed");
return;
}
PCR_DISPLAY_ENTRY pEntry = CrDemEntryGetCreate(&cr_server.PresentTexturepMap, texture, cr_server.currentCtxInfo);
if (!pEntry)
{
crWarning("CrDemEntryGetCreate Failed");
return;
}
if (!RT_SUCCESS(rc))
{
return;
}
if (!RT_SUCCESS(rc))
{
return;
}
}