Commit 12252d05 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Use the context manager to select the primary render target.

parent 7253fae3
......@@ -2444,12 +2444,6 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
object->ddraw_format = pixelformat_for_depth(GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES));
ReleaseDC(0, hDC);
/* Allocate one context for now */
object->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(WineD3DContext *));
object->contexts[0] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineD3DContext));
object->numContexts = 1;
object->activeContext = 0;
return WINED3D_OK;
create_device_error:
......
......@@ -237,6 +237,10 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
if(iface == device->ddraw_primary)
device->ddraw_primary = NULL;
if(iface == device->lastActiveRenderTarget) {
device->lastActiveRenderTarget = NULL;
}
TRACE("(%p) Released\n", This);
HeapFree(GetProcessHeap(), 0, This);
......@@ -714,23 +718,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
} else if (swapchain != NULL) {
IWineD3DSwapChainImpl *implSwapChain;
IWineD3DDevice_GetSwapChain((IWineD3DDevice *)myDevice, 0, (IWineD3DSwapChain **)&implSwapChain);
if (swapchain->glCtx == implSwapChain->render_ctx && swapchain->drawable == implSwapChain->win) {
/* This will fail for the implicit swapchain, which is why there needs to be a context manager */
if (backbuf) {
glReadBuffer(GL_BACK);
} else if (iface == swapchain->frontBuffer) {
glReadBuffer(GL_FRONT);
} else if (iface == myDevice->depthStencilBuffer) {
FIXME("Stencil Buffer lock unsupported for now\n");
} else {
FIXME("Should have got here!\n");
glReadBuffer(GL_BACK);
}
/* ActivateContext should have selected the correct opengl context for that */
if (backbuf) {
glReadBuffer(GL_BACK);
} else if (iface == swapchain->frontBuffer) {
glReadBuffer(GL_FRONT);
} else if (iface == myDevice->depthStencilBuffer) {
FIXME("Stencil Buffer lock unsupported for now\n");
} else {
/* We need to switch contexts to be able to read the buffer!!! */
FIXME("The buffer requested isn't in the current openGL context\n");
notInContext = TRUE;
/* TODO: check the contexts, to see if were shared with the current context */
FIXME("Should have got here!\n");
glReadBuffer(GL_BACK);
}
IWineD3DSwapChain_Release((IWineD3DSwapChain *)implSwapChain);
}
......
......@@ -125,10 +125,11 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
/* Clean up the context */
/* check that we are the current context first */
if(glXGetCurrentContext() == This->glCtx){
if(glXGetCurrentContext() == This->context->glCtx){
glXMakeCurrent(This->display, None, NULL);
}
glXDestroyContext(This->display, This->glCtx);
glXDestroyContext(This->display, This->context->glCtx);
DeleteContext(This->wineD3DDevice, This->context);
/* IUnknown_Release(This->parent); This should only apply to the primary swapchain,
all others are created by the caller, so releasing the parent should cause
the child to be released, not the other way around!
......@@ -183,15 +184,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
/* TODO: If only source rect or dest rect are supplied then clip the window to match */
TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable);
TRACE("preseting display %p, drawable %ld\n", This->display, This->context->drawable);
/* Don't call checkGLcall, as glGetError is not applicable here */
if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
/* Set this swapchain up to point to the new destination.. */
#ifdef USE_CONTEXT_MANAGER
/* TODO: use a context mamager */
#endif
/* Ok, now we switch the opengl context behind the context manager's back. Tidy this up when
* the ctx manager is completely in place
*/
/* FIXME: Never access */
IWineD3DSwapChainImpl *swapChainImpl;
IWineD3DDevice_GetSwapChain((IWineD3DDevice *)This->wineD3DDevice, 0 , (IWineD3DSwapChain **)&swapChainImpl);
......@@ -204,7 +205,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
XVisualInfo template;
int num;
Display *oldDisplay = This->display;
GLXContext oldContext = This->glCtx;
GLXContext oldContext = This->context->glCtx;
IUnknown* tmp;
GLXContext currentContext;
Drawable currentDrawable;
......@@ -234,21 +235,21 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
/* Now we have problems? well not really we just need to know what the implicit context is */
/* now destroy the old context and create a new one (we should really copy the buffers over, and do the whole make current thing! */
/* destroy the active context?*/
TRACE("Creating new context for %p %p %p\n",This->display, This->visInfo, swapChainImpl->glCtx);
This->glCtx = glXCreateContext(This->display, This->visInfo, swapChainImpl->glCtx, GL_TRUE);
TRACE("Creating new context for %p %p %p\n",This->display, This->visInfo, swapChainImpl->context->glCtx);
This->context->glCtx = glXCreateContext(This->display, This->visInfo, swapChainImpl->context->glCtx, GL_TRUE);
if (NULL == This->glCtx) {
if (NULL == This->context->glCtx) {
ERR("cannot create glxContext\n");
}
This->drawable = This->win;
This->render_ctx = This->glCtx;
This->context->drawable = This->win;
This->render_ctx = This->context->glCtx;
/* Setup some default states TODO: apply the stateblock to the new context */
/** save current context and drawable **/
currentContext = glXGetCurrentContext();
currentDrawable = glXGetCurrentDrawable();
if (glXMakeCurrent(This->display, This->win, This->glCtx) == False) {
ERR("Error in setting current context (display %p context %p drawable %ld)!\n", This->display, This->glCtx, This->win);
if (glXMakeCurrent(This->display, This->win, This->context->glCtx) == False) {
ERR("Error in setting current context (display %p context %p drawable %ld)!\n", This->display, This->context->glCtx, This->win);
}
checkGLcall("glXMakeCurrent");
......@@ -301,7 +302,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
/* TODO: The slow way, save the data to memory, create a new context for the destination window, transfer the data cleanup, it may be a good idea to the move this swapchain over to the using the target winows context so that it runs faster in feature. */
glXSwapBuffers(This->display, This->drawable); /* TODO: cycle through the swapchain buffers */
glXSwapBuffers(This->display, This->context->drawable); /* TODO: cycle through the swapchain buffers */
TRACE("glXSwapBuffers called, Starting new frame\n");
/* FPS support */
......
......@@ -466,7 +466,7 @@ struct WineD3DContext {
DWORD numDirtyEntries;
DWORD isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
/* TODO: Render target / swapchain this ctx belongs to */
IWineD3DSurface *surface;
/* TODO: Thread this ctx belongs to */
/* Stores some inforation about the context state for optimization */
......@@ -478,6 +478,10 @@ struct WineD3DContext {
BOOL lastWasPow2Texture[MAX_TEXTURES];
GLenum tracking_parm; /* Which source is tracking current colour */
BOOL last_was_blit;
/* The actual opengl context */
GLXContext glCtx;
Drawable drawable;
};
typedef enum ContextUsage {
......@@ -487,6 +491,11 @@ typedef enum ContextUsage {
} ContextUsage;
void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, Window win);
WineD3DContext *AddContext(IWineD3DDeviceImpl *This, GLXContext glCtx, Drawable drawable);
void DeleteContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
void set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target);
/* Routine to fill gl caps for swapchains and IWineD3D */
BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display);
......@@ -547,33 +556,12 @@ typedef struct IWineD3DImpl
extern const IWineD3DVtbl IWineD3D_Vtbl;
/** Hacked out start of a context manager!! - Subject to removal **/
typedef struct glContext {
int Width;
int Height;
int usedcount;
GLXContext context;
Drawable drawable;
IWineD3DSurface *pSurface;
#if 0 /* TODO: someway to represent the state of the context */
IWineD3DStateBlock *pStateBlock;
#endif
/* a few other things like format */
} glContext;
/* TODO: setup some flags in the regestry to enable, disable pbuffer support
(since it will break quite a few things until contexts are managed properly!) */
extern BOOL pbuffer_support;
/* allocate one pbuffer per surface */
extern BOOL pbuffer_per_surface;
/* Maximum number of contexts/pbuffers to keep in cache,
set to 100 because ATI's drivers don't support deleting pBuffers properly
this needs to be migrated to a list and some option availalbe for controle the cache size.
*/
#define CONTEXT_CACHE 100
typedef struct ResourceList {
IWineD3DResource *resource;
struct ResourceList *next;
......@@ -633,6 +621,10 @@ struct IWineD3DDeviceImpl
IWineD3DSurface *stencilBufferTarget;
/* Caches to avoid unneeded context changes */
IWineD3DSurface *lastActiveRenderTarget;
IWineD3DSwapChain *lastActiveSwapChain;
/* palettes texture management */
PALETTEENTRY palettes[MAX_PALETTES][256];
UINT currentPalette;
......@@ -662,9 +654,6 @@ struct IWineD3DDeviceImpl
HRESULT state;
BOOL d3d_initialized;
/* Screen buffer resources - subject to removal */
glContext contextCache[CONTEXT_CACHE];
/* A flag to check for proper BeginScene / EndScene call pairs */
BOOL inScene;
......@@ -695,9 +684,11 @@ struct IWineD3DDeviceImpl
BOOL useDrawStridedSlow;
/* Context management */
WineD3DContext **contexts; /* Dynamic array containing pointers to context structures */
UINT activeContext; /* Only 0 for now */
UINT numContexts; /* Always 1 for now */
WineD3DContext **contexts; /* Dynamic array containing pointers to context structures */
WineD3DContext *activeContext; /* Only 0 for now */
UINT numContexts; /* Always 1 for now */
WineD3DContext *pbufferContext; /* The context that has a pbuffer as drawable */
DWORD pbufferWidth, pbufferHeight; /* Size of the buffer drawable */
};
extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
......@@ -1340,20 +1331,15 @@ typedef struct IWineD3DSwapChainImpl
long prev_time, frames; /* Performance tracking */
/* TODO: move everything up to drawable off into a context manager
and store the 'data' in the contextManagerData interface.
IUnknown *contextManagerData;
*/
WineD3DContext *context; /* Later a array for multithreading */
HWND win_handle;
Window win;
Display *display;
GLXContext glCtx;
XVisualInfo *visInfo;
GLXContext render_ctx;
/* This has been left in device for now, but needs moving off into a rendertarget management class and separated out from swapchains and devices. */
Drawable drawable;
} IWineD3DSwapChainImpl;
extern const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment