请问 UIView 是怎么渲染自己的? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
jox0
V2EX    iDev

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

  •  
  •   jox0 2017-02-10 21:40:55 +08:00 3608 次点击
    这是一个创建于 3240 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如果不用 drawRect ,也不用 CALayer 的 contents 属性,一个 UIView 要怎么渲染自己的内容?比如一个背景颜色为黄色的、尺寸 100x100 的 UIView ,其中背景颜色使用 UIView 的 backgroundColor 或者 layer 的 backgroundColor 来设置。这个 UIView 的 layer 的 backing store bitmap data 是怎么生成的?
    第 1 条附言    2017-02-13 11:20:11 +08:00
    根据已知的各种文档和 wwdc 视频,所有的 UIView 都是 layer backed ,所有的 layer 都会缓存一份 bitmap ,如果开发者不实现 drawRect ,也不使用 layer 的 contents 属性来为 layer 提供内容,那么 Core Animation 会使用内部的 drawing path ,这个内部的 drawing path 是使用硬件加速的,我很好奇在这种情况下 Core Animation 内部会怎么做。 apple 提供的 API 里可以把 UIView 的 layer 类型切换为 CAEAGLLayer ,这样就可以使用 OpenGL ES 来绘制 layer 的内容,比直接使用 OpenGL ES 绘图的 set up 过程要简单一些,我非常好奇 Core Animation 内部的实现是否与此类似,与直接使用 CAEAGLLayer 有什么不同
    5 条回复    2017-06-19 17:12:20 +08:00
    ningcool
        1
    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
        2
    jox0  
    OP
       2017-02-13 11:13:59 +08:00
    @ningcool 非常感谢,您说的这些我都了解,我就是想知道 “这些绘制离不开 OpenGL 和 GPU ” 这部分的技术细节,请问您是否了解?
    ningcool
        3
    ningcool  
       2017-02-16 12:15:00 +08:00   1
    @jox0 我也只是了解一些宏观感念,没专门搞过: 计算机图形 基础就是 OpenGL 实现的算法逻辑,并在 GPU 实现计算渲染,最后输出屏幕。那么,界面上的图形控件肯定是封装了底层逻辑。至于 OpenGL 是怎么绘制图形的: 1 : 算法(算法很多,自己可以去了解一些)实现路径,计算像素点区域等(比如圆角路径,阴影路径,颜色等)。 2: 交给 GPU 处理路径填充,颜色渲染等,这些计算后的值需要映射到内存中,并输出屏幕。 不对的可以指出哈!!
    jox0
        4
    jox0  
    OP
       2017-02-16 12:55:41 +08:00
    @ningcool 3Q~ 我用了我的一张 RTI ,这两天正在通过邮件询问 Apple 的一个工程师这方面的问题,过两天如果有答案我再来这里更新
    jox0
        5
    jox0  
    OP
       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
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2691 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 11:28 PVG 19:28 LAX 03:28 JFK 06:28
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86