Skip to content

Commit

Permalink
update GlSurfaceView:onPause/Resume docs
Browse files Browse the repository at this point in the history
fixes: 22448595

Also delete some epically outdated code to
match the documented behavior

Change-Id: I2bb5b475433ebff8ca82db385e228fef11e32e20
  • Loading branch information
jreck committed Jun 29, 2016
1 parent d2e8ae4 commit cf89019
Showing 1 changed file with 31 additions and 131 deletions.
162 changes: 31 additions & 131 deletions opengl/java/android/opengl/GLSurfaceView.java
Expand Up @@ -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;
Expand All @@ -29,15 +36,6 @@
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.
Expand Down Expand Up @@ -119,9 +117,9 @@
* {@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>
Expand Down Expand Up @@ -294,10 +292,12 @@ public int getDebugFlags() {
* 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.
Expand Down Expand Up @@ -554,20 +554,26 @@ public void surfaceRedrawNeeded(SurfaceHolder holder) {


/**
* 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() {
mGLThread.onPause();
}

/**
* 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() {
Expand Down Expand Up @@ -1354,24 +1360,14 @@ private void guardedRun() throws InterruptedException {
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());
}
}
}

// 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) {
Expand Down Expand Up @@ -1411,7 +1407,7 @@ private void guardedRun() throws InterruptedException {
if (! mHaveEglContext) {
if (askedToReleaseEglContext) {
askedToReleaseEglContext = false;
} else if (sGLThreadManager.tryAcquireEglContextLocked(this)) {
} else {
try {
mEglHelper.start();
} catch (RuntimeException t) {
Expand Down Expand Up @@ -1506,7 +1502,6 @@ private void guardedRun() throws InterruptedException {
if (createGlInterface) {
gl = (GL10) mEglHelper.createGL();

sGLThreadManager.checkGLDriver(gl);
createGlInterface = false;
}

Expand Down Expand Up @@ -1888,111 +1883,16 @@ public synchronized void threadExiting(GLThread thread) {
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();
Expand Down

0 comments on commit cf89019

Please sign in to comment.