Multi-windows in a desktop environment

I’m trying to set a multi-windowed program, where the windows are managed by the OS (ie. calling glfxCreateWindow for each window I want to create).

Currently, cocos doesn’t appear to support this. Couple questions from that:

1 - is there any plan to support multiple windows?

2 - if there’s no plan (and we take on the task), what would be the most recommended implementation strategy?

3 - If we implement it, is there a process to get it approved to be rolled into future official releases?

Regarding 2, I have been thinking of a few strategies.

The first is to refactor the Director singleton so that it’s not a singleton anymore, but consists of many instances managed by a DirectorManager (or some other name). The DirectorManager would manage the various instances of Director, keeping a 1:1 ratio of director to window. The various things that need to be shared (like the texture cache) would be moved up to the manager so that all directors still work on shared textures. My gut feeling is that this is closer to the “correct” solution but comes with a significant amount of refactoring. Due to the refactoring necessary, integrating future releases will be incredibly painful.

The second is to have a hacked Scene subclass which is responsible for the layout of all the windows at once. It would have to know about windows and can call directly or indirectly glfwCreateWindow. It would probably also have to manage its own window size and keep a track of its own projection matrix, scale factor, and assume responsibility for some other things that Director takes care of. This probably wouldn’t require as much refactoring as the first solution but is messy, and I believe we lose on some of the nice features that Director gives us, such as scene transitions.

I’ve only spent about a week looking through the cocos code, so hopefully someone will tell me I’m crazy and that there’s a much better way to do this :smile:

Can you explain a real use case for this? I feel like if you want multiple windows in a scene you would use a layer or node or ui::widget or something. When you say multi-windowed I automatically thing much like you would find on a standard PC desktop or Finder on OS X.

It does not and can not support this currently. Each windows would need its own gl context which would have its own state. At the moment the state is cached globally, and is not aware of multiple contexts.

Thanks for the replies. To go into more detail, we have what is basically a card/board game and we’d like to be able to launch multiple game instances simultaneously, but all under a single process. Sometimes the master process needs to “communicate” to a specific table or sometimes broadcast to all of them.

Currently, the single GLView manages the window and there’s a bunch of singletons (like the director) which are supposed to go 1:1 with the window. Since each window requires its own GLView and director, one possible solution is to create context switcher which is responsible for changing what the various singletons point to. For this, we’d basically have to go through the code and see which singletons can stay as true singletons, and which ones we need to allow multiple instancing. For shared resources like the texture cache in the director singleton, we’d could make it statically shared across all directors. A drawback to this solution is that iterating through the directors will need to be single threaded.

There’s also the multi-window scene solution where we’d create an augmented scene subclass that’s responsible for switching GLViews and updating all the windows. That solution is a bit messy.

The main point of my question though was to see if multi-windows is even on the radar as something you guys might want to ever support, and what you’d recommend as the best way to approach the problem. If it’s something you might one day support, we don’t want our solution to deviate too far from yours, or we’ll end up with integration nightmares when you implement it.

IMO you’d be much better off just going multi process and communicating via sockets or pipes or whatever. It would solve all the context issues, would be extremely stable since a crash in one process would be isolated to that process. You can debug one process at a time if need be. It’s just way simpler.

seperate processes wouldn’t benefit from resource sharing though

Most platforms can allocate shared memory, like a memory mapped file for example. But why not share the same context then and use threads? If you have multiple contexts, you are probably going to have duplicate framebuffers and possibly textures anyway.

That’s a good point. Unfortunately, our requirements are that it needs to be all created from a parent. I also mispoke earlier when I said our additional tables were spawned as child processes. They’re not, they’re only spawned as new windows, but still all under the same process.

Additionally, I’m seeing comments similar to this peppered throughout the cocos code
// FIXME: it should be a Director ivar. Move it there once support for multiple directors is added

If multiple directors are a planned thing, this will be the ideal way to allow for multiple directors. One way or another, we’ll need to make changes to cocos to allow for multiple windows and using multiple directors seems to be the “proper” way to do it.

Are there any plans in the future to support multiple directors and/or windows?

If there are, what does that plan look like? If we can do our changes in a way that’s similar to your strategy, it will keep our integration pains down when the feature is implemented on your side. Alternatively, could this be something where we provide a solution and it gets integrated (after review) into the mainline on your end?

I don’t see multiple directors happening, but I could be wrong. I do see multiple gl contexts happening, which would allow for multiple threads, and also multiple windows. I think that the director could have multiple scenes, one for each context. This could be used for writing tools in cocos where you have a main window, and separate palette windows for tools etc. Also supporting multiple contexts for doing work in a background thread would be useful, i.e. triple buffering and rendering command buffers on separate cores in parallel. I think that’s the direction its more likely to go. I think that this will happen in 4.0 at the earliest.

Thanks for the informative reply. So to hopefully keep our integration effort low when 4.0 rolls around, should we approach the multi window problem the way you described?

-multiple GLViews
-multiple scenes (could end up as a large director refactor)
-window specific settings would then be saved in scenes? (for example, they’d need their own model view matrix and flags to handle things like some windows being 2d ortho and others 3d perspective)
-cached window settings would probably also need to live on the scene, then retrieved by the director when needed
-animation intervals will also need to be moved to the scene?

This is just from going over the director code. I’m certainly no expert in Cocos, having only really been looking at it for a few weeks, and this problem specifically for a few days.

Can you think of other changes that would be necessary? Also, how confident are you that this is the implementation path you’d take to support multi windows?

The multiple scene thing is not a big deal. The Director has one scene, but you could have an array of scenes inside that one scene that you visit, one for each view. The scene is just the root of the graph that you want to render for a particular view. You could use cameras as well, and mark each node as belonging to a camera. Have one per view and that would achieve the same effect. There’s nothing to prevent you from creating additional views and attaching them to windows. The Director will only know about one of them, but you can use and manipulate the others. It won’t be portable, but you could abstract it so that it was.

No need to store the matrix. The MV matrix is indentity for the scene. If you use multiple cameras, then they will have the projection matrix.

Not sure why animation intervals come into play.

As for confidence on implementation? I can’t really say. I know how I would do things, but large teams and especially open source projects evolve differently from a small personal project.

Thanks again for the reply.

Regarding the animation interval, it looks like it’s wired up to the top level application code that controls the rate of update for the main game loop. Currently, it gets set when you pause and for use, pausing one window shouldn’t pause them all. So the pause functionality itself would probably need to be moved to a child scheduler that’s used just for the window/scene. Not sure if I explained this well.

I’ve currently started breaking apart director and moving members that should exist on a per window basis into a new struct which director will hold in a map. I feel like this is the ideal way to do it and the cleanest implementation. However, it involves quite a bit of refactoring to director.

After I get it working, would there be any interest in us submitting a pull request of our changes and having you review them?

Cheers

Absolutely, send a PR to cocos2d-x and send me a link and I will take a look. No guarantees it will get integrated, but we may learn a lot from your experience and use that to implement those features in 4.0

I’ve submitted the multi-window implementation pull request

This is my first time contributing to a project on GitHub, let alone cocos, so I’m not sure where discussion goes regarding the pull request.

There are some build errors that need resolving in some test cpp files that I never built. You can still have a look at it, specifically Director.cpp and GLViewImpl-desktop.cpp, as those files contain the brunt of the changes.

Very cool. I see the engine developers are chatting in the PR with you.

There’s still a few build errors in win32 that I can’t reproduce.

It looks like it’s with some auto generated files (jsb_cocos2dx_auto, for example). What do I need to do to regenerate all the .h/.cpp files?

Looks like it’s done by

D:\cocosCustomExternal\tools\bindings-generator\test\test.bat

However, I don’t have an android SDK. I’m just trying to fix some build errors in the windows environment but am blocked by these autogenerated files.

Can someone give me a hand with this?

Apart from the autogenerated js/lua stuff, cpp-empty-test should work. cpp-test works too, but since that test is basically a giant singleton, it’s not really compatible with multi-windows anyways.

It’d be great if I could get some feedback on this.

Hi all,
I’m strongly interested in the multi-windows feature.
This thread looked promising but it seems that this brilliant PR never made it to the official release.
Is there any similar feature available? Do you think there is a simple way to get a multi-windows application in the current version of Cocos2d-x?

Thanks
Pasquale

It will be good option for me too. E.g. for creating of arcade terminals or VLT.
Is it possible to add this feature into Cocos2d-x?

1 Like