问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

OpenGL 图片从文件渲染到屏幕的过程

发布网友 发布时间:2022-09-05 23:34

我来回答

1个回答

热心网友 时间:2024-11-26 16:18

实际上iPhone有两个帧缓冲区,一个叫屏幕缓冲区,一个叫离屏缓冲区。

从上述流程可以看出,图片的显示是通过CPU和GPU的配合完成,这其中会出现一个问题,就是在GPU收到V-Sync信号时,CPU和GPU开始工作,在下一个V-Sync信号出现时CPU和GPU都没有处理完自己的工作,导致此时的离屏缓冲区中没有帧数据,就会出现卡顿现象。 更详细的解释可以参考ibireme大神的 iOS 保持界面流畅的技巧 。

在开始探索图片加载的流程前,先弄清楚两个概念。

我们先说说CPU都要做什么?

当使用UIImage的几个方法加载图片时,图片并不会立刻解码,它会经过一系列的步骤

以上就是着色器的渲染过程。

看到这里,我们已经知道图片解码过程非常耗时,对于App来说,静止的倒还好说,滑动的列表下,性能影响就会很严重了。 我们通常会用帧数FPS(Frames Per Second)来衡量手机的性能问题,60FPS(每秒60帧)是衡量会不会卡顿的标准,换算过来1帧的处理时间不应该超过0.1666s即16.7ms,接下来学习一下UIImage和YYImage的处理方式有什么可取之处。

UIImage有多种方法可以获取图片,那这些不同方法的区别是什么呢? 一、imageNamed

imageNamed 方式,在第一次渲染到屏幕上时会在主线程进行图片解码操作,位图数据会被缓存起来,之后再访问这个图片时,就从缓存获取了,看网上有说在手机发出内存警告时会清除UIImage的缓存。有两个问题: 1、第一次的图片解码操作还是在主线程做的 2、位图数据如果非常大,这么存到缓存里不太好。

二、imageWithContentsOfFile和imageWithData

imageWithContentsOfFile 和 imageWithData 在第一次渲染到屏幕时同样会在主线程进行图片解码操作,若把 UIImage 对象释放掉以后,再访问还是会出现在主线程进行图片解码的操作,这个小icon还好,大图就是有问题

所以一般市面上的做法是把图片解码强制提前执行,即在CPU进行解压缩前使用 CGBitmapContextCreate 在子线程中对其重新绘制。

找了YYKit的Demo直接拿来用了,YYImage的调用方式如下

YYImage集成自UIImage,重写了 imageNamed 方法避免了系统的全局缓存

这里面基本上就是从磁盘获取图片的二进制数据的过程。 scales 是类似@[@1,@2,@3]的数组,由于不同机型的物理分辨率或逻辑分辨率不同,相应的查询优先级也不同。 YYImage的多个方法都统一调用 initWithData ,接着看 initWithData

_preloadedLock :这是线程锁,通过信号量控制,为了预加载数据读取安全。 @autoreleasepool :在内部会产生大量的临时变量,为保证内存峰值不会暴涨,使用自动释放池控制 YYImageDecoder :获取图片的一些基本信息,图片宽高、帧数、图片类型 YYImageFrame :此时已经得到了解压缩后的位图

YYImage中使用的是Image I/O进行的图片解码,有两种方式 一、CGImageGetDataProvider(imageRef)方式

CGImageSourceRef :使用 CGImageSourceCreateWithData 函数,根据从磁盘获取的图片二进制数据创建imageSource CGImageRef :使用 CGImageSourceCreateImageAtIndex 函数创建一个CGImage CGDataProviderRef :位图数据提供者, CGImageGetDataProvider 函数,总之就是能从这里拿到位图数据 CFDataRef : CGDataProviderCopyData ,从DataProvider中获取CFDataRef数据。 CGImageRef : CGImageCreate ,根据位图数据再创建一个CGImage。

二、CGBitmapContextCreate方式

这里使用的是 CGBitmapContextCreate 函数进行的解压缩操作

可以看到这个函数有如下参数

通过打印执行这个函数时的线程可以看到,这个操作是异步执行的,后面我们会知道这确切来说是异步串行

YYAnimatedImageView集成UIImageView,并重写了很多方法,先从初始化开始看

初始化时定义了一个 runloopMode 为 NSRunLoopCommonModes ,表示在runloop切换时也要播放动图。

_link :是 CADisplayLink ,计时器,用来播放动画的。 第一次进入 setImage 会先执行 imageChanged 方法来确定图片和容器大小,以及标记定时器,等待下次runloop开始播放动画。

在 resetAnimated 方法中进行了初始化操作,包括 _lock 线程锁、 _buffer 缓存容器的初始化、 _requestQueue 线程队列的初始化以及定时器 _link 的初始化等等。

1、图片渲染到屏幕的过程:从磁盘读取文件->计算Frame->图片解码->通过数据总线提交给GPU渲染->顶点着色器->光栅化处理->片元着色器着色->渲染到帧缓冲区->视频控制器指向帧缓冲区->显示。 2、YYImage避免了全局缓存,在图片显示之前就异步强制图片解压缩,对性能有很大提高,其实这个库还有很多优点,没有再仔细的去看,以后会抽时间看一下。

收录: 原文地址

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
黑色芳纶哪家的好一些? 苏子叶我们中国叫什么苏子叶在中国叫什么 福州小车过户多少钱啊 福州车辆过户要多少钱 民生山西怎么查不到医疗保险信息 app查询养老金医疗保险方法介绍_百度... 太原医保查询平台(附入口二维码) 鉴定伤残等级去哪个部门 2024年中国铝业集团高管团队名单 2024中铝集团董事会成员一览 右枕位胎儿图怎么睡 一鸣楼宇对讲,刷卡开不了门,但分机能开,对讲能用,怎样维修? 电脑在OPENGL模式下特别卡,CPU100% 广西师范大学音乐系文化类成绩是多少 广西师范大学2010艺术类文化录取分数线是多少 想问一下艺术分220分+300文化分在广西能上师范大学吗? 黄帝内经24节气养生原文 黄帝内经五味养生原文 帮忙翻译一段摘要 measures to rectify livestreaming 这段英文怎么翻译?请高手指点 胶片如何保管 小沈阳好兄弟这首歌表达的是什么 悍跳、双爆狼战术探讨 狼人杀拍刀只能刀神吗 狼人杀“拍刀”是一种怎样的体验? 最后一神最后一狼可以拍刀吗 狼人拍刀买单买双什么条件 2023大学生母亲节活动策划方案5篇 余额转入余额宝的钱不能提现到银行卡里么 双迪国家基因检测能投原始股真的还是假的? 《饺子》这电影好看吗 OpenGL-渲染流程 OpenGL入门 - 1 炒鱼肉怎么做好吃,辣椒炒鱼肉的家常做法 被烟头烫掉一层皮,这时怎么办?我用了牙膏涂了下 管中流是什么电影 口译和笔译 水浒108魔星的卡片叫什么名字 108张卡片,甲比乙少了18张,丙比乙多12张,各几张 怎样使用油画颜料 当一个男人问你想他不,你怎么回答他为好? 男生问你想他了没 该怎么回答好 崔玉涛育儿知识 2020幼儿园春季工作计划【六篇】 高中生军训决心书 高中军训决心书 苍之女武神重氪怎么玩? switch上怎么下载龙珠世界2dlc 带DLC的卡带怎么还要下载 白木耳烧好可以放速冻保存吗? 春季幼儿园保教工作计划