Remove EglViewport usages

egloo2
Mattia Iavarone 5 years ago
parent 4f7e1366aa
commit 7f1d5b26b7
  1. 14
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/filter/BaseFilterTest.java
  2. 22
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/filter/MultiFilterTest.java
  3. 16
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/overlay/OverlayDrawerTest.java
  4. 5
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/Issue514Workaround.java
  5. 103
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/egl/EglViewport.java
  6. 27
      cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayDrawer.java
  7. 51
      cameraview/src/main/java/com/otaliastudios/cameraview/preview/GlCameraPreview.java

@ -8,7 +8,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.otaliastudios.cameraview.BaseEglTest; import com.otaliastudios.cameraview.BaseEglTest;
import com.otaliastudios.cameraview.internal.egl.EglViewport; import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.opengl.program.GlTextureProgram; import com.otaliastudios.opengl.program.GlTextureProgram;
import org.junit.Test; import org.junit.Test;
@ -111,18 +111,18 @@ public class BaseFilterTest extends BaseEglTest {
@Test @Test
public void testDraw() { public void testDraw() {
// Use an EglViewport which cares about GL setup. // Use a drawer which cares about GL setup.
filter = spy(new TestFilter()); filter = spy(new TestFilter());
EglViewport viewport = new EglViewport(filter); GlTextureDrawer drawer = new GlTextureDrawer();
int texture = viewport.createTexture(); drawer.setFilter(filter);
float[] matrix = new float[16]; float[] matrix = drawer.getTextureTransform();
viewport.draw(0L, texture, matrix); drawer.draw(0L);
verify(filter, times(1)).onPreDraw(0L, matrix); verify(filter, times(1)).onPreDraw(0L, matrix);
verify(filter, times(1)).onDraw(0L); verify(filter, times(1)).onDraw(0L);
verify(filter, times(1)).onPostDraw(0L); verify(filter, times(1)).onPostDraw(0L);
viewport.release(); drawer.release();
} }
@Test(expected = RuntimeException.class) @Test(expected = RuntimeException.class)

@ -11,7 +11,7 @@ import com.otaliastudios.cameraview.filters.AutoFixFilter;
import com.otaliastudios.cameraview.filters.BrightnessFilter; import com.otaliastudios.cameraview.filters.BrightnessFilter;
import com.otaliastudios.cameraview.filters.DuotoneFilter; import com.otaliastudios.cameraview.filters.DuotoneFilter;
import com.otaliastudios.cameraview.filters.VignetteFilter; import com.otaliastudios.cameraview.filters.VignetteFilter;
import com.otaliastudios.cameraview.internal.egl.EglViewport; import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.opengl.program.GlProgram; import com.otaliastudios.opengl.program.GlProgram;
import org.junit.Test; import org.junit.Test;
@ -142,11 +142,11 @@ public class MultiFilterTest extends BaseEglTest {
DuotoneFilter filter = spy(new DuotoneFilter()); DuotoneFilter filter = spy(new DuotoneFilter());
MultiFilter multiFilter = new MultiFilter(filter); MultiFilter multiFilter = new MultiFilter(filter);
multiFilter.setSize(WIDTH, HEIGHT); multiFilter.setSize(WIDTH, HEIGHT);
EglViewport viewport = new EglViewport(multiFilter); GlTextureDrawer drawer = new GlTextureDrawer();
int texture = viewport.createTexture(); drawer.setFilter(multiFilter);
float[] matrix = new float[16]; float[] matrix = drawer.getTextureTransform();
viewport.draw(0L, texture, matrix); drawer.draw(0L);
viewport.release(); drawer.release();
// The child should have experienced the whole lifecycle. // The child should have experienced the whole lifecycle.
verify(filter, atLeastOnce()).getVertexShader(); verify(filter, atLeastOnce()).getVertexShader();
@ -165,7 +165,9 @@ public class MultiFilterTest extends BaseEglTest {
final DuotoneFilter filter2 = spy(new DuotoneFilter()); final DuotoneFilter filter2 = spy(new DuotoneFilter());
final MultiFilter multiFilter = new MultiFilter(filter1, filter2); final MultiFilter multiFilter = new MultiFilter(filter1, filter2);
multiFilter.setSize(WIDTH, HEIGHT); multiFilter.setSize(WIDTH, HEIGHT);
float[] matrix = new float[16]; GlTextureDrawer drawer = new GlTextureDrawer();
drawer.setFilter(multiFilter);
float[] matrix = drawer.getTextureTransform();
final int[] result = new int[1]; final int[] result = new int[1];
doAnswer(new Answer() { doAnswer(new Answer() {
@ -199,10 +201,8 @@ public class MultiFilterTest extends BaseEglTest {
} }
}).when(filter2).draw(eq(0L), any(float[].class)); }).when(filter2).draw(eq(0L), any(float[].class));
EglViewport viewport = new EglViewport(multiFilter); drawer.draw(0L);
int texture = viewport.createTexture(); drawer.release();
viewport.draw(0L, texture, matrix);
viewport.release();
// Verify that both are drawn. // Verify that both are drawn.
verify(filter1, times(1)).draw(0L, matrix); verify(filter1, times(1)).draw(0L, matrix);

@ -7,7 +7,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.otaliastudios.cameraview.BaseEglTest; import com.otaliastudios.cameraview.BaseEglTest;
import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.size.Size; import com.otaliastudios.cameraview.size.Size;
import org.hamcrest.BaseMatcher; import org.hamcrest.BaseMatcher;
@ -60,22 +59,19 @@ public class OverlayDrawerTest extends BaseEglTest {
@Test @Test
public void testRender() { public void testRender() {
OverlayDrawer drawer = new OverlayDrawer(mock(Overlay.class), new Size(WIDTH, HEIGHT)); OverlayDrawer drawer = new OverlayDrawer(mock(Overlay.class), new Size(WIDTH, HEIGHT));
drawer.mViewport = spy(drawer.mViewport); drawer.mTextureDrawer = spy(drawer.mTextureDrawer);
drawer.draw(Overlay.Target.PICTURE_SNAPSHOT); drawer.draw(Overlay.Target.PICTURE_SNAPSHOT);
drawer.render(0L); drawer.render(0L);
verify(drawer.mViewport, times(1)).draw( verify(drawer.mTextureDrawer, times(1)).draw(0L);
0L,
drawer.mTextureId,
drawer.getTransform()
);
} }
@Test @Test
public void testRelease() { public void testRelease() {
OverlayDrawer drawer = new OverlayDrawer(mock(Overlay.class), new Size(WIDTH, HEIGHT)); OverlayDrawer drawer = new OverlayDrawer(mock(Overlay.class), new Size(WIDTH, HEIGHT));
EglViewport viewport = spy(drawer.mViewport); drawer.mTextureDrawer = spy(drawer.mTextureDrawer);
drawer.mViewport = viewport;
drawer.release(); drawer.release();
verify(viewport, times(1)).release(); verify(drawer.mTextureDrawer, times(1)).release();
} }
} }

@ -6,7 +6,6 @@ import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext; import android.opengl.GLES11Ext;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.view.Surface; import android.view.Surface;
import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.preview.RendererThread; import com.otaliastudios.cameraview.preview.RendererThread;
@ -84,7 +83,7 @@ import com.otaliastudios.cameraview.preview.RendererThread;
* *
* This makes no sense, since overlaySurfaceTexture.updateTexImage() is setting it to * This makes no sense, since overlaySurfaceTexture.updateTexImage() is setting it to
* overlayTextureId anyway, but it fixes the issue. Specifically, after any draw operation with * overlayTextureId anyway, but it fixes the issue. Specifically, after any draw operation with
* {@link EglViewport}, the bound texture is reset to 0 so this must be undone here. We offer: * {@link GlTextureDrawer}, the bound texture is reset to 0 so this must be undone here. We offer:
* *
* - {@link #beforeOverlayUpdateTexImage()} to be called before the * - {@link #beforeOverlayUpdateTexImage()} to be called before the
* {@link SurfaceTexture#updateTexImage()} call * {@link SurfaceTexture#updateTexImage()} call
@ -92,7 +91,7 @@ import com.otaliastudios.cameraview.preview.RendererThread;
* *
* Since updating and rendering can happen on different threads with a shared EGL context, * Since updating and rendering can happen on different threads with a shared EGL context,
* in case they do, the {@link #beforeOverlayUpdateTexImage()}, the actual updateTexImage() and * in case they do, the {@link #beforeOverlayUpdateTexImage()}, the actual updateTexImage() and
* finally the {@link EglViewport} drawing operations should be synchronized with a lock. * finally the {@link GlTextureDrawer} drawing operations should be synchronized with a lock.
* *
* REFERENCES * REFERENCES
* https://github.com/natario1/CameraView/issues/514 * https://github.com/natario1/CameraView/issues/514

@ -1,103 +0,0 @@
package com.otaliastudios.cameraview.internal.egl;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import androidx.annotation.NonNull;
import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.filter.Filter;
import com.otaliastudios.cameraview.filter.NoFilter;
import com.otaliastudios.opengl.program.GlProgram;
public class EglViewport {
private final static CameraLogger LOG = CameraLogger.create(EglViewport.class.getSimpleName());
private int mProgramHandle = -1;
private int mTextureTarget;
private int mTextureUnit;
private Filter mFilter;
private Filter mPendingFilter;
public EglViewport() {
this(new NoFilter());
}
public EglViewport(@NonNull Filter filter) {
mTextureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES;
mTextureUnit = GLES20.GL_TEXTURE0;
mFilter = filter;
createProgram();
}
private void createProgram() {
mProgramHandle = GlProgram.create(mFilter.getVertexShader(),
mFilter.getFragmentShader());
mFilter.onCreate(mProgramHandle);
}
public void release() {
if (mProgramHandle != -1) {
mFilter.onDestroy();
GLES20.glDeleteProgram(mProgramHandle);
mProgramHandle = -1;
}
}
public int createTexture() {
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
Egloo.checkGlError("glGenTextures");
int texId = textures[0];
GLES20.glActiveTexture(mTextureUnit);
GLES20.glBindTexture(mTextureTarget, texId);
Egloo.checkGlError("glBindTexture " + texId);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
Egloo.checkGlError("glTexParameter");
return texId;
}
public void setFilter(@NonNull Filter filter) {
// TODO see if this is needed. If setFilter is always called from the correct GL thread,
// we don't need to wait for a new draw call (which might not even happen).
mPendingFilter = filter;
}
public void draw(long timestampUs, int textureId, float[] textureMatrix) {
if (mPendingFilter != null) {
release();
mFilter = mPendingFilter;
mPendingFilter = null;
createProgram();
}
Egloo.checkGlError("draw start");
// Select the program and the active texture.
GLES20.glUseProgram(mProgramHandle);
Egloo.checkGlError("glUseProgram");
GLES20.glActiveTexture(mTextureUnit);
GLES20.glBindTexture(mTextureTarget, textureId);
// Draw.
mFilter.draw(timestampUs, textureMatrix);
// Release.
GLES20.glBindTexture(mTextureTarget, 0);
GLES20.glUseProgram(0);
}
}

@ -12,8 +12,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.cameraview.internal.Issue514Workaround; import com.otaliastudios.cameraview.internal.Issue514Workaround;
import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.size.Size; import com.otaliastudios.cameraview.size.Size;
import java.nio.Buffer; import java.nio.Buffer;
@ -27,7 +27,7 @@ import java.nio.Buffer;
* - Renders this into the current EGL window: {@link #render(long)} * - Renders this into the current EGL window: {@link #render(long)}
* - Applies the {@link Issue514Workaround} the correct way * - Applies the {@link Issue514Workaround} the correct way
* *
* In the future we might want to use a different approach than {@link EglViewport}, * In the future we might want to use a different approach than {@link GlTextureDrawer},
* {@link SurfaceTexture} and {@link GLES11Ext#GL_TEXTURE_EXTERNAL_OES}, * {@link SurfaceTexture} and {@link GLES11Ext#GL_TEXTURE_EXTERNAL_OES},
* for example by using a regular {@link GLES20#GL_TEXTURE_2D} that might * for example by using a regular {@link GLES20#GL_TEXTURE_2D} that might
* be filled through {@link GLES20#glTexImage2D(int, int, int, int, int, int, int, int, Buffer)}. * be filled through {@link GLES20#glTexImage2D(int, int, int, int, int, int, int, int, Buffer)}.
@ -40,22 +40,19 @@ public class OverlayDrawer {
private static final CameraLogger LOG = CameraLogger.create(TAG); private static final CameraLogger LOG = CameraLogger.create(TAG);
private Overlay mOverlay; private Overlay mOverlay;
@VisibleForTesting int mTextureId;
private SurfaceTexture mSurfaceTexture; private SurfaceTexture mSurfaceTexture;
private Surface mSurface; private Surface mSurface;
private float[] mTransform = new float[16]; @VisibleForTesting GlTextureDrawer mTextureDrawer;
@VisibleForTesting EglViewport mViewport;
private Issue514Workaround mIssue514Workaround; private Issue514Workaround mIssue514Workaround;
private final Object mIssue514WorkaroundLock = new Object(); private final Object mIssue514WorkaroundLock = new Object();
public OverlayDrawer(@NonNull Overlay overlay, @NonNull Size size) { public OverlayDrawer(@NonNull Overlay overlay, @NonNull Size size) {
mOverlay = overlay; mOverlay = overlay;
mViewport = new EglViewport(); mTextureDrawer = new GlTextureDrawer();
mTextureId = mViewport.createTexture(); mSurfaceTexture = new SurfaceTexture(mTextureDrawer.getTexture().getId());
mSurfaceTexture = new SurfaceTexture(mTextureId);
mSurfaceTexture.setDefaultBufferSize(size.getWidth(), size.getHeight()); mSurfaceTexture.setDefaultBufferSize(size.getWidth(), size.getHeight());
mSurface = new Surface(mSurfaceTexture); mSurface = new Surface(mSurfaceTexture);
mIssue514Workaround = new Issue514Workaround(mTextureId); mIssue514Workaround = new Issue514Workaround(mTextureDrawer.getTexture().getId());
} }
/** /**
@ -77,7 +74,7 @@ public class OverlayDrawer {
mIssue514Workaround.beforeOverlayUpdateTexImage(); mIssue514Workaround.beforeOverlayUpdateTexImage();
mSurfaceTexture.updateTexImage(); mSurfaceTexture.updateTexImage();
} }
mSurfaceTexture.getTransformMatrix(mTransform); mSurfaceTexture.getTransformMatrix(mTextureDrawer.getTextureTransform());
} }
/** /**
@ -86,7 +83,7 @@ public class OverlayDrawer {
* @return the transform matrix * @return the transform matrix
*/ */
public float[] getTransform() { public float[] getTransform() {
return mTransform; return mTextureDrawer.getTextureTransform();
} }
/** /**
@ -105,7 +102,7 @@ public class OverlayDrawer {
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
synchronized (mIssue514WorkaroundLock) { synchronized (mIssue514WorkaroundLock) {
mViewport.draw(timestampUs, mTextureId, mTransform); mTextureDrawer.draw(timestampUs);
} }
} }
@ -125,9 +122,9 @@ public class OverlayDrawer {
mSurface.release(); mSurface.release();
mSurface = null; mSurface = null;
} }
if (mViewport != null) { if (mTextureDrawer != null) {
mViewport.release(); mTextureDrawer.release();
mViewport = null; mTextureDrawer = null;
} }
} }
} }

@ -14,7 +14,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.otaliastudios.cameraview.R; import com.otaliastudios.cameraview.R;
import com.otaliastudios.cameraview.internal.egl.EglViewport; import com.otaliastudios.cameraview.internal.GlTextureDrawer;
import com.otaliastudios.cameraview.filter.Filter; import com.otaliastudios.cameraview.filter.Filter;
import com.otaliastudios.cameraview.filter.NoFilter; import com.otaliastudios.cameraview.filter.NoFilter;
import com.otaliastudios.cameraview.size.AspectRatio; import com.otaliastudios.cameraview.size.AspectRatio;
@ -63,10 +63,8 @@ import javax.microedition.khronos.opengles.GL10;
public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceTexture> { public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceTexture> {
private boolean mDispatched; private boolean mDispatched;
private final float[] mTransformMatrix = new float[16];
private int mOutputTextureId = 0;
private SurfaceTexture mInputSurfaceTexture; private SurfaceTexture mInputSurfaceTexture;
private EglViewport mOutputViewport; private GlTextureDrawer mOutputTextureDrawer;
// A synchronized set was not enough to avoid crashes, probably due to external classes // A synchronized set was not enough to avoid crashes, probably due to external classes
// removing the callback while this set is being iterated. CopyOnWriteArraySet solves this. // removing the callback while this set is being iterated. CopyOnWriteArraySet solves this.
private final Set<RendererFrameCallback> mRendererFrameCallbacks = new CopyOnWriteArraySet<>(); private final Set<RendererFrameCallback> mRendererFrameCallbacks = new CopyOnWriteArraySet<>();
@ -146,14 +144,15 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT
if (mCurrentFilter == null) { if (mCurrentFilter == null) {
mCurrentFilter = new NoFilter(); mCurrentFilter = new NoFilter();
} }
mOutputViewport = new EglViewport(mCurrentFilter); mOutputTextureDrawer = new GlTextureDrawer();
mOutputTextureId = mOutputViewport.createTexture(); mOutputTextureDrawer.setFilter(mCurrentFilter);
mInputSurfaceTexture = new SurfaceTexture(mOutputTextureId); final int textureId = mOutputTextureDrawer.getTexture().getId();
mInputSurfaceTexture = new SurfaceTexture(textureId);
getView().queueEvent(new Runnable() { getView().queueEvent(new Runnable() {
@Override @Override
public void run() { public void run() {
for (RendererFrameCallback callback : mRendererFrameCallbacks) { for (RendererFrameCallback callback : mRendererFrameCallbacks) {
callback.onRendererTextureCreated(mOutputTextureId); callback.onRendererTextureCreated(textureId);
} }
} }
}); });
@ -176,10 +175,9 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT
mInputSurfaceTexture.release(); mInputSurfaceTexture.release();
mInputSurfaceTexture = null; mInputSurfaceTexture = null;
} }
mOutputTextureId = 0; if (mOutputTextureDrawer != null) {
if (mOutputViewport != null) { mOutputTextureDrawer.release();
mOutputViewport.release(); mOutputTextureDrawer = null;
mOutputViewport = null;
} }
} }
@ -207,17 +205,17 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT
// Latch the latest frame. If there isn't anything new, // Latch the latest frame. If there isn't anything new,
// we'll just re-use whatever was there before. // we'll just re-use whatever was there before.
final float[] transform = mOutputTextureDrawer.getTextureTransform();
mInputSurfaceTexture.updateTexImage(); mInputSurfaceTexture.updateTexImage();
mInputSurfaceTexture.getTransformMatrix(mTransformMatrix); mInputSurfaceTexture.getTransformMatrix(transform);
// LOG.v("onDrawFrame:", "timestamp:", mInputSurfaceTexture.getTimestamp()); // LOG.v("onDrawFrame:", "timestamp:", mInputSurfaceTexture.getTimestamp());
// For Camera2, apply the draw rotation. // For Camera2, apply the draw rotation.
// See TextureCameraPreview.setDrawRotation() for info. // See TextureCameraPreview.setDrawRotation() for info.
if (mDrawRotation != 0) { if (mDrawRotation != 0) {
Matrix.translateM(mTransformMatrix, 0, 0.5F, 0.5F, 0); Matrix.translateM(transform, 0, 0.5F, 0.5F, 0);
Matrix.rotateM(mTransformMatrix, 0, mDrawRotation, 0, 0, 1); Matrix.rotateM(transform, 0, mDrawRotation, 0, 0, 1);
Matrix.translateM(mTransformMatrix, 0, -0.5F, -0.5F, 0); Matrix.translateM(transform, 0, -0.5F, -0.5F, 0);
} }
if (isCropping()) { if (isCropping()) {
@ -228,11 +226,11 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT
// of the preview (not the center one). // of the preview (not the center one).
float translX = (1F - mCropScaleX) / 2F; float translX = (1F - mCropScaleX) / 2F;
float translY = (1F - mCropScaleY) / 2F; float translY = (1F - mCropScaleY) / 2F;
Matrix.translateM(mTransformMatrix, 0, translX, translY, 0); Matrix.translateM(transform, 0, translX, translY, 0);
Matrix.scaleM(mTransformMatrix, 0, mCropScaleX, mCropScaleY, 1); Matrix.scaleM(transform, 0, mCropScaleX, mCropScaleY, 1);
} }
mOutputViewport.draw(mInputSurfaceTexture.getTimestamp() / 1000L,
mOutputTextureId, mTransformMatrix); mOutputTextureDrawer.draw(mInputSurfaceTexture.getTimestamp() / 1000L);
for (RendererFrameCallback callback : mRendererFrameCallbacks) { for (RendererFrameCallback callback : mRendererFrameCallbacks) {
callback.onRendererFrame(mInputSurfaceTexture, mCropScaleX, mCropScaleY); callback.onRendererFrame(mInputSurfaceTexture, mCropScaleX, mCropScaleY);
} }
@ -301,7 +299,10 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT
@Override @Override
public void run() { public void run() {
mRendererFrameCallbacks.add(callback); mRendererFrameCallbacks.add(callback);
if (mOutputTextureId != 0) callback.onRendererTextureCreated(mOutputTextureId); if (mOutputTextureDrawer != null) {
int textureId = mOutputTextureDrawer.getTexture().getId();
callback.onRendererTextureCreated(textureId);
}
callback.onRendererFilterChanged(mCurrentFilter); callback.onRendererFilterChanged(mCurrentFilter);
} }
}); });
@ -322,7 +323,7 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
protected int getTextureId() { protected int getTextureId() {
return mOutputTextureId; return mOutputTextureDrawer != null ? mOutputTextureDrawer.getTexture().getId() : -1;
} }
/** /**
@ -354,8 +355,8 @@ public class GlCameraPreview extends FilterCameraPreview<GLSurfaceView, SurfaceT
getView().queueEvent(new Runnable() { getView().queueEvent(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mOutputViewport != null) { if (mOutputTextureDrawer != null) {
mOutputViewport.setFilter(filter); mOutputTextureDrawer.setFilter(filter);
} }
for (RendererFrameCallback callback : mRendererFrameCallbacks) { for (RendererFrameCallback callback : mRendererFrameCallbacks) {
callback.onRendererFilterChanged(filter); callback.onRendererFilterChanged(filter);

Loading…
Cancel
Save