Я пытаюсь заставить игру на основе NDK работать на Android ICS.Он отлично работал на Honeycomb и Gingerbread.
В игре используется некоторый 2D-рендеринг, некоторый 3D-рендеринг, переключение между ними на разных этапах исполнения.(Это не подлежит обсуждению из-за стороннего кода.) Мы используем ANativeWindow_lock()
/ ANativeWindow_unlockAndPost()
для 2D-рендеринга и eglCreateWindowSurface()
/ gl*()
/ eglSwapBuffers()
для 3D-рендеринга.
На Honeycomb и Gingerbread все это работало нормально.На ICS eglCreateWindowSurface()
завершается сбоем со следующими сообщениями в журнале:
E/SurfaceTexture( 1765): [com.fnord/com.fnord.MyActivity] connect: already connected (cur=2, req=1)
E/libEGL ( 5466): EGLNativeWindowType 0x29e9b8 already connected to another API
E/libEGL ( 5466): eglCreateWindowSurface:374 error 300b (EGL_BAD_NATIVE_WINDOW)
E/libEGL ( 5466): call to OpenGL ES API with no current context (logged once per thread)
Глядя на исходный код, кажется довольно очевидным, что eglCreateWindowSurface()
дает сбой, потому что что-то открыло собственное окно для 2D-рендерингаэто не позволит мне изменить его на 3D, не отпустив сначала поверхность.Тем не менее, API-интерфейс ANativeWindow, похоже, не имеет очевидного способа сделать это.
Кто-нибудь еще сталкивался с этим, и каково решение?
Обновлено
Итак, я переписал свой код 2D-рендеринга, чтобы вместо него использовать примитивы OpenGL (загрузить backbuffer в текстуру, визуализировать текстуру через пару треугольников, swapbuffers).Это работает до определенного момента. Теперь происходит то, что 2D-рендеринг работает нормально;затем я разрушаю поверхность, создаю новую для подготовки к 3D-рендерингу, и второй вызов eglCreateWindowSurface()
не выполняется.На этот раз с:
E/SurfaceTexture( 1869): [com.fnord/com.fnord.MyActivity] connect: already connected (cur=1, req=1)
... и выдается ошибка EGL AEGL_BAD_NATIVE_WINDOW
.
Обратите внимание, что новая поверхность создается с точно такими же атрибутами как старый.Я даже пытался убедиться, что я вызываю eglTerminate()
/ eglInitialize()
между двумя вызовами на eglCreateWindowSurface()
.
. Может ли это быть, что я могу использовать каждое ANativeWindow точно один раз?Если это так, разве это не провалит тесты на соответствие EGL от Khronos?Есть ли способ заставить NativeActivity воссоздать окно?прежде чем уничтожить контекст и поверхность.Это приводило к тому, что уничтожение задерживалось до тех пор, пока поток не освободил контекст и поверхность, что, конечно, не было, поэтому законный вызов eglCreateWindowSurface()
не состоялся (у вас не может быть двух оконных поверхностей в одном собственном окне).).
Это бит , противоречащее интуиции, поскольку можно предположить, что вызов eglTerminate()
уничтожит все ресурсы EGL, но разрешено спецификацией.Будьте предупреждены!