Первый вызов glDrawArrays на iPad очень медленный - PullRequest
1 голос
/ 02 ноября 2010

У меня есть приложение для iPad с пользовательским интерфейсом, написанным на OpenGL ES 2.0, некоторые элементы пользовательского интерфейса по умолчанию скрыты, и когда мне нужно показать их, перед их показом появляется довольно большая задержка (около 300-500 мс для элемента управления, который содержит около 20 других элементов управления внутри), используя Instruments.app. Я определил, что при рендеринге каждого уникального объекта его рендеринг выполняется намного дольше, чем после его рендеринга хотя бы один раз, и разница во времени рендеринга огромна. Вот код, который у меня есть для рендеринга, и этот код показывается приборами, принимающими всю эту задержку:

- (void)render:(id <ESRenderer>)renderer
{
    [shader useShader];
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, _squareVertices);
    glEnableVertexAttribArray(ATTRIB_TEXTCOORD);
    glVertexAttribPointer(ATTRIB_TEXTCOORD, 2, GL_SHORT, 0, 0, coords);
    float x1 = self.position.x;
    float y1 = self.position.y;
    glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_X], -x1+_squareVertices[0]);
    glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_Y], -y1+_squareVertices[1]);
    glUniform1f(shader.ext_uniforms[UNIFORM_ROTATE], self.rotation); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableVertexAttribArray(ATTRIB_VERTEX);
    glDisableVertexAttribArray(ATTRIB_TEXTCOORD);
}

Когда он вызывается хотя бы один раз, он работает совершенно быстро. Мой шейдер тоже очень прост:

vec4 col = texture2D(texture, coordVarying);
gl_FragColor = col;

Спасибо!

Ответы [ 3 ]

1 голос
/ 02 ноября 2010

Я полагаю, что фактическая передача данных в графический процессор происходит только один раз. Вы должны быть в состоянии форсировать загрузку / компиляцию в какой-то момент перед первым рендерингом, чтобы убрать это снижение производительности. Либо передача вершинных данных, если она огромная, либо передача / компиляция шейдеров.

РЕДАКТИРОВАТЬ: как отмечено в другом ответе, есть также данные текстуры, которые могут быть переданы.

0 голосов
/ 21 августа 2015

Я тоже это понял. Для меня это была проблема с текстурой. На NVIDA все работало быстро. Но моя оптическая оптимизация привела к тому, что карта ATI едва не ушла в отставку.

Я работаю с текстурой размером 4720 x 5600 (примерно), и современные карты хорошо с ней работают.

Я пытался оптимизировать границы, используя Wrapmode = GL_CLAMP_TO_BORDER_ARB. Поэтому мне нужно предоставить аргумент border для glTeximage2D как минимум == 1. Поскольку сомнительная карта не поддерживала границы в HW, оказалось, что на один кадр уходит 20 секунд. Возвращаясь к GL_CLAMP_TO_BORDER + border param == 0, он снова ускорился.

0 голосов
/ 02 ноября 2010

Реализации OpenGL обычно загружают текстуры «лениво», то есть текстура фактически инициализируется только при первом использовании (в значительной степени то, что сказал jv42, но не данные геометрии). Может быть, это то, что происходит здесь. Если вы не меняете свои текстуры между объектами, вы получаете такие же замедления?

Одно из решений - нарисовать несколько тривиальных внеэкранных треугольников с вашими текстурами, привязанными во время инициализации, чтобы заставить эти текстуры быть загруженными до основного цикла рендеринга.

Кстати, я бы не стал особо оценивать длину отдельных вызовов на отрисовку для отложенного рендеринга, такого как в iPhone.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...