server_muralfbo.c revision dea65cada3ff5e4b07cfacd85d96b389cdfdff05
/* $Id$ */
/** @file
* VBox crOpenGL: Window to FBO redirect support.
*/
/*
* Copyright (C) 2010 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 "server.h"
#include "cr_string.h"
#include "cr_mem.h"
#include "render/renderspu.h"
{
int i;
for (i=0; i<cr_server.screenCount; ++i)
{
{
return i;
}
}
return -1;
}
{
}
{
int overlappingScreenCount, primaryS, i;
{
return;
}
{
}
else
{
for (i=0; i<cr_server.screenCount; ++i)
{
|| crServerMuralCoverScreen(mural, i))
{
}
}
if (!overlappingScreenCount)
{
primaryS = 0;
}
}
{
}
{
{
}
}
else
{
{
}
else
{
{
}
}
{
}
}
}
{
}
{
if (redir)
{
if (!crServerSupportRedirMuralFBO())
{
crWarning("FBO not supported, can't redirect window output");
return;
}
{
}
{
}
}
else
{
{
}
}
}
{
/*Color texture*/
{
}
/*Depth&Stencil*/
/*FBO*/
{
}
/*PBO*/
{
{
crWarning("PBO create failed");
}
}
/*Restore gl state*/
{
}
}
{
{
mural->idColorTex = 0;
mural->idDepthStencilRB = 0;
}
{
}
}
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
{
}
{
rect->x2 = MIN(mural->gX+(int)mural->fboWidth, cr_server.screen[sId].x+(int)cr_server.screen[sId].w);
rect->y2 = MIN(mural->gY+(int)mural->fboHeight, cr_server.screen[sId].y+(int)cr_server.screen[sId].h);
}
static void crServerCopySubImage(char *pDst, char* pSrc, CRrecti *pRect, int srcWidth, int srcHeight)
{
int i;
for (i=0; i<height; ++i)
{
pSrc -= srcrowsize;
pDst += dstrowsize;
}
}
{
}
{
int i, j;
{
return;
}
{
return;
}
{
crWarning("Mural doesn't have PBO even though bUsePBOForReadback is set!");
}
if (bUsePBO)
{
}
else
{
{
}
if (!pixels)
{
crWarning("Out of memory in crServerPresentFBO");
return;
}
}
/*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, pixels);
/*restore gl state*/
if (bUsePBO)
{
if (!pixels)
{
crWarning("Failed to MapBuffer in crServerPresentFBO");
return;
}
}
for (i=0; i<cr_server.screenCount; ++i)
{
{
/* rect in window relative coords */
if (!mural->pVisibleRects)
{
/*we don't get any rects info for guest compiz windows, so we treat windows as visible unless explicitly received 0 visible rects*/
if (!mural->bReceivedRects)
{
if (!tmppixels)
{
crWarning("Out of memory in crServerPresentFBO");
return;
}
/*Note: pfnPresentFBO would free tmppixels*/
cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, rect.y2-rect.y1);
}
}
else
{
for (j=0; j<mural->cVisibleRects; ++j)
{
{
if (!tmppixels)
{
crWarning("Out of memory in crServerPresentFBO");
return;
}
/*Note: pfnPresentFBO would free tmppixels*/
}
}
}
}
}
if (bUsePBO)
{
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
}
else
{
{
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
}
}
}
{
}