2014-09-23 2 views
0

Я написал игру, в которой, когда вызывается onDrawFrame(), я сначала обновляю состояние игры (логика игры и буферы для рисования), а затем продолжаю делать фактические чертежи. На Moto G и Nexus 7 все работает плавно, и каждый вызов onDrawFrame() занимает всего 1-5 мс. Однако на Samsung Galaxy S3 в 90% случаев вызов onDrawFrame() занимает 30-50 мс для обновления.GLES20 вызывает onDrawFrame вызывает длительную задержку

Дальнейшее исследование проблемы я нашел, что проблема полностью лежит на первом методе рендеринга, который я прикладываю ниже: - (Edit: блок теперь находится на glclear(); удалив ненужные вызовы для получения дескрипторов, см. в комментариях)

public void render(float[] m, FloatBuffer vertex, FloatBuffer texture, ShortBuffer indices, int TextureNumber) { 
     GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertex);    
     GLES20.glEnableVertexAttribArray(mPositionHandle);    

     GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, texture);    
     GLES20.glEnableVertexAttribArray(mTexCoordLoc);    

     GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);    

     int mSamplerLoc = GLES20.glGetUniformLocation(fhGraphicTools.sp_Image, "s_texture");    

     GLES20.glUniform1i(mSamplerLoc, TextureNumber);    

     GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.capacity(), GLES20.GL_UNSIGNED_SHORT, indices);    
     // Disable vertex arrays used 
     GLES20.glDisableVertexAttribArray(mPositionHandle);    
     GLES20.glDisableVertexAttribArray(mTexCoordLoc);    
    } 

выше метод вызывается 5 раз в каждом onDrawFrame(), чтобы сделать вещи на различных атласе текстуры. (первые 4 на самом деле являются фоном игры, который является 1 длинным прямоугольником). После авторизовались время, необходимое в каждой строке кода я обнаружил, что запаздывание я имею на S3 всегда проживаете в одной из следующих строк:

int mPositionHandle = GLES20.glGetAttribLocation(fhGraphicTools.sp_Image, "vPosition"); 

или

GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.capacity(), GLES20.GL_UNSIGNED_SHORT, indices); 

Отставание только происходит в первом вызове render(), поскольку последующие вызовы занимают около 1-2 мс каждый. Я попытался отключить первый вызов render(), но затем второй, который прежде всего принимает только 1-2 мс, теперь становится источником задержки в тех же строках.

Есть ли у кого-нибудь представление о том, что не так в моем коде, который S3 не мог обработать? Кажется, что у S3 есть проблема, начинающая вызовы GL в начале каждого onDrawFrame(), но почему такое поведение меня озадачивает. Что можно сделать, чтобы уменьшить задержку запуска?

Огромное спасибо за ваше терпение в чтении.

Отредактированный код для рекомендации Selvin.

+0

Почему вы получаете атрибуты места и униформы в onDrawFrame? вместо этого сохраните его в fx 'fhGraphicTools.sp_Image_mPositionHandle' сразу после компиляции' fhGraphicTools.sp_Image' shader – Selvin

+0

У меня, как вы сказали, хранились ручки после компиляции. Теперь «блок» происходит от glClear(), который занимает от 18 до 50 мс. Я сделал поиск и нашел этот пост http://stackoverflow.com/questions/12224230/why-is-glclear-blocking-in-openglesbut Прочитав его, я все еще не совсем понимаю проблему в моем случае ... – user3846551

ответ

0

Я исправил проблему, когда я переместил все мои файлы png-изображений из/drawable в/drawable-nodpi, скорость игры вернулась к нормальной работе на S3. Я предполагаю, что автомасштабирование, сделанное Android, вызывает необработанное растровое изображение, которое я предоставил opengl в «плохих» размерах, вызывая ненужную фильтрацию текстур на каждом onDrawFrame, в результате чего вызов пропустил vsync и дал долгую задержку для glClear, ожидая следующий vsync. Пожалуйста, поправьте меня, если я ошибаюсь, все еще новичок в графике.

Смежные вопросы