[PATCH] winex11: Don't create a temporary context each time X11DRV_wglBindTexImageARB is called.

Miklós Máté mtmkls at gmail.com
Fri Feb 26 17:29:46 CST 2016


Theoretically wglBindTexImageARB is supposed to be a fast
render-to-texture method, and creating a new context is anything but fast.

This fixes horrible performance in Star Wars
Knights of the Old Republic when post-process effects are enabled.

v2: fix context caching, fix destructor, fix comments

Signed-off-by: Miklós Máté <mtmkls at gmail.com>
---
 dlls/winex11.drv/opengl.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 99befde..d945f9b 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -235,6 +235,8 @@ struct wgl_pbuffer
     GLenum     texture_type;
     GLuint     texture;
     int        texture_level;
+    GLXContext tmp_context;
+    GLXContext prev_context;
 };
 
 enum dc_gl_type
@@ -2320,6 +2322,7 @@ static BOOL X11DRV_wglDestroyPbufferARB( struct wgl_pbuffer *object )
     TRACE("(%p)\n", object);
 
     pglXDestroyPbuffer(gdi_display, object->drawable);
+    pglXDestroyContext(gdi_display, object->tmp_context);
     HeapFree(GetProcessHeap(), 0, object);
     return GL_TRUE;
 }
@@ -2925,7 +2928,6 @@ static BOOL X11DRV_wglBindTexImageARB( struct wgl_pbuffer *object, int iBuffer )
         int prev_binded_texture = 0;
         GLXContext prev_context;
         Drawable prev_drawable;
-        GLXContext tmp_context;
 
         prev_context = pglXGetCurrentContext();
         prev_drawable = pglXGetCurrentDrawable();
@@ -2940,21 +2942,27 @@ static BOOL X11DRV_wglBindTexImageARB( struct wgl_pbuffer *object, int iBuffer )
         }
 
         TRACE("drawable=%lx, context=%p\n", object->drawable, prev_context);
-        tmp_context = pglXCreateNewContext(gdi_display, object->fmt->fbconfig, object->fmt->render_type, prev_context, True);
+        if (!object->tmp_context) {
+            object->tmp_context = pglXCreateNewContext(gdi_display, object->fmt->fbconfig, object->fmt->render_type, prev_context, True);
+            object->prev_context = prev_context;
+        } else if (object->prev_context != prev_context) {
+            pglXDestroyContext(gdi_display, object->tmp_context);
+            object->tmp_context = pglXCreateNewContext(gdi_display, object->fmt->fbconfig, object->fmt->render_type, prev_context, True);
+            object->prev_context = prev_context;
+        }
 
         opengl_funcs.gl.p_glGetIntegerv(object->texture_bind_target, &prev_binded_texture);
 
         /* Switch to our pbuffer */
-        pglXMakeCurrent(gdi_display, object->drawable, tmp_context);
+        pglXMakeCurrent(gdi_display, object->drawable, object->tmp_context);
 
         /* Make sure that the prev_binded_texture is set as the current texture state isn't shared between contexts.
-         * After that upload the pbuffer texture data. */
+         * After that copy the pbuffer texture data. */
         opengl_funcs.gl.p_glBindTexture(object->texture_target, prev_binded_texture);
         opengl_funcs.gl.p_glCopyTexImage2D(object->texture_target, 0, object->use_render_texture, 0, 0, object->width, object->height, 0);
 
-        /* Switch back to the original drawable and upload the pbuffer-texture */
+        /* Switch back to the original drawable and context */
         pglXMakeCurrent(gdi_display, prev_drawable, prev_context);
-        pglXDestroyContext(gdi_display, tmp_context);
         return GL_TRUE;
     }
 
-- 
2.7.0




More information about the wine-patches mailing list