Hello, I played a little with GLSurfaceView introduced in SDK 1.5 release and it appears that only one instance of it can be used at a time. If another instance is created on top then the associated renderer is not invoked. It is demonstrated by the below code, which is slightly reworked GLSurfaceView usage example posted here http://android-developers.blogspot.com/2009/04/introducing-glsurfaceview.html
The modification is that once the finger is lifted off from the screen another instance of the ClearActivity is created, which in turn creates one more instance of ClearGLSurfaceView. However the associated renderer is never invoked --- Source code starts here import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; import dalvik.system.VMRuntime; public class ClearActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { instance = counter++; Log.e("ClearActivity", ":::::: onCreate: instance" + instance + " is created"); super.onCreate(savedInstanceState); mGLView = new ClearGLSurfaceView(this); setContentView(mGLView); } @Override protected void onPause() { Log.e("ClearActivity", ":::::: instance" + instance + " onPause: is called"); super.onPause(); mGLView.onPause(); } @Override protected void onResume() { Log.e("ClearActivity", ":::::: instance" + instance + " onResume: is called"); super.onResume(); mGLView.onResume(); } @Override protected void onStop() { Log.e("ClearActivity", ":::::: instance" + instance + " onStop: is called"); super.onStop(); } @Override protected void onDestroy() { Log.e("ClearActivity", ":::::: instance" + instance + " onDestroy: is called"); super.onDestroy(); } private GLSurfaceView mGLView; private static int counter = 0; private int instance; } class ClearGLSurfaceView extends GLSurfaceView { public ClearGLSurfaceView(Context context) { super(context); instance = counter++; Log.e("ClearGLSurfaceView", ":::::: instance" + instance + " is created"); mRenderer = new ClearRenderer(); setRenderer(mRenderer); } public boolean onTouchEvent(final MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: {// falling through on purpose here Log.e("ClearGLSurfaceView", ":::::: instance" + instance + " onTouchEvent: handling down or move action"); queueEvent(new Runnable(){ public void run() { mRenderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f); }} ); return true; } case MotionEvent.ACTION_UP: { // launch a second instance of the same activity Log.e("ClearGLSurfaceView", ":::::: instance" + instance + " onTouchEvent: handling up action"); Intent intent = new Intent(); intent.setClass(getContext(), ClearActivity.class); getContext().startActivity(intent); } } return true; } @Override protected void onDetachedFromWindow() { Log.e("ClearGLSurfaceView", ":::::: instance" + instance + " onDetachedFromWindow: is called"); super.onDetachedFromWindow(); } ClearRenderer mRenderer; private static int counter = 0; private int instance; } class ClearRenderer implements GLSurfaceView.Renderer { public ClearRenderer() { instance = counter++; Log.e("ClearRenderer", ":::::: instance" + instance + " is created"); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Do nothing special. Log.e("ClearRenderer", ":::::: instance" + instance + " onSurfaceCreated: is called"); } public void onSurfaceChanged(GL10 gl, int w, int h) { Log.e("ClearRenderer", ":::::: instance" + instance + " onSurfaceChanged: is called"); gl.glViewport(0, 0, w, h); } public void onDrawFrame(GL10 gl) { gl.glClearColor(mRed, mGreen, mBlue, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); } public int[] getConfigSpec() { Log.e("ClearRenderer", ":::::: instance" + instance + " getConfigSpec: is called"); int[] configSpec = { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE }; return configSpec; } public void setColor(float r, float g, float b) { Log.e("ClearRenderer", ":::::: instance" + instance + " setColor: is called"); mRed = r; mGreen = g; mBlue = b; } private float mRed; private float mGreen; private float mBlue; private static int counter = 0; private int instance; --- Source code ends here --- Log starts here E/ClearActivity( 1092): :::::: onCreate: instance0 is created E/ClearGLSurfaceView( 1092): :::::: instance0 is created E/ClearRenderer( 1092): :::::: instance0 is created E/ClearRenderer( 1092): :::::: instance0 getConfigSpec: is called E/ClearActivity( 1092): :::::: instance0 onResume: is called E/ClearRenderer( 1092): :::::: instance0 onSurfaceCreated: is called E/ClearRenderer( 1092): :::::: instance0 onSurfaceChanged: is called E/ClearGLSurfaceView( 1092): :::::: instance0 onTouchEvent: handling down or move action E/ClearRenderer( 1092): :::::: instance0 setColor: is called E/ClearGLSurfaceView( 1092): :::::: instance0 onTouchEvent: handling down or move action E/ClearRenderer( 1092): :::::: instance0 setColor: is called E/ClearGLSurfaceView( 1092): :::::: instance0 onTouchEvent: handling down or move action E/ClearRenderer( 1092): :::::: instance0 setColor: is called E/ClearGLSurfaceView( 1092): :::::: instance0 onTouchEvent: handling down or move action E/ClearRenderer( 1092): :::::: instance0 setColor: is called E/ClearGLSurfaceView( 1092): :::::: instance0 onTouchEvent: handling down or move action E/ClearRenderer( 1092): :::::: instance0 setColor: is called E/ClearGLSurfaceView( 1092): :::::: instance0 onTouchEvent: handling down or move action E/ClearRenderer( 1092): :::::: instance0 setColor: is called E/ClearGLSurfaceView( 1092): :::::: instance0 onTouchEvent: handling up action E/ClearActivity( 1092): :::::: instance0 onPause: is called E/ClearActivity( 1092): :::::: onCreate: instance1 is created E/ClearGLSurfaceView( 1092): :::::: instance1 is created E/ClearRenderer( 1092): :::::: instance1 is created E/ClearActivity( 1092): :::::: instance1 onResume: is called E/ClearActivity( 1092): :::::: instance0 onStop: is called E/ClearGLSurfaceView( 1092): :::::: instance1 onTouchEvent: handling down or move action E/ClearGLSurfaceView( 1092): :::::: instance1 onTouchEvent: handling down or move action E/ClearGLSurfaceView( 1092): :::::: instance1 onTouchEvent: handling down or move action E/ClearGLSurfaceView( 1092): :::::: instance1 onTouchEvent: handling down or move action --- Log ends here I studied the source code for GLSurfaceView and it looks like the reason for this behavior is that the renderer provided to GLSurfaceView is run in a separate thread implemented by the class GLThread. Whenever the renderer is set to GLSurfaceView through setRenderer() an instance of GLThread is created, which runs the code for that renderer. Now, the thread acquires sEglSemaphore to run and only releases it once mDone is set to true, which happens in GLThread.requestExitAndWait() which is called from GLSurfaceView.onDetachedFromWindow(). And this one is not called when the first instance of ClearGLSurfaceView is covered by the second one (i.e. its onPause(0 is called), it is only called when the first instance of ClearAcitivity is destroyed at the end of its life cycle What it looks like to me is either a bug in Android framework or intentional limitation, which is unfortunately not documented in the GLSurfaceView reference page http://developer.android.com/reference/android/opengl/GLSurfaceView.html. Even more, the reference page says that GLSurfaceView would release and recreate OpenGL display whenever the activity goes through pause- resume cycle: "GLSurfaceView clients are required to call onPause() when the activity pauses and onResume() when the activity resumes. These calls allow GLSurfaceView to pause and resume the rendering thread, and also allow GLSurfaceView to release and recreate the OpenGL display. " So, any advice (especially from Android framework team) would be greatly appreciated -- Best regards, Dmitry --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "android-framework" group. To post to this group, send email to android-framework@googlegroups.com To unsubscribe from this group, send email to android-framework+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-framework?hl=en -~----------~----~----~----~------~----~------~--~---