Я пытаюсь заставить довольно простую программу openGL ES 1 запускать ровные твердые 60 кадров в секунду на паре устройств, и я застреваю на желании HTC.Сам телефон быстрый, быстрый, мощный и в целом удобный для использования;однако я не могу отобразить что-нибудь в полноэкранном режиме со скоростью 60 кадров в секунду с OpenGL.После долгого застревания с моим приложением я решил создать тестовое приложение с кодом прямо из примера кода из документации.
Вот что я делаю.Простой код инициализации с GLSurfaceView.У меня есть три версии onDrawFrame, все очень просто.Один пуст.Один содержит только glClear.Один содержит достаточно состояния, чтобы нарисовать только полноэкранный квад.Время трассировки до и после.В моей программе нет другого представления, кроме моего GLSurfaceView.Я не могу объяснить, сколько раз я получаю.
Во всех случаях сама функция onDrawFrame всегда заканчивается менее 2 мс.Но очень часто onDrawFrame не вызывается снова до 30 ~ 40 мс, снижая частоту кадров до 30 кадров в секунду или меньше.Я получаю около 50 кадров в секунду с пустым onDrawFrame, 45 с glClear и 35 с четырехугольником.Этот же код работает на скорости 60 кадров в секунду на HTC Magic, на Samsung Galaxy S, на Sharp ISO1.Sony Experia X10 показывает 30 кадров в секунду благодаря своему экрану.Я делал намного более сложные сцены с высокой частотой 60 кадров в секунду на HTC Magic, который на очень слабее по сравнению с Desire.У меня нет Nexus One, пригодного для тестирования.Конечно, я за исключением замены буфера в блоке на пару миллисекунд.Но он все время перепрыгивает через кадры.
Пытаясь выяснить, что делает телефон вне обработчика onDrawFrame, я попытался использовать Debug.startMethodTracing.Нет никакого способа, которым я мог бы заставить трассировку отражать фактическое время, которое телефон проводит вне цикла.В конце onDrawFrame я использую startMethodTracing, затем сохраняю текущее время (SystemClock.uptimeMillis) в переменной.В начале следующего я записываю разницу во времени с момента последнего выхода из функции и stopMethodTracing.Это будет вызываться снова и снова, поэтому я организую остановку, как только получу трассировку для итерации с паузой более 40 мс.Временная шкала на полученной трассировке составляет менее 2 мс, как если бы система тратила 38 мс вне моей программы.
Я много чего пробовал.Перечислите EGL-конфиги и попробуйте их все одно за другим.Чтобы посмотреть, изменилось ли что-нибудь, я переключился на рендер, когда грязная схема запрашивала перерисовку в каждом кадре.Но безрезультатно.Что бы я ни делал, ожидаемый промежуток в 14 ~ 16 мс для замены буферов займет около 30 мс примерно вдвое, и, независимо от того, что я делаю, кажется, что устройство ожидает двух обновлений экрана.PS на устройстве показывает мое приложение на уровне около 10% CPU, а System_server на уровне 35%.Конечно, я также пробовал очевидное, убивая другие процессы, перезагружая устройство ... Я всегда получаю один и тот же точный результат.
У меня нет той же проблемы с рисованием на холсте.
Кто-нибудь знает, почему Desire (и только Desire) ведет себя так?
Для справки, вот как выглядит мой тестовый код:
public class GLTest extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(this);
mGLView.setRenderer(new ClearRenderer());
setContentView(mGLView);
}
@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}
@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}
private GLSurfaceView mGLView;
}
class ClearRenderer implements GLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 gl, EGLConfig config) {}
public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); }
long start;
long end;
public void onDrawFrame(GL10 gl)
{
start = System.currentTimeMillis();
if (start - end > 20)
Log.e("END TO START", Long.toString(start - end));
// gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
end = System.currentTimeMillis();
if (end - start > 15)
Log.e("START TO END", Long.toString(end - start));
}
}