Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/adapter_gl.c | 2 +- dlls/wined3d/context.c | 18 +++++----- dlls/wined3d/device.c | 5 +-- dlls/wined3d/swapchain.c | 80 +++++++++++++++++++++++------------------- dlls/wined3d/wined3d_private.h | 14 ++++---- 5 files changed, 64 insertions(+), 55 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index cf5cb0e79c7..0b7fcf47297 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4637,7 +4637,7 @@ static HRESULT adapter_gl_init_3d(struct wined3d_device *device)
wined3d_cs_init_object(device->cs, wined3d_device_create_primary_opengl_context_cs, device); wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (!device->swapchains[0]->num_contexts) + if (!wined3d_swapchain_gl(device->swapchains[0])->context_count) return E_FAIL;
device->d3d_initialized = TRUE; diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 89f37cd6613..6742f21cc80 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1935,7 +1935,7 @@ HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct w return WINED3D_OK; }
-HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wined3d_swapchain *swapchain) +HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wined3d_swapchain_gl *swapchain_gl) { const struct wined3d_format *color_format, *ds_format; struct wined3d_context *context = &context_gl->c; @@ -1947,9 +1947,9 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi HGLRC ctx, share_ctx; unsigned int i;
- TRACE("context_gl %p, swapchain %p.\n", context_gl, swapchain); + TRACE("context_gl %p, swapchain %p.\n", context_gl, swapchain_gl);
- wined3d_context_init(&context_gl->c, swapchain); + wined3d_context_init(&context_gl->c, &swapchain_gl->s);
device = context->device; gl_info = &device->adapter->gl_info; @@ -1968,7 +1968,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi
if (!context_gl->dc) { - if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(wined3d_swapchain_gl(context->swapchain)))) + if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) { ERR("Failed to retrieve a device context.\n"); return E_FAIL; @@ -2056,7 +2056,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags);
/* Try to find a pixel format which matches our requirements. */ - if (!swapchain->ds_format) + if (!swapchain_gl->s.ds_format) { for (i = 0; i < ARRAY_SIZE(ds_formats); ++i) { @@ -2064,7 +2064,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi if ((context_gl->pixel_format = context_choose_pixel_format(device, context_gl->dc, color_format, ds_format, TRUE))) { - swapchain->ds_format = ds_format; + swapchain_gl->s.ds_format = ds_format; break; }
@@ -2075,7 +2075,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi else { context_gl->pixel_format = context_choose_pixel_format(device, - context_gl->dc, color_format, swapchain->ds_format, TRUE); + context_gl->dc, color_format, swapchain_gl->s.ds_format, TRUE); } } else @@ -4242,7 +4242,7 @@ struct wined3d_context *wined3d_context_gl_acquire(const struct wined3d_device * { TRACE("Rendering onscreen.\n");
- if (!(context_gl = wined3d_context_gl(swapchain_get_context(texture->swapchain)))) + if (!(context_gl = wined3d_swapchain_gl_get_context(wined3d_swapchain_gl(texture->swapchain)))) return NULL; } else @@ -4253,7 +4253,7 @@ struct wined3d_context *wined3d_context_gl_acquire(const struct wined3d_device * * context for the primary swapchain. */ if (current_context && current_context->c.device == device) context_gl = current_context; - else if (!(context_gl = wined3d_context_gl(swapchain_get_context(device->swapchains[0])))) + else if (!(context_gl = wined3d_swapchain_gl_get_context(wined3d_swapchain_gl(device->swapchains[0])))) return NULL; }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c37f386f99a..81a6d3ab36c 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -962,6 +962,7 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi void wined3d_device_delete_opengl_contexts_cs(void *object) { struct wined3d_resource *resource, *cursor; + struct wined3d_swapchain_gl *swapchain_gl; struct wined3d_device *device = object; struct wined3d_context_gl *context_gl; struct wined3d_device_gl *device_gl; @@ -991,8 +992,8 @@ void wined3d_device_delete_opengl_contexts_cs(void *object)
while (device->context_count) { - if (device->contexts[0]->swapchain) - swapchain_destroy_contexts(device->contexts[0]->swapchain); + if ((swapchain_gl = wined3d_swapchain_gl(device->contexts[0]->swapchain))) + wined3d_swapchain_gl_destroy_contexts(swapchain_gl); else wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); } diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index eb515f0a6dd..62bab65fcf3 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -27,11 +27,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(fps);
-static void wined3d_swapchain_destroy_object(void *object) -{ - swapchain_destroy_contexts(object); -} - void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) { HRESULT hr; @@ -66,9 +61,6 @@ void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) swapchain->back_buffers = NULL; }
- wined3d_cs_destroy_object(swapchain->device->cs, wined3d_swapchain_destroy_object, swapchain); - wined3d_cs_finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); - /* Restore the screen resolution if we rendered in fullscreen. * This will restore the screen resolution to what it was before creating * the swapchain. In case of d3d8 and d3d9 this will be the original @@ -97,10 +89,20 @@ void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) } }
+static void wined3d_swapchain_gl_destroy_object(void *object) +{ + wined3d_swapchain_gl_destroy_contexts(object); +} + void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) { + struct wined3d_cs *cs = swapchain_gl->s.device->cs; + wined3d_swapchain_cleanup(&swapchain_gl->s);
+ wined3d_cs_destroy_object(cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); + wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); + if (swapchain_gl->backup_dc) { TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain_gl->backup_wnd, swapchain_gl->backup_dc); @@ -440,6 +442,7 @@ static void wined3d_swapchain_gl_rotate(struct wined3d_swapchain *swapchain, str static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, unsigned int swap_interval, DWORD flags) { + struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(swapchain); const struct wined3d_swapchain_desc *desc = &swapchain->state.desc; struct wined3d_texture *back_buffer = swapchain->back_buffers[0]; const struct wined3d_fb_state *fb = &swapchain->device->cs->fb; @@ -530,7 +533,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, if (swapchain->render_to_fbo) swapchain_blit(swapchain, context, src_rect, dst_rect);
- if (swapchain->num_contexts > 1) + if (swapchain_gl->context_count > 1) gl_info->gl_ops.gl.p_glFinish();
/* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ @@ -1013,9 +1016,6 @@ err: heap_free(swapchain->back_buffers); }
- wined3d_cs_destroy_object(device->cs, wined3d_swapchain_destroy_object, swapchain); - wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (swapchain->front_buffer) { wined3d_texture_set_swapchain(swapchain->front_buffer, NULL); @@ -1039,10 +1039,19 @@ HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d, st HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) { + HRESULT hr; + TRACE("swapchain_gl %p, device %p, desc %p, parent %p, parent_ops %p.\n", swapchain_gl, device, desc, parent, parent_ops);
- return wined3d_swapchain_init(&swapchain_gl->s, device, desc, parent, parent_ops, &swapchain_gl_ops); + if (FAILED(hr = wined3d_swapchain_init(&swapchain_gl->s, device, desc, parent, parent_ops, &swapchain_gl_ops))) + { + /* Cleanup any context that may have been created for the swapchain. */ + wined3d_cs_destroy_object(device->cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); + wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + } + + return hr; }
HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain *swapchain_vk, struct wined3d_device *device, @@ -1085,13 +1094,12 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win return hr; }
-static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain *swapchain) +static struct wined3d_context_gl *wined3d_swapchain_gl_create_context(struct wined3d_swapchain_gl *swapchain_gl) { - struct wined3d_device *device = swapchain->device; + struct wined3d_device *device = swapchain_gl->s.device; struct wined3d_context_gl *context_gl; - struct wined3d_context **ctx_array;
- TRACE("Creating a new context for swapchain %p, thread %u.\n", swapchain, GetCurrentThreadId()); + TRACE("Creating a new context for swapchain %p, thread %u.\n", swapchain_gl, GetCurrentThreadId());
wined3d_from_cs(device->cs);
@@ -1101,7 +1109,7 @@ static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain return NULL; }
- if (FAILED(wined3d_context_gl_init(context_gl, swapchain))) + if (FAILED(wined3d_context_gl_init(context_gl, swapchain_gl))) { WARN("Failed to initialise context.\n"); heap_free(context_gl); @@ -1119,47 +1127,45 @@ static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain
context_release(&context_gl->c);
- if (!(ctx_array = heap_calloc(swapchain->num_contexts + 1, sizeof(*ctx_array)))) + if (!wined3d_array_reserve((void **)&swapchain_gl->contexts, &swapchain_gl->contexts_size, + swapchain_gl->context_count + 1, sizeof(*swapchain_gl->contexts))) { ERR("Failed to allocate new context array memory.\n"); wined3d_context_gl_destroy(context_gl); return NULL; } - memcpy(ctx_array, swapchain->context, sizeof(*ctx_array) * swapchain->num_contexts); - heap_free(swapchain->context); - ctx_array[swapchain->num_contexts] = &context_gl->c; - swapchain->context = ctx_array; - swapchain->num_contexts++; + swapchain_gl->contexts[swapchain_gl->context_count++] = context_gl;
- return &context_gl->c; + return context_gl; }
-void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) +void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) { unsigned int i;
- for (i = 0; i < swapchain->num_contexts; ++i) + for (i = 0; i < swapchain_gl->context_count; ++i) { - wined3d_context_gl_destroy(wined3d_context_gl(swapchain->context[i])); + wined3d_context_gl_destroy(swapchain_gl->contexts[i]); } - heap_free(swapchain->context); - swapchain->num_contexts = 0; - swapchain->context = NULL; + heap_free(swapchain_gl->contexts); + swapchain_gl->contexts_size = 0; + swapchain_gl->context_count = 0; + swapchain_gl->contexts = NULL; }
-struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) +struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) { DWORD tid = GetCurrentThreadId(); unsigned int i;
- for (i = 0; i < swapchain->num_contexts; ++i) + for (i = 0; i < swapchain_gl->context_count; ++i) { - if (wined3d_context_gl(swapchain->context[i])->tid == tid) - return swapchain->context[i]; + if (swapchain_gl->contexts[i]->tid == tid) + return swapchain_gl->contexts[i]; }
- /* Create a new context for the thread */ - return swapchain_create_context(swapchain); + /* Create a new context for the thread. */ + return wined3d_swapchain_gl_create_context(swapchain_gl); }
HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4ce2a2a29ca..80ed41bb845 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -78,6 +78,7 @@ struct wined3d_fragment_pipe_ops; struct wined3d_adapter; struct wined3d_context; struct wined3d_state; +struct wined3d_swapchain_gl; struct wined3d_texture_gl; struct wined3d_vertex_pipe_ops;
@@ -2110,7 +2111,7 @@ GLenum wined3d_context_gl_get_offscreen_gl_buffer(const struct wined3d_context_g const unsigned int *wined3d_context_gl_get_tex_unit_mapping(const struct wined3d_context_gl *context_gl, const struct wined3d_shader_version *shader_version, unsigned int *base, unsigned int *count) DECLSPEC_HIDDEN; HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; void wined3d_context_gl_load_tex_coords(const struct wined3d_context_gl *context_gl, const struct wined3d_stream_info *si, GLuint *current_bo, const struct wined3d_state *state) DECLSPEC_HIDDEN; void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl, @@ -4399,17 +4400,12 @@ struct wined3d_swapchain
LONG prev_time, frames; /* Performance tracking */
- struct wined3d_context **context; - unsigned int num_contexts; - struct wined3d_swapchain_state state; HWND win_handle; };
void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN; void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, const struct wined3d_device *device) DECLSPEC_HIDDEN; @@ -4422,6 +4418,10 @@ struct wined3d_swapchain_gl { struct wined3d_swapchain s;
+ struct wined3d_context_gl **contexts; + SIZE_T contexts_size; + SIZE_T context_count; + HDC backup_dc; HWND backup_wnd; }; @@ -4432,7 +4432,9 @@ static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_s }
void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;