在Chromium for Android中能否用TextureView替代SurfaceView
在开发Browser 2.0时,碰到一个非常头疼的问题,往布局上添加SurfaceView时,会引起黑屏闪一下。为了解决这个问题,我们不得不在初始化阶段就把SurfaceView添加好,之后也不能调整大小、移动位置。当时就考虑是不是能够用TextureView替代SurfaceView,不过由于计划上的调整,没有做进一步的尝试。今天在网上看到这篇文章,正好解答了我的疑问,在此把文章翻译过来,供参考。
Android SurfaceView和textureView
本文将简要介绍SurfaceView和TextureView的不同之处
SurfaceView和TextureView
SurfaceView和TextureView都继承自android.view.View类,他们都可以在另一个独立线程中绘制和渲染,这是和其它View的最大不同。Crosswalk采用这一分离绘制特性,独立的GPU线程显著提高了渲染效率。
SurfaceView提供一个嵌入在视图层次上的专用绘制表面,您可以控制该表面(Surface)的格式和尺寸。SurfaceView负责将表面放置在屏幕上正确的位置。它的行为多少有些类似于传统桌面系统上的onscreen窗口,比如,X11系统中的XWindow可以是无边框的,嵌入在另一个XWindow中。
SurfaceView存在如下两个缺点:
- 不能应用动画、变换和缩放
- 不能叠加(Overlay)两个SurfaceView
TextureView看似更像一个通用的View,可以应用动画、变换和缩放,就如同TextView。TextureView只能用在硬件加速的窗口。但是,TextureView比SurfaceView更耗内存,而且可能会有1~3帧的延迟,请参考讨论3。
使用可以动画的XWalkView
Crosswalk Embedding API for Android很好的支持了SurfaceView和TextureView。XWalkView缺省使用SurfaceView,也允许您在以下情况下使用TextureView:
- 您想让XWalkView支持动画和变换
- 您想叠加两个XWalkView
设置布尔标识ANIMATIBLE_XWALK_VIEW为true即可启用TextureView。
文中提到的讨论起源是在google groups中有人提出如下问题:
在当前ContentViewRenderView实现中,使用SurfaceView作为合成表面(compositing surface),如我们所知,SurfaceView是一个特别的视图,无法进行动画或者变换。
TextureView可以做SufaceView同样的事情,比如,您可以在另一个独立线程中渲染,也可以从底下的SurfaceTexture创建一个egl表面(eglSurface)。更主要的是,TextureView可以进行动画和变换。
我很好奇为什么不使用TextureView作为合成表面,是否TextureView在使用上有一些特别的考虑,比如性能问题?欢迎任何讨论。
Google groups有人做如下回复:
事实上chrome过去使用TextureView作为合成表面,但我们出于几个原因切换到SurfaceView:
- 由于失效(invalidation)和缓冲的特性,TextureView增加了额外1~3帧的延迟显示画面更新
- TextureView总是使用GL合成,而SurfaceTexture可以使用硬件overlay后端,可以占用更少的内存带宽,消耗更少的能量
- TextureView的内部缓冲队列导致比SurfaceView使用更多的内存
- TextureView的动画和变换能力我们用不上
所以结论是Chromium for Android中可以使用TextureView替代SurfaceView作为合成表面,但带来的后果是占用更多的内存,性能下降。