Open gkoz opened 8 years ago
@mjkoo
Either way to me it looks like GtkGLArea creates a context for you, but relies on you to correctly infer the correct way to load and use OpenGL functions after initialization, so the same type of logic with the same type of assumptions probably needs to go somewhere to make this usable.
What would happen if we gave epoxy_get_proc_address
to gl::load_with
?
Pretty sure that should work, I can give it a try in a bit to confirm. That seems to be about half of what epoxy provides, the other half is autogenerated wrappers around OpenGL functions which load the required symbols at runtime lazily. This is pretty much exactly what gl-rs does AFAICT, so we don't necessarily care about that. Given that, not sure if it would make more sense to make bindings and add in a dependency to libepoxy or just use FFI to call the underlying glx/wgl/egl functions based on the target platform in the same manner epoxy and glutin does.
I'd favor adding limited bindings over replicating libepoxy
logic.
I'm also unsure if gdk_gl_context_set_required_version
and gdk_gl_context_set_forward_compatible
can influence the selection of gl*
functions in a problematic way or just let you get an error if the implementation is incompatible.
It might be possible to look for the epoxy_get_proc_address
symbol on demand at runtime instead of adding a dependency.
Looking into it now, one issue is that epoxy_get_proc_address
is not exposed by libepoxy
, likely because it takes some bootstrapping to get it working, which we would also need to make sure gets done prior to using it even if we expose it. We could instead try to load libepoxy
at runtime like you said and have gl::load_with
attempt to dlsym
the equivalent symbols from libepoxy
. This is somewhat janky because now there's two levels of symbol lookup and function pointer caching being done, but it looks like not doing that will involve a considerable amount of tearing libepoxy
apart.
Regarding gdk_gl_context_set_required_version
and gdk_gl_context_set_forward_compatible
, it looks like they just influence the parameters passed to glXCreateContextAttribsARB
from gdk (https://github.com/GNOME/gtk/blob/master/gdk/x11/gdkglcontext-x11.c#L578), which should result in calling an invalid function returning an error code according to https://open.gl/context , so this shouldn't be a worry I think.
Diving into the gdk source it looks like they themselves already depend on libepoxy
and use it to set up the context behind the scenes, so that's good news. Do you know of a relatively platform-independent way to dlsym
or similar from rust to get at the epoxy_*
wrappers from gl-rs
?
I'm only aware of unstable std::dynamic_lib. FWIW, GTK relies on dlfcn-win32 to provide dlsym
on Windows.
Pushed a PoC of the example from https://github.com/gtk-rs/examples/pull/44 back to the same branch, now loading OpenGL function addresses from epoxy, relying on it being loaded already by gdk. Uses the shared_library
crate which is also used in glutin (std::dynamic_lib
is deprecated according to rustc I guess).
This is not correct as it stands, as I'm pretty sure gl-rs
's caching of function pointers means that it will always invoke the libepoxy
lookup function even when epoxy has already resolved the address and altered it's internal function pointer table resulting in many superfluous dlsym
invocations, but is a start.
After researching it a bit, I think the best way forward is to use gl_generator
from gl-rs
with a custom generator to wrap libepoxy
and let it handle lookup and caching of the relevant functions when using it with GdkGLContext
. I've modified the StaticStructGenerator
from gl_generator
to generate bindings for epoxy in a build.rs
, and modified the example again to use this new method (https://github.com/mjkoo/examples/tree/epoxy-glgenerator) This supports the goal of integrating with glium, as it uses the similar StructGenerator
to construct it's own bindings, but using the get_proc_address
from glutin or similar.
Wanted to get some thoughts on this before moving forward, but I'm thinking that the build.rs
from the branch above can be cleaned up and put into gdk, and the epoxy wrapper struct made accessible from GdkGLContext
. A GtkGLArea
user can then use the reference to the context in its render handler and can use this to draw to its window.
Oh wow, that's some sudden explosion of complexity :)
If generating epoxy bindings is the way to go, that's outside the scope of gdk
. In the near term you'd probably want to put an epoxy-gl
crate on github and import that in the example.
and the epoxy wrapper struct made accessible from
GdkGLContext
From what I can see there's nothing but magical side-effects to tie a particular GLContext
instance to the gl*
impls, so I'm not sure what the GLContext
/GLArea
bindings could do except reexport the epoxy bindings.
Perhaps the best solution would be to ignore the whole epoxy/GLContext/GLArea
stack and implement a new widget, that would really be in control of its context. Like, wrap the window primitive, that glium
creates, in a GdkWindow
or vice versa.
Okay sure, crate is up and example is updated.
From what I can see there's nothing but magical side-effects to tie a particular GLContext instance to the gl* impls, so I'm not sure what the GLContext/GLArea bindings could do except reexport the epoxy bindings.
Yep, I agree with that assessment. Using the epoxy
bindings though should allow us to get some integration going with glium
now, perhaps with a small modification to glium
to allow generic gl::Gl
type structs in glium::context::Context
(epoxy::Gl
should be a drop-in replacement). If @tomaka isn't for that, potentially a small get_proc_address
-like shim could be added to epoxy
to allow interop with gl/glium
without running into the function pointer caching issue. Will keep exploring down these lines for the time being.
As an update, I've ported the simple example from the examples repo to use glium
with a GLArea
. There's definitely some cleanup to do and some decisions on where things belong, but it seems to work. The work in progress code can be found at https://github.com/mjkoo/examples/tree/glium
That's impressive progress :)
FWIW it seems GLContext
can be made capable of telling if it's current (by comparing what gdk_gl_context_get_current
returns with itself) and the dimensions could be retrieved from its GdkWindow
.
swap_buffers
... it appears the window painting mechanisms take care of swapping the buffers. Wouldn't queue_render
there lead to constant repainting?
Thanks! Cool that's good to know, I will change is_current
accordingly and try it out. Spot on with your comment on swap_buffers
, I actually just fixed that up :)
I'm thinking that once the Backend
and Facade
implementations are looking good they probably also belong in a separate crate, similar to glium_sdl2
, unless you'd like to see this put into gdk
somewhere?
I will change is_current accordingly and try it out
This will require patching gdk
as I don't think PartialEq/Eq
is implemented for objects. Not even sure if it would be appropriate in general to implement it as pointers equality. Specialization will make that decision easier :)
I'm thinking that once the Backend and Facade implementations are looking good they probably also belong in a separate crate, similar to glium_sdl2, unless you'd like to see this put into gdk somewhere?
Still not sure but a separate crate is a good bet.
Ok cool I will defer doing that for now then, let me know what you'd like to see going forward.
A separate crate seems more flexible, we wouldn't need to track changes to glium
and epoxy
in the gdk
and gtk
crates and it wouldn't matter that GLArea
and GLContext
are in different crates.
Hey @mjkoo - sorry for digging up an old thread!
Has there been any progress on this front? (another crate being spawned or something similar)
I'd really like to use glium in some of my gtk apps. :-}
Sorry I ended up going a different route for the project that I was working on and therefore didn't pursue this further, not sure what the glium + gtk story is today.
What is the state of this? Wanted to render into Flutter which uses GTK, it gives me a GTKWindow and GdkGlContext. Works in C++ so should work in Rust
There currently is no reliable way to use the
glium
/gl
crates together withGLContext
(andgtk::GLArea
), which a very limited API. Previous discussion is at https://github.com/gtk-rs/examples/pull/44, let's continue it here.