Ошибка сегментации из-за попытки запустить нативное приложение gles2/egl на Android без нативной активности

Извините за мой английский, я не носитель языка.

Я пытаюсь запустить простое приложение gles2/egl на Android (Galaxy S4, Jelly Bean) без native_activity.

У меня есть следующий main.c:

#include <stdio.h>
#include <stdlib.h>

#include <EGL/egl.h>
#include <GLES2/gl2.h>

int main( void )
{
  EGLDisplay dpy;

  printf( "hello world.\n" );

  dpy = eglGetDisplay( EGL_DEFAULT_DISPLAY );
  printf( "egl dpy: %p.\n", dpy );

  return 0;
}

И следующий Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS) 

LOCAL_MODULE := hello_world_gr
LOCAL_SRC_FILES := main.c

# I have found libGLESv2.so and libEGL.so libraries and appropriate header files in ndk.
LOCAL_LDLIBS := -L/home/ila/programs/android-ndk-r10e/platforms/android-18/arch-arm/usr/lib -lGLESv2 -lEGL
LOCAL_C_INCLUDES := /home/ila/programs/android-ndk-r10e/platforms/android-18/arch-arm/usr/include

include $(BUILD_EXECUTABLE)

Я выбрал 18-й уровень API с поддержкой NDK, так как у меня версия Android 4.3 (Jelly Bean).

Каталог моего проекта выглядит так (до сборки):

prj:
--  jni:
    -- main.c
    -- Android.mk

Итак, я запускаю ndk-build (в каталоге prj) и получаю исполняемый файл ARM ELF в prj/libs/armeabi и в prj/obj/local/armeabi/ с именем hello_world_gr.

Также я пытался вытащить из телефона библиотеки libEGL.so и libGLESv2.so и использовать их для линковки.

В обоих случаях приложение успешно запускается на телефоне без каких-либо ошибок компоновщика, приложение выводит hello world и получает ошибку сегментации в eglGetDisplay с некоторой задержкой (при которой ничего не происходит).

Если я попытаюсь сделать это на рабочем столе Ubuntu:

$ gcc -o hello_world_gr main.c -lGLESv2 -lEGL
$ ./hello_world_gr
hello world.
egl dpy: 0x25e7010.

Как видите, все в порядке.

На цели на основе X11 я могу получить EGLNativeDisplay через, например, xcb_connect() и передать его в eglGetDisplay, существует ли такая функция для Android (конечно, я имею в виду функцию C/C++)?

Вы можете посмотреть на https://android.googlesource.com/platform/hardware/libhardware/+/master/tests/hwc/ и убедитесь, что это не моя сумасшедшая идея.

Я собрал и запустил этот пример, но снова получил такую ​​ошибку сегментации в eglGetDisplay. (Я также создал это приложение вручную с помощью ndk, полной сборки для Android нет.)

Кто-нибудь пытался это сделать? Вы добились успеха?


person sergs    schedule 30.07.2015    source источник


Ответы (1)


Я не знаю, почему ваш фрагмент кода крашится, но я не ожидал, что он сработает. Конечно, не тогда, когда работает остальная часть платформы Android.

Хотя нам нравится думать, что компьютеры и устройства имеют буфер кадров, на практике такая вещь может быть недоступна или вообще не существовать — возможно, заменена набором настраиваемых оверлеев. В Android кадровые буферы и наложения управляются на самом низком уровне аппаратным компоновщиком (HWC), а на несколько более высоком уровне — компоновщиком системной графики (SurfaceFlinger).

Лучшее место для поиска примеров, не относящихся к приложениям, — это frameworks/native/opengl/tests каталог. Если системный компоновщик запущен, вы можете запросить у него поверхность для рисования. Демонстрация "angeles" представляет собой хороший пример. Он использует WindowSurface (в каталоге lib), чтобы получить поверхность верхнего уровня размером с дисплей из SurfaceFlinger. Он будет работать даже во время работы приложений.

Если SurfaceFlinger недоступен, вам необходимо напрямую взаимодействовать с аппаратным компоновщиком. Это делают тесты в каталоге hwc. Обратите внимание, что они не будут работать, если запущен SurfaceFlinger. (И они достаточно старые, чтобы вообще больше не работать.)

Ни в одном из них не используются общедоступные API-интерфейсы SDK, поэтому ваш код может сломаться при запуске на более старой или более новой версии Android.

Дополнительную информацию о графической архитектуре Android, особенно о SurfaceFlinger и HWC, можно найти здесь.

person fadden    schedule 30.07.2015
comment
Спасибо, особенно за ангельскую демонстрацию и статью о SurfaceFlinger и HWC. Я узнаю о них. - person sergs; 31.07.2015