Android:是否可以在没有 SurfaceView 的情况下创建 SurfaceTexture? [英] Android: Is it possible to create a SurfaceTexture without a SurfaceView?

查看:28
本文介绍了Android:是否可以在没有 SurfaceView 的情况下创建 SurfaceTexture?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个具有我可以管理的 OpenGL 纹理的 SurfaceTexture,设置类似于 这个答案.(此处引用:)

<块引用>

  1. 通过 OpenGL 创建纹理
  2. 将此纹理传递给新 SurfaceTexture 的构造函数.
  3. 将这个新的 SurfaceTexture 赋予相机.
  4. 确保您使用的是 OES_External(请参阅文档详情).

但是,创建 OpenGL 纹理(如答案的第 1 步)需要 EGL 上下文,这需要将 EGLSurface 设为最新,这需要 SurfaceTexture.似乎创建 EGL 上下文的唯一方法是创建一个 SurfaceView(或另一个具有 SurfaceTexture 的视图),并使用它来初始化 EGLSurface,然后使 EGLContext 成为当前的.

我的目标是创建一个 EGLContext 并使其在后台线程中处于当前状态,以对相机预览图像进行一些屏幕外计算(主要使用 NDK).我想创建一个库,并使其尽可能独立于 UI.两个相关问题:

在 Java 端,是否可以在不预先创建 SurfaceTexture 的情况下创建 EGLContext?

在 NDK 方面,曾经有一个私有 API 调用来创建原生窗口 android_createDisplaySurface(),但它不再起作用了,而且它是一个私有 API.有什么方法可以使用 NDK 创建表面吗?

我对使用 EGL 很陌生,我不明白为什么需要 EGLSurface 才能使 EGLContext 成为最新.在 iOS 中,可以先创建 EAGLContexts,然后根据需要创建 framebuffers.使用 EGL,您似乎总是需要一个原生窗口.

解决方案

您可以在 涂鸦.连续捕获"活动是其中之一,但它使用了您提到的技术:为了避免创建 EGLSurface,它只是从附近的 SurfaceView 借用了一个.

您确实需要一个 EGLSurface,但它不需要是一个 window 表面.您可以创建一个 1x1 pbuffer 表面并使用它.这是通过 eglCreatePbufferSurface() 调用完成的;以 Grafika 中的 EglCore 类为例.

这些示例是用 Java 编写的,但 Java 实现只是包装了本机 EGL/GLES 调用.

android_createDisplaySurface() 是一个内部调用,正如您所发现的,它不适用于较新的设备.而是在 NDK 中搜索 ANativeWindow.

更新:对于通过搜索到达这里的任何人,android_createDisplaySurface() 依赖于一个名为 FramebufferNativeWindow 的内部类,该类在此更改中的 Android 5.0.使用它的内部 OpenGL ES 测试代码已在 this改变.测试代码的原始版本需要关闭 Android 应用程序框架,以便它可以获取帧缓冲区;较新的版本只是要求 SurfaceFlinger 提供一个覆盖屏幕并合成在其他所有内容之上的窗口.

I want to create a SurfaceTexture with an OpenGL texture that I can manage, in a setup similar to this answer. (Quoted here:)

  1. Create a texture through OpenGL
  2. Pass this texture to the constructor of new SurfaceTexture.
  3. Give this new SurfaceTexture to the camera.
  4. Make sure you are using OES_External (see documentation for details).

However, creating an OpenGL texture (as in step 1 of the answer), requires an EGL context, which requires a EGLSurface to be made current, which requires a SurfaceTexture. It seems the only way of creating the EGL context is by creating a SurfaceView (or another view that has a SurfaceTexture), and use it to initialise the EGLSurface and then make the EGLContext current.

My objective is to create an EGLContext and make it current in a background thread, to do some offscreen computation on the camera preview image (mostly using the NDK). I want to create a library, and make it as independent of the UI as possible. Two related questions:

On the Java side, is it possible to create an EGLContext without having a SurfaceTexture created beforehand?

On the NDK side, there used to be a private API call to create native windows android_createDisplaySurface(), but it doesn't work anymore, and well, it's a private API. Is there any way of creating a surface with the NDK?

I'm quite new to using EGL, and I fail to understand why you need an EGLSurface for an EGLContext to be made current. In iOS, EAGLContexts can be created first, and then framebuffers can be created as needed. Using EGL it seems you always need a native window.

解决方案

You can see a number of examples that manipulate Camera output, SurfaceTexture, and EGL in Grafika. The "Continuous capture" activity is one, but it uses the technique you mentioned: to avoid having to create an EGLSurface, it just borrows the one from the nearby SurfaceView.

You do need to have an EGLSurface, but it doesn't need to be a window surface. You can create a 1x1 pbuffer surface and just use that. This is done with the eglCreatePbufferSurface() call; see the EglCore class in Grafika for an example.

These examples are in Java, but the Java implementation just wraps the native EGL/GLES calls.

android_createDisplaySurface() is an internal call that, as you discovered, doesn't work on newer devices. Search the NDK for ANativeWindow instead.

Update: for anyone who gets here by searching, android_createDisplaySurface() relied on an internal class called FramebufferNativeWindow, which was marked obsolete in Android 5.0 in this change. The internal OpenGL ES test code that used it was updated with a SurfaceFlinger-based replacement in this change. The original version of the test code required shutting down the Android app framework so it could grab the frame buffer; the newer version just asks SurfaceFlinger for a window that covers the screen and is composited on top of everything else.

这篇关于Android:是否可以在没有 SurfaceView 的情况下创建 SurfaceTexture?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆