Coder Social home page Coder Social logo

Comments (16)

floooh avatar floooh commented on June 24, 2024 3

Ok, I've started implementing context support in a branch and also wrote a small GLFW sample. I stumbled over another more important problem: I need to track in which context a resource has been created, and the resource needs to be destroyed while the same context is active (when the resource is destroyed manually).

For automatic resource destruction I had to add a method sg_discard_context(ctx), similar to sg_shutdown() this destroys any left-over resources, but only for the context that's being discarded.

So all in all it looks like this now:

  • there's a new handle type sg_context
  • ...and 3 new functions:
/* called once after a new GL context is initialized */
sg_context sg_setup_context();
/* called after switching GL contexts */
void sg_activate_context(sg_context ctx);
/* called before discarding GL context, also destroys all context resources */
void sg_discard_context();

Here's a sample program with GLFW: https://github.com/floooh/sokol-samples/blob/contexts/glfw/multiwindow-glfw.c

screen shot 2018-04-18 at 21 04 43

from sokol.

floooh avatar floooh commented on June 24, 2024 1

You could also create unshared resources by switching to the right GL context right before calling the sg_create_xxx() functions, you just need to make sure to use the right resources with the right context later...

I guess I'll try to write a little GLFW multiwindow demo later today to see if everything works as expected :)

from sokol.

floooh avatar floooh commented on June 24, 2024 1

It might work by running sgl_make_context() after it's associated glfwMakeContextCurrent() and sg_activate_context(), to make sure that any resource objects created by sokol-gl end up in the right GL- and sokol-gfx context but that's never been tested. sokol-gl contexts were actually intended for rendering into different render passes, not different GL contexts, but maybe it still works.

The entire idea of sokol-gfx contexts is more or less just a hack to support rendering into different GL contexts, but working with multiple GL contexts is so fragile that it doesn't make much sense to attempt fixing any issues.

from sokol.

floooh avatar floooh commented on June 24, 2024

Argh, yeah, I knew that would come up sooner or later ;) For the GL and D3D11 backends this isn't a big issue, all the currently global state can be gathered in a context struct behind a single global pointer, and some sort of context concept (with a 'currently active context').

I need to come up with an idea for the Metal backend though. In C, ARC doesn't allow to store Obj-C id's in structs, that's the reason why there are so many globals in the Metal backend currently.

from sokol.

pplux avatar pplux commented on June 24, 2024

I have no experience with Obj-C, but I thought there were ways to hold resources from C, with the
ownership qualification (http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership-qualification) but really, no idea.

Personally, I'm a huge fan of no-global-variables, I'd rather have an API where a context is created and every single call uses that context as first parameter, with a complete re-entrant API (even better if that means that each context can be handled by a different thread).

In the meantime maybe the "makeCurrent" function, or whatever solution you finally decide to settle with, might be a platform dependent solution. One of the beautiful things of sokol_gfx is the fact that it doesn't completely hides the platform under some abstraction, shaders for instance depends on the platform, and there are slightly different ways of declaring vertices, etc... I would find perfectly fine having the makeCurrent function working only on some backends.

If the makCurrent is allowed to work only on some platforms I can help with the OpenGL backend, which is the one I normally use if you want to.

from sokol.

floooh avatar floooh commented on June 24, 2024

__unsafe_unretained works in structs with Obj-C ARC, but I still need to keep a strong reference somewhere so that the object won't be released. Bit of a chicken/egg problem... I'll also need to find out what the equivalent of a GL context is for other APIs (in D3D11 a device is associated with a swap chain, but I don't know if it's possible to have several devices in the same process, likewise, in Metal, the docs say one MTLDevice represents one GPU, so what is a GL context would be done through a MTLRenderPassDescriptor and Drawable (which is already provided from the outside, so Sokol wouldn't actually need any extra context switching features for Metal...)

BUUUUT: ...maybe the GL Sokol backend also doesn't need anything extra... The GL context is managed outside Sokol anyway, and you would switch to another GL context with glfwMakeContextCurrent() outside of a begin_default_pass/end_pass/commit. The only thing you'd need to do is calling sg_reset_state_cache() after sg_commit() (it probably even makes sense to do this automatically in sg_commit().

Did you try if this works?

// render to first window...
glfwMakeContextCurrent(w0);
sg_begin_default_pass(...);
...
sg_end_pass();
sg_commit();
sg_reset_state_cache();

// render to another window...
glfwMakeContextCurrent(w1);
sg_begin_default_pass(...);
...
sg_end_pass();
sg_commit();
sg_reset_state_cache();
...

From sokol's point of view, two normal frames would be rendered, but outside sokol you're switching to another GL context between the first and second frame...

If this works I'd prefer this solution (but maybe move the reset state cache into sg_commit).

from sokol.

pplux avatar pplux commented on June 24, 2024

Indeed that should work on GLFW since GLFW context by default share OpenGL resources, thanks! I will definitely try that out. I haven't tested this, since I was checking if sokol would be able to work with multiple windows before actually working on it.

from sokol.

floooh avatar floooh commented on June 24, 2024

Hmm already found a problem with this approach... the global VAO object that's created because of OSX Core Profile requirements only exists on one context... I'll try find a stateless solution, but the naive solution (just check if a vertex array is bound, if not create and bind one) clashes with the idea that applications can do their own GL rendering...

from sokol.

floooh avatar floooh commented on June 24, 2024

...I guess the best solution is indeed to have 2 new functions:

glfwMakeContextCurrent(w);
sg_context ctx = sg_init_context();
...
sg_activate_context(ctx);
...

...this would only store data that's associated with a GL context, and inside sg_activate_context() I could also do the sg_reset_state_cache()...

from sokol.

pplux avatar pplux commented on June 24, 2024

That looks fine for me, as said I'd rather reentrant api without global variables, buuuut that just my personal preference. It would be nice if sg_activate_context internally restores the state (reset_state_cache)

from sokol.

pplux avatar pplux commented on June 24, 2024

Wonderful!! thanks for being so quickly!

from sokol.

floooh avatar floooh commented on June 24, 2024

This stuff is now in the master branch. I'm closing this issue. If anything pops up related to this it's better to open a new ticket.

from sokol.

timeinpixels avatar timeinpixels commented on June 24, 2024

Quick question - will this work with two separate threads?
One OpenGL context per thread. The 2nd thread will only call sg_update_image.
I tried it but I am having some issues...

from sokol.

floooh avatar floooh commented on June 24, 2024

Nope, the sokol header APIs all expect to be called from the same thread they have been initialized on.

from sokol.

Larpon avatar Larpon commented on June 24, 2024

Question: can we initialize a sokol_gl context for each new sokol_gfx context somehow? (I've tried with various ways over various versions of gfx/gl and I've only had little success in getting sokol_gl rendering going in multiple windows).

from sokol.

Larpon avatar Larpon commented on June 24, 2024

Thanks for the answer. I'll see if I can get it to work with this order - I was fighting some assert errors and think I also tried using sgl_make_context after those calls already (although with some offscreen stuff also, which might also have complicated things). My code base has grown a bit out of control since, though so I'll try it again with a more minimal setup to test with instead 🙂

from sokol.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.