update GlSurfaceView:onPause/Resume docs
fixes: 22448595 Also delete some epically outdated code to match the documented behavior Change-Id: I2bb5b475433ebff8ca82db385e228fef11e32e20
This commit is contained in:
@@ -16,6 +16,13 @@
|
||||
|
||||
package android.opengl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Trace;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
@@ -29,15 +36,6 @@ import javax.microedition.khronos.egl.EGLSurface;
|
||||
import javax.microedition.khronos.opengles.GL;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ConfigurationInfo;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
/**
|
||||
* An implementation of SurfaceView that uses the dedicated surface for
|
||||
* displaying OpenGL rendering.
|
||||
@@ -119,9 +117,9 @@ import android.view.SurfaceView;
|
||||
* {@link #setRenderMode}. The default is continuous rendering.
|
||||
* <p>
|
||||
* <h3>Activity Life-cycle</h3>
|
||||
* A GLSurfaceView must be notified when the activity is paused and resumed. GLSurfaceView clients
|
||||
* are required to call {@link #onPause()} when the activity pauses and
|
||||
* {@link #onResume()} when the activity resumes. These calls allow GLSurfaceView to
|
||||
* A GLSurfaceView must be notified when to pause and resume rendering. GLSurfaceView clients
|
||||
* are required to call {@link #onPause()} when the activity stops and
|
||||
* {@link #onResume()} when the activity starts. These calls allow GLSurfaceView to
|
||||
* pause and resume the rendering thread, and also allow GLSurfaceView to release and recreate
|
||||
* the OpenGL display.
|
||||
* <p>
|
||||
@@ -294,10 +292,12 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
* resumed.
|
||||
* <p>
|
||||
* If set to true, then the EGL context may be preserved when the GLSurfaceView is paused.
|
||||
* Whether the EGL context is actually preserved or not depends upon whether the
|
||||
* Android device that the program is running on can support an arbitrary number of EGL
|
||||
* contexts or not. Devices that can only support a limited number of EGL contexts must
|
||||
* release the EGL context in order to allow multiple applications to share the GPU.
|
||||
* <p>
|
||||
* Prior to API level 11, whether the EGL context is actually preserved or not
|
||||
* depends upon whether the Android device can support an arbitrary number of
|
||||
* EGL contexts or not. Devices that can only support a limited number of EGL
|
||||
* contexts must release the EGL context in order to allow multiple applications
|
||||
* to share the GPU.
|
||||
* <p>
|
||||
* If set to false, the EGL context will be released when the GLSurfaceView is paused,
|
||||
* and recreated when the GLSurfaceView is resumed.
|
||||
@@ -554,9 +554,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
|
||||
|
||||
/**
|
||||
* Inform the view that the activity is paused. The owner of this view must
|
||||
* call this method when the activity is paused. Calling this method will
|
||||
* pause the rendering thread.
|
||||
* Pause the rendering thread, optionally tearing down the EGL context
|
||||
* depending upon the value of {@link #setPreserveEGLContextOnPause(boolean)}.
|
||||
*
|
||||
* This method should be called when it is no longer desirable for the
|
||||
* GLSurfaceView to continue rendering, such as in response to
|
||||
* {@link android.app.Activity#onStop Activity.onStop}.
|
||||
*
|
||||
* Must not be called before a renderer has been set.
|
||||
*/
|
||||
public void onPause() {
|
||||
@@ -564,10 +568,12 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
}
|
||||
|
||||
/**
|
||||
* Inform the view that the activity is resumed. The owner of this view must
|
||||
* call this method when the activity is resumed. Calling this method will
|
||||
* recreate the OpenGL display and resume the rendering
|
||||
* thread.
|
||||
* Resumes the rendering thread, re-creating the OpenGL context if necessary. It
|
||||
* is the counterpart to {@link #onPause()}.
|
||||
*
|
||||
* This method should typically be called in
|
||||
* {@link android.app.Activity#onStart Activity.onStart}.
|
||||
*
|
||||
* Must not be called before a renderer has been set.
|
||||
*/
|
||||
public void onResume() {
|
||||
@@ -1354,7 +1360,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
GLSurfaceView view = mGLSurfaceViewWeakRef.get();
|
||||
boolean preserveEglContextOnPause = view == null ?
|
||||
false : view.mPreserveEGLContextOnPause;
|
||||
if (!preserveEglContextOnPause || sGLThreadManager.shouldReleaseEGLContextWhenPausing()) {
|
||||
if (!preserveEglContextOnPause) {
|
||||
stopEglContextLocked();
|
||||
if (LOG_SURFACE) {
|
||||
Log.i("GLThread", "releasing EGL context because paused tid=" + getId());
|
||||
@@ -1362,16 +1368,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
}
|
||||
}
|
||||
|
||||
// When pausing, optionally terminate EGL:
|
||||
if (pausing) {
|
||||
if (sGLThreadManager.shouldTerminateEGLWhenPausing()) {
|
||||
mEglHelper.finish();
|
||||
if (LOG_SURFACE) {
|
||||
Log.i("GLThread", "terminating EGL because paused tid=" + getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Have we lost the SurfaceView surface?
|
||||
if ((! mHasSurface) && (! mWaitingForSurface)) {
|
||||
if (LOG_SURFACE) {
|
||||
@@ -1411,7 +1407,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
if (! mHaveEglContext) {
|
||||
if (askedToReleaseEglContext) {
|
||||
askedToReleaseEglContext = false;
|
||||
} else if (sGLThreadManager.tryAcquireEglContextLocked(this)) {
|
||||
} else {
|
||||
try {
|
||||
mEglHelper.start();
|
||||
} catch (RuntimeException t) {
|
||||
@@ -1506,7 +1502,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
if (createGlInterface) {
|
||||
gl = (GL10) mEglHelper.createGL();
|
||||
|
||||
sGLThreadManager.checkGLDriver(gl);
|
||||
createGlInterface = false;
|
||||
}
|
||||
|
||||
@@ -1888,111 +1883,16 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
Log.i("GLThread", "exiting tid=" + thread.getId());
|
||||
}
|
||||
thread.mExited = true;
|
||||
if (mEglOwner == thread) {
|
||||
mEglOwner = null;
|
||||
}
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tries once to acquire the right to use an EGL
|
||||
* context. Does not block. Requires that we are already
|
||||
* in the sGLThreadManager monitor when this is called.
|
||||
*
|
||||
* @return true if the right to use an EGL context was acquired.
|
||||
*/
|
||||
public boolean tryAcquireEglContextLocked(GLThread thread) {
|
||||
if (mEglOwner == thread || mEglOwner == null) {
|
||||
mEglOwner = thread;
|
||||
notifyAll();
|
||||
return true;
|
||||
}
|
||||
checkGLESVersion();
|
||||
if (mMultipleGLESContextsAllowed) {
|
||||
return true;
|
||||
}
|
||||
// Notify the owning thread that it should release the context.
|
||||
// TODO: implement a fairness policy. Currently
|
||||
// if the owning thread is drawing continuously it will just
|
||||
// reacquire the EGL context.
|
||||
if (mEglOwner != null) {
|
||||
mEglOwner.requestReleaseEglContextLocked();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Releases the EGL context. Requires that we are already in the
|
||||
* sGLThreadManager monitor when this is called.
|
||||
*/
|
||||
public void releaseEglContextLocked(GLThread thread) {
|
||||
if (mEglOwner == thread) {
|
||||
mEglOwner = null;
|
||||
}
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
public synchronized boolean shouldReleaseEGLContextWhenPausing() {
|
||||
// Release the EGL context when pausing even if
|
||||
// the hardware supports multiple EGL contexts.
|
||||
// Otherwise the device could run out of EGL contexts.
|
||||
return mLimitedGLESContexts;
|
||||
}
|
||||
|
||||
public synchronized boolean shouldTerminateEGLWhenPausing() {
|
||||
checkGLESVersion();
|
||||
return !mMultipleGLESContextsAllowed;
|
||||
}
|
||||
|
||||
public synchronized void checkGLDriver(GL10 gl) {
|
||||
if (! mGLESDriverCheckComplete) {
|
||||
checkGLESVersion();
|
||||
String renderer = gl.glGetString(GL10.GL_RENDERER);
|
||||
if (mGLESVersion < kGLES_20) {
|
||||
mMultipleGLESContextsAllowed =
|
||||
! renderer.startsWith(kMSM7K_RENDERER_PREFIX);
|
||||
notifyAll();
|
||||
}
|
||||
mLimitedGLESContexts = !mMultipleGLESContextsAllowed;
|
||||
if (LOG_SURFACE) {
|
||||
Log.w(TAG, "checkGLDriver renderer = \"" + renderer + "\" multipleContextsAllowed = "
|
||||
+ mMultipleGLESContextsAllowed
|
||||
+ " mLimitedGLESContexts = " + mLimitedGLESContexts);
|
||||
}
|
||||
mGLESDriverCheckComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkGLESVersion() {
|
||||
if (! mGLESVersionCheckComplete) {
|
||||
mGLESVersion = SystemProperties.getInt(
|
||||
"ro.opengles.version",
|
||||
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
|
||||
if (mGLESVersion >= kGLES_20) {
|
||||
mMultipleGLESContextsAllowed = true;
|
||||
}
|
||||
if (LOG_SURFACE) {
|
||||
Log.w(TAG, "checkGLESVersion mGLESVersion =" +
|
||||
" " + mGLESVersion + " mMultipleGLESContextsAllowed = " + mMultipleGLESContextsAllowed);
|
||||
}
|
||||
mGLESVersionCheckComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This check was required for some pre-Android-3.0 hardware. Android 3.0 provides
|
||||
* support for hardware-accelerated views, therefore multiple EGL contexts are
|
||||
* supported on all Android 3.0+ EGL drivers.
|
||||
*/
|
||||
private boolean mGLESVersionCheckComplete;
|
||||
private int mGLESVersion;
|
||||
private boolean mGLESDriverCheckComplete;
|
||||
private boolean mMultipleGLESContextsAllowed;
|
||||
private boolean mLimitedGLESContexts;
|
||||
private static final int kGLES_20 = 0x20000;
|
||||
private static final String kMSM7K_RENDERER_PREFIX =
|
||||
"Q3Dimension MSM7500 ";
|
||||
private GLThread mEglOwner;
|
||||
}
|
||||
|
||||
private static final GLThreadManager sGLThreadManager = new GLThreadManager();
|
||||
|
||||
Reference in New Issue
Block a user