Mac OS X:一个进程能否渲染到另一个进程的窗口?

23

问候!

我目前正在将一个网络浏览器插件从Win32移植到MacOSX。该插件的一个特性是,在加载插件时,它会生成一个独立的进程作为插件的“引擎”,并在插件窗口中执行绘图操作(具体来说,通过将OpenGL上下文附加到父进程的窗口并在该上下文中执行OpenGL渲染命令)。我们这样做是因为插件通常作为浏览器进程中的线程加载,因此插件中的崩溃会导致整个浏览器崩溃。通过把“重活”分配到一个单独的进程中并保持插件代码非常精简,我们可以保护用户免受此类崩溃的影响。

我想保留这种子进程渲染器架构在MacOSX上,但我听说过一个恶意谣言(与Google Chrome网络浏览器有关),即MacOSX不允许一个进程将其窗口交给另一个进程处理。我自己在这个领域的搜索结果并不确定;如果有人对此问题有任何了解,并可以提供一些如何实现此目标的建议或更具决定性的“无法实现”的答案,那将非常有帮助。

感谢您的帮助!


这可能会对您有兴趣。http://developer.apple.com/DOCUMENTATION/CoreFoundation/Conceptual/CFPlugIns/CFPlugIns.html - Jonathan
3
原始发帖人询问的内容和这个问题并没有真正相关。 - Chris Hanson
嗨 - 关于Win32的文档在哪里?我想了解多进程窗口所有权的限制。 - drudru
3个回答

10
我大约一年前正在研究这个问题的解决方案。我在苹果邮件列表上发了几个帖子:

http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg08056.html

http://www.mail-archive.com/quartzcomposer-dev@lists.apple.com/msg01878.html

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

我不得不使用CGWindowListCreateImage的解决方案,它获取opengl进程窗口的屏幕截图并将其转换为位图以在主进程窗口中显示。这远非高效,因为像素数据从视频内存传输到系统内存。

我还尝试过一个浮动窗口的解决方案。opengl进程窗口浮在主进程窗口之上,响应来自主窗口的鼠标移动。但是,我遇到了拖动延迟和窗口z顺序等问题。

你可能认为NSWindowSharingReadWrite可以满足你的需求,但当时几乎没有文档或示例。

但是也许在过去的一年里情况已经改变了。如果你发现了任何新的东西,请让我知道!

祝你好运

JC


1
经过大约一周的调查,我基本上到了这里。我向苹果提出了关于这个问题的请求,但是没有人告诉我如何利用NSWindowSharingType设置为NSWindowSharingReadWrite的窗口。从Mac OS 10.5开始,我将不得不将写入窗口称为“不存在”或“文档太差以至于无法关注”。我使用的解决方案是使用shm_open和mmap创建共享内存缓冲区,从进程A中进行glReadPixels,然后在进程B中进行glTexImage2D和渲染到四边形。速度足够快。 - fixermark
我也尝试过让OpenGL进程窗口浮在主进程之上的方法。处理Spaces需要使用一个私有API,该API会在用户切换屏幕或使用Expose时向您发送通知。最糟糕的部分是处理点击事件,这会导致主窗口的z位置在OpenGL窗口前面,但我在[NSWindow sendEvent]中找到了一个部分解决它的私有函数。这很丑陋,我也在寻找更好的解决方案。 - neoneye

6

这是苹果开发团队的综合答案。

在MacOSX 10.5及更早版本中,没有一种方法可以像将OpenGL渲染上下文附加到另一个进程的窗口那样干净地完成。人们开发的各种黑科技可能是这些情况下最好的解决方案。

在MacOS 10.6中,我们拥有最接近的东西是IOSurface系统;在10.6中使用它似乎是最干净的解决方案。如果你希望在渲染过程中截取到渲染到进程中的点击事件,你需要自己打包事件并使用你认为最合适的方法将其传递给渲染进程。

有关IOSurface的更多信息可以在此StackOverflow条目中找到。


4

如果将 NSWindowSharingType 设置为 NSWindowSharingReadWrite,则一个进程中的窗口可以被另一个进程写入。这个功能在 Leopard 中添加。请注意,我自己没有使用过这个功能,但至少可以消除“无法完成”的障碍。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接