server_rpw.cpp revision c04472d7ec89d8a8806f367048d5e3d451508e61
/* $Id$ */
/** @file
* VBox crOpenGL: Read Pixels worker
*/
/*
* Copyright (C) 2010-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 "server.h"
#include "cr_string.h"
#include "cr_mem.h"
#include "cr_vreg.h"
#include "render/renderspu.h"
{
{
cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, CR_SERVER_RPW_ENTRY_TEX(pCurEntry, Worker));
{
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, CR_SERVER_RPW_ENTRY_PBO_CUR(pCurEntry));
/*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
}
else
{
if (pvData)
{
cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvData);
}
else
{
crWarning("crAlloc failed");
}
}
}
}
{
{
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, CR_SERVER_RPW_ENTRY_PBO_COMPLETED(pCurEntry));
void *pvData = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
cr_server.head_spu->dispatch_table.BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, pCurEntry->Size.cx*pCurEntry->Size.cy*4, 0, GL_STREAM_READ_ARB);
}
}
static void crServerRpwWorkerGpuMarkGpuCompletedSubmitedLocked(PRTLISTNODE pGpuSubmitedList, PRTLISTNODE pWorkList)
{
{
}
{
{
/* PBO mode, put to the GPU submitted queue*/
}
else
{
/* no PBO, we are already done entry data processing, free it right away */
}
}
}
{
{
}
}
{
bool fExit = false;
bool fForceComplete = false;
bool fNotifyCmdCompleted = false;
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
goto end;
}
for (;;)
{
/* the crit sect is locked here */
{
}
{
switch (enmCtlType)
{
break;
fExit = true;
break;
default:
break;
}
fNotifyCmdCompleted = true;
}
bool fCompleted = false;
if (fNewItems)
{
}
if (!RTListIsEmpty(&GpuSubmittedList))
{
if (fForceComplete || fNewItems)
{
fForceComplete = false;
fCompleted = true;
}
}
if (!RT_SUCCESS(rc))
{
break;
}
/* fNewGpuItems means new entries arrived. WorkList contains new GPU submitted data
* fCompleted means completion was performed, GpuSubmittedList contains old GPU submitted data,
* which is now completed and should be released */
if (fNewItems || fCompleted)
{
}
{
if (fNotifyCmdCompleted)
{
if (!RT_SUCCESS(rc))
{
break;
}
fNotifyCmdCompleted = false;
}
if (fExit)
break;
if (!RTListIsEmpty(&GpuSubmittedList))
else
{
break;
}
if (rc == VERR_TIMEOUT)
{
fForceComplete = true;
}
if (!RT_SUCCESS(rc))
{
break;
}
}
}
end:
return rc;
}
{
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
{
}
}
else
{
}
}
else
{
int tmpRc;
if (RT_SUCCESS(tmpRc))
{
}
else
{
}
}
return rc;
}
static int crServerRpwCtl(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_CTL_TYPE enmType, CR_SERVER_RPW_ENTRY *pEntry)
{
if (RT_SUCCESS(rc))
{
}
else
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
int rc;
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
pWorker->ctxId = cr_server.head_spu->dispatch_table.CreateContext("", cr_server.MainContextInfo.CreateInfo.visualBits, cr_server.MainContextInfo.SpuContext);
{
if (pDummyMural)
{
/* since CreateContext does not actually create it on some platforms, e.g. on win,
* we need to do MakeCurrent to ensure it is created.
* There is some black magic in doing that to work around ogl driver bugs
* (i.e. we need to switch offscreen rendering off before doing make current) */
if (cr_server.currentCtxInfo)
{
cr_server.currentCtxInfo->SpuContext > 0 ? cr_server.currentCtxInfo->SpuContext : cr_server.MainContextInfo.SpuContext);
}
else
cr_server.head_spu->dispatch_table.MakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
rc = RTThreadCreate(&pWorker->hThread, crServerRpwWorkerThread, pWorker, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "CrServerDw");
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
else
{
}
}
else
{
}
}
else
{
crWarning("Failed to get dummy mural");
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
return rc;
}
int crServerRpwEntryResizeCleaned(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, uint32_t width, uint32_t height)
{
{
return VINF_SUCCESS;
}
if (!cr_server.currentCtxInfo)
{
if (!pDummy)
{
crWarning("crServerGetDummyMural failed");
return VERR_GENERAL_FAILURE;
}
}
{
}
for (int i = 0; i < 4; ++i)
{
}
{
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pContext->bufferobject.unpackBuffer->hwid);
}
{
for (int i = 0; i < 2; ++i)
{
cr_server.head_spu->dispatch_table.BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, width*height*4, 0, GL_STREAM_READ_ARB);
}
{
cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pContext->bufferobject.packBuffer->hwid);
}
else
{
}
}
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!cr_server.currentCtxInfo)
{
if (!pDummy)
{
crWarning("crServerGetDummyMural failed");
return VERR_GENERAL_FAILURE;
}
}
{
}
return VINF_SUCCESS;
}
int crServerRpwEntryResize(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, uint32_t width, uint32_t height)
{
{
width = 0;
height = 0;
}
return VINF_SUCCESS;
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
}
return rc;
}
int crServerRpwEntryInit(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, uint32_t width, uint32_t height, PFNCR_SERVER_RPW_DATA pfnData)
{
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
{
crWarning("submitting empty entry, ignoting");
return VERR_INVALID_PARAMETER;
}
if (RT_SUCCESS(rc))
{
{
}
else
{
}
}
else
{
return rc;
}
return rc;
}
static int crServerRpwEntryCancelCtl(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, CR_SERVER_RPW_CTL_TYPE enmType)
{
{
crWarning("Entry should be null for term request");
}
if (RT_SUCCESS(rc))
{
if (pEntry)
{
{
}
if (!CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Worker) && !CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Gpu))
{
/* can cancel it wight away */
return VINF_SUCCESS;
}
}
else
{
{
}
}
}
else
{
return rc;
}
if (!RT_SUCCESS(rc))
{
}
return VINF_SUCCESS;
}
{
if (!RT_SUCCESS(rc))
{
}
return rc;
}
{
}
{
if (!RT_SUCCESS(rc))
{
}
return rc;
}
{
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}