Вопрос или проблема
Существует ли способ перебрать подключенные внешние дисплеи и выбрать, для какого дисплея я хочу создать поверхность с помощью EGL? Идеально, если это можно сделать без использования среды JNI, так как я пробовал это, но ничего не вышло, потому что, когда я пытался создать поверхность на предоставленном ANativeWindow, происходил сбой, а когда я просто выполнял обычное создание EGL (просто получая значение по умолчанию), все работало нормально.
Спасибо!
Ответ или решение
Для разработки приложения на Android, использующего несколько внешних дисплеев с EGL и C++, важно знать, как правильно выбирать дисплей для создания поверхности. Давайте рассмотрим, как это можно реализовать, не прибегая к JNI, что может привести к сбоям.
Понимание основ
EGL является интерфейсом, который позволяет связывать OpenGL ES и различные платформы, включая Android. В Android существует возможность использовать несколько внешних дисплеев, что расширяет возможности взаимодействия с приложением.
Итерация по подключённым дисплеям
Для начала, стоит отметить, что для доступа к информации о дисплеях и управления ими вам нужно использовать определённые API Android. Один из наиболее подходящих способов — воспользоваться классом DisplayManager
.
Вот пример того, как можно итерировать через подключённые дисплеи:
-
Получение экземпляра DisplayManager
Сначала нужно получить доступ кDisplayManager
:ANativeActivity* activity = ...; // Ваш экземпляр активности DisplayManager* displayManager = (DisplayManager*)activity->instance; jclass displayManagerClass = env->GetObjectClass(displayManager); jmethodID getDisplaysMethod = env->GetMethodID(displayManagerClass, "getDisplays", "()[Landroid/view/Display;"); jobjectArray displaysArray = (jobjectArray)env->CallObjectMethod(displayManager, getDisplaysMethod);
-
Итерация по массиву дисплеев
Далее, чтобы выбрать конкретный дисплей, вы можете итерировать по всем доступным экземплярам:jsize displayCount = env->GetArrayLength(displaysArray); for (jsize i = 0; i < displayCount; ++i) { jobject display = env->GetObjectArrayElement(displaysArray, i); // Получите имя или свойства дисплея, чтобы определить, нужный ли это нам дисплей }
-
Создание ANativeWindow для выбранного дисплея
После выбора нужного дисплея, вам потребуется создатьANativeWindow
. Это можно сделать черезSurface
.ANativeWindow* nativeWindow = ...; // Получение вашего ANativeWindow
-
Инициализация EGL
Далее следует инициализация EGL и создание поверхности на выбранномANativeWindow
. Убедитесь, что используете правильные параметры:EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(eglDisplay, nullptr, nullptr); EGLConfig config; EGLint numConfigs; eglChooseConfig(eglDisplay, /* параметры выбираемого конфига */, &config, 1, &numConfigs); EGLSurface eglSurface = eglCreateWindowSurface(eglDisplay, config, nativeWindow, nullptr);
Радикальное улучшение качества кода
Обязательно обрабатывайте все возможные исключения и ошибки в процессе работы с EGL, так как возникают ситуации, когда создание поверхности может завершиться неудачей.
Заключение
Итак, вы можете итерировать через доступные дисплеи, создавая поверхности для них без использования JNI, уменьшая вероятность возникновения сбоев. При этом важно тщательно управлять памятью и ресурсами, особенно когда работаете с несколькими дисплеями. Если у вас есть доступные примеры кода или документация, не стесняйтесь использовать их, чтобы улучшить вашу реализацию.
Пользуясь этими рекомендациями, вы сможете эффективно управлять несколькими дисплеями в вашем Android-приложении, используя возможности EGL и C++.