Fix tests and cleanup

pull/559/head
Mattia Iavarone 6 years ago
parent 3f210baab8
commit 802b6915a8
  1. 16
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/filter/MultiFilterTest.java
  2. 41
      cameraview/src/main/java/com/otaliastudios/cameraview/filter/MultiFilter.java

@ -24,9 +24,11 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
@ -172,8 +174,8 @@ public class MultiFilterTest extends BaseEglTest {
public Object answer(InvocationOnMock invocation) { public Object answer(InvocationOnMock invocation) {
MultiFilter.State state = multiFilter.states.get(filter1); MultiFilter.State state = multiFilter.states.get(filter1);
assertNotNull(state); assertNotNull(state);
assertTrue(state.framebufferId != -1); assertTrue(state.isCreated);
assertTrue(state.textureId != -1); assertTrue(state.isFramebufferCreated);
GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, result, 0); GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, result, 0);
assertTrue(result[0] != 0); assertTrue(result[0] != 0);
@ -181,20 +183,22 @@ public class MultiFilterTest extends BaseEglTest {
} }
}).when(filter1).draw(matrix); }).when(filter1).draw(matrix);
// Note: second filter is drawn with the identity matrix!
doAnswer(new Answer() { doAnswer(new Answer() {
@Override @Override
public Object answer(InvocationOnMock invocation) { public Object answer(InvocationOnMock invocation) {
// The last filter has no FBO / texture. // The last filter has no FBO / texture.
MultiFilter.State state = multiFilter.states.get(filter2); MultiFilter.State state = multiFilter.states.get(filter2);
assertNotNull(state); assertNotNull(state);
assertEquals(-1, state.framebufferId); assertTrue(state.isCreated);
assertEquals(-1, state.textureId); assertFalse(state.isFramebufferCreated);
GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, result, 0); GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, result, 0);
assertEquals(0, result[0]); assertEquals(0, result[0]);
return null; return null;
} }
}).when(filter2).draw(matrix); }).when(filter2).draw(any(float[].class));
EglViewport viewport = new EglViewport(multiFilter); EglViewport viewport = new EglViewport(multiFilter);
int texture = viewport.createTexture(); int texture = viewport.createTexture();
@ -203,7 +207,7 @@ public class MultiFilterTest extends BaseEglTest {
// Verify that both are drawn. // Verify that both are drawn.
verify(filter1, times(1)).draw(matrix); verify(filter1, times(1)).draw(matrix);
verify(filter2, times(1)).draw(matrix); verify(filter2, times(1)).draw(any(float[].class));
} }
} }

@ -39,15 +39,15 @@ import java.util.Map;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilter { public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilter {
private final static int TARGET = GLES20.GL_TEXTURE_2D;
@VisibleForTesting @VisibleForTesting
static class State { static class State {
boolean isCreated = false; @VisibleForTesting boolean isCreated = false;
int programHandle = -1; @VisibleForTesting boolean isFramebufferCreated = false;
int framebufferId = -1; @VisibleForTesting Size size = null;
int textureId = -1;
Size size = null; private int programHandle = -1;
private int framebufferId = -1;
private int textureId = -1;
} }
@VisibleForTesting final List<Filter> filters = new ArrayList<>(); @VisibleForTesting final List<Filter> filters = new ArrayList<>();
@ -135,7 +135,9 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
if (isLast) return; if (isLast) return;
State state = states.get(filter); State state = states.get(filter);
//noinspection ConstantConditions //noinspection ConstantConditions
if (state.framebufferId == -1) { if (!state.isFramebufferCreated) {
state.isFramebufferCreated = true;
int[] framebufferArray = new int[1]; int[] framebufferArray = new int[1];
int[] textureArray = new int[1]; int[] textureArray = new int[1];
GLES20.glGenFramebuffers(1, framebufferArray, 0); GLES20.glGenFramebuffers(1, framebufferArray, 0);
@ -143,16 +145,16 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
state.framebufferId = framebufferArray[0]; state.framebufferId = framebufferArray[0];
state.textureId = textureArray[0]; state.textureId = textureArray[0];
GLES20.glBindTexture(TARGET, state.textureId); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, state.textureId);
GLES20.glTexImage2D(TARGET, 0, GLES20.GL_RGBA, state.size.getWidth(), state.size.getHeight(), 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, state.size.getWidth(), state.size.getHeight(), 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
GLES20.glTexParameterf(TARGET, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(TARGET, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(TARGET, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(TARGET, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, state.framebufferId); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, state.framebufferId);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_COLOR_ATTACHMENT0,
TARGET, GLES20.GL_TEXTURE_2D,
state.textureId, state.textureId,
0); 0);
@ -161,7 +163,7 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
throw new RuntimeException("Invalid framebuffer generation. Error:" + status); throw new RuntimeException("Invalid framebuffer generation. Error:" + status);
} }
GLES20.glBindTexture(TARGET, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
} }
} }
@ -169,7 +171,8 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
private void maybeDestroyFramebuffer(@NonNull Filter filter) { private void maybeDestroyFramebuffer(@NonNull Filter filter) {
State state = states.get(filter); State state = states.get(filter);
//noinspection ConstantConditions //noinspection ConstantConditions
if (state.framebufferId != -1) { if (state.isFramebufferCreated) {
state.isFramebufferCreated = false;
GLES20.glDeleteFramebuffers(1, new int[]{state.framebufferId}, 0); GLES20.glDeleteFramebuffers(1, new int[]{state.framebufferId}, 0);
state.framebufferId = -1; state.framebufferId = -1;
GLES20.glDeleteTextures(1, new int[]{state.textureId}, 0); GLES20.glDeleteTextures(1, new int[]{state.textureId}, 0);
@ -264,9 +267,9 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
// It is the framebuffer texture from this cycle. If this is the last // It is the framebuffer texture from this cycle. If this is the last
// filter, reset this value just to cleanup. // filter, reset this value just to cleanup.
if (!isLast) { if (!isLast) {
GLES20.glBindTexture(TARGET, state.textureId); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, state.textureId);
} else { } else {
GLES20.glBindTexture(TARGET, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
} }
GLES20.glUseProgram(0); GLES20.glUseProgram(0);

Loading…
Cancel
Save