请问 UIView 是怎么渲染自己的?

2017-02-10 21:40:55 +08:00
 jox0
如果不用 drawRect ,也不用 CALayer 的 contents 属性,一个 UIView 要怎么渲染自己的内容?比如一个背景颜色为黄色的、尺寸 100x100 的 UIView ,其中背景颜色使用 UIView 的 backgroundColor 或者 layer 的 backgroundColor 来设置。这个 UIView 的 layer 的 backing store bitmap data 是怎么生成的?
3062 次点击
所在节点    iDev
5 条回复
ningcool
2017-02-13 11:10:25 +08:00
1: UIView 无法渲染自己, UIView 是 CALayer 的一个包装,并实现了交互操作。
2: 对 UIView 的创建,属性的设置,绘制都是默认调用了 CALayer 的属性和实现,并且禁用了 CALayer 的隐式动画,智能在 UIView 的 animation block 中设置属性才会有动画效果......
3: CALayer 是 QuartzCore 框架中实现的,其本质是内存中的位图。 QuartzCore 又是 Core Foundation 框架下的, Core Foundation 框架底层是原始的 OpenGL 绘图。所以,这些绘制离不开 OpenGl 和 GPU 。

4: backing store bitmap data :位图可以存储图片的每一个像素点的信息,其中就是颜色值,通过编辑这些颜色实现 CALayer 的颜色。其他叠加,混合等可能是更复杂的 GPU 处理了。。
jox0
2017-02-13 11:13:59 +08:00
@ningcool 非常感谢,您说的这些我都了解,我就是想知道 “这些绘制离不开 OpenGL 和 GPU ” 这部分的技术细节,请问您是否了解?
ningcool
2017-02-16 12:15:00 +08:00
@jox0 我也只是了解一些宏观感念,没专门搞过: 计算机图形 基础就是 OpenGL 实现的算法逻辑,并在 GPU 实现计算渲染,最后输出屏幕。那么,界面上的图形控件肯定是封装了底层逻辑。至于 OpenGL 是怎么绘制图形的: 1 : 算法(算法很多,自己可以去了解一些)实现路径,计算像素点区域等(比如圆角路径,阴影路径,颜色等)。 2: 交给 GPU 处理路径填充,颜色渲染等,这些计算后的值需要映射到内存中,并输出屏幕。 不对的可以指出哈!!
jox0
2017-02-16 12:55:41 +08:00
@ningcool 3Q~ 我用了我的一张 RTI ,这两天正在通过邮件询问 Apple 的一个工程师这方面的问题,过两天如果有答案我再来这里更新
jox0
2017-06-19 17:12:20 +08:00
已经过去半年了,这段时间我学习了一下 opengl 绘图,想起来还有这么个帖子

当时苹果的工程师也没有给太多具体的技术细节,只是提到了最终 Core Animation 会 issue OpenGL drawing command 来生成最终的 bitmap。

随着新一代的绘图 API 的出现,现在 Core Animation 的底层很可能不再使用 OpenGL,而转而使用苹果新推出的 Metal。不过这都不重要,重要的是我当初提出的这个问题。

对于一个 UIView,如果不提供 bitmap (设置 layer 的 contents 属性),也不实现 drawRect 或者 CALayer drawing 的那几个 draw 函数,那么一个 UIView 的内容会根据这个 UIView 的状态( backgroundColor,bounds,其实都是 layer 的状态),提交到 render server,并由 render server 调用底层的图形 API 来绘制这个 UIView 的内容,并将最终绘制的 bitmap 结果通过类似 glReadPixels 的 API 从显寸上复制到 CPU 内存里,这部分内存由 CALayer 的内部私有变量来负责持有,这部分数据目前是无法直接获取到的,只能通过 CALayer 的 renderInContext:等 API 间接的取到,这里与 CALayer 的 contents 属性不同,contents 只是用来为一个 CALayer 提供内容的。

所以一个 UIView 有三种方式来生成内容,分别是 drawRect:,设置 layer 的 contents 属性,设置 UIView 本身或者 layer 的属性,这三种方式最终内存占用是一模一样的,但是消耗的 CPU 和 GPU 资源却不同,第一种需要调用 CPU 绘图 API 来绘制图形,CPU bound ;第二种虽然不需要调用 CPU 来绘图,但是可能会使用 CPU 来解压缩图片文件,所以也是 CPU bound ;第三种 CPU 只负责必要的状态修改,由 GPU 来完成主要的绘图工作,因为 GPU 绘图效率比 CPU 高,所以这种方式应该是效率最高的,整体的性能消耗也最低,GPU bound

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/339669

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX