Android上的硬件加速双缓冲

Android上的硬件加速双缓冲,android,performance,hardware-acceleration,Android,Performance,Hardware Acceleration,我们的应用程序需要双缓冲语义,例如,当在一次绘制操作中绘制一条线时,该线下一次仍应存在(无擦除,使用相同的缓冲区)。这非常适合我们使用SurfaceView、lock等 然而,我们觉得我们可能会错过一些Android设备的性能 在iOS上运行时,我们使用OpenGL和保留备份模式,防止操作系统在每次重画时擦除显示。我希望Android有类似的功能,可以防止无效调用擦除之前在屏幕上绘制的元素,但除了创建位图,我找不到其他选项 绘制位图也是一种选择(这就是我们今天所做的),但是我们如何利用这里的硬件

我们的应用程序需要双缓冲语义,例如,当在一次绘制操作中绘制一条线时,该线下一次仍应存在(无擦除,使用相同的缓冲区)。这非常适合我们使用SurfaceView、lock等

然而,我们觉得我们可能会错过一些Android设备的性能

在iOS上运行时,我们使用OpenGL和保留备份模式,防止操作系统在每次重画时擦除显示。我希望Android有类似的功能,可以防止无效调用擦除之前在屏幕上绘制的元素,但除了创建位图,我找不到其他选项


绘制位图也是一种选择(这就是我们今天所做的),但是我们如何利用这里的硬件加速?

我们在Androidplot库中遇到了类似的挑战,因为我们排除了SurfaceView作为合法解决方案的可能性,因为一次显示两个或多个SurfaceView存在问题。我们最终创建了自己的实现,它实际上只是一个使用位图的乒乓缓冲区


就硬件加速而言,它应该在默认情况下启用,并且(据我所知)只要不使用任何硬件加速,代码就应该“正常工作”。您会注意到,由于这个原因,上面链接的代码必须显式禁用加速。

不要绘制位图,坚持使用OpenGL并使用帧缓冲区对象(FBO)。

这似乎与双缓冲方法的实现方式不太一样


我最后做的是使用
postInvalidate(int,int,int,int)
方法,构建一个任务队列来绘制已更改的元素。对我来说真正有问题的是Android一直在删除屏幕,这实际上是因为我们没有调用
activity.getWindow().setBackgroundDrawable(null)我们在软件渲染中没有感觉到,但在硬件加速渲染中会导致屏幕擦除。

谢谢,不幸的是,据我所知,绘制位图将使用CPU,因此只有blit部分会被硬件加速。这对于某些用例来说可能并不坏,但我希望有更快的东西。明白了。FWIW根据使用的绘制方法,可以排除渲染阶段的硬件加速。据我所知,如果您使用或依赖其中任何一个,您将需要删除它们或禁用加速。例如,如果您使用clipRect并希望支持API 18之前的任何内容,则不能使用它。这不是问题的解决方案,但可能会将问题简化到上面:“…任何一个…”转换为“…任何不受支持的绘图操作…”目标是实现硬件加速并充分利用它。据我所知,大多数双缓冲策略有效地禁用了硬件加速。OpenGLES是搜索硬件加速最安全的方法。我可能大错特错,但我认为双缓冲是默认启用的,它与您描述的内容无关。为了在框架之间保留绘制的形状,在onDrawFrame中不调用glClear()应该足够了(?)谢谢,但我对将代码移植到OpenGL不感兴趣,有很多代码,OGL不是最适合这种类型的代码(很多文本等)。我们在iOS上使用OGL,所以我很清楚我将面临的痛苦。双缓冲是为了防止应用程序造成的屏幕闪烁,这些应用程序确实需要清除屏幕并从头开始绘制每一帧。您要求不要擦拭屏幕,但另一方面您说“需要双缓冲”。这听起来很矛盾;我会说完全禁用双缓冲,你应该很好。我是否误解了这个问题,或者我是否遗漏了一些与我多年前使用的移动平台不同的关于Android的信息。。。我们需要的是语义而不是双缓冲本身。谢谢,但我不是在构建游戏。我需要做的很多工作是文本绘制,虽然它可以在OGL中完成(我们在iOS上完成),但这太糟糕了。默认情况下,OGL(在iOS上)不会清除屏幕,但也不会保留它,尽管这有点离题。我不确定Android的情况如何,但我没有考虑采用开放式GL路线。我在哪里说过游戏?你说你在iOS版本上使用OpenGL,所以在Android版本上使用OpenGL是非常可行的,因为它是完全相同的API。你仍然可以将文本绘制到位图,然后将位图渲染到FBO。我假设整个要点是将所有昂贵的每帧文本渲染(每帧大概不会改变)从屏幕外缓冲区减少到一个blit。在iOS上,我们使用OpenGL,因为它是在那里执行任何性能图形的唯一选项。从长远来看,这不是一个理想的方法。iOS代码依赖于KeaglDrawablePropertyRetaineBacking,这也不理想。为了让我正确理解(因为我可能面临类似的情况),如果在使用缓冲区
位图
支持的
画布上进行绘图调用,这是真的吗,那么硬件加速不能帮助从绘图操作转换为位图上的像素?这就是在您的情况下避免使用缓冲区
位图
的原因吗?(换句话说,就我所知,从
isHardwareAccelerated()
返回
true
Canvas
是不是只有
视图的
onDraw()
中提供的
Canvas
?)就是这种情况。也许可以用不同的方式获得硬件加速画布,但我找不到任何方法获得指向位图的硬件加速画布,这与我使用OpenGL的个人经验是有道理的。