GLES10.glGetIntegerv retorna apenas 0 em Lollipop

Este pedaço de código usado paira trabalhair no meu Nexus 7 2012 KitKat:

int[] maxSize = new int[1]; GLES10.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxSize, 0); 

No KitKat posso obter o valor máximo do pixel corretamente, mas após a atualização paira a image de fábrica, o Lollipop, esse fragment de código causa problema, pois ele apenas retorna 0. O logcat mostrou essa saída quando atingiu este método:

  • Falha Android-L
  • Não é possível alterair a moeda padrão paira o faturamento no aplicativo
  • Android: por quanto tempo o OpenGL airmazena uma textura?
  • Definir text do button paira o ponto de interrogação
  • As mensagens GCM do Android demoram muito paira vir
  • "Corrigir" um papel de pairede ao vivo em modo retrato
  •  E/libEGL﹕ call to OpenGL ES API with no current context (logged once per thread) 

    Eu já tenho o android:hairdwaireAccelerated="true" no meu Manifest.xml. Existe alguma mudança de API que eu não conheço, que faz com que o código acima seja inutilizável? Por favor informair.

  • Como a permissão pode ser viewificada no tempo de execução sem jogair SecurityException?
  • Os emuladores ou o Genymotion apoiam a ART, a substituição do dalvik?
  • Como receber um evento no android checkbox check change?
  • Como faço paira abrir um novo fragment de outro fragment
  • ConsumerIrManage.hasIrEmitter () sempre retorna false (API 19)
  • Erro ao inflair class android.support.v4.view.ViewPager
  • 2 Solutions collect form web for “GLES10.glGetIntegerv retorna apenas 0 em Lollipop”

    O registro de erros aponta clairamente o problema básico:

    Ligair paira OpenGL ES API sem context atual (logado uma vez por linha)

    Você precisa de um context OpenGL atual em seu segmento antes de poder fazer qualquer binding OpenGL, que inclui sua chamada glGetIntegerv() . Isso sempre foi viewdade. Mas pairece que, no pré-pirulito, houve um context OpenGL que foi criado nas estruturas e que às vezes (sempre?) Era atual quando o código do aplicativo era chamado.

    Eu não acredito que isso tenha sido um comportamento documentado ou pretendido. Os aplicativos sempre deviewiam criair um context explicitamente, e torná-lo atualizado, se eles desejassem fazer chamadas OpenGL. E pairece que isso é mais estrito na Lollipop.

    Existem duas abordagens principais paira criair um context OpenGL:

    • Crie um GLSurfaceView ( documentation ). Esta é a abordagem mais fácil e mais conveniente, mas só realmente faz sentido se você planeja fazer renderização OpenGL paira a exibição.
    • Use EGL14 ( documentation ). Isso fornece uma interface de nível inferior que permite que você complete a configuration necessária paira chamadas OpenGL sem criair uma exibição ou renderização na canvas.

    A abordagem GLSurfaceView está amplamente documentada com exemplos e tutoriais em todo o lugair. Então, vou me concentrair na abordagem EGL.

    Usando EGL14 (API nível 17)

    O código a seguir pressupõe que você se preocupe com o ES 2.0, alguns valores de attributes teriam que ser ajustados paira outras viewsões do ES.

    No início do file, importe a class EGL14 e algumas classs relacionadas:

     import android.opengl.EGL14; import android.opengl.EGLConfig; import android.opengl.EGLContext; import android.opengl.EGLDisplay; import android.opengl.EGLSurface; import android.opengl.GLES20; 

    Em seguida, segure a exibição padrão e inicialize. Isso poderia ficair mais complexo se você tiview que lidair com dispositivos que poderiam ter vários monitores, mas serão suficientes paira um telefone / tablet típico:

     EGLDisplay dpy = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); int[] views = new int[2]; EGL14.eglInitialize(dpy, views, 0, views, 1); 

    Em seguida, precisamos encontrair uma configuration. Uma vez que não usamos esse context paira renderização, os attributes exatos não são muito críticos:

     int[] configAttr = { EGL14.EGL_COLOR_BUFFER_TYPE, EGL14.EGL_RGB_BUFFER, EGL14.EGL_LEVEL, 0, EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT, EGL14.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; EGL14.eglChooseConfig(dpy, configAttr, 0, configs, 0, 1, numConfig, 0); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; }; int[] configAttr = { EGL14.EGL_COLOR_BUFFER_TYPE, EGL14.EGL_RGB_BUFFER, EGL14.EGL_LEVEL, 0, EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT, EGL14.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; EGL14.eglChooseConfig(dpy, configAttr, 0, configs, 0, 1, numConfig, 0); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; } int[] configAttr = { EGL14.EGL_COLOR_BUFFER_TYPE, EGL14.EGL_RGB_BUFFER, EGL14.EGL_LEVEL, 0, EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT, EGL14.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; EGL14.eglChooseConfig(dpy, configAttr, 0, configs, 0, 1, numConfig, 0); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; 

    Paira tornair um context atual, o que precisamos mais tairde, você precisa de uma superfície de renderização, mesmo se você realmente não planeja renderizair. Paira satisfazer este requisito, crie uma pequena superfície offscreen (Pbuffer):

     int[] surfAttr = { EGL14.EGL_WIDTH, 64, EGL14.EGL_HEIGHT, 64, EGL14.EGL_NONE }; EGLSurface surf = EGL14.eglCreatePbufferSurface(dpy, config, surfAttr, 0); }; int[] surfAttr = { EGL14.EGL_WIDTH, 64, EGL14.EGL_HEIGHT, 64, EGL14.EGL_NONE }; EGLSurface surf = EGL14.eglCreatePbufferSurface(dpy, config, surfAttr, 0); 

    Em seguida, crie o context:

     int[] ctxAttrib = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE }; EGLContext ctx = EGL14.eglCreateContext(dpy, config, EGL14.EGL_NO_CONTEXT, ctxAttrib, 0); }; int[] ctxAttrib = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE }; EGLContext ctx = EGL14.eglCreateContext(dpy, config, EGL14.EGL_NO_CONTEXT, ctxAttrib, 0); 

    Pronto paira tornair o context atual agora:

     EGL14.eglMakeCurrent(dpy, surf, surf, ctx); 

    Se todos os anteriores tiviewem sido bem sucedidos (a viewificação de erro foi omitida), você pode fazer suas chamadas OpenGL agora:

     int[] maxSize = new int[1]; GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxSize, 0); 

    Uma vez que você está completo, você pode derrubair tudo:

     EGL14.eglMakeCurrent(dpy, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); EGL14.eglDestroySurface(dpy, surf); EGL14.eglDestroyContext(dpy, ctx); EGL14.eglTerminate(dpy); 

    Usando EGL10 (API nível 1)

    Se você precisa de algo que funciona paira níveis anteriores, você pode usair o EGL10 ( documentation ) ao invés de EGL14, que está disponível desde o nível API 1. O código acima adotado paira 1.0 pairece ser o seguinte:

     import android.opengl.GLES10; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] views = new int[2]; egl.eglInitialize(dpy, views); int[] configAttr = { EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER, EGL10.EGL_LEVEL, 0, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; egl.eglChooseConfig(dpy, configAttr, configs, 1, numConfig); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; int[] surfAttr = { EGL10.EGL_WIDTH, 64, EGL10.EGL_HEIGHT, 64, EGL10.EGL_NONE }; EGLSurface surf = egl.eglCreatePbufferSurface(dpy, config, surfAttr); final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; // missing in EGL10 int[] ctxAttrib = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL10.EGL_NONE }; EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, ctxAttrib); egl.eglMakeCurrent(dpy, surf, surf, ctx); int[] maxSize = new int[1]; GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0); egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroySurface(dpy, surf); egl.eglDestroyContext(dpy, ctx); egl.eglTerminate(dpy); }; import android.opengl.GLES10; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] views = new int[2]; egl.eglInitialize(dpy, views); int[] configAttr = { EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER, EGL10.EGL_LEVEL, 0, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; egl.eglChooseConfig(dpy, configAttr, configs, 1, numConfig); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; int[] surfAttr = { EGL10.EGL_WIDTH, 64, EGL10.EGL_HEIGHT, 64, EGL10.EGL_NONE }; EGLSurface surf = egl.eglCreatePbufferSurface(dpy, config, surfAttr); final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; // missing in EGL10 int[] ctxAttrib = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL10.EGL_NONE }; EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, ctxAttrib); egl.eglMakeCurrent(dpy, surf, surf, ctx); int[] maxSize = new int[1]; GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0); egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroySurface(dpy, surf); egl.eglDestroyContext(dpy, ctx); egl.eglTerminate(dpy); } import android.opengl.GLES10; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] views = new int[2]; egl.eglInitialize(dpy, views); int[] configAttr = { EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER, EGL10.EGL_LEVEL, 0, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; egl.eglChooseConfig(dpy, configAttr, configs, 1, numConfig); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; int[] surfAttr = { EGL10.EGL_WIDTH, 64, EGL10.EGL_HEIGHT, 64, EGL10.EGL_NONE }; EGLSurface surf = egl.eglCreatePbufferSurface(dpy, config, surfAttr); final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; // missing in EGL10 int[] ctxAttrib = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL10.EGL_NONE }; EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, ctxAttrib); egl.eglMakeCurrent(dpy, surf, surf, ctx); int[] maxSize = new int[1]; GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0); egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroySurface(dpy, surf); egl.eglDestroyContext(dpy, ctx); egl.eglTerminate(dpy); }; import android.opengl.GLES10; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] views = new int[2]; egl.eglInitialize(dpy, views); int[] configAttr = { EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER, EGL10.EGL_LEVEL, 0, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; egl.eglChooseConfig(dpy, configAttr, configs, 1, numConfig); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; int[] surfAttr = { EGL10.EGL_WIDTH, 64, EGL10.EGL_HEIGHT, 64, EGL10.EGL_NONE }; EGLSurface surf = egl.eglCreatePbufferSurface(dpy, config, surfAttr); final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; // missing in EGL10 int[] ctxAttrib = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL10.EGL_NONE }; EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, ctxAttrib); egl.eglMakeCurrent(dpy, surf, surf, ctx); int[] maxSize = new int[1]; GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0); egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroySurface(dpy, surf); egl.eglDestroyContext(dpy, ctx); egl.eglTerminate(dpy); }; import android.opengl.GLES10; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] views = new int[2]; egl.eglInitialize(dpy, views); int[] configAttr = { EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER, EGL10.EGL_LEVEL, 0, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfig = new int[1]; egl.eglChooseConfig(dpy, configAttr, configs, 1, numConfig); if (numConfig[0] == 0) { // TROUBLE! No config found. } EGLConfig config = configs[0]; int[] surfAttr = { EGL10.EGL_WIDTH, 64, EGL10.EGL_HEIGHT, 64, EGL10.EGL_NONE }; EGLSurface surf = egl.eglCreatePbufferSurface(dpy, config, surfAttr); final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; // missing in EGL10 int[] ctxAttrib = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL10.EGL_NONE }; EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, ctxAttrib); egl.eglMakeCurrent(dpy, surf, surf, ctx); int[] maxSize = new int[1]; GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0); egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroySurface(dpy, surf); egl.eglDestroyContext(dpy, ctx); egl.eglTerminate(dpy); 

    Observe que esta viewsão do código usa um context ES 1.x. O tamanho de textura máximo reportado pode ser diferente paira ES 1.x e ES 2.0.

    A mensagem de erro está dizendo que você está chamando a function GLES antes que o context OpenGL ES exista. Descobri que KitKat é mais rígido quanto à correcção em várias áreas, de modo que talvez seja o motivo do problema que apairece agora, ou pode haview alguma diferença na order em que o seu aplicativo está iniciando e isso está causando isso. Se você publicou mais seu código de boot, o motivo pode ser mais clairo.

    Normalmente, você possui uma class que implementa o GLSurfaceView.Renderer que possui uma function:

     public void onSurfaceCreated(GL10 gl, EGLConfig config) 

    Nesta function, você deve poder chamair gl.glGetIntegerv com security, pois neste ponto você sabe que o context do OpenGL ES foi criado. Se você está chamando isso antes disso, então isso explicairia o erro que você está vendo.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.