Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Unified Diff: talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java

Issue 1389203003: Android SurfaceViewRenderer: Allow to re-init after release() has been called (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Move init check first Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java
diff --git a/talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java b/talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java
index b4e687f79e1e75606258f014a4388ffb0c9fdef4..28404c9d6f13782562dd3d2c635e2a8a5e7defa4 100644
--- a/talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java
+++ b/talk/app/webrtc/java/android/org/webrtc/SurfaceViewRenderer.java
@@ -91,6 +91,8 @@ public class SurfaceViewRenderer extends SurfaceView
// layout and surface size.
private int surfaceWidth;
private int surfaceHeight;
+ // |isSurfaceCreated| keeps track of the current status in surfaceCreated()/surfaceDestroyed().
+ private boolean isSurfaceCreated;
// Last rendered frame dimensions, or 0 if no frame has been rendered yet.
private int frameWidth;
private int frameHeight;
@@ -128,6 +130,7 @@ public class SurfaceViewRenderer extends SurfaceView
*/
public SurfaceViewRenderer(Context context) {
super(context);
+ getHolder().addCallback(this);
}
/**
@@ -135,24 +138,48 @@ public class SurfaceViewRenderer extends SurfaceView
*/
public SurfaceViewRenderer(Context context, AttributeSet attrs) {
super(context, attrs);
+ getHolder().addCallback(this);
}
/**
- * Initialize this class, sharing resources with |sharedContext|.
+ * Initialize this class, sharing resources with |sharedContext|. It is allowed to call init() to
+ * reinitialize the renderer after a previous init()/release() cycle.
*/
public void init(
EGLContext sharedContext, RendererCommon.RendererEvents rendererEvents) {
- if (renderThreadHandler != null) {
- throw new IllegalStateException("Already initialized");
+ synchronized (handlerLock) {
+ if (renderThreadHandler != null) {
+ throw new IllegalStateException("Already initialized");
+ }
+ Logging.d(TAG, "Initializing");
+ this.rendererEvents = rendererEvents;
+ renderThread = new HandlerThread(TAG);
+ renderThread.start();
+ drawer = new GlRectDrawer();
+ eglBase = new EglBase(sharedContext, EglBase.ConfigType.PLAIN);
+ renderThreadHandler = new Handler(renderThread.getLooper());
}
- Logging.d(TAG, "Initializing");
- this.rendererEvents = rendererEvents;
- renderThread = new HandlerThread(TAG);
- renderThread.start();
- renderThreadHandler = new Handler(renderThread.getLooper());
- eglBase = new EglBase(sharedContext, EglBase.ConfigType.PLAIN);
- drawer = new GlRectDrawer();
- getHolder().addCallback(this);
+ tryCreateEglSurface();
+ }
+
+ /**
+ * Create and make an EGLSurface current if both init() and surfaceCreated() have been called.
+ */
+ public void tryCreateEglSurface() {
+ // |renderThreadHandler| is only created after |eglBase| is created in init(), so the
+ // following code will only execute if eglBase != null.
+ runOnRenderThread(new Runnable() {
+ @Override public void run() {
+ synchronized (layoutLock) {
+ if (isSurfaceCreated) {
+ eglBase.createSurface(getHolder().getSurface());
+ eglBase.makeCurrent();
+ // Necessary for YUV frames with odd width.
+ GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1);
+ }
+ }
+ }
+ });
}
/**
@@ -179,6 +206,9 @@ public class SurfaceViewRenderer extends SurfaceView
GLES20.glDeleteTextures(3, yuvTextures, 0);
yuvTextures = null;
}
+ // Clear last rendered image to black.
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+ eglBase.swapBuffers();
eglBase.release();
eglBase = null;
}
@@ -197,6 +227,20 @@ public class SurfaceViewRenderer extends SurfaceView
// The |renderThread| cleanup is not safe to cancel and we need to wait until it's done.
ThreadUtils.joinUninterruptibly(renderThread);
renderThread = null;
+ // Reset statistics and event reporting.
+ synchronized (layoutLock) {
+ frameWidth = 0;
+ frameHeight = 0;
+ frameRotation = 0;
+ rendererEvents = null;
+ }
+ synchronized (statisticsLock) {
+ framesReceived = 0;
+ framesDropped = 0;
+ framesRendered = 0;
+ firstFrameTimeNs = 0;
+ renderTimeNs = 0;
+ }
}
/**
@@ -286,20 +330,17 @@ public class SurfaceViewRenderer extends SurfaceView
@Override
public void surfaceCreated(final SurfaceHolder holder) {
Logging.d(TAG, "Surface created");
- runOnRenderThread(new Runnable() {
- @Override public void run() {
- eglBase.createSurface(holder.getSurface());
- eglBase.makeCurrent();
- // Necessary for YUV frames with odd width.
- GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1);
- }
- });
+ synchronized (layoutLock) {
+ isSurfaceCreated = true;
+ }
+ tryCreateEglSurface();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Logging.d(TAG, "Surface destroyed");
synchronized (layoutLock) {
+ isSurfaceCreated = false;
surfaceWidth = 0;
surfaceHeight = 0;
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698