2010-05-20 24 views
2

最快的2D帧率可能与android NDK,我的尝试,更好的选择?最快的2D帧率可能与android NDK,我的尝试包括,更好的选择可用?

我用NDK和OpenGL ES 2.0显示一帧作为一个GL_TRIANGLE_STRIP纹理。 这是在HTC Desire上完成的,与Nexus One采用相同的硬件。 我试图加载多个GL_RGBA纹理和纹理之间切换,因为与单一纹理正常填充率为低得令人失望:

  • 1质地:4.78 FPS
  • 2纹理:19.68 FPS
  • 3纹理:20.18 FPS
  • 4纹理:28.52 FPS
  • 5个纹理:29.01 FPS
  • 6个纹理:30.32 FPS

我想即使30.32 fps的RGBA仍然太慢。

所以这是去达到最快的2D帧速率(有相同的质量)的方式吗? 任何建议,以加快?

下面是相关的代码,它是基于HELLO-GL2 NDK例如:

=== GL2JNIView.java:

init(false, 0, 0); 
ConfigChooser(5, 6, 5, 0, depth, stencil); 

=== gl_code.cpp:

#include <GLES2/gl2.h> 
#include <GLES2/gl2ext.h> 

#include <android/log.h> 

#include <stdlib.h> 
#include <time.h> 

typedef unsigned char byte; 

static int view_width, view_height; 
static byte* framebuffer; 
static int framebuffer_size; 
static GLuint texture_id[6]; 
static const char* vertexSrc = 
"precision highp float;\n" 
"precision highp int;\n" 
"attribute vec4 vertexCoords;\n" 
"attribute vec2 textureCoords;\n" 
"varying vec2 f_textureCoords;\n" 
"void main() {\n" 
" f_textureCoords = textureCoords;\n" 
" gl_Position = vertexCoords;\n" 
"}\n"; 
static const char* fragmentSrc = 
"precision highp float;\n" 
"precision highp int;\n" 
"uniform sampler2D texture;\n" 
"varying vec2 f_textureCoords;\n" 
"void main() {\n" 
" gl_FragColor = texture2D(texture, f_textureCoords);\n" 
"}\n"; 
static GLuint shaderProgram; 
static GLint attrib_vertexCoords; 
static GLint attrib_textureCoords; 
static GLint uniform_texture; 
static const GLfloat vertexCoords[] = {-1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0}; 
static const GLfloat textureCoords[] = {0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0}; 

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height) { 
view_width = width; 
view_height = height; 

framebuffer_size = 4*view_width*view_height; 
framebuffer = (byte*)calloc(framebuffer_size, sizeof(byte)); 
for (int i = 0; i < framebuffer_size; i++) framebuffer[i] = 0; 

glViewport(0, 0, view_width, view_height); 

glGenTextures(6, &texture_id[0]); 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, texture_id[0]); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, texture_id[1]); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
glActiveTexture(GL_TEXTURE2); 
glBindTexture(GL_TEXTURE_2D, texture_id[2]); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
glActiveTexture(GL_TEXTURE3); 
glBindTexture(GL_TEXTURE_2D, texture_id[3]); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
glActiveTexture(GL_TEXTURE4); 
glBindTexture(GL_TEXTURE_2D, texture_id[4]); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
glActiveTexture(GL_TEXTURE5); 
glBindTexture(GL_TEXTURE_2D, texture_id[5]); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 

shaderProgram = glCreateProgram(); 
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexSrc, NULL); 
    glCompileShader(vertexShader); 
glAttachShader(shaderProgram, vertexShader); 
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShader, 1, &fragmentSrc, NULL); 
    glCompileShader(fragmentShader); 
glAttachShader(shaderProgram, fragmentShader); 
glLinkProgram(shaderProgram); 
glUseProgram(shaderProgram); 

uniform_texture = glGetUniformLocation(shaderProgram, "texture"); 
glUniform1i(uniform_texture, 0); 

attrib_vertexCoords = glGetAttribLocation(shaderProgram, "vertexCoords"); 
glEnableVertexAttribArray(attrib_vertexCoords); 
glVertexAttribPointer(attrib_vertexCoords, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords); 

attrib_textureCoords = glGetAttribLocation(shaderProgram, "textureCoords"); 
glEnableVertexAttribArray(attrib_textureCoords); 
glVertexAttribPointer(attrib_textureCoords, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); 
} 

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj) { 
static int frame_count = 0; 
static clock_t last_time = clock(); 
static int last_frame_count = 0; 

frame_count++; 
if (clock()-last_time > 1e7) { 
    __android_log_print(ANDROID_LOG_INFO, "libgl2jni", "fps: %f", ((float)frame_count-last_frame_count)/(clock()-last_time)*1e6); 
    last_time = clock(); 
    last_frame_count = frame_count; 
} 

static byte val = 0; 
val++; 
if (val == 256) val = 0; 
for (int i = 0; i < framebuffer_size; i++) framebuffer[i] = val; 

int tst = frame_count%6; 
if (tst == 0) { 
    glActiveTexture(GL_TEXTURE0); 
} else if (tst == 1) { 
    glActiveTexture(GL_TEXTURE1); 
} else if (tst == 2) { 
    glActiveTexture(GL_TEXTURE2); 
} else if (tst == 3) { 
    glActiveTexture(GL_TEXTURE3); 
} else if (tst == 4) { 
    glActiveTexture(GL_TEXTURE4); 
} else if (tst == 5) { 
    glActiveTexture(GL_TEXTURE5); 
} 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
} 
+0

你的问题不是很清楚(你的代码也不是很清楚)。你究竟想要测试什么?你在第6帧结束时会产生6个活动纹理,我们不知道你的着色器在做什么。更不用说他实际上已经在初始化代码中激活了它。同样你为什么每一帧都创建一个纹理? – Goz 2010-08-13 11:26:47

回答

9

我明白你的问题是相当老了,你可能已经或者解决它或移动到别的东西,但我会的情况下,给一个建议,如果其他人遇到此。

首先,glTexImage2D要求图形子系统在每次调用纹理对象时都执行内存释放和重新分配,因为纹理参数可能在调用之间发生变化。优化后的驱动程序可能会查看宽度,高度和格式,如果它们完全相同,则可以跳过重新分配,但Android驱动程序实施者实际上不可能这样做。

为了避免质地完全重新分配,你可以使用glTexSubImage2D来代替完整的位图,或只是它的一部分。如果将此与上述纹理缓冲方案结合使用,则会看到相当大的速度增加。你甚至可以扩展它来检测显示器的修改区域,并只更新帧之间已经改变的矩形部分。

总之,改变你的纹理初始化代码来调用glTexImage2D用NULL指针位图,所以只OpenGL的分配内存的质地和不会将任何数据实际复制到它像这样:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view_width, view_height, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
0

最快可能在屏幕上的帧速率实际上由屏幕刷新率,这是供应商特定的上限:然后在你的游戏循环中更新每一帧。我的猜测是至少60赫兹(每秒60帧)。 离屏渲染不受刷新率限制,取决于您正在执行的计算强度。带有一些gl代码的无限循环运行速度可能比60 Hz快得多,或者就此而言,速度会更慢。

+0

60GHz意味着每秒60亿帧,请编辑为60Hz(我不能少于6个字符) – fathyb 2017-07-27 08:39:51

+1

哦,对,你是;) – 2017-07-31 16:34:54