SDL 1.3 window and OpenGL context management

Hi,

in addition to my previous post, I have a few less code-specific comments.

First of all, I’m glad that SDL 1.3 supports creating and managing several
windows and several OpenGL contexts, and that I do no longer have to call
wglGetProcAddress, wglMakeCurrent and wglSwapBuffers directly.

I’m particularly interested in having a separate “rendering thread” for OpenGL
(I mean for any GL commands including 3D graphics, not only SDL’s GL-based
renderer). MS Windows supports rendering outside the main thread. It worked for
me to deactivate an SDL_GLContext in the main thread (where it was created along
with a window) and activate it in a different thread. It would be nice if SDL
would officially support this (or similar) functionality on appropriate platforms.

One problem I see here is the need to call SDL_GL_SwapWindow in the rendering
thread, which indirectly calls SDL_GetWindowFromID, reading some global,
“unprotected” data. Creating a window at the same time in a different thread may
cause SDL_GetWindowFromID to malfunction. So the caller must make sure these
function calls will not overlap, by using a mutex, for example.
I think this issue might be worth noting in SDL documentation.

Changing SDL’s interface to use the pointers (SDL_Window *) directly instead of
SDL_WindowID might relax some restrictions on multi-threading. What is the
motivation behind SDL_WindowID?

BTW, could you let SDL_GL_GetProcAddress return a pointer-to-function rather
than a pointer-to-object? While C does not care, C++ disallows casting between
those kinds of pointers. When I tried, MinGW GCC 3.4.5 complained about such a
cast when it was a reinterpret_cast, but accepted it in C-style notation (still
compiling C++). I guess this is a GCC compatibility feature, not strictly
compliant with the standard.

Regards
Martin

Hi,

Because the function signature is not know, returning void* is semantically correct; returning void (*)(void) would be incorrect as not all functions returned would be this (and you’d have to cast it anyway) - better to be completely wrong that mostly wrong.

You can cast from void * to anything. If it’s not working, you’re just not doing it right (sorry!). Do a typedef of the function signature and use that in your reinterpret_cast.

Eddy________________________________________
From: sdl-bounces@lists.libsdl.org [sdl-bounces at lists.libsdl.org] On Behalf Of Martin [name.changed.by.editors at online.de]
Sent: 02 August 2008 14:32
To: sdl at lists.libsdl.org
Subject: [SDL] SDL 1.3 window and OpenGL context management

Hi,

in addition to my previous post, I have a few less code-specific comments.

First of all, I’m glad that SDL 1.3 supports creating and managing several
windows and several OpenGL contexts, and that I do no longer have to call
wglGetProcAddress, wglMakeCurrent and wglSwapBuffers directly.

I’m particularly interested in having a separate “rendering thread” for OpenGL
(I mean for any GL commands including 3D graphics, not only SDL’s GL-based
renderer). MS Windows supports rendering outside the main thread. It worked for
me to deactivate an SDL_GLContext in the main thread (where it was created along
with a window) and activate it in a different thread. It would be nice if SDL
would officially support this (or similar) functionality on appropriate platforms.

One problem I see here is the need to call SDL_GL_SwapWindow in the rendering
thread, which indirectly calls SDL_GetWindowFromID, reading some global,
“unprotected” data. Creating a window at the same time in a different thread may
cause SDL_GetWindowFromID to malfunction. So the caller must make sure these
function calls will not overlap, by using a mutex, for example.
I think this issue might be worth noting in SDL documentation.

Changing SDL’s interface to use the pointers (SDL_Window *) directly instead of
SDL_WindowID might relax some restrictions on multi-threading. What is the
motivation behind SDL_WindowID?

BTW, could you let SDL_GL_GetProcAddress return a pointer-to-function rather
than a pointer-to-object? While C does not care, C++ disallows casting between
those kinds of pointers. When I tried, MinGW GCC 3.4.5 complained about such a
cast when it was a reinterpret_cast, but accepted it in C-style notation (still
compiling C++). I guess this is a GCC compatibility feature, not strictly
compliant with the standard.

Regards
Martin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

[…]

BTW, could you let SDL_GL_GetProcAddress return a pointer-to-function rather
than a pointer-to-object? While C does not care, C++ disallows casting between
those kinds of pointers. When I tried, MinGW GCC 3.4.5 complained about such a
cast when it was a reinterpret_cast, but accepted it in C-style notation (still
compiling C++). I guess this is a GCC compatibility feature, not strictly
compliant with the standard.

Why don’t you try using a C-style cast?

Cheers,
RF.> From: sdl-bounces at lists.libsdl.org [sdl-bounces at lists.libsdl.org] On Behalf Of Martin [name.changed.by.editors at online.de]

Hi

[…] When I tried, MinGW GCC 3.4.5 complained about such a
cast when it was a reinterpret_cast, but accepted it in C-style notation (still
compiling C++). I guess this is a GCC compatibility feature, not strictly
compliant with the standard.

Why don’t you try using a C-style cast?

Just as I said above, GCC did accept that indeed. I’m currently using it as a
workaround, but I don’t think it’s compliant with the C++ Standard.

Thanks anyway

Martin

Hi

cullen e.a. (eac203) wrote:

Because the function signature is not know, returning void* is semantically correct; returning void (*)(void) would be incorrect as not all functions returned would be this (and you’d have to cast it anyway) - better to be completely wrong that mostly wrong.
You can cast from void * to anything. If it’s not working, you’re just not doing it right (sorry!). Do a typedef of the function signature and use that in your reinterpret_cast.

I know that this is correct for the C language. And I even agree that void*
would have better semantics than some arbitrary pointer-to-function type.
But the C++ standard thinks differently. I guess they tried to strictly separate
code from data. But they forgot to define a “void type for functions”, to allow
having a pointer to a function of unknown signature, like void* is a pointer to
an object of unknown type.

Here’s what the GCC C++ compiler responded to my first attempt:

“error: ISO C++ forbids casting between pointer-to-function and pointer-to-object”

I hope you agree that this is not just a syntax error (I’ll show you the code
below).
See The C++ Standard, section 5.2.10 “Reinterpret cast”, paragraphs 6 and 7, as
well as section 5.4 “Explicit type conversion (cast notation)”, both supporting
the compiler’s claim.

So, what I am asking for is to make the declaration of SDL_GL_GetProcAddress
"C++ compatible". Returning a pointer-to-function works for both C and C++
reliably, but returning a pointer-to-object is problematic for C++.

See the Windows API for comparison: wglGetProcAddress returns a PROC, which is a
pointer-to-function type (windef.h: typedef int (WINAPI *PROC)(); ).

Now for the code. My first attempt was:

template
static inline void
GetExtensionProcAddress(tFuncPtr & rFunc, char const * name)
{
rFunc = reinterpret_cast(SDL_GL_GetProcAddress(name));
}

Things I also tried:
(1) rFunc = (tFuncPtr)SDL_GL_GetProcAddress(name);
(2) rFunc =
reinterpret_cast(reinterpret_cast<intptr_t>(SDL_GL_GetProcAddress(name)));
(3) union { tFuncPtr f; void * g; } u;
u.g = SDL_GL_GetProcAddress(name);
rFunc = u.f;

MinGW GCC 3.4.5 accepted all three. (1) should then be working as desired on any
32-bit Windows (as it does on my Vista machine).
I didn’t dare to run (2) or (3). :wink:

Despite these results, I still don’t think that (1) is allowed by the C++
standard, see the sections I mentioned.
(2) and (3) are allowed, but involve too much “implementation-definedness” for
my taste.

Martin--------

BTW, could you let SDL_GL_GetProcAddress return a pointer-to-function rather
than a pointer-to-object? While C does not care, C++ disallows casting between
those kinds of pointers. When I tried, MinGW GCC 3.4.5 complained about such a
cast when it was a reinterpret_cast, but accepted it in C-style notation (still
compiling C++). I guess this is a GCC compatibility feature, not strictly
compliant with the standard.

Regards
Martin

Martin wrote:

I know that this is correct for the C language. And I even agree that
void* would have better semantics than some arbitrary
pointer-to-function type.
But the C++ standard thinks differently. I guess they tried to strictly
separate code from data. But they forgot to define a “void type for
functions”, to allow having a pointer to a function of unknown
signature, like void* is a pointer to an object of unknown type.

Important data point: In 16 bit DOS, one of the memory models used 16
bit pointers for data and 32 bit pointers for functions. While you
could cast a function pointer to void * back to function pointer in this
memory model, doing so would generate an incorrect result. Casting
between function pointer types may be wrong on the theoretical level,
but would generate the correct result in this memory model.–
Rainer Deyke - rainerd at eldwood.com