Потеря AWT DrawingSurface, когда Canvas скрыт - PullRequest
0 голосов
/ 20 февраля 2020

Я пишу модуль 3D-рендеринга для приложения AWT / Swing.

Чтобы обеспечить хороший 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), переменная ds остается прежней, но после этого она не работает. По сути, даже если я вызываю переменную только тогда, когда она видна и находится сверху - любой вызов, использующий ds , вызовет исключение. Например, функция lock () перестает работать.

Мне интересно, почему это так?

Также я попытался получить новый DS, если я сверну, а затем максимизирую снова окно, но это также не работает - новый адрес DS возвращается, как и должно, но я не могу использовать этот новый объект так же, как не мог использовать исходный.

Возможно, что-то есть Глупо я здесь скучаю, но я не могу понять, что. Пожалуйста, помогите мне разобраться с этим. Спасибо!

1 Ответ

0 голосов
/ 26 февраля 2020

Решение:

Когда 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());
    }
}

Как видите, я воссоздаю отображение и поверхность, но я использую ранее созданный контекст для рендеринга, без необходимости его повторного создания.

...