Android: Allow construction of GlTextureFrameBuffer from non-OpenGL thread

This CL makes it possible to create a GlTextureFrameBuffer from any
thread. The actual GL resources will be allocated the first time
setSize() is called. The purpose is to be able to use 'final' variables
more often for this class and avoid @Nullable annotations.

Bug: None
Change-Id: I350304bcd33fd674990254df37a615995972f322
Reviewed-on: https://webrtc-review.googlesource.com/69241
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22835}
This commit is contained in:
Magnus Jedvert
2018-04-11 14:25:14 +02:00
committed by Commit Bot
parent 6e641e64b2
commit 2ed62b3c9b
2 changed files with 20 additions and 20 deletions

View File

@ -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;
}
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());

View File

@ -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;
}