[waffle] [PATCH 03/12] core: store current context in wcore_display
Chad Versace
chad.versace at intel.com
Fri Apr 8 23:36:10 UTC 2016
n 01/08/2016 04:15 AM, Emil Velikov wrote:
> On 6 January 2016 at 21:56, Frank Henigman <fjhenigman at google.com> wrote:
>> For core functions that need to know the current context, like the
>> forthcoming wflinfo-like function.
>>
>> Signed-off-by: Frank Henigman <fjhenigman at google.com>
>> ---
>> src/waffle/api/waffle_gl_misc.c | 11 +++++++----
>> src/waffle/core/wcore_display.c | 1 +
>> src/waffle/core/wcore_display.h | 2 ++
>> 3 files changed, 10 insertions(+), 4 deletions(-)
>> diff --git a/src/waffle/core/wcore_display.c b/src/waffle/core/wcore_display.c
>> index 18262c3..bcaeacb 100644
>> --- a/src/waffle/core/wcore_display.c
>> +++ b/src/waffle/core/wcore_display.c
>> @@ -52,6 +52,7 @@ wcore_display_init(struct wcore_display *self,
>> mtx_unlock(&mutex);
>>
>> self->platform = platform;
>> + self->current_context = NULL;
> We calloc the struct so we should need this ?
I think the explicit assignment to NULL is appropriate here, as the call to calloc
is in another file. The explicit assignment makes it easy to *locally* verify that
the code is correct. If the call to calloc were local to this function, then I would feel
differently.
>> diff --git a/src/waffle/core/wcore_display.h b/src/waffle/core/wcore_display.h
>> index 6e374e3..1ccff6f 100644
>> struct wcore_display {
>> struct api_object api;
>> + struct wcore_context *current_context;
> Not 100% if wcore_display is the "right" struct, but keeping a
> reference in waffle sounds great imho. The alternative (using every
> permutation of GetCurrentContext) does feel like an overkill.
Waffle should keep a reference to the current context, but storing it in the
display is incorrect. The problem is that, at least in GLX and EGL, there
exists no context current to the *display*. Instead, a context may be current
to a *thread*. The distinction is significant, because a single display may be
bound to multiple threads, with a different context bound in each thread. In
other words, a display may have multiple current contexts, one per thread.
As a consequence, the thread's current context must be stored in thread-local
storage.
In response to this patch, I wrote my own patch [1] on my personal branch
'get-current' [2] that does exactly that: adds the current context and display
to Waffle's TLS. I plan on committing the patch after I submit to Intel's CI
and verify it doesn't interfere with any Piglit tests. (Intel's Mesa CI is down
for maintenance for today).
[1] https://github.com/chadversary/waffle/commit/1fdf3bd7f68bd1efa703c2cec4cd8a193c2182b5
[2] https://github.com/chadversary/waffle/commits/get-current
For reference, I quote below a comment from the patch that explains in more
detail the topic of "current objects".
Frank, wherever your patch series uses wcore_display::current_context, it should use
wcore_tinfo::current_context instead.
---- snip ----
/// A note on the current display and context:
///
/// EGL allows a thread to have current one the below combinations of display,
/// context, and surface.
///
/// a. No display, no context, no surface.
///
/// This case occurs when the thread has not previously called
/// eglMakeCurrent(), or when the thread has calls
/// eglMakeCurrent(EGL_DISPLAY_NONE, EGL_NO_SURFACE, EGL_NO_SURFACE,
/// EGL_NO_CONTEXT). Note that the EGL 1.5 specification mandates that
/// calling eglMakeCurrent() with EGL_DISPLAY_NONE generate an error,
/// but some implementations allow it anyway according to the footnote
/// in the EGL 1.5 specification (2014.08.27), p59:
///
/// Some implementations have chosen to allow EGL_NO_DISPLAY as
/// a valid dpy parameter for eglMakeCurrent. This behavior is not
/// portable to all EGL implementations, and should be considered as
/// an undocumented vendor extension.
///
/// b. One display, no context, no surface.
///
/// This case occurs when the thread calls eglMakeCurrent() with
/// a valid display but no context.
///
/// c. One display, one context, no surface.
///
/// Supported by EGL 1.5, EGL_KHR_surfaceless_context, and
/// EGL_KHR_create_context.
///
/// d. One display; one context, and both a draw and read surface.
///
/// The classic case.
///
/// EGL permits a context to be current to at most one thread. Same for
/// surfaces. However, a display may be current to multiple threads.
///
/// Therefore, to support waffle_get_current(), Waffle must track all three
/// objects (display, context, and waffle_window) in thread-specific storage.
/// It is insufficient to maintain a reference to the current context and
/// window in the current display, as there may exist multiple contexts and
/// surfaces, each current in different threads, but all children to the same
/// display.
///
struct wcore_tinfo {
...
struct wcore_display *current_display;
struct wcore_window *current_window;
struct wcore_context *current_context;
...
};
More information about the waffle
mailing list