eglQuerySurface выдает неправильный размер

#opengl-es #android-ndk

#opengl-es #android-ndk

Вопрос:

Когда я поворачиваю свое устройство и получаю результаты моего приложения APP_CMD_CONFIG_CHANGED , я пытаюсь обновить окно просмотра OpenGL следующим образом:

 EGLint width;
EGLint height;
eglQuerySurface(display,surface,EGL_WIDTH,amp;width);
eglQuerySurface(display,surface,EGL_HEIGHT,amp;height);

glViewport(0,0,width,height);

MY_LOG_MACRO2("New window size: %d x %d",width,height);
  

Это работает примерно в 20% случаев. Остальные 80% времени ширина и высота являются предыдущими значениями. Другими словами, большую часть времени, когда я перевожу свое устройство в альбомный режим, записывается портретный размер. И когда я возвращаюсь к портрету, записывается размер ландшафта.

Мне не очень повезло с получением размера из ANativeWindow либо.

Что я должен делать, чтобы получить правильный размер окна после поворота?

Обновить:

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

Комментарии:

1. Где вы вызываете этот код? Контекст Opengl зависит от потока. Если этот код выполняется в случайном потоке, он может работать только при использовании потока с заданным контекстом

2. @crazyjul В моем приложении есть только один поток. Эта функция вызывается, когда ALooper_pollAll получает APP_CMD_CONFIG_CHANGED событие, а затем я запускаю pollSource->process(appState,pollSource) . Мой цикл событий почти идентичен образцу кода.

3. Сообщение с форумов Android с той же проблемой groups.google.com/group/android-ndk/browse_thread/thread /…

Ответ №1:

Для обнаружения изменения ориентации экрана я решил не перехватывать APP_CMD_CONFIG_CHANGED , а вызывать eglQuerySurface() каждый кадр. Если значения размера экрана не соответствуют сохраненным значениям, ориентация экрана была изменена.

Два вызова eglQuerySurface() для получения ширины и высоты занимают около 10 микросекунд (100 миллисекунд при вызове 10000 раз), поэтому это не снижает производительность и дает 100% гарантию того, что поворот экрана будет обработан.

Я думаю, что это решение лучше, чем ждать несколько кадров после APP_CMD_CONFIG_CHANGED . Кстати, поворот устройства на 180 градусов (вверх ногами) вызывает получение APP_CMD_CONFIG_CHANGED события, но на самом деле ориентация экрана не была изменена, и никаких действий, зависящих от изменения размера, выполняться не должно.

Ответ №2:

Это может не сработать, потому что, например, размер поверхности может быть установлен при создании контекста, и вы запрашиваете «предыдущий» размер (при создании контекста). Редактировать: я протестировал его на SGS2 (2.3.5), и я сразу получаю правильные результаты, так что это может быть проблема с поставщиком устройства (или проблема с версией Android).

Редактирование 2: похоже, я допустил какую-то ошибку во время тестирования, я тоже получаю странные результаты как @IronMensan. Иногда это работает правильно, но в основном нет. Извините за мою ошибку. Поэтому я бы остался при воссоздании контекста EGL, как в моем первоначальном ответе (ниже).

Когда я получаю APP_CMD_CONFIG_CHANGED, я просто просто уничтожаю и воссоздаю контекст EGL (с шейдерами, текстурами и т. Д.), аналогично, Когда я получаю APP_CMD_TERM_WINDOW -> APP_CMD_INIT_WINDOW.

Комментарии:

1. Взгляните еще раз на вопрос и обновление, которое я только что добавил — размер поверхности изменяется, просто обычно не сразу. В среднем требуется около пяти кадров.

2. @IronMensan: я только что протестировал его, и он работает правильно, после того, как я получу APP_CMD_CONFIG_CHANGED, тогда eglQuerySurface(EGL_WIDTH / EGL_HEIGHT) немедленно выдает мне правильные результаты. Протестировано на SGSII (2.3.5-KI3). Так что это может быть проблема с реализацией какого-то поставщика. Какое у вас устройство и версия Android?

3. HTC Evo 4G Android 2.3.3. Похоже, тестирование совместимости будет более болезненным, чем я ожидал.

4. Для справки, у меня есть герой, работающий под управлением Gingerbread 2.3.4 (через модифицированный ROM, я использую Elelinux), и я тоже это вижу.

5. @IronMensan: я отредактировал свой ответ, я вижу такое же странное поведение.