【发布时间】:2011-09-11 16:45:23
【问题描述】:
我正在使用一个简单的 OpenGL ES 2.0 应用程序,更具体地说,我正在使用 GLWallpaperService 制作动态壁纸。感谢 StackOverflow 社区的大量帮助(谢谢大家!),我已经设法找到了一个很好的方法,但我似乎遇到了一些性能问题,尽管它仍然非常简单。
现在,就绘图而言,我只在屏幕上绘制了四个三角形条,并为每个条应用了纹理。虽然我确信这并不理想,但我认为通过对 glDrawArrays 的四个单独调用来执行此操作会很好,但显然此操作比我想象的要费力得多。从 60 到 20 年代中期,仅这四个绘图调用似乎就将我在 Droid X 上的壁纸的 FPS 降低了一半以上。
虽然出于显而易见的原因我不想让我以最大 FPS 渲染壁纸,但在我只绘制四个三角形条带的早期阶段出现这种极端下降是不可接受的。在最终版本中将进行更多绘图,包括粒子系统,在我控制好我的表现之前我无法继续前进。
我还没有仔细研究过 VBO,因为我认为我还不需要,但在这种情况下,它们听起来像是我应该做的。即使是这样简单的绘图调用,它们真的需要吗?不久前我还读到他们在某些手机上存在问题,但我相信这仅适用于旧手机,这不适用于我,因为我需要 OpenGL ES 2.0 以及动态壁纸支持。
另外,在这里偷偷问另一个问题,我无法启用调试以查看我的壁纸到底发生了什么。我的清单设置正确,经过快速搜索,我添加了以下行:
android.os.Debug.waitForDebugger();
到我的代码,但它永远不会附加,只是在等待(永远)时让我的壁纸保持黑色。当监控性能对于动态壁纸之类的东西如此重要时,这肯定是个问题,因此也为对此的任何见解提供奖励。
EDIT :: 这是我当前的片段着色器。这是非常拼凑的,只是为了暂时让事情正常工作,并且有一些与我的应用程序其他部分相关的错误,但我认为它不会导致我的问题。
final String fragmentShader =
"precision mediump float; \n"
+ "varying vec2 v_Color; \n"
+ "uniform sampler2D s_baseMap; \n"
+ "uniform vec4 u_Color; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 baseColor = texture2D( s_baseMap, v_Color ); \n"
+ " vec4 colorAdd1 = vec4(u_Color); \n"
+ " if(baseColor.a > 0.0){ \n"
+ " if(baseColor.a < 0.5){ \n"
+ " baseColor.a = 0.0; \n"
+ " } else { \n"
+ " baseColor = (baseColor + colorAdd1); \n"
+ " } \n"
+ " } \n"
+ " gl_FragColor = baseColor; \n"
+ "} \n";
为了自定义目的,我正在以编程方式“着色”我的纹理,这就是“u_Color”向量所代表的内容。检查纹理 alpha 的混乱是为了防止它只将颜色应用于每个像素,并且只在“实心”像素上进行。我确实删除了一次该部分以查看我的 FPS 的结果,虽然它确实增加了,但似乎只是 3-5FPS 的一小部分。
编辑 :: 我只是通过日志消息进行了一些测试,似乎我的“onDraw”方法中没有任何东西会造成我的问题。如果我在我的 onDraw 方法的一开始记录一些东西,然后在我的所有绘图和所有内容之后的最后记录一些东西,它们几乎每次都会立即记录,当然不足以造成我正在经历的巨大差距。除非这是日志系统的一些故障,否则我必须在其他地方得到这些帧速率的滞后。
以我目前对 OpenGL ES 2.0 的了解,这对我来说似乎很莫名其妙。我被引导相信,一旦它使用 onDraw 方法,它会像循环一样在该方法中持续运行,直到某些状态发生变化,例如改变方向和调用 onSurfaceChanged。如果我上面描述的不是 logcat 处理事情的方式的错误,那么它必须离开这个循环并去某个让我陷入困境的地方。
对此我能想到的唯一解释是,我使用 GLWallpaperService 设置来在动态壁纸中使用 OpenGL ES 2.0 是罪魁祸首。不幸的是,除非我可以对此进行调试以准确显示减速发生的位置,否则我不确定如何找到并(希望)修复它,因此似乎无法使用调试工具对我来说是最大的问题。
【问题讨论】:
-
glDrawArrays 几乎是瞬时的,因为它实际上并没有绘制任何东西。它将原语添加到管道的开头并返回。然后 GPU 与 CPU 并行绘制。
-
在绘制调用之外花费的时间可能在 eglSwapBuffers 中,如果 GPU 仍在处理前一帧,则可能会阻塞。
-
我刚刚认为这是我自己的代码中的东西,而不是我正在使用的 GLWallpaperService 代码,它试图处理很多工作,包括 eglSwapBuffers。我确实找到了对 eglSwapBuffers 的调用,但经过一些测试后,我似乎也没有发现任何明显的延迟。
标签: android debugging opengl-es live-wallpaper frame-rate