Re: [android-developers] How to replace GLSurfaceView with TextureView in Android Ice Cream Sandwich?
There is a dearth of high-quality information on this topic -- any updates on the crashes or on syncing the thread, or on best practices using TextureView with OpenGL? I'm looking to migrate from GLSurfaceView to TextureView to work around some issues with view composition, but the lack of an official solution makes me nervous. I've noticed that even when using Choreographer, there are inexplicable jitters in the displayed frames that don't occur with GLSurfaceView and are not visible by observing the logs or frame timestamps. On Wednesday, 11 July 2012 16:43:50 UTC-4, mor...@gmail.com wrote: > > Hi Romain, > > I am wondering about the Thread.sleep() call in the rendering thread's run > loop. Is that technically necessary? If so, may I ask why? And if so, then > how would one implement a high-framerate OpenGL game (for instance) using > TextureView? > > What prompted these questions is that I have run into a few devices where > this code 'crashes' with (randomly) one of the two following errors. Are > you able to comment on this? > > >1. queueBuffer: slot 2 is current! >2. dequeueBuffer: buffer 0 is both FREE and current! > > > > Many thanks, > -Nathan Morse > > > On Wednesday, November 23, 2011 9:17:28 AM UTC-8, Romain Guy (Google) > wrote: >> >> GLSurfaceView handles GL setup for you, which TextureView will not do. A >> TextureView can be used as the native window when you create an EGL >> surface. Here is an example (the interesting part is the call >> to eglCreateWindowSurface()): >> >> @Override >> public void onSurfaceTextureAvailable(SurfaceTexture surface, int >> width, int height) { >> mRenderThread = new RenderThread(getResources(), surface); >> mRenderThread.start(); >> } >> >> private static class RenderThread extends Thread { >> private static final String LOG_TAG = "GLTextureView"; >> >> static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; >> static final int EGL_OPENGL_ES2_BIT = 4; >> >> private volatile boolean mFinished; >> >> private final Resources mResources; >> private final SurfaceTexture mSurface; >> >> private EGL10 mEgl; >> private EGLDisplay mEglDisplay; >> private EGLConfig mEglConfig; >> private EGLContext mEglContext; >> private EGLSurface mEglSurface; >> private GL mGL; >> >> RenderThread(Resources resources, SurfaceTexture surface) { >> mResources = resources; >> mSurface = surface; >> } >> >> private static final String sSimpleVS = >> "attribute vec4 position;\n" + >> "attribute vec2 texCoords;\n" + >> "varying vec2 outTexCoords;\n" + >> "\nvoid main(void) {\n" + >> "outTexCoords = texCoords;\n" + >> "gl_Position = position;\n" + >> "}\n\n"; >> private static final String sSimpleFS = >> "precision mediump float;\n\n" + >> "varying vec2 outTexCoords;\n" + >> "uniform sampler2D texture;\n" + >> "\nvoid main(void) {\n" + >> "gl_FragColor = texture2D(texture, outTexCoords);\n" + >> "}\n\n"; >> >> private static final int FLOAT_SIZE_BYTES = 4; >> private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 >> * FLOAT_SIZE_BYTES; >> private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; >> private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; >> private final float[] mTriangleVerticesData = { >> // X, Y, Z, U, V >> -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, >> 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, >> -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, >> 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, >> }; >> >> @Override >> public void run() { >> initGL(); >> >> FloatBuffer triangleVertices = >> ByteBuffer.allocateDirect(mTriangleVerticesData.length >> * >> FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); >> triangleVertices.put(mTriangleVerticesData).position(0); >> >> int texture = loadTexture(R.drawable.large_photo); >> int program = buildProgram(sSimpleVS, sSimpleFS); >> >> int attribPosition = glGetAttribLocation(program, "position"); >> checkGlError(); >> >> int attribTexCoords = glGetAttribLocation(program, >> "texCoords"); >> checkGlError(); >> >> int uniformTexture = glGetUniformLocation(program, "texture"); >> checkGlError(); >> >> glBindTexture(GL_TEXTURE_2D, texture); >> checkGlError(); >> >> glUseProgram(program); >> checkGlError(); >> >> glEnableVertexAttribArray(attribPositi
Re: [android-developers] How to replace GLSurfaceView with TextureView in Android Ice Cream Sandwich?
Hi Romain, I am wondering about the Thread.sleep() call in the rendering thread's run loop. Is that technically necessary? If so, may I ask why? And if so, then how would one implement a high-framerate OpenGL game (for instance) using TextureView? What prompted these questions is that I have run into a few devices where this code 'crashes' with (randomly) one of the two following errors. Are you able to comment on this? 1. queueBuffer: slot 2 is current! 2. dequeueBuffer: buffer 0 is both FREE and current! Many thanks, -Nathan Morse On Wednesday, November 23, 2011 9:17:28 AM UTC-8, Romain Guy (Google) wrote: > > GLSurfaceView handles GL setup for you, which TextureView will not do. A > TextureView can be used as the native window when you create an EGL > surface. Here is an example (the interesting part is the call > to eglCreateWindowSurface()): > > @Override > public void onSurfaceTextureAvailable(SurfaceTexture surface, int > width, int height) { > mRenderThread = new RenderThread(getResources(), surface); > mRenderThread.start(); > } > > private static class RenderThread extends Thread { > private static final String LOG_TAG = "GLTextureView"; > > static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; > static final int EGL_OPENGL_ES2_BIT = 4; > > private volatile boolean mFinished; > > private final Resources mResources; > private final SurfaceTexture mSurface; > > private EGL10 mEgl; > private EGLDisplay mEglDisplay; > private EGLConfig mEglConfig; > private EGLContext mEglContext; > private EGLSurface mEglSurface; > private GL mGL; > > RenderThread(Resources resources, SurfaceTexture surface) { > mResources = resources; > mSurface = surface; > } > > private static final String sSimpleVS = > "attribute vec4 position;\n" + > "attribute vec2 texCoords;\n" + > "varying vec2 outTexCoords;\n" + > "\nvoid main(void) {\n" + > "outTexCoords = texCoords;\n" + > "gl_Position = position;\n" + > "}\n\n"; > private static final String sSimpleFS = > "precision mediump float;\n\n" + > "varying vec2 outTexCoords;\n" + > "uniform sampler2D texture;\n" + > "\nvoid main(void) {\n" + > "gl_FragColor = texture2D(texture, outTexCoords);\n" + > "}\n\n"; > > private static final int FLOAT_SIZE_BYTES = 4; > private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * > FLOAT_SIZE_BYTES; > private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; > private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; > private final float[] mTriangleVerticesData = { > // X, Y, Z, U, V > -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, > 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, > -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, > 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, > }; > > @Override > public void run() { > initGL(); > > FloatBuffer triangleVertices = > ByteBuffer.allocateDirect(mTriangleVerticesData.length > * > FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); > triangleVertices.put(mTriangleVerticesData).position(0); > > int texture = loadTexture(R.drawable.large_photo); > int program = buildProgram(sSimpleVS, sSimpleFS); > > int attribPosition = glGetAttribLocation(program, "position"); > checkGlError(); > > int attribTexCoords = glGetAttribLocation(program, > "texCoords"); > checkGlError(); > > int uniformTexture = glGetUniformLocation(program, "texture"); > checkGlError(); > > glBindTexture(GL_TEXTURE_2D, texture); > checkGlError(); > > glUseProgram(program); > checkGlError(); > > glEnableVertexAttribArray(attribPosition); > checkGlError(); > > glEnableVertexAttribArray(attribTexCoords); > checkGlError(); > > glUniform1i(uniformTexture, texture); > checkGlError(); > > while (!mFinished) { > checkCurrent(); > > glClearColor(0.0f, 0.0f, 0.0f, 0.0f); > checkGlError(); > > glClear(GL_COLOR_BUFFER_BIT); > checkGlError(); > > // drawQuad > > triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); > glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, > TRIANGLE_VERTICES_DATA_STRIDE_BYTES, > triangleVertic
Re: [android-developers] How to replace GLSurfaceView with TextureView in Android Ice Cream Sandwich?
GLSurfaceView handles GL setup for you, which TextureView will not do. A TextureView can be used as the native window when you create an EGL surface. Here is an example (the interesting part is the call to eglCreateWindowSurface()): @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mRenderThread = new RenderThread(getResources(), surface); mRenderThread.start(); } private static class RenderThread extends Thread { private static final String LOG_TAG = "GLTextureView"; static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; static final int EGL_OPENGL_ES2_BIT = 4; private volatile boolean mFinished; private final Resources mResources; private final SurfaceTexture mSurface; private EGL10 mEgl; private EGLDisplay mEglDisplay; private EGLConfig mEglConfig; private EGLContext mEglContext; private EGLSurface mEglSurface; private GL mGL; RenderThread(Resources resources, SurfaceTexture surface) { mResources = resources; mSurface = surface; } private static final String sSimpleVS = "attribute vec4 position;\n" + "attribute vec2 texCoords;\n" + "varying vec2 outTexCoords;\n" + "\nvoid main(void) {\n" + "outTexCoords = texCoords;\n" + "gl_Position = position;\n" + "}\n\n"; private static final String sSimpleFS = "precision mediump float;\n\n" + "varying vec2 outTexCoords;\n" + "uniform sampler2D texture;\n" + "\nvoid main(void) {\n" + "gl_FragColor = texture2D(texture, outTexCoords);\n" + "}\n\n"; private static final int FLOAT_SIZE_BYTES = 4; private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; private final float[] mTriangleVerticesData = { // X, Y, Z, U, V -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, }; @Override public void run() { initGL(); FloatBuffer triangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); triangleVertices.put(mTriangleVerticesData).position(0); int texture = loadTexture(R.drawable.large_photo); int program = buildProgram(sSimpleVS, sSimpleFS); int attribPosition = glGetAttribLocation(program, "position"); checkGlError(); int attribTexCoords = glGetAttribLocation(program, "texCoords"); checkGlError(); int uniformTexture = glGetUniformLocation(program, "texture"); checkGlError(); glBindTexture(GL_TEXTURE_2D, texture); checkGlError(); glUseProgram(program); checkGlError(); glEnableVertexAttribArray(attribPosition); checkGlError(); glEnableVertexAttribArray(attribTexCoords); checkGlError(); glUniform1i(uniformTexture, texture); checkGlError(); while (!mFinished) { checkCurrent(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); checkGlError(); glClear(GL_COLOR_BUFFER_BIT); checkGlError(); // drawQuad triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { throw new RuntimeException("Cannot swap buffers"); } checkEglError(); try { Thread.sleep(2000); } catch (InterruptedException e) { // Ignore } } finishGL(); } private int loadTexture(int resource) { int[] textures = new int[1]; glActiveTexture(GL_TEXTURE0); glGenTextures(1, textures, 0); checkGlError(); in
[android-developers] How to replace GLSurfaceView with TextureView in Android Ice Cream Sandwich?
The TextureView documentation states that it can be used to render OpenGL content. In the blog post announcing TextureView, it states: A TextureView can just as easily be used to embed an OpenGL scene in your application. As of Android 4.0, eglCreateWindowSurface() can be used to render into a SurfaceTexture object. Which seems to imply that to use TextureView instead of GLSurfaceView, one would have to do all the EGL setup themselves and manage the EGLContext and the threading (since GLSurfaceView maintains a GLThread). There doesn't seem to be any sample code in the Android 4.0 SDK that demonstrates how the "TextureView can just as easily be used to embed an OpenGL scene". TextureView seems to plug in more cleanly to the Camera preview (setPreviewTexture) and MediaPlayer (setSurface). Is it possible to use GLSurfaceView in conjunction with TextureView by using GLSurfaceView.setEGLWindowSurfaceFactory to make it render to the TextureView's SurfaceTexture? Again, it would be nice if there were some sample code. p.s. Posted on stackoverflow.com as well. Feel free to answer: http://stackoverflow.com/questions/8231978/how-to-replace-glsurfaceview-with-textureview-in-android-ice-cream-sandwich -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en