[Mesa-dev] [PATCH 21/26] mesa: Add an attribute for conditions to turn off threading.

Marek Olšák maraeo at gmail.com
Wed Feb 8 18:03:35 UTC 2017

From: Eric Anholt <eric at anholt.net>

The threading for GL core is in place, but there are so few applications
actually using a core GL context that it would be nice to extend support
back.  However, some of the features of compat GL (particularly user
vertex arrays) would be so expensive to track state for that we want to be
able to disable threading when we discover that the app is using them.
 src/mapi/glapi/gen/gl_API.dtd     | 7 ++++++-
 src/mapi/glapi/gen/gl_marshal.py  | 8 ++++++++
 src/mapi/glapi/gen/marshal_XML.py | 1 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/mapi/glapi/gen/gl_API.dtd b/src/mapi/glapi/gen/gl_API.dtd
index 133bc04..dc4a199 100644
--- a/src/mapi/glapi/gen/gl_API.dtd
+++ b/src/mapi/glapi/gen/gl_API.dtd
@@ -32,21 +32,22 @@
                    count               CDATA   #IMPLIED
                    value               NMTOKEN #REQUIRED>
 <!ATTLIST function name                NMTOKEN #REQUIRED
                    alias               NMTOKEN #IMPLIED
                    vectorequiv         NMTOKEN #IMPLIED
                    es1                 CDATA   "none"
                    es2                 CDATA   "none"
                    deprecated          CDATA   "none"
                    exec                NMTOKEN #IMPLIED
                    desktop             (true | false) "true"
-                   marshal             NMTOKEN #IMPLIED>
+                   marshal             NMTOKEN #IMPLIED
+                   marshal_fail        CDATA #IMPLIED>
 <!ATTLIST size     name                NMTOKEN #REQUIRED
                    count               NMTOKEN #IMPLIED
                    mode                (get | set) "set">
 <!ATTLIST param    name                NMTOKEN #REQUIRED
                    type                CDATA   #REQUIRED
 		   client_only	       (true | false) "false"
                    count               NMTOKEN #IMPLIED
                    counter             (true | false) "false"
                    count_scale         NMTOKEN "1"
                    output              (true | false) "false"
@@ -122,20 +123,24 @@ param:
         For example, this will insert an empty "height" field after the
         "width" field in the protocol for TexImage1D.
      marshal - One of "sync", "async", "draw", or "custom", defaulting to
         async unless one of the arguments is something we know we can't
         codegen for.  If "sync", we finish any queued glthread work and call
         the Mesa implementation directly.  If "async", we queue the function
         call to be performed by glthread.  If "custom", the prototype will be
         generated but a custom implementation will be present in marshal.c.
         If "draw", it will follow the "async" rules except that "indices" are
         ignored (since they may come from a VBO).
+     marshal_fail - an expression that, if it evaluates true, causes glthread
+        to finish and tear down before the Mesa implementation is called
+        directly.  Used to disable glthread for GL compatibility interactions
+        that we don't want to track state for.
      rop - Opcode value for "render" commands
      sop - Opcode value for "single" commands
      vendorpriv - Opcode value for vendor private (or vendor private with
          reply) commands
      large - set to "true" of the render command can use RenderLarge protocol.
      doubles_in_order - older commands always put GLdouble data at the
          start of the render packet.  Newer commands (e.g., 
          ProgramEnvParameter4dvARB) put the in the order that they appear
diff --git a/src/mapi/glapi/gen/gl_marshal.py b/src/mapi/glapi/gen/gl_marshal.py
index 1a63343..a50d773 100644
--- a/src/mapi/glapi/gen/gl_marshal.py
+++ b/src/mapi/glapi/gen/gl_marshal.py
@@ -229,20 +229,28 @@ class PrintCode(gl_XML.gl_print_base):
                 if p.img_null_flag:
                     size = '({0} ? {1} : 0)'.format(p.name, size)
             out('size_t cmd_size = {0};'.format(' + '.join(size_terms)))
             out('{0} *cmd;'.format(struct))
+            if func.marshal_fail:
+                out('if ({0}) {{'.format(func.marshal_fail))
+                with indent():
+                    out('_mesa_glthread_destroy(ctx);')
+                    self.print_sync_dispatch(func)
+                    out('return;')
+                out('}')
             out('if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {')
             with indent():
             out('} else {')
             with indent():
             if func.marshal == 'draw':
                 out('/* We relied on all vertex and index data being in VBOs */')
diff --git a/src/mapi/glapi/gen/marshal_XML.py b/src/mapi/glapi/gen/marshal_XML.py
index d56e4dd..80f7f54 100644
--- a/src/mapi/glapi/gen/marshal_XML.py
+++ b/src/mapi/glapi/gen/marshal_XML.py
@@ -51,20 +51,21 @@ class marshal_function(gl_XML.gl_function):
         for p in self.parameters:
             if p.is_padding:
             if p.is_variable_length():
         # Store the "marshal" attribute, if present.
         self.marshal = element.get('marshal')
+        self.marshal_fail = element.get('marshal_fail')
     def marshal_flavor(self):
         """Find out how this function should be marshalled between
         client and server threads."""
         # If a "marshal" attribute was present, that overrides any
         # determination that would otherwise be made by this function.
         if self.marshal not in (None, 'draw'):
             return self.marshal
         if self.exec_flavor == 'skip':

More information about the mesa-dev mailing list