我正在寻找从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或主线程或onSurfaceChanged中的onDrawFrame上尝试了此代码。
但始终返回-22值。
我在错误的地方叫这个api?
是否可以将ANativeWindow_lock用于GLSurfaceView?
任何帮助都会非常感激〜
答案 0 :(得分:0)
尝试这样做:
http://forums.arm.com/index.php?/topic/15782-glreadpixels/
希望您可以使用ANativeWindow作为缓冲区,这样您就不必直接调用gralloc了......
答案 1 :(得分:0)
我不确定是否需要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);
}
答案 2 :(得分:0)
当您遇到相同的错误消息时,
[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线程中