wined3d: Offscreen rendering from foreign threads.
This commit is contained in:
parent
f13f48876c
commit
9928a4c4fd
|
@ -628,6 +628,27 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* findThreadContextForSwapChain
|
||||||
|
*
|
||||||
|
* Searches a swapchain for all contexts and picks one for the thread tid.
|
||||||
|
* If none can be found the swapchain is requested to create a new context
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
static WineD3DContext *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain, DWORD tid) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
|
||||||
|
if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
|
||||||
|
return ((IWineD3DSwapChainImpl *) swapchain)->context[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new context for the thread */
|
||||||
|
return IWineD3DSwapChainImpl_CreateContextForThread(swapchain);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* ActivateContext
|
* ActivateContext
|
||||||
*
|
*
|
||||||
|
@ -660,17 +681,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
if(hr == WINED3D_OK && swapchain) {
|
if(hr == WINED3D_OK && swapchain) {
|
||||||
TRACE("Rendering onscreen\n");
|
TRACE("Rendering onscreen\n");
|
||||||
|
|
||||||
context = NULL;
|
context = findThreadContextForSwapChain(swapchain, tid);
|
||||||
for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
|
|
||||||
if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
|
|
||||||
context = ((IWineD3DSwapChainImpl *) swapchain)->context[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!context) {
|
|
||||||
/* Create a new context for the thread */
|
|
||||||
context = IWineD3DSwapChainImpl_CreateContextForThread(swapchain);
|
|
||||||
}
|
|
||||||
This->render_offscreen = FALSE;
|
This->render_offscreen = FALSE;
|
||||||
/* The context != This->activeContext will catch a NOP context change. This can occur
|
/* The context != This->activeContext will catch a NOP context change. This can occur
|
||||||
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
|
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
|
||||||
|
@ -685,6 +697,10 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
glDrawBuffer(GL_FRONT);
|
glDrawBuffer(GL_FRONT);
|
||||||
checkGLcall("glDrawBuffer(GL_FRONT)");
|
checkGLcall("glDrawBuffer(GL_FRONT)");
|
||||||
}
|
}
|
||||||
|
} else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
|
||||||
|
if(This->pbufferContext && tid == This->pbufferContext->tid) {
|
||||||
|
This->pbufferContext->tid = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IWineD3DSwapChain_Release(swapchain);
|
IWineD3DSwapChain_Release(swapchain);
|
||||||
|
|
||||||
|
@ -699,21 +715,20 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
TRACE("Rendering offscreen\n");
|
TRACE("Rendering offscreen\n");
|
||||||
This->render_offscreen = TRUE;
|
This->render_offscreen = TRUE;
|
||||||
|
|
||||||
if(tid != This->lastThread) {
|
|
||||||
FIXME("Offscreen rendering is only supported from the creation thread yet\n");
|
|
||||||
FIXME("Expect a crash now ...\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(wined3d_settings.offscreen_rendering_mode) {
|
switch(wined3d_settings.offscreen_rendering_mode) {
|
||||||
case ORM_FBO:
|
case ORM_FBO:
|
||||||
/* FBOs do not need a different context. Stay with whatever context is active at the moment */
|
/* FBOs do not need a different context. Stay with whatever context is active at the moment */
|
||||||
if(This->activeContext) {
|
if(This->activeContext && tid == This->lastThread) {
|
||||||
context = This->activeContext;
|
context = This->activeContext;
|
||||||
} else {
|
} else {
|
||||||
/* This may happen if the app jumps streight into offscreen rendering
|
/* This may happen if the app jumps streight into offscreen rendering
|
||||||
* Start using the context of the primary swapchain
|
* Start using the context of the primary swapchain. tid == 0 is no problem
|
||||||
|
* for findThreadContextForSwapChain.
|
||||||
|
*
|
||||||
|
* Can also happen on thread switches - in that case findThreadContextForSwapChain
|
||||||
|
* is perfect to call.
|
||||||
*/
|
*/
|
||||||
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0];
|
context = findThreadContextForSwapChain(This->swapchains[0], tid);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -738,6 +753,10 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
}
|
}
|
||||||
|
|
||||||
if(This->pbufferContext) {
|
if(This->pbufferContext) {
|
||||||
|
if(This->pbufferContext->tid != 0 && This->pbufferContext->tid != tid) {
|
||||||
|
FIXME("The PBuffr context is only supported for one thread for now!\n");
|
||||||
|
}
|
||||||
|
This->pbufferContext->tid = tid;
|
||||||
context = This->pbufferContext;
|
context = This->pbufferContext;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -748,13 +767,17 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
|
|
||||||
case ORM_BACKBUFFER:
|
case ORM_BACKBUFFER:
|
||||||
/* Stay with the currently active context for back buffer rendering */
|
/* Stay with the currently active context for back buffer rendering */
|
||||||
if(This->activeContext) {
|
if(This->activeContext && tid == This->lastThread) {
|
||||||
context = This->activeContext;
|
context = This->activeContext;
|
||||||
} else {
|
} else {
|
||||||
/* This may happen if the app jumps streight into offscreen rendering
|
/* This may happen if the app jumps streight into offscreen rendering
|
||||||
* Start using the context of the primary swapchain
|
* Start using the context of the primary swapchain. tid == 0 is no problem
|
||||||
|
* for findThreadContextForSwapChain.
|
||||||
|
*
|
||||||
|
* Can also happen on thread switches - in that case findThreadContextForSwapChain
|
||||||
|
* is perfect to call.
|
||||||
*/
|
*/
|
||||||
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0];
|
context = findThreadContextForSwapChain(This->swapchains[0], tid);
|
||||||
}
|
}
|
||||||
glDrawBuffer(This->offscreenBuffer);
|
glDrawBuffer(This->offscreenBuffer);
|
||||||
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
|
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
|
||||||
|
|
Loading…
Reference in New Issue