Текстура рисования Android с OpenGL ES 2.0 медленная на некоторых устройствах

В моем приложении для Android 4.3 я хотел бы загрузить текстуру из локального png в TextureView. Я не знаком с OpenGL и использую код из GLTextureActivity тест аппаратного ускорения. Я также вставляю сюда загрузочную часть текстуры:

    private int loadTexture(int resource) {
        int[] textures = new int[1];

        glActiveTexture(GL_TEXTURE0);
        glGenTextures(1, textures, 0);
        checkGlError();

        int texture = textures[0];
        glBindTexture(GL_TEXTURE_2D, texture);
        checkGlError();

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource);

        GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
        checkGlError();

        bitmap.recycle();

        return texture;
    }

Я запускаю код на двух устройствах: Nexus 7 и телефоне Galaxy Nexus, и я заметил огромную разницу в скорости между ними. Для Nexus 7 рисование занимает около 170 мс, а для Galaxy Nexus — 459 мс. Самая трудоёмкая операция это загрузка текстуры и особенно вызов texImage2D. Я читал, что есть устройства с чипами, которые медленно выполняют texImage2D-texSubImage2D функции, но как кто-то может определить, какие это устройства, и как мне избежать использования этих функций для достижения того же результата?

Заранее спасибо.

// РЕДАКТИРОВАТЬ: вызов glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) также кажется значительно медленнее в телефонном устройстве. Почему это происходит? Как я мог этого избежать?


person drgr    schedule 05.03.2014    source источник
comment
Между прочим, я добавил в Grafika тест времени glTexImage2D() (github.com/google/grafika). В основном, чтобы иметь простой способ сравнить загрузку текстур RGBA 512x512 на разных устройствах.   -  person fadden    schedule 20.05.2014


Ответы (1)


Вы загружаете текстуры при каждой перерисовке кадра? Это просто неправильно - вы должны загружать текстуры только один раз перед основным циклом рендеринга. Вы не получите мгновенную загрузку текстур даже на самом быстром устройстве — вы загружаете ресурс, декодируете из него растровое изображение, а затем загружаете его в GPU. Это занимает некоторое время.

person keaukraine    schedule 05.03.2014
comment
Я изменил метод loadTextures(), так что операции выполняются во время инициализации, и единственный вызов, который я делаю при каждой перерисовке кадра, — это GLUtils.texImage2D, потому что мне нужно рисовать несколько PNG, поэтому я каждый раз рисую разные растровые изображения. время. Это неправильно? Как еще я мог это сделать? Почему это происходит быстрее, когда кадры поступают, например, с камеры или медиаплеера на SurfaceTexture? - person drgr; 06.03.2014
comment
texImage2D() очень ресурсоёмкая операция. Он обрабатывает исходное растровое изображение и загружает его в GPU. Это далеко не «мгновенная» операция. Нет необходимости менять ваш метод loadTexture(), он правильный. У вас может быть столько текстур, сколько может поместиться в GPU. Просто создайте массив или набор целых чисел, затем сохраните все ваши идентификаторы текстур (возвращенные из loadTexture()) перед основным циклом рендеринга, а затем передайте только необходимые идентификаторы шейдеру через юниформу. - person keaukraine; 06.03.2014