隐藏 Canvas 时丢失 AWT DrawingSurface
Losing AWT DrawingSurface when Canvas is hidden
我正在为 AWT/Swing 应用程序编写 3d 渲染模块。
为了提供良好的 FPS,我无法使用 Swing/AWT 方法和图形进行绘制。相反,我从 Canvas 元素获取绘图表面,然后直接渲染到它。像这样:
public class Window {
private Component canvas;
private JAWTDrawingSurface ds;
public static final JAWT awt;
static {
awt = JAWT.calloc();
awt.version(JAWT_VERSION_1_4);
if (!JAWT_GetAWT(awt))
throw new AssertionError("GetAWT failed");
}
public void lock() throws AWTException {
int lock = JAWT_DrawingSurface_Lock(ds, ds.Lock());
if ((lock & JAWT_LOCK_ERROR) != 0)
throw new AWTException("JAWT_DrawingSurface_Lock() failed");
}
public void unlock() throws AWTException {
JAWT_DrawingSurface_Unlock(ds, ds.Unlock());
}
public void Init2()
{
this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
try
{
lock();
// Create GL Capabilities
unlock();
}
}
我第一次调用它时它工作正常。
但是当我出于任何原因隐藏 canvas 时(例如最小化 window 或显示另一个面板而不是 Canvas),ds 变量仍然是一样,但之后就不行了。
基本上,即使我确保仅在变量可见且位于顶部时才调用该变量——任何使用 ds 的调用都会引发异常。例如 lock() 函数停止工作。
我想知道这是为什么?
此外,如果我最小化然后再次最大化 window,我尝试基本上获得一个新的 DS,但这也不起作用 - 新的 DS 地址按应有的方式返回,但我可以'不要使用那个新对象,就像我不能使用原来的对象一样。
我可能在这里遗漏了一些愚蠢的东西,但我不知道是什么。
请帮我解决这个问题。谢谢!
解决方法:
当Canvas隐藏时,调用eglMakeCurrent(eglDisplay,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT)解绑当前上下文
当你需要重新开始绘图时,你需要做这样的事情:
public void Reinit()
{
System.err.println("Context Reinit()");
this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
try
{
lock();
try
{
JAWTDrawingSurfaceInfo dsi = JAWT_DrawingSurface_GetDrawingSurfaceInfo(ds, ds.GetDrawingSurfaceInfo());
JAWTX11DrawingSurfaceInfo dsiWin = JAWTX11DrawingSurfaceInfo.create(dsi.platformInfo());
this.display = dsiWin.display();
this.drawable = dsiWin.drawable();
eglDisplay = eglGetDisplay(display);
surface = eglCreateWindowSurface(eglDisplay,fbConfigs.get(0),drawable,(int[])null);
eglMakeCurrent(eglDisplay,surface,surface,context);
GLES.setCapabilities(glesCaps);
JAWT_DrawingSurface_FreeDrawingSurfaceInfo(dsi, ds.FreeDrawingSurfaceInfo());
}
finally
{
unlock();
System.err.printf("Unlock \n");
}
}
catch (Exception e)
{
System.err.println("JAWT Failed" + e.getMessage());
}
}
如您所见,我重新创建了显示和表面,但是我使用之前创建的上下文进行渲染,而不需要重新创建它。
我正在为 AWT/Swing 应用程序编写 3d 渲染模块。
为了提供良好的 FPS,我无法使用 Swing/AWT 方法和图形进行绘制。相反,我从 Canvas 元素获取绘图表面,然后直接渲染到它。像这样:
public class Window {
private Component canvas;
private JAWTDrawingSurface ds;
public static final JAWT awt;
static {
awt = JAWT.calloc();
awt.version(JAWT_VERSION_1_4);
if (!JAWT_GetAWT(awt))
throw new AssertionError("GetAWT failed");
}
public void lock() throws AWTException {
int lock = JAWT_DrawingSurface_Lock(ds, ds.Lock());
if ((lock & JAWT_LOCK_ERROR) != 0)
throw new AWTException("JAWT_DrawingSurface_Lock() failed");
}
public void unlock() throws AWTException {
JAWT_DrawingSurface_Unlock(ds, ds.Unlock());
}
public void Init2()
{
this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
try
{
lock();
// Create GL Capabilities
unlock();
}
}
我第一次调用它时它工作正常。 但是当我出于任何原因隐藏 canvas 时(例如最小化 window 或显示另一个面板而不是 Canvas),ds 变量仍然是一样,但之后就不行了。 基本上,即使我确保仅在变量可见且位于顶部时才调用该变量——任何使用 ds 的调用都会引发异常。例如 lock() 函数停止工作。
我想知道这是为什么?
此外,如果我最小化然后再次最大化 window,我尝试基本上获得一个新的 DS,但这也不起作用 - 新的 DS 地址按应有的方式返回,但我可以'不要使用那个新对象,就像我不能使用原来的对象一样。
我可能在这里遗漏了一些愚蠢的东西,但我不知道是什么。 请帮我解决这个问题。谢谢!
解决方法:
当Canvas隐藏时,调用eglMakeCurrent(eglDisplay,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT)解绑当前上下文
当你需要重新开始绘图时,你需要做这样的事情:
public void Reinit()
{
System.err.println("Context Reinit()");
this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
try
{
lock();
try
{
JAWTDrawingSurfaceInfo dsi = JAWT_DrawingSurface_GetDrawingSurfaceInfo(ds, ds.GetDrawingSurfaceInfo());
JAWTX11DrawingSurfaceInfo dsiWin = JAWTX11DrawingSurfaceInfo.create(dsi.platformInfo());
this.display = dsiWin.display();
this.drawable = dsiWin.drawable();
eglDisplay = eglGetDisplay(display);
surface = eglCreateWindowSurface(eglDisplay,fbConfigs.get(0),drawable,(int[])null);
eglMakeCurrent(eglDisplay,surface,surface,context);
GLES.setCapabilities(glesCaps);
JAWT_DrawingSurface_FreeDrawingSurfaceInfo(dsi, ds.FreeDrawingSurfaceInfo());
}
finally
{
unlock();
System.err.printf("Unlock \n");
}
}
catch (Exception e)
{
System.err.println("JAWT Failed" + e.getMessage());
}
}
如您所见,我重新创建了显示和表面,但是我使用之前创建的上下文进行渲染,而不需要重新创建它。