无法进行渲染(android、SurfaceView、ndk、ANativeWindow)
Can' get rendering to work(android,SurfaceView,ndk,ANativeWindow)
我搜索了一整天,仍然无法弄清楚,我错过了什么。我找到的所有示例要么不完整(只有未连接的片段)要么过度完整(如果原理看不到真正的部分)
我有一个 Activity,它有一个扩展 SurfaceView 的视图,应该使用本机方法填充它。它目前由 memset(..,0,..) 实现,但我的视图是白色的,尽管所有调用看起来都很好。
我的观点:
public class MyView extends SurfaceView implements SurfaceHolder.Callback
{
public MyView(Context context)
{
super(context);
SurfaceHolder sh = getHolder();
sh.addCallback(this);
}
// protected void onDraw(Canvas canvas) // works to make the view red
// { canvas.drawColor(Color.RED);}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
nativeRender(holder.getSurface(), width, height);
}
public void surfaceCreated(SurfaceHolder holder)
{}
public void surfaceDestroyed(SurfaceHolder holder)
{}
private native void nativeRender(Object surface, int width, int height);
}
本机方法:
void ...nativeRender(JNIEnv* env, jobject myView, jobject surface, jint width, jint height)
{
ANativeWindow* pWindow(ANativeWindow_fromSurface(env, surface));
ANativeWindow_setBuffersGeometry(pWindow, width,height,WINDOW_FORMAT_RGBX_8888);
ANativeWindow_Buffer buffer;
if (ANativeWindow_lock(pWindow, &buffer, NULL) == 0)
{
memset(buffer.bits, 0, buffer.stride*buffer.height*4);
ANativeWindow_unlockAndPost(pWindow);
}
ANativeWindow_release(pWindow);
}
我检查的内容:
- return 所有 ANativeWindow_* 的值都是 0。
- 缓冲区size/format符合预期
我尝试过的事情:
- 从 onDraw() 调用 nativeRender()
- 重复调用 nativeRender() (Handler(mainLooper(), postDelayed())
- 将 ANativeWindow* 保持为静态变量(多次调用上述方法)
- 没有 ANativeWindow_release(pWindow);
相同
- WINDOW_FORMAT_RGBX_8888 对比 WINDOW_FORMAT_RGBA_8888
- 填充图案
所以在我看来,我填充了一个从未显示过的正确尺寸的缓冲区。可能我遗漏了一些明显的东西,因为似乎没有其他人有那样的问题。
提前致谢
莫里茨
谢谢!
法登的评论就是答案。我的代码实际上调用了 setBackgroundColor() ,这显然不是我想要的...
(虽然我希望在这种情况下这个 属性 没有任何意义或者缓冲区将被预填充...)
我搜索了一整天,仍然无法弄清楚,我错过了什么。我找到的所有示例要么不完整(只有未连接的片段)要么过度完整(如果原理看不到真正的部分)
我有一个 Activity,它有一个扩展 SurfaceView 的视图,应该使用本机方法填充它。它目前由 memset(..,0,..) 实现,但我的视图是白色的,尽管所有调用看起来都很好。
我的观点:
public class MyView extends SurfaceView implements SurfaceHolder.Callback
{
public MyView(Context context)
{
super(context);
SurfaceHolder sh = getHolder();
sh.addCallback(this);
}
// protected void onDraw(Canvas canvas) // works to make the view red
// { canvas.drawColor(Color.RED);}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
nativeRender(holder.getSurface(), width, height);
}
public void surfaceCreated(SurfaceHolder holder)
{}
public void surfaceDestroyed(SurfaceHolder holder)
{}
private native void nativeRender(Object surface, int width, int height);
}
本机方法:
void ...nativeRender(JNIEnv* env, jobject myView, jobject surface, jint width, jint height)
{
ANativeWindow* pWindow(ANativeWindow_fromSurface(env, surface));
ANativeWindow_setBuffersGeometry(pWindow, width,height,WINDOW_FORMAT_RGBX_8888);
ANativeWindow_Buffer buffer;
if (ANativeWindow_lock(pWindow, &buffer, NULL) == 0)
{
memset(buffer.bits, 0, buffer.stride*buffer.height*4);
ANativeWindow_unlockAndPost(pWindow);
}
ANativeWindow_release(pWindow);
}
我检查的内容:
- return 所有 ANativeWindow_* 的值都是 0。
- 缓冲区size/format符合预期
我尝试过的事情:
- 从 onDraw() 调用 nativeRender()
- 重复调用 nativeRender() (Handler(mainLooper(), postDelayed())
- 将 ANativeWindow* 保持为静态变量(多次调用上述方法)
- 没有 ANativeWindow_release(pWindow); 相同
- WINDOW_FORMAT_RGBX_8888 对比 WINDOW_FORMAT_RGBA_8888
- 填充图案
所以在我看来,我填充了一个从未显示过的正确尺寸的缓冲区。可能我遗漏了一些明显的东西,因为似乎没有其他人有那样的问题。
提前致谢 莫里茨
谢谢!
法登的评论就是答案。我的代码实际上调用了 setBackgroundColor() ,这显然不是我想要的...
(虽然我希望在这种情况下这个 属性 没有任何意义或者缓冲区将被预填充...)