1

我已经创建了一个用于绘制线条、圆圈的 android 应用程序。通过在 OpenGLES 2.0 中使用 GLSurfaceView,就像 Auto cad 应用程序一样。

该应用程序在 Google Nexus 7 上运行良好,从某种意义上说,如果我们画一条线,然后画一个圆圈,则该线不会在表面视图中被删除。但三星 Galaxy Note II 则完全不同。

在绘制圆之前绘制的线将被删除。即,每次如果我们画一条新的线或圆,前一个会被删除。我一次只能画一张图像。我需要的是与我在三星 Galaxy Note II 中的 Google Nexus 7 中获得的相同输出。即我想一次在 GLSurfaceView 中绘制多个图像。

注意:Google Nexus 7 和三星 Galaxy Note II 中的 Android 操作系统都是 Jelly Bean 4.2。但两种设备都是不同的 GPU。Google Nexus 7 GPU 是 ULP GeForce,三星 Galaxy Note II 是 Mali400MP。

这会是 Surfaceview 输出渲染的问题吗?

我们应该在编码时考虑 GPU 吗?

谁能告诉我为什么在不同设备中出现不同输出的问题?

4

2 回答 2

4

我们应该在编码时考虑 GPU 吗?没办法,OpenGL API 是您的应用程序和硬件之间的一层。

这对于桌面图形在很大程度上是正确的,因为所有 GPU 都是即时渲染器,但是,在移动图形中并非如此。

Mali GPU 使用基于图块的即时模式渲染。对于这种类型的渲染,帧缓冲区被分成大小为 16 x 16 像素的图块。多边形列表生成器 (PLB) 将来自应用程序的输入数据组织到多边形列表中。每个图块都有一个多边形列表。当一个图元覆盖一个图块的一部分时,一个称为多边形列表命令的条目被添加到该图块的多边形列表中。像素处理器获取一个图块的多边形列表,并在开始处理下一个图块之前计算该图块中所有像素的值。由于这种基于切片的方法使用快速的片上切片缓冲区,因此 GPU 仅在每个切片末尾将切片缓冲区内容写入主存储器中的帧缓冲区。基于非平铺的即时模式渲染器通常需要更多的帧缓冲区访问。

另一个区别是渲染缓冲区的处理。即时渲染器将“保存”缓冲区的内容,有效地允许您仅在先前存在的内容之上绘制渲染场景中的差异。但是,此 IS 在 Mali 中可用,但默认情况下未启用,因为如果使用不当可能会导致不良影响。

有一个 Mali GLES2 SDK 示例,说明如何在GLES2 SDK 中正确使用“EGL Preserve”

基于 Geforce ULP 的 nexus 7 按预期工作的原因是,作为基于即时的渲染器,它默认保留缓冲区,而 Mali 没有。

来自 Khronos EGL 规范:

EGL_SWAP_BEHAVIOR

指定使用 eglSwapBuffers 发布表面对颜色缓冲区的影响。EGL_BUFFER_PRESERVED 值表示颜色缓冲区内容不受影响,而 EGL_BUFFER_DESTROYED 值表示颜色缓冲区内容可能会被操作破坏或更改。

* EGL_SWAP_BEHAVIOR 的初始值由实现选择。*

Mali 平台上 EGL_SWAP_BEHAVIOUR 的默认值为 EGL_BUFFER_DESTROYED。这是由于在渲染新帧之前必须从内存中获取前一个缓冲区并在最后存储它以及带宽消耗(这对移动设备上的电池寿命也非常不利)相关的性能损失。我无法肯定地评论 Tegra SoC 的默认行为,但是对我来说很明显它们的默认行为是 EGL_BUFFER_PRESERVED。

为了阐明 Mali 对 Khronos GLES 规范的立场 - Mali 完全符合要求。

于 2013-07-15T10:16:55.693 回答
0

我没有看到你的代码,但你可能做错了什么。也许你交换缓冲区,擦除它,等等,你不能。

我们应该在编码时考虑 GPU 吗?没办法,OpenGL API 是您的应用程序和硬件之间的一层。

于 2013-06-19T09:27:19.960 回答