说说MIUI 6的毛玻璃效果的技术实现。
 
很久以前我们的文件夹打开和最近任务等几个地方就使用了毛玻璃效果,在技术上讲就是背景模糊。应该是比iOS 7的使用要早很多。不过那时候我们使用的是先对背景截图,再将其模糊处理,然后作为app的背景图,所以是一张静止的图片,当背景内容发生变化时模糊的图片并不会随之变化,因此比较生硬。而iOS 7的背景模糊则是实时的,当背景变化的时候,模糊内容也会实时的变化。这就把我们给比下去了。于是我们也不能闲着,既然做了,那就做好。然后我就开始做实时的背景模糊。
 
如果沿用之前的方式,先截图,再模糊,由于这个过程远远大于一帧的时间16.7毫秒。因此就算不停的更新背景,虽然也能呈现出变化的模糊背景,但会很卡顿,不流畅,不自然,资源消耗大。
 
于是考虑更为自然的实现方式:在Window上添加标记,SurfaceFlinger合并层的时候对其后面的内容用OpenGL ES进行模糊处理。
这种方式没有截图的过程,绘制的时候用OpenGL ES绘制,加上一些优化,最终轻松达到60FPS的满帧率。
 
下面说说代码的主要过程和一些关键点。
  1. 需要背景模糊的Window给自己添加一个标记:FLAG_BLUR_BEHIND,这个标记是Android SDK提供的,因为Android的早期版本是有支持背景模糊的,不过由于他们不是用的OpenGL ES实时绘制,性能比较差,于是后来把这个功能给废弃了。我们便顺理成章的又把这个标记给用起来。第三方应用也完全可以使用这个标记在MIUI 6用上这个特性。
  2. 在WindowManagerService这边检测到Window有这个标记后,将标记传给SurfaceFlinger中Window对应的Layer。
  3. Layer收到背景模糊标记后,分配一个Texture。
  4. 在SurfaceFlinger合成层的方法doComposeSurfaces中,把背景模糊的层后面的内容用OpenGL ES以模糊的方式绘制到之前分配的Texture中,于是构建好了模糊的内容。在接下来绘制这个层的时候先绘制含有模糊内容的Texture。
整个过程大致就是这样。
另外,由于在大部分情况下SurfaceFlinger合成层是使用的Hardware Composer来合成的,并不是OpenGL ES,因此我们需要检测发现有背景模糊层的时候指明不使用Hardware Composer。
 
模糊算法的主要耗时点是很大的采样次数。我们想了一些办法来优化性能:
    1. 将图片先缩小,再模糊,绘制的时候再放大。由于先缩小再放大也是一种模糊方法,因此控制得好的话并没有什么问题。但防止缩小太厉害会导致背景移动的时候画面闪烁,我们会逐级缩小。(GL_TEXTURE_EXTERNAL_OES不支持mipmap)
    2. 模糊的主要实现过程使用OpenGL ES Fragment Shader来实现,先横向计算一遍,再纵向计算一遍,这样处理则每个像素的采样次数从n*n变成了n*2(n是模糊直径)。事实上我们在背景模糊的Layer里分配了两个Texture,循环使用。
    3. 采样取像素值的时候并不需要每个像素取一次,而是利用OpenGL ES中纹理采样的线性过滤特性,在两个像素中间取值,返回的是两个像素的平均值,这样可以让采样次数减半,效果不变。(真实代码中并不是完全中间,而是根据权重计算位置)
    4. 如果上一帧已经产生了模糊的Texture,而这一帧背景又没有变化,则直接使用上一帧的就行了,不需要再做模糊处理。

MIUI 6的毛玻璃效果的技术实现(实时模糊)的更多相关文章

  1. CSS技巧收集——毛玻璃效果

    先上 demo和 源码 其实毛玻璃的模糊效果技术上比较简单,只是用到了 css 滤镜(filter)中的 blur 属性.但是要做一个好的毛玻璃效果,需要注意很多细节. 比如我们需要将上图中页面中间的 ...

  2. 一次H5毛玻璃效果有感

    印象中H5实现毛玻璃效果是挺好实现的,主要的代码就是css的filter:blur. 之前也用过几次,给背景图加高斯模糊啊,给一个div加高斯模糊啊.只要给需要添加高斯模糊的元素直接添加filter属 ...

  3. CSS 奇思妙想 | 全兼容的毛玻璃效果

    通过本文,你能了解到 最基本的使用 CSS backdrop-filter 实现磨砂玻璃(毛玻璃)的效果 在至今不兼容 backdrop-filter 的 firefox 浏览器,如何利用一些技巧性的 ...

  4. 使用CSS3制作导航条和毛玻璃效果

    导航条对于每一个Web前端攻城狮来说并不陌生,但是毛玻璃可能会相对陌生一些.简单的说,毛玻璃其实就是让图片或者背景使用相应的方法进行模糊处理.这种效果对用户来说是十分具有视觉冲击力的. 本次分享的主题 ...

  5. 解决css3毛玻璃效果(blur)有白边问题

    做一个登录页,全屏背景图毛玻璃效果,实现方法如下: HTML: <body> <div class="login-wrap"> <div class= ...

  6. Swift 之模糊效果(毛玻璃效果,虚化效果)的实现

    前言: 之前项目中有用到过Objective-C的的模糊效果,感觉很是不错,而且iOS8之后官方SDK也直接提供了可以实现毛玻璃效果的三个类:UIBlurEffect.UIVibrancyEffect ...

  7. css毛玻璃效果

    毛玻璃其实就是磨砂玻璃,能够模糊的看清背后的风景,让人感觉有种朦胧美,让界面看上去有些层次感. 比如: 高大上啊,接下来肯定是眼馋手痒的过程... 当然,用ps搞一个全景毛玻璃背景毫无疑问是最省事的, ...

  8. iOS模糊效果(毛玻璃效果)的实现

    前一段时间项目中用到毛玻璃效果,那时对UIBlurEffect类和 UIVisualEffectView这两个类做了一部分了解.但当时并没有去特别的深入研究,直到项目做完后,才静下心来好好研究了一番. ...

  9. qt qml fuzzyPanel 毛玻璃效果

    毛玻璃效果,用qml来写代码真是简短,大爱qml:) [下载地址]http://download.csdn.net/detail/surfsky/8426641 [核心代码] Rectangle{ c ...

随机推荐

  1. 【appium】根据xpath定位元素

    1. 背景 本文尝试使用的试验对象是SDK自带的NotePad应用实例,假设已经有两个Notes分别是“note1”和“note2”添加到Notepad上面,我们要做的就是尝试用xpath的方法来定位 ...

  2. Action<T>和Func<T>委托

    Action<T>和Func<T>委托 泛型Action<T>委托和Func<T>委托是系统定义的两个泛型委托. Action<T>委托表示 ...

  3. 10个CSS+HOVER 的创意按钮

    CSS hover 样式很简单,但是想创造出有意思.实用.有创意性的特效是很考验设计师的创意能力,所以设计达人每隔一段时间都会分享一些与鼠标点击.悬停的相关特效,以便大家获得更好的创造灵感. 今天我们 ...

  4. ASP.NET ASHX中获得Session

    有时候需要在ASHX中获取Session,可是一般是获取不到的,如何解决? 1-在 aspx和aspx.cs中,都是以Session["xxx"]="aaa"和 ...

  5. 惠普(HP)战66 Pro G1 - 批量GHOST[Win10专业版 ] (UEFI)

    笔记本型号:惠普(HP)战66 Pro G1 14英寸轻薄笔记本电脑(i5-8250U 8G 256G PCIe SSD+500G 标压MX150 2G独显)银色 需求: 公司一共采购10台笔记本,需 ...

  6. android datepicker monthOfYear getMonth(): 获取当前月(注意:返回数值为0..11,需要自己+1来显示).....

    关键点: 1. getMonth():     获取当前月(注意:返回数值为0..11,需要自己+1来显示) 2. 初始年(译者注:注意使用new Date()初始化年时,需要+1900,如下:dat ...

  7. wxWidgets:前景色与背景色

    wxWidgets中有多个函数可以用来设定前景色和背景色,下面就来看看他们的用法区别: wxWindow::SetBackgroundColour(const wxColour &) 在你重绘 ...

  8. Qt中路径问题小结

    转载:奋斗Andy 在做Qt项目的时候,我们难免遇到到文件路径问题. 如QFile file("text.txt")加载不成功.QPixmap("../text.png& ...

  9. 在VS2013平台下如何快速解决c++代码内存泄漏问题

    在学习FPS3000人脸关键点定位算法时,发现github上的源码,存在大量的内存泄漏问题,在训练的时发现内存一直在增长,测试的时候也存在内存无法彻底释放的问题. 一直以为是存放模型参数vector& ...

  10. while循环的讲解

    条件语句有两种方式: if() 条件语句 switch()   条件语句 循环语句: for() 循环语句 for in 遍历队象属性的循环 while 循环 案例:算出1到10的和 1.var i= ...