views:

832

answers:

4

Greetings!

I'm currently porting a web browser plugin from Win32 to MacOSX. One of the features of the plugin is that when the plugin is loaded, it spawns a separate process that serves as the "engine" of the plugin and executes drawing operations into the window of the plugin (specifically, by attaching an OpenGL context to the parent process's window and executing OpenGL rendering commands into that context). We do this because the plugin is typically loaded as a thread within the browser process, so crashes in the plugin would take down the whole browser. By partitioning the 'heavy lifting' into a separate process and keeping the plugin code very slim, we can protect users against such crashes.

I'd like to preserve this child-process-renderer architecture on MacOSX, but I've heard a nasty rumor (related to the Google Chrome web browser) that MacOSX doesn't allow a process to hand access to its windows to another process. My own search in this space has been inconclusive; if anyone has any knowledge of this problem and could either provide some advice on how to accomplish this goal or a more conclusive "can't be done," it would be extremely helpful.

Thank you for your help!

+3  A: 

A window in one process can be written to by another process, seemingly if the NSWindowSharingType is set to NSWindowSharingReadWrite. That was added in Leopard. Note that I haven't used this myself, but I would say that it at least removes the "can't be done" obstacle for you ;-)

Graham Lee
+4  A: 

I was investigating a solution to this almost a year ago. I started a few threads on the apple mailing lists:

http://www.mail-archive.com/[email protected]/msg08056.html

http://www.mail-archive.com/[email protected]/msg01878.html

http://lists.apple.com/archives/mac-opengl/2008/May/msg00099.html

I had to revert to a solution which used CGWindowListCreateImage which took a screen grab of the opengl process window and convert it to a bitmap for display in the main process window. This is far from effeicient since pixel data is transfered from video ram to system ram.

I also tried a floating window solution. The opengl process window floated above the main process window and respond to mouse movements from the main window. But I had issues with dragging lag and window z order.

You would think NSWindowSharingReadWrite would do what you require, but doumentation/examples back then were practically non existent.

But maybe things have changed in the last year. Keep me posted if you find anything new !

Good luck

JC

JonnyC
After investigating this issue for about a week, I landed more-or-less here. I have outstanding requests to Apple on the issue, but nobody has gotten back to me on how to take advantage of a window with NSWindowSharingType set to NSWindowSharingReadWrite. As of Mac OS 10.5, I'm going to have to call writing-to-windows either "nonexistant" or "too poorly documented to care."The solution I used was to create a shared memory buffer with shm_open and mmap, glReadPixels into that from process A, and then glTexImage2D and render to a quad in process B. It's fast enough.
fixermark
I also tried the approach where the opengl process window floats above the main process. Dealing with Spaces requires that you use a private API that gives you notifications when the user switches screens or uses expose. The worst part is dealing with clicks, that causes the main window's z position to go in front of the opengl window, but I found a private function in [NSWindow sendEvent] that partially solved it. This is ugly and I'm looking for a better solution as well.
neoneye
A: 

Did any body try this? (NSWindowSharingType set to NSWindowSharingReadWrite)

Where can I find more information or a sample?

Thomas3D
Thomas, That's the big problem... There are no samples that use NSWindowSharingReadWrite to my knowledge and no more information. I actually have an outstanding question with some Apple reps right now on this issue.I hear that Safari in Mac OS X 10.6 does plugin sandboxing like Chrome does; if this rumor is true, it would imply heavily to me that this feature has been "fixed" in 10.6, if it doesn't work in 10.5
fixermark
+1  A: 

Here is the overall answer received from Apple's development team.

There is essentially no way to do this in MacOSX 10.5 and earlier that is as clean as attaching an OpenGL rendering context to another process's window. The hacks people have developed may be the best solutions in those cases.

The closest thing we have in MacOS 10.6 is the IOSurface system; using that in 10.6 seems to be the cleanest solution. If you want clicks in the rendered-to process to be intercepted by the rendering process, you'll have to bundle up the events yourself and pass them to the rendering process using whatever method you find most appropriate.

More information on IOSurface could be found in this StackOverflow entry

fixermark