【问题标题】:Why is OpenGL rendering so slow with SDL2 on Android?为什么在 Android 上使用 SDL2 的 OpenGL 渲染如此缓慢?
【发布时间】:2013-09-06 10:06:03
【问题描述】:

我正在借助 NDK 和 SDL 将 C++ 2D 游戏移植到 Android;我使用 OpenGL 来渲染精灵。表演很令人失望。

经过一番调查,我发现瓶颈在于渲染过程中的 OpenGL 调用。 等一下!在粘贴经典答案之前,告诉不要更改 GL 状态,不要绑定已绑定的纹理等,请阅读以下内容。

实际上,即使我在黑屏中间显示单个 364x353 rgba 纹理,渲染也需要将近 20 毫秒。过程可以总结如下:

编辑 下面的代码用来调用glFlush()。正如 thokra 在 cmets 中指出的那样,这不是必需的。然而,删除它并没有提高性能。

glClear( GL_COLOR_BUFFER_BIT );

glBindTexture( the_texture );
glEnable(GL_BLEND);

glEnableClientState( GL_COLOR_ARRAY );
glColorPointer( 4, GL_FLOAT, 0, colors );

glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, positions );

glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, 0, texture_positions );

glDrawArrays( GL_TRIANGLE_FAN, 0, vertex_count );

glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glDisable(GL_BLEND);

//glFlush();
SDL_GL_SwapWindow( window );

这个函数的最后两行(flush 和 swap)的执行时间很不规律。可能需要 4 到 12 毫秒!

我在网上能找到的最好的提示是this question on StackOverflow 和这个thread on Google Groups。

StackOverflow 上的问题的答案没有任何帮助。根据问题的作者:

使用 glClear 清除与不清除帧对我来说不会影响 fps。启用/禁用混合也不行。

和

[...] 只是想看看使用压缩纹理是否会提高填充率。好像没有[…]

Google Groups 的帖子与我的问题非常相似,但作者放弃后就结束了:

所以基本上,没有办法绘制 480x854 由于纹素读取,屏幕上的图像以 60fps 的 OpenGL 速度显示 瓶颈。

说真的,不行吗?为什么调用glFlush() 和SDL_GL_SwapWindow() 需要这么长时间?为什么它如此不规则?我对此无能为力吗?

我在 SDL2 的源代码和found 中进行了快速搜索,SDL_GL_SwapWindow() 使用 Java 本机接口调用将完成工作的 Java 方法。这可能是不规则的原因吗?我该怎么办?

【问题讨论】:

  • 更好的问题是,为什么要冲洗?
  • 嗯……我不记得为什么glFlush() 电话会在这里,只是很久以前觉得有必要。必要的,否则我看不到精灵。你觉得我可以扔掉它吗?为什么?
  • glFlush 将强制在此之前的命令尽快执行,有效地优先处理您为 GL 提供的任何工作。通常 GL 实现可以很好地确定需要执行什么以及何时执行。调用 glFlush,您告诉 GL 要做什么,从而限制执行顺序最佳的机会。它不像 glFinish 那样糟糕,它会阻塞直到完成,但在大多数应用程序中仍然是不必要的。此外,如果您没有看到精灵,则冲洗不是解决方案。只是某个地方出了点问题。
  • 好的,我会尝试删除glFlush() 并尽快测试,看看是否有任何差异。尽管如此,OpenGL documentation on glFlush() 告诉“所有程序都应该调用 glFlush,只要他们指望完成所有先前发出的命令。例如,在等待取决于生成图像的用户输入之前调用glFlush”。因此我对实际结果有些怀疑。
  • 好吧,这就是 glFlush 被很好地指定的地方:即使之前发出的命令尚未完成,它也可能返回。因此,调用 glFlush 后直接依赖结果是不安全的。依靠glFinish之后的结果是。问题是:你真的依赖已执行的命令吗?我真的不明白你为什么会出现在你的例子中。

标签: android c++ opengl-es sdl


【解决方案1】:

我不知道您是否还在这样做,但请尝试就此事咨询 Google。您不会从网络上的其他任何地方得到合理的答案。 20ms 基本上是 50FPS。完成您要求的那些简单任务时,您通常会获得 250FPS。万一,万一它是故意放慢的呢?

我们曾经在简单的拦截调用中编写代码并使用整个 VGA 卡。但如今,即使在智能手机中,它也以虚拟模式运行。您需要在汇编或 c 级别获得对视频芯片的直接访问权限。就此向谷歌咨询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 2015-02-05
    • 2016-11-08
    • 1970-01-01
    相关资源
    最近更新 更多