[Mesa-dev] [PATCH 1/4] mesa: Add new MESA_multithread_makecurrent extension.

Ian Romanick idr at freedesktop.org
Tue Feb 22 11:57:38 PST 2011

Hash: SHA1

On 02/21/2011 02:41 PM, Eric Anholt wrote:
> This extension allows a client to bind one context in multiple threads
> simultaneously.  It is then up to the client to manage synchronization of
> access to the GL, just as normal multithreaded GL from multiple contexts
> requires synchronization management to shared objects.

With the exception of Mesa, every GL implementation implements a series
of useful optimizations for the multicontext case.  Operations that
modify GL objects are staged.  Each context has a cached copy of object
state (e.g., texture wrap mode).  Reads of state happen only from the
local copy.  Writes occur to the local copy and to the shared copy.  The
local copy is updated when Bind is called or when the context is made
current.  Almost all of the weird wording in appendix D (Shared Objects
and Multiple Contexts), especially the rules in D.3.3, of the GL spec is
designed to allow this implementation.

The big advantage of this scheme is that there is no locking on the
cached copy.  The lock on the per-context cached copy is implicitly
taken by MakeCurrent.  The shared copy is only needs explicit locking on
writes and binds.  In the common case, this greatly reduces the lock
contention and overhead.

As a follow-on optimization, writes to object state can be logged
instead of performed directly on the object.  Lockless log append
techniques are well known, and this further reduces lock activity.  At
least one of the major closed-source Linux OpenGL drivers does this, and
I believe the other does as well.

This adds overhead to the single-threaded cases, so most drivers
implement separate paths for single-threaded applications and
multithread applications.  Mesa used to do that too for some cases.  The
switch to TLS made the existing optimizations in Mesa unnecessary, so we
removed them a few years ago.

These are all well known techniques in multithreaded programming for
dealing with shared objects, so there's no magic here.  We really want
these optimizations in Mesa, but it's a lot of work to convert any large
inherently single-threaded code base to be optimized for multithreading.
 I had hoped to implement some of the required infrastructure as part of
the texture rework we have planned for this year.  That work keeps
getting pushed back, so who knows what will happen.

As far as I can tell, allowing multiple threads access to a single
context makes it impossible to eliminate the reader lock.  This also
means that no other vendor will ever implement this functionality.

The real problem is the significant impedance mismatch between the Cairo
API and the OpenGL API.  The Cairo model is
single-context-multiple-threads (SCMT) - a single context that is shared
by all threads.  The GL model is mutiple-contexts-multiple-threads
(MCMT) - a context per thread with data shared by the contexts.  We're
not going the change the fundamental designs of either API.  I believe
that we can optimize the behavior of SCMT applications with Mesa without
pessimizing MCMT.

At the very least, we could make this opt-in behavior.  We could add a
flag (or a set of flags) to glXCreateContextAttribsARB to enable this
for certain contexts.  That should allow both the SCMT optimization
today and the MCMT optimization in the future.  It may be difficult to
implement both in a single (driver) code base, but it seems solvable.

I thought we also decided that the bulk of the MakeCurrent overhead in
cairo-gl was due to the implicit flush in the old context when making a
new context current.  Can't we just fix that instead?  Though even that
is tricky to accurately specify and implement in the presence of
multiple contexts with shared objects.  At the very least we'd need to
make it clear that there's a lot of potentially undefined behavior.  For
example, even in a single threaded case changes to object X in context A
may not be visible in context B across a MakeCurrent from A to B even if
the object is rebound in B.

We may need to make the new behavior opt-in per-context anyway.  This
changes some very subtle and touchy GL behaviors, so some of these
changes may have unforeseen affects on existing apps.  Changing these
things always makes me nervous.  Over the years we've all independently
discovered that MakeCurrent and SwapBuffers are like Koch snowflakes...
there are *only* corner cases.
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/


More information about the mesa-dev mailing list