简体   繁体   English

由于尝试在Android上启动本机gles2 / egl应用程序而没有本机活动,导致分段错误

[英]Segmentation fault due to attempt to launch native gles2/egl app on android, without native activity

Sorry my English, I'm not native speaker. 对不起,我的英语不是我的母语。

I'm trying to launch simple gles2/egl app on android (Galaxy S4, Jelly Bean) without native_activity. 我正在尝试在没有native_activity的Android(Galaxy S4,Jelly Bean)上启动简单的gles2 / egl应用程序。

I have next main.c: 我有下一个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;
}

And next Android.mk: 接下来的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)

I have chosen 18-th NDK-supported API level due to I have 4.3 (Jelly Bean) android release. 由于我有4.3(Jelly Bean)android版本,因此选择了第18个NDK支持的API级别。

My project's directory looks like (before building): 我的项目的目录如下(在构建之前):

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

So, I launch ndk-build (in prj directory) and obtain ARM ELF executable file in prj/libs/armeabi and in prj/obj/local/armeabi/ with name hello_world_gr. 因此,我启动ndk-build(在prj目录中)并在prj / libs / armeabi和prj / obj / local / armeabi /中获得名称为hello_world_gr的ARM ELF可执行文件。

Also I was trying to pull out libEGL.so and libGLESv2.so libraries from phone and use them for linking. 我也试图从电话中提取libEGL.so和libGLESv2.so库,并使用它们进行链接。

In both cases, app is successfully launched on phone without any linker error, app prints hello world and receives segmentation fault in eglGetDisplay with some delay (in which nothing is occurred). 在这两种情况下,应用程序都成功在电话上启动,没有任何链接器错误,应用程序打出了问候世界,并在eglGetDisplay中出现了一段延迟(其中什么也没有发生)的分段错误。

If I try to do this on desktop Ubuntu: 如果我尝试在桌面Ubuntu上执行此操作:

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

As you can see, all is fine. 如您所见,一切都很好。

On X11-based target, I can obtain EGLNativeDisplay via, for example, xcb_connect(), and pass it to eglGetDisplay, does such function exist for android (of course I mean about C/C++ function)? 在基于X11的目标上,我可以通过例如xcb_connect()获得EGLNativeDisplay,并将其传递给eglGetDisplay,这样的功能对于android是否存在(当然,我的意思是关于C / C ++函数)?

You can look to https://android.googlesource.com/platform/hardware/libhardware/+/master/tests/hwc/ and ensure that it isn't my crazy idea. 您可以查看https://android.googlesource.com/platform/hardware/libhardware/+/master/tests/hwc/并确保它不是我的疯狂主意。

I have built and launched this example but, again, have received such segmentation fault within eglGetDisplay. 我已经构建并启动了此示例,但是再次在eglGetDisplay中收到了此类分段错误。 (I have built this app also manually via ndk, no full Android build.) (我也通过ndk手动构建了此应用,没有完整的Android构建。)

Did anybody try to do this? 有人尝试这样做吗? Did you get success? 你成功了吗?

I'm not sure why your code snippet is crashing , but I wouldn't expect it to work. 我不确定您的代码段为何崩溃 ,但我不希望它起作用。 Certainly not while the rest of the Android framework is running. 当然,在其余的Android框架运行时不会。

While we like to think of computers and devices as having The Frame Buffer, in practice such a thing might be inaccessible or not exist at all -- perhaps replaced by a set of configurable overlays. 尽管我们喜欢将计算机和设备视为具有“帧缓冲区”,但实际上,这种事情可能无法访问或根本不存在-可能由一组可配置的覆盖物替代。 On Android, framebuffers and overlays are managed at the lowest level by the hardware composer (HWC), and at a slightly higher level by the system graphics compositor (SurfaceFlinger). 在Android上,帧缓冲和覆盖由硬件编辑器(HWC)最低级别管理,而系统图形合成器(SurfaceFlinger)则稍高级别。

The best place to look for non-app examples is the frameworks/native/opengl/tests directory. 查找非应用程序示例的最佳位置是frameworks/native/opengl/tests目录。 If the system compositor is running, you can ask it for a surface to draw on. 如果系统合成器正在运行,则可以要求它在其上绘制表面。 The "angeles" demo provides a nice example. “天使”演示提供了一个很好的例子。 It uses the WindowSurface class (in the lib directory) to get a top-level display-sized surface from SurfaceFlinger. 它使用WindowSurface类(在lib目录中)从SurfaceFlinger获取顶级显示大小的表面。 It will work even while apps are running. 即使在应用程序运行时,它也可以工作。

If SurfaceFlinger isn't available, you'll need to interact with the hardware composer directly. 如果SurfaceFlinger不可用,则需要直接与硬件编辑器进行交互。 The tests in the hwc directory do this. hwc目录中的测试可以做到这一点。 Note they will not work if SurfaceFlinger is running. 请注意,如果SurfaceFlinger正在运行,则它们将不起作用。 (And they're old enough that they might not work at all anymore.) (它们已经足够老了,可能根本无法工作了。)

None of this uses public SDK APIs, so your code is likely to break if run on an older or newer version of Android. 这些都不使用公共SDK API,因此,如果在旧版本或更新版本的Android上运行,您的代码很可能会损坏。

More information about the Android graphics architecture, especially SurfaceFlinger and the HWC, can be found here . 有关Android图形体系结构的更多信息,尤其是SurfaceFlinger和HWC,可以在这里找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM