【问题标题】:OpenGL ES 2.0 severe FPS drop on glDrawArraysglDrawArrays 上的 OpenGL ES 2.0 严重 FPS 下降
【发布时间】: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


【解决方案1】:

是的,OpenGL ES 需要 VBO/VAO,因为此版本不再支持固定功能的东西 (glBegin/End)。

很难说问题出在哪里,没有一些代码。但它肯定不应该是这样的。 (我没有安卓手机)
但是我可以发布一些链接...
http://www.songho.ca/opengl/gl_vbo.html(我更喜欢这个)
http://www.songho.ca/opengl/gl_vertexarray.html(你也可以试试这个)

【讨论】:

  • 好吧,既然还是使用 VBO 会更好,我会继续努力的。我的动态壁纸从仅四个 glDrawArray 调用经历如此严重的减速是否正常?或者它可能是我的代码中其他内容的结果?不幸的是,我的代码目前绝对是史诗般的混乱,但如果有人知道这样的问题可能出在哪里,我可以尝试将它的片段制作成半可呈现的。我想让这个项目尽可能高效和“正确”编码。
  • glBegin/glEnd 不是固定功能,它也与着色器兼容。但它们在 ES 中不存在。
【解决方案2】:

除非您正在绘制一些非常大的顶点数组,否则 glDrawArray 调用可能不是问题。问题更可能是您与 glDrawArray 一起进行的调用,或者您的片段着色器中发生了什么。例如,如果您使用 2048x2048 纹理的混合和采样填充整个屏幕 4 次,或者如果您每次都重新编译着色器,则预计会下降到 20 fps。

【讨论】:

  • 好吧,如果图像没有被绘制,要么是因为我删除了 glDrawArrays 调用,要么我去掉了与保持所有内容定位的矩阵相关的几行,它将回到 60 FPS .所有四个图像都存储在一个 1024x1024 纹理图集中(它们没有完全填充它,这正是我必须使用它们来适应 2 的纹理)。如果我禁用混合,导致纹理失去其 alpha,FPS 会上升到 50FPS(这仍然低于我在早期阶段想要的,即使一切正常。)
  • 如果混合或不混合会产生 20 对 50 fps 的差异,那么您的问题肯定出在像素填充上。尝试以更小的尺寸(如 2x2px)绘制三角形,看看它对性能有何影响。
  • 看来你是对的。我正在使用三角形条创建四边形来应用纹理,我在屏幕上制作的越小,我的 FPS 似乎就越高。这可能是某个地方出现小错误的原因,还是我误解了一些基本原理(正如我在这里学习的那样)并且一开始就做错了什么?
  • 您可能只是达到了 GPU 的极限。您正在开发哪种设备?您尝试填充每帧多少像素?你的片段着色器是什么样的?请记住,对于动态壁纸,您必须与 Launcher 和 SurfaceFlinger 共享 GPU,因此您可以更快地达到限制。
  • 我现在正在使用 Droid X 进行测试,我已经用它做了一些非常密集的事情,不要想象如果我做的事情正确,纹理四组三角形会伤害它所以糟糕,即使作为动态壁纸。我将在主帖中发布我正在使用的片段着色器,尽管目前它有点混乱,但根据我看过的其他示例,它似乎没有什么可怕的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多