1

有时图形上下文这个术语有点抽象。它们实际上是系统资源,但它们是来自显卡的资源,就像文件句柄是来自硬盘驱动器或任何永久存储设备的系统资源一样?

正如文件句柄有一些关于文件句柄是只读还是读/写的状态,以及下一次读取操作的当前位置——状态,图形上下文有关于当前笔画颜色、笔画宽度、或任何相关数据。(更新:在写入模式下,我们可以转到 200MB 文件中的任何点并更改数据,就像我们拥有 Graphics Context 的画布并在其上绘制东西一样)

所以图形上下文实际上是全局的、系统范围的资源。它们不是应用程序单例或任何东西的一部分,就像文件或文件句柄不是(必然)应用程序单例的一部分一样。

如果没有强大的图形卡(或者如果图形卡已经耗尽资源),那么操作系统可以使用位图的低级图形例程模拟图形上下文,而不是让图形卡处理它。

这就是图形上下文在 iOS 和大多数其他常见操作系统上的实际工作方式吗?

4

2 回答 2

3

我认为最好不要根据特定的系统资源来考虑图形上下文。据我所知,图形上下文不再对应于任何特定资源,而不是任何类“对象”,当然除了内存。实际上,Graphics 上下文旨在为核心图形功能提供“画布”以进行操作。事实是,Apple 并没有向我们提供图形上下文如何在内部工作的具体细节。但是我们确实知道一些事情:

  1. 图形上下文基本上是一种“状态”,而不是其他任何东西。它为一组特定的绘图例程保存诸如描边/填充颜色、线宽等信息。

  2. 它不在 GPU 上处理。相反,它在 CPU 上处理(完成所有绘制)并将生成的图像(某种形式的位图)“传递”到 GPU 以进行显示/动画处理(实际上它将图像直接渲染到 GPU 的缓冲区)。这就是为什么 'renderInContext' 方法在新 iPad 3 中不能很好地工作的原因。 renderInContext首先为您提供图像,这涉及渲染和复制图像。如果您希望随后显示它,则必须将其传递回 Core Graphics,然后由 Core Graphics 将图像写回。在 iPad 3 上,这涉及大量内存(取决于视图的大小)并且很容易溢出缓冲区。

  3. 为 UIView 的“drawRect”方法提供的图形上下文旨在提供尽可能高效的上下文。这就是为什么你不能在上下文之外的视图中绘制任何东西,也不能为要绘制的视图创建自己的上下文。实际的绘制是在运行循环中处理的,这就是为什么我们使用这种方法来标记一个需要绘制的 UIView: [view setNeedsDisplay].

  4. UIViews 的图形上下文在主线程上绘制,是的,再次在 CPU 上处理。这确实意味着过于复杂的绘图可能会占用您的主要应用程序,但现在使用多核处理器已经不是什么大问题了。

  5. 你可以创建一个图形上下文,但只能绘制到一个图像上。这与 UIView 上下文的作用完全相同,只是它是供您使用的,而不是绘制到屏幕上或动画。从 iOS 4 开始,您可以在其他线程(除了主线程)中处理这些图像上下文。

    如果您正在寻找进行 GPU 绘图,我相信这样做的唯一方法是在使用 iOS 时使用 OpenGL。如果您使用的是 MacOS,我认为您实际上可以使用 QuartzGL 在 GPU 上启用 Quartz(核心图形......同样的东西)绘图。但这可能不值得努力,看这篇文章:Mac QuartzGL(显卡上的2D绘图)性能

更新

正如您在下面的评论中看到的,Apple 目前对 Quartz 绘图的安排可能是最好的,特别是因为视图直接绘制到 GPU 缓冲区。人们很容易认为处理任何视觉效果都应该在 GPU 上完成,但事实是,GPU 并不是为矢量图而设计的。它们旨在处理大量变换、照明、纹理映射等。通过使用 CPU 处理矢量绘图并将其他所有内容留给 GPU,Apple 已经适当地拆分了图形处理。此外,由于 Quartz 直接绘制到 GPU 的缓冲区(这避免了繁重的 memcpy),因此您不会在 CPU 和 GPU 之间的数据传输中失去任何效率。

于 2012-05-27T18:29:01.667 回答
1

有时图形上下文这个术语有点抽象。

是的,故意的。Quartz 是一种抽象的通用绘图系统。它可能会或可能不会在内部对图形硬件进行一些优化,但您对此没有太多了解。它所做的优化类型可能会随着时间和不同类型的图形硬件而改变。

它们实际上是系统资源,但它们是来自显卡的资源

不,绝对不是。Quartz 是一种软件渲染器——即使在没有图形硬件存在的情况下也能工作,并且可以绘制到图形硬件没有任何用处的 PDF 之类的东西上。

在内部,Quartz(及其与操作系统其余部分的接口)可能有一些“快速路径”,在某些情况下可以利用 GPU。但这绝不是常见的情况。

正如文件句柄有一些关于文件句柄是只读还是读/写的状态,以及下一次读取操作的当前位置——这些状态,图形上下文有关于当前笔画颜色、笔画宽度、或任何相关数据。

这是对的。

所以图形上下文实际上是全局的、系统范围的资源。

不,Quartz 只是一个在您的应用程序中运行代码的库。如果您创建一个新的 CGContext,那么只有您的应用程序会受到影响——就像您的代码创建了您自己的类之一的新实例一样。

如果没有强大的图形卡(或者如果图形卡已经耗尽资源),那么操作系统可以使用位图的低级图形例程模拟图形上下文,而不是让图形卡处理它。

你把这两个案子颠倒了。一般来说,Quartz 在软件中工作,带有位图。在少数情况下,它可能会使用 GPU 更快地将这些位图显示在屏幕上,前提是一切都完全正确。

于 2012-05-27T18:30:38.377 回答