воссоздать eglCreateWindowSurface с тем же собственным окном

Я написал библиотеку, используя API EGL. Эта библиотека имеет функции «init» и «deinit». В функции 'init' создается собственный идентификатор окна, переданный пользователем, с использованием этого собственного идентификатора окна создается eglCreateWindowSurface. В функции 'deinit' поверхность уничтожается с помощью eglDestroySurface.

Теперь пользователь снова вызывает функцию 'init', чтобы создать другой eglCreateWindowSurface, но он передал тот же идентификатор окна, что и раньше (поскольку он не закрыл свое окно), здесь eglCreateWindowSurface завершился с ошибкой EGL_BAD_ALLOC.

Я читал спецификации EGL

Если уже есть EGLSurface, связанный с win (в результате предыдущего вызова eglCreateWindowSurface), то генерируется ошибка EGL_BAD_ALLOC.

Я не понимаю этого, когда я уже разрушил поверхность, используя eglDestroySurface, почему его надо создавать снова, используя тот же идентификатор окна.

Эта проблема может возникнуть, когда xserver повторно использует ранее закрытый идентификатор окна?


person Naseeb Panghal    schedule 28.01.2019    source источник


Ответы (2)


Вернул ли eglDestroySurface значение EGL_TRUE?

В противном случае уничтожение может быть неудачным.

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

person Bram    schedule 28.01.2019
comment
К сожалению, я не упоминаю, что eglDestroySurface возвращает значение EGL_TRUE. Также это не связано с достаточным количеством ресурсов. Если пользователь закрывает окно и передает новый дескриптор, создается поверхность egl. Кажется, что egl сделал некоторую запись идентификатора окна, которая не очищается даже при успешном возврате eglDestroySurface. Меня беспокоит то, что если xserver вернет тот же идентификатор окна, который только что закрылся, тогда также egl не сможет создать egl Surface. Также мне нужно подождать некоторое время, прежде чем создавать поверхность egl с тем же идентификатором окна? - person Naseeb Panghal; 29.01.2019

Ваш EGLSurface не может быть уничтожен даже после eglDestroySurface или eglTerminate. Вероятно, вы вызвали eglMakeCurrent( display, surface... context) — это привязывает вашу поверхность к фреймбуферу по умолчанию контекста GL. Вам нужно отвязать, чтобы поверхность могла быть действительно удалена. Вызов eglMakeCurrent(display, EGL_NO_SURFACE... EGL_NO_CONTEXT) - это приводит к тому, что активный поток освобождает контекст и поверхности. Теперь вы обнаружите, что EGL забыл/удалил поверхность, и вы можете повторно использовать идентификатор окна. eglReleaseThread должен сделать то же самое.

eglMakeCurrent (отображение, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); отвяжет вашу поверхность и позволит удалить ее, это не мгновенно, eglMakeCurrent вызовет glFlush в этом контексте. Таким образом, может потребоваться немного времени, чтобы завершить вызванные вами отрисовки и преобразовать изображение в буфер. В противном случае GPU может выйти из строя. Вызовите glFinish() перед eglMakeCurrent, чтобы гарантировать завершение, или создайте забор и дождитесь его. Неважно, вызываете ли вы eglDeleteSurface до или после eglMakeCurrent(... EGL_NO_SURFACE...), но все команды gl должны выполняться до eglMakeCurrent(... EGL_NO_SURFACE..., EGL_NO_CONTEXT). Потому что это не делает контекст текущим, а команды gl не будут выполняться без текущего контекста.

Вы можете попробовать вызвать eglGetCurrentContext и eglGetCurrentSurface, чтобы проверить, существует ли еще поверхность — вы получите дескриптор не EGL_NO_SURFACE. Но дескриптор поверхности определенно бесполезен после eglDeleteSurface. См. спецификацию EGL 1.5, раздел 3.7.4, но, как я сказал выше, он существует только потому, что привязан к текущему контексту. См. раздел 3.7.3.

person stonesthrow    schedule 14.02.2019
comment
ценю ваши усилия, чтобы объяснить это... но мне жаль говорить, что это все еще не сработало для меня... я использовал eglMakeCurrent(display, EGL_NO_SURFACE... EGL_NO_CONTEXT) и после уничтожения поверхности, контекст eglGetCurrentSurface не смог получить поверхность и в следующем вызове инициализации «eglCreateWindowSurface» не удалось выполнить заданный вопрос. - person Naseeb Panghal; 28.02.2019
comment
Хм, похоже, есть проблема с повторным использованием идентификатора xwindow. Можете ли вы проверить, что это все еще действительный объект X? После шагов, которые я указал, в EGL больше не должно быть ассоциаций. Так что я должен думать, что что-то с Xwindow недействительно. Если EGL что-то сохраняет, то это ошибка в этом драйвере. - person stonesthrow; 06.03.2019
comment
xwindow ID является допустимым объектом X. Есть только одно изменение, xwindow изменяется на новое значение. Но это не должно быть проблемой, если я не закрываю существующий контекст EGL и поверхность EGL, то же самое работает отлично даже с измененным размером идентификатора xwindow. Единственная проблема возникает при закрытии и повторном открытии поверхности окна egl. - person Naseeb Panghal; 07.03.2019