如何在Mac OS X(和iOS)中实现“窗口合成器”(WindowServer Process)?

时间:2013-07-30 02:16:20

标签: macos shared-memory quartz-graphics window-managers

如果我错了,请纠正我。我的理解是Mac OS X有一个WindowServer进程,它可以合成来自所有应用程序的窗口并在屏幕上绘制最终的合成图像。接下来的问题是WindowServer进程获取其他应用程序的“windows数据”(以某种形式,如位图)。它是通过应用程序和WindowServer进程之间的共享内存机制实现的吗?任何关于此的信息或指针/文件都会有所帮助!

此外,iOS在这个方面是否也有类似的实现?

谢谢!

1 个答案:

答案 0 :(得分:9)

将窗口位图封送到WindowServer进程的机制是一个无证实现的实现细节,实际上是“不透明的”,所以即使你现在努力弄清楚它是如何工作的,它也可能会从发布中改变发布。那说......

如果我不得不猜测它是如何工作的,我的猜测是有一块共享内存支持每个窗口,当你的窗口去绘制它的视图层次结构时,[NSGraphicsContext currentContext]被设置最多指向由该共享内存块支持的CGContext。当窗口绘制序列完成时,我猜想从您的进程向WindowServer进程发送一个或多个mach消息,告诉它是时候呈现刚刚绘制的帧。

在iOS上,似乎Springboard进程扮演窗口服务器角色,我想象的工作方式类似,但是,所有这些细节都是未记录的实现细节,因此不透明。由于CoreGraphics同时存在于OSX和iOS中,因此其机制相似。

您可以使用vmmap和调试器(或dtrace)找到此假设的一些证据。例如,您可以在可以将虚拟内存区域映射到流程(mmapvm_allocate等)的所有不同函数上设置断点(或dtrace探针),然后执行前/后比较在打开新窗口的行为中输出vmmap。您将看到有新的VM区域已映射到您的进程中,但您不会在断点/ dtrace探测器上看到任何相应的命中(即,您的进程中没有 映射这些区域)。这是窗口服务器进程将共享内存区域映射到进程的证据。有关这些区域的元信息将使用mach消息(最有可能)传递给您的进程。在一个简单的示例应用程序上尝试这个,打开一个新窗口并查看vmmap输出中的差异,显示该区域很可能是我们最近创建的窗口的后备存储:

CG backing stores      00000001c73f2000-00000001c74cc000 [  872K] rw-/rw- SM=SHM