[PATCH 4/5] wined3d: Move the context array from struct wined3d_swapchain to struct wined3d_swapchain_gl.

Henri Verbeet hverbeet at codeweavers.com
Tue Aug 13 03:31:39 CDT 2019


Signed-off-by: Henri Verbeet <hverbeet at 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;
-- 
2.11.0




More information about the wine-devel mailing list