2010-05-20 1 views
2

안 드 로이드 NDK로 가장 빠른 2D 프레임 속도 가능, 시도해 보았습니다. 더 좋은 옵션이 있습니까?안드로이드 NDK에서 가능한 가장 빠른 2D 프레임 속도, 포함 시키십시오, 더 나은 옵션이 있습니까?

프레임을 GL_TRIANGLE_STRIP에 텍스처로 표시하기 위해 NDK 및 OpenGL ES 2.0을 사용했습니다. 이것은 Nexus One과 동일한 하드웨어 인 HTC Desire에서 수행되었습니다.

  • 1 텍스처 : 4.78 FPS
  • 2 텍스처 : 단일 텍스처 정상 률은 실망 낮은 때문에 는 I 여러 GL_RGBA 텍스처로드 텍스처를 전환하려고 19.68 FPS
  • 3 질감 : 20.18 FPS
  • 4 텍스쳐 : 28.52 FPS
  • 5 개 텍스처 : 29.01 FPS
  • 6 개 텍스처 : 30.32 FPS

30.32 fps RGBA도 여전히 느리다 고 생각합니다.

이렇게하면 (동일한 품질의) 가장 빠른 2D 프레임 속도를 얻으려면 어떻게해야합니까? 속도를 높이려는 제안이 있으십니까? 여기

은 관련 코드이를 헬로 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 개의 활성 텍스처로 끝나고 쉐이더가 어떤 작업을하는지 알지 못합니다. 사실 그들은 모두 초기화 코드에서 활성화 된 것을 언급하지 않을 것입니다. 똑같이 모든 프레임마다 텍스처를 만드는 이유는 무엇입니까? – Goz

답변

9

나는 당신의 질문이 다소 오래되었다는 것을 알고 있으며, 당신은 그것을 해결했거나 다른 것으로 옮겼을 가능성이 있지만, 다른 누군가가이 문제를 발견 할 경우를 대비해 제안 할 것입니다.

우선, 텍스쳐 파라미터가 호출간에 바뀔 수 있기 때문에은 그래픽 서브 시스템이 호출 할 때마다 텍스쳐 오브젝트를 메모리없이 자유롭게 재 할당해야한다. 최적화 된 드라이버는 너비, 높이 및 형식을 볼 수 있으며 모두 동일하면 재 할당을 건너 뛸 수 있지만 Android 드라이버 구현자가 실제로이 작업을 수행하지는 않습니다.

텍스처 재 할당을 완전히 피하려면 glTexSubImage2D을 사용하여 전체 비트 맵 또는 일부만 대체하십시오. 위의 텍스처 버퍼링 체계와 결합하면 속도가 상당히 빨라집니다. 이 기능을 확장하여 디스플레이의 수정 된 영역을 감지하고 프레임간에 변경된 직사각형 부분 만 업데이트 할 수도 있습니다.

는 요약에 NULL 비트 맵 포인터로 glTexImage2D를 호출하여 질감 초기화 코드를 변경, 그래서 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 Hz (초당 60 프레임)입니다. 오프 스크린 렌더링은 새로 고침 빈도에 의해 제한되지 않으며 수행중인 컴퓨팅의 강도에 따라 달라집니다. 일부 gl 코드가있는 무한 루프는 60Hz보다 훨씬 빠르게 실행될 수 있습니다. 즉, 느리게 실행될 수 있습니다.

+0

60GHz는 초당 60 억 프레임을 의미하며, 60Hz로 편집하십시오 (6 자 미만일 수 없음) – fathyb

+1

아, 맞습니다.) –