我正在寻找从Android GLSurfaceView非常快速地获取绘图缓冲区的方法。
虽然我知道glreadpixel可以完成这项工作,glreadpixel太慢而无法获得绘图缓冲区。
我想读取保持30 fps的缓冲区。
ANativeWindow api似乎就像我在寻找的......
我找不到任何用于GLSurfaceView的ANativeWindow api的例子。
我的程序:
我使用Android“BasicGLSurfaceView”示例尝试了下面的jni代码。
JNIEXPORT void JNICALL Java_com_example_android_basicglsurfaceview_BasicGLSurfaceViewActivity_readSurface(JNIEnv* jenv, jobject obj, jobject surface)
{
LOG_INFO("Java_com_example_android_basicglsurfaceview_BasicGLSurfaceViewActivity_readSurface");
if (surface != 0) {
ANativeWindow *window = ANativeWindow_fromSurface(jenv, surface);
LOG_INFO("Got window %p", window);
if(window > 0)
{
int width = ANativeWindow_getWidth(window);
int height = ANativeWindow_getHeight(window);
LOG_INFO("Got window %d %d", width,height);
ANativeWindow_setBuffersGeometry(window,0,0,WINDOW_FORMAT_RGBA_8888);
ANativeWindow_Buffer buffer;
memset((void*)&buffer,0,sizeof(buffer));
int lockResult = -22;
lockResult = ANativeWindow_lock(window, &buffer, NULL);
if (lockResult == 0) { \
LOG_INFO("ANativeWindow_locked");
ANativeWindow_unlockAndPost(window);
}
else
{
LOG_INFO("ANativeWindow_lock failed error %d",lockResult);
}
LOG_INFO("Releasing window");
ANativeWindow_release(window);
}
} else {
LOG_INFO("surface is null");
}
return;
}
ANativeWindow_fromSurface和getHeight,setBuffersGeometry api运行良好。
但是ANativeWindow_lock api总是无法返回-22值。
错误信息
[Surfaceview]连接:已连接(cur = 1,req = 2)
我在Renderer中的onDrawFrame或主线程或onSurfaceChanged上尝试了此代码。
但总是它返回-22值。
我在错误的地方叫这个api?
是否可以将ANativeWindow_lock用于GLSurfaceView?
任何帮助将非常感谢〜
尝试这样做:
http://forums.arm.com/index.php?/topic/15782-glreadpixels/
希望您可以使用ANativeWindow作为缓冲区,这样您就不必直接调用gralloc了...
我不确定是否需要memset
操作。
这对我有用:
ANativeWindow *window = ANativeWindow_fromSurface(env, surface);
if(window > 0){
unsigned char *data = ... // an RGBA(8888) image
int32_t w = ANativeWindow_getWidth(window);
int32_t h = ANativeWindow_getHeight(window);
ANativeWindow_setBuffersGeometry(window, w, h, WINDOW_FORMAT_RGBA_8888);
ANativeWindow_Buffer buffer;
int lockResult = -1;
lockResult = ANativeWindow_lock(window, &buffer, NULL);
if(lockResult == 0){
//write data
memcpy(buffer.bits, data, w * h * 4);
ANativeWindow_unlockAndPost(window);
}
//free data...
ANativeWindow_release(window);
}
当您遇到相同的错误消息时,
[Surfaceview] connect: already connected
您可以在调用本机部分之前通过GLSurface.onPause()解决此问题。您可以在本机代码中通过ANativeWindow_lock,写帧缓冲区,ANativeWindow_unlockAndPost进行渲染。
// Java
SurfaceHolder holder = mGLSurfaceView.getHolder();
mPreviewSurface = holder.getSurface();
mGLSurfaceView.onPause();
camera.nativeSetPreviewDisplay(mPreviewSurface);
我只为发布EGL上下文调用GLSurfaceView onPause()。 GLSurfaceView将由本机代码呈现。
至少我认为这可以成为问题的答案“是否可以在GLSurfaceView中使用ANativeWindow_lock?”。是的。
但是这样,您只能使用窗口缓冲区渲染视图。您不能使用opengl api,因为在GLSurfaceView暂停后不会调用GLSurfaceView.Renderer onDrawFrame()。它仍然表现出比使用更好的性能,但如果你需要opengl api它是没用的。
着色器调用应位于onSurfaceChanged(),onSurfaceCreated()或onDrawFrame()的GL线程内