server_rpw.cpp revision c04472d7ec89d8a8806f367048d5e3d451508e61
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * VBox crOpenGL: Read Pixels worker
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * Copyright (C) 2010-2013 Oracle Corporation
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * available from http://www.virtualbox.org. This file is free software;
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * you can redistribute it and/or modify it under the terms of the GNU
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * General Public License (GPL) as published by the Free Software
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic void crServerRpwWorkerGpuSubmit(PRTLISTNODE pWorkList)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListForEach(pWorkList, pCurEntry, CR_SERVER_RPW_ENTRY, WorkerWorkEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, CR_SERVER_RPW_ENTRY_TEX(pCurEntry, Worker));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, CR_SERVER_RPW_ENTRY_PBO_CUR(pCurEntry));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync void *pvData = crAlloc(4*pCurEntry->Size.cx*pCurEntry->Size.cy);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvData);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, 0);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic void crServerRpwWorkerGpuComplete(PRTLISTNODE pGpuSubmitedList)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListForEach(pGpuSubmitedList, pCurEntry, CR_SERVER_RPW_ENTRY, GpuSubmittedEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync Assert(CR_SERVER_RPW_ENTRY_PBO_IS_ACTIVE(pCurEntry));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, CR_SERVER_RPW_ENTRY_PBO_COMPLETED(pCurEntry));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync void *pvData = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
c04472d7ec89d8a8806f367048d5e3d451508e61vboxsync cr_server.head_spu->dispatch_table.BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, pCurEntry->Size.cx*pCurEntry->Size.cy*4, 0, GL_STREAM_READ_ARB);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic void crServerRpwWorkerGpuMarkGpuCompletedSubmitedLocked(PRTLISTNODE pGpuSubmitedList, PRTLISTNODE pWorkList)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListForEachSafe(pGpuSubmitedList, pCurEntry, pNextEntry, CR_SERVER_RPW_ENTRY, GpuSubmittedEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_INVALIDATE(pCurEntry, Gpu);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListForEachSafe(pWorkList, pCurEntry, pNextEntry, CR_SERVER_RPW_ENTRY, WorkerWorkEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync Assert(CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pCurEntry, Worker));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync /* PBO mode, put to the GPU submitted queue*/
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListAppend(pGpuSubmitedList, &pCurEntry->GpuSubmittedEntry);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_PROMOTE(pCurEntry, Worker, Gpu);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync /* no PBO, we are already done entry data processing, free it right away */
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync Assert(!CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pCurEntry, Gpu));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_INVALIDATE(pCurEntry, Worker);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic void crServerRpwWorkerGetWorkLocked(CR_SERVER_RPW *pWorker, PRTLISTNODE pWorkList)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListForEachSafe(&pWorker->WorkList, pCurEntry, pNextEntry, CR_SERVER_RPW_ENTRY, WorkEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListAppend(pWorkList, &pCurEntry->WorkerWorkEntry);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_PROMOTE(pCurEntry, Submitted, Worker);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic DECLCALLBACK(int) crServerRpwWorkerThread(RTTHREAD ThreadSelf, void *pvUser)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_CTL_TYPE enmCtlType = CR_SERVER_RPW_CTL_TYPE_UNDEFINED;
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CRMuralInfo *pDummyMural = crServerGetDummyMural(pWorker->ctxVisBits);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync bool fExit = false;
c04472d7ec89d8a8806f367048d5e3d451508e61vboxsync int rc = RTSemEventSignal(pWorker->Ctl.hCompleteEvent);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.MakeCurrent(pDummyMural->spuWindow, 0, pWorker->ctxId);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync /* the crit sect is locked here */
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (pWorker->Ctl.enmType != CR_SERVER_RPW_CTL_TYPE_UNDEFINED)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync pWorker->Ctl.enmType = CR_SERVER_RPW_CTL_TYPE_UNDEFINED;
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crServerRpwWorkerGetWorkLocked(pWorker, &WorkList);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (enmCtlType != CR_SERVER_RPW_CTL_TYPE_UNDEFINED)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync bool fCompleted = false;
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync /* fNewGpuItems means new entries arrived. WorkList contains new GPU submitted data
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * fCompleted means completion was performed, GpuSubmittedList contains old GPU submitted data,
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * which is now completed and should be released */
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crServerRpwWorkerGpuMarkGpuCompletedSubmitedLocked(&GpuSubmittedList, &WorkList);
c04472d7ec89d8a8806f367048d5e3d451508e61vboxsync rc = RTSemEventSignal(pWorker->Ctl.hCompleteEvent);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync rc = RTSemEventWait(pWorker->hSubmitEvent, cWaitMillis);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic int crServerRpwCtlNotify(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync rc = RTSemEventWait(pWorker->Ctl.hCompleteEvent, RT_INDEFINITE_WAIT);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync pWorker->Ctl.enmType = CR_SERVER_RPW_CTL_TYPE_UNDEFINED;
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("RTSemEventSignal failed tmpRc %d", tmpRc);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic int crServerRpwCtl(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_CTL_TYPE enmType, CR_SERVER_RPW_ENTRY *pEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("crServerRpwCtlNotify failed rc %d", rc);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync rc = RTSemEventCreate(&pWorker->Ctl.hCompleteEvent);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CRASSERT(cr_server.MainContextInfo.CreateInfo.visualBits);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync pWorker->ctxId = cr_server.head_spu->dispatch_table.CreateContext("", cr_server.MainContextInfo.CreateInfo.visualBits, cr_server.MainContextInfo.SpuContext);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync pWorker->ctxVisBits = cr_server.MainContextInfo.CreateInfo.visualBits;
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync pDummyMural = crServerGetDummyMural(pWorker->ctxVisBits);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync /* since CreateContext does not actually create it on some platforms, e.g. on win,
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * we need to do MakeCurrent to ensure it is created.
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * There is some black magic in doing that to work around ogl driver bugs
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync * (i.e. we need to switch offscreen rendering off before doing make current) */
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.MakeCurrent(pDummyMural->spuWindow, 0, pWorker->ctxId);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.MakeCurrent(cr_server.currentMural->spuWindow, 0,
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.currentCtxInfo->SpuContext > 0 ? cr_server.currentCtxInfo->SpuContext : cr_server.MainContextInfo.SpuContext);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.MakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync rc = RTThreadCreate(&pWorker->hThread, crServerRpwWorkerThread, pWorker, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "CrServerDw");
c04472d7ec89d8a8806f367048d5e3d451508e61vboxsync rc = RTSemEventWait(pWorker->Ctl.hCompleteEvent, RT_INDEFINITE_WAIT);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.DestroyContext(pWorker->ctxId);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncint crServerRpwEntryResizeCleaned(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, uint32_t width, uint32_t height)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CRMuralInfo *pDummy = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.visualBits);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crServerPerformMakeCurrent(pDummy, &cr_server.MainContextInfo);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync for (int i = 0; i < 4; ++i)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.GenTextures(1, &pEntry->aidWorkerTexs[i]);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, pEntry->aidWorkerTexs[i]);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pContext->bufferobject.unpackBuffer->hwid);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync for (int i = 0; i < 2; ++i)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.GenBuffersARB(1, &pEntry->aidPBOs[i]);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pEntry->aidPBOs[i]);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, width*height*4, 0, GL_STREAM_READ_ARB);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pContext->bufferobject.packBuffer->hwid);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync GLuint uid = pContext->texture.unit[pContext->texture.curTextureUnit].currentTexture2D->hwid;
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, uid);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncint crServerRpwEntryCleanup(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("crServerRpwEntryCancel failed rc %d", rc);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CRMuralInfo *pDummy = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.visualBits);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crServerPerformMakeCurrent(pDummy, &cr_server.MainContextInfo);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.DeleteTextures(4, pEntry->aidWorkerTexs);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync cr_server.head_spu->dispatch_table.DeleteBuffersARB(2, pEntry->aidPBOs);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync memset(pEntry->aidPBOs, 0, sizeof (pEntry->aidPBOs));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync memset(pEntry->aidWorkerTexs, 0, sizeof (pEntry->aidWorkerTexs));
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Submitted);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncint crServerRpwEntryResize(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, uint32_t width, uint32_t height)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (width == pEntry->Size.cx && width == pEntry->Size.cy)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("crServerRpwEntryCleanup failed rc %d", rc);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync rc = crServerRpwEntryResizeCleaned(pWorker, pEntry, width, height);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("crServerRpwEntryResizeCleaned failed rc %d", rc);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncint crServerRpwEntryInit(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, uint32_t width, uint32_t height, PFNCR_SERVER_RPW_DATA pfnData)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync int rc = crServerRpwEntryResizeCleaned(pWorker, pEntry, width, height);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("crServerRpwEntryResizeCleaned failed rc %d", rc);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncint crServerRpwEntrySubmit(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (!CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Draw))
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync Assert(pWorker->Ctl.enmType == CR_SERVER_RPW_CTL_TYPE_UNDEFINED);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (!CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Submitted))
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_PROMOTE_KEEPVALID(pEntry, Draw, Submitted);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListAppend(&pWorker->WorkList, &pEntry->WorkEntry);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_XCHG_VALID(pEntry, Draw, Submitted);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic int crServerRpwEntryCancelCtl(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry, CR_SERVER_RPW_CTL_TYPE enmType)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (CR_SERVER_RPW_CTL_TYPE_TERM == enmType && pEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("Entry should be null for term request");
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Submitted))
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_INVALIDATE(pEntry, Submitted);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync if (!CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Worker) && !CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pEntry, Gpu))
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync /* can cancel it wight away */
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync RTListForEachSafe(&pWorker->WorkList, pCurEntry, pNextEntry, CR_SERVER_RPW_ENTRY, WorkEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_IS_VALID(pCurEntry, Submitted);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync CR_SERVER_RPW_ENTRY_TEX_INVALIDATE(pEntry, Submitted);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync crWarning("crServerRpwCtlNotify failed rc %d", rc);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncint crServerRpwEntryWaitComplete(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync int rc = crServerRpwCtl(pWorker, CR_SERVER_RPW_CTL_TYPE_WAIT_COMPLETE, pEntry);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncint crServerRpwEntryCancel(CR_SERVER_RPW *pWorker, CR_SERVER_RPW_ENTRY *pEntry)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync return crServerRpwEntryCancelCtl(pWorker, pEntry, CR_SERVER_RPW_CTL_TYPE_WAIT_COMPLETE);
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsyncstatic int crServerRpwCtlTerm(CR_SERVER_RPW *pWorker)
f0b06b8e4de2a0d9ddb10ac0a30d68fafd73d8c1vboxsync int rc = crServerRpwEntryCancelCtl(pWorker, NULL, CR_SERVER_RPW_CTL_TYPE_TERM);