diff --git a/sdk/android/api/org/webrtc/EglRenderer.java b/sdk/android/api/org/webrtc/EglRenderer.java index c6e98123aa..dccd11105b 100644 --- a/sdk/android/api/org/webrtc/EglRenderer.java +++ b/sdk/android/api/org/webrtc/EglRenderer.java @@ -131,7 +131,8 @@ public class EglRenderer implements VideoRenderer.Callbacks, VideoSink { private long renderSwapBufferTimeNs; // Used for bitmap capturing. - @Nullable private GlTextureFrameBuffer bitmapTextureFramebuffer; + private final GlTextureFrameBuffer bitmapTextureFramebuffer = + new GlTextureFrameBuffer(GLES20.GL_RGBA); private final Runnable logStatisticsRunnable = new Runnable() { @Override @@ -233,10 +234,7 @@ public class EglRenderer implements VideoRenderer.Callbacks, VideoSink { drawer = null; } frameDrawer.release(); - if (bitmapTextureFramebuffer != null) { - bitmapTextureFramebuffer.release(); - bitmapTextureFramebuffer = null; - } + bitmapTextureFramebuffer.release(); if (eglBase != null) { logD("eglBase detach and release."); eglBase.detachCurrent(); @@ -637,9 +635,6 @@ public class EglRenderer implements VideoRenderer.Callbacks, VideoSink { continue; } - if (bitmapTextureFramebuffer == null) { - bitmapTextureFramebuffer = new GlTextureFrameBuffer(GLES20.GL_RGBA); - } bitmapTextureFramebuffer.setSize(scaledWidth, scaledHeight); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, bitmapTextureFramebuffer.getFrameBufferId()); diff --git a/sdk/android/api/org/webrtc/GlTextureFrameBuffer.java b/sdk/android/api/org/webrtc/GlTextureFrameBuffer.java index 164dff29cb..b906fe56e0 100644 --- a/sdk/android/api/org/webrtc/GlTextureFrameBuffer.java +++ b/sdk/android/api/org/webrtc/GlTextureFrameBuffer.java @@ -15,13 +15,13 @@ import android.opengl.GLES20; /** * Helper class for handling OpenGL framebuffer with only color attachment and no depth or stencil * buffer. Intended for simple tasks such as texture copy, texture downscaling, and texture color - * conversion. + * conversion. This class is not thread safe and must be used by a thread with an active GL context. */ // TODO(magjed): Add unittests for this class. public class GlTextureFrameBuffer { - private final int frameBufferId; - private final int textureId; private final int pixelFormat; + private int frameBufferId; + private int textureId; private int width; private int height; @@ -39,16 +39,8 @@ public class GlTextureFrameBuffer { default: throw new IllegalArgumentException("Invalid pixel format: " + pixelFormat); } - - // Create texture. - textureId = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D); this.width = 0; this.height = 0; - - // Create framebuffer object. - final int frameBuffers[] = new int[1]; - GLES20.glGenFramebuffers(1, frameBuffers, 0); - frameBufferId = frameBuffers[0]; } /** @@ -57,7 +49,7 @@ public class GlTextureFrameBuffer { * least once before using the framebuffer. May be called multiple times to change size. */ public void setSize(int width, int height) { - if (width == 0 || height == 0) { + if (width <= 0 || height <= 0) { throw new IllegalArgumentException("Invalid size: " + width + "x" + height); } if (width == this.width && height == this.height) { @@ -65,6 +57,15 @@ public class GlTextureFrameBuffer { } this.width = width; this.height = height; + // Lazy allocation the first time setSize() is called. + if (textureId == 0) { + textureId = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D); + } + if (frameBufferId == 0) { + final int frameBuffers[] = new int[1]; + GLES20.glGenFramebuffers(1, frameBuffers, 0); + frameBufferId = frameBuffers[0]; + } // Allocate texture. GLES20.glActiveTexture(GLES20.GL_TEXTURE0); @@ -96,10 +97,12 @@ public class GlTextureFrameBuffer { return height; } + /** Gets the OpenGL frame buffer id. This value is only valid after setSize() has been called. */ public int getFrameBufferId() { return frameBufferId; } + /** Gets the OpenGL texture id. This value is only valid after setSize() has been called. */ public int getTextureId() { return textureId; } @@ -110,7 +113,9 @@ public class GlTextureFrameBuffer { */ public void release() { GLES20.glDeleteTextures(1, new int[] {textureId}, 0); + textureId = 0; GLES20.glDeleteFramebuffers(1, new int[] {frameBufferId}, 0); + frameBufferId = 0; width = 0; height = 0; }