Use lock instead of afterOverlayGlDrawn

pull/528/head
Mattia Iavarone 6 years ago
parent d6eea6e08f
commit 9fa43a1120
  1. 16
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/Issue514Workaround.java
  2. 37
      cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayDrawer.java

@ -80,18 +80,14 @@ import com.otaliastudios.cameraview.preview.RendererThread;
*
* This makes no sense, since overlaySurfaceTexture.updateTexImage() is setting it to overlayTextureId,
* but it fixes the issue. Specifically, after any draw operation with {@link EglViewport}, the bound
* texture is reset to 0.
* texture is reset to 0 so this must be undone here. We offer:
*
* So, since updating and drawing can happen on different threads, to maximize the chances that
* when updateTexImage() is called we have bound the cameraTextureId, and to avoid using a lock,
* we require to call
* - {@link #beforeOverlayUpdateTexImage()} right before the {@link SurfaceTexture#updateTexImage()} call
* - {@link #afterOverlayGlDrawn()} right after the last {@link EglViewport#drawFrame(int, float[])} call
* - {@link #end()} to release
* - {@link #beforeOverlayUpdateTexImage()} to be called before the {@link SurfaceTexture#updateTexImage()} call
* - {@link #end()} to release and bring things back to normal state
*
* If filling the texture and rendering happen on two different threads (with a shared EGL context)
* there is still a chance that updateTexImage() is called with a current texture that creates this
* issue (0?), but the alternative would be creating a lock.
* 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
* finally the {@link EglViewport} drawing operations should be synchronized with a lock.
*
* REFERENCES
* https://android.googlesource.com/platform/frameworks/native/+/5c1139f/libs/gui/SurfaceTexture.cpp

@ -4,6 +4,8 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.view.Surface;
import androidx.annotation.NonNull;
@ -13,6 +15,24 @@ import com.otaliastudios.cameraview.internal.Issue514Workaround;
import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.size.Size;
import java.nio.Buffer;
/**
* Draws overlays through {@link Overlay}.
*
* - Provides a {@link Canvas} to be passed to the Overlay
* - Lets the overlay draw there: {@link #draw(Overlay.Target)}
* - Renders this into the current EGL window: {@link #render()}
* - Applies the {@link Issue514Workaround} the correct way
*
* In the future we might want to use a different approach than {@link EglViewport},
* {@link SurfaceTexture} and {@link GLES11Ext#GL_TEXTURE_EXTERNAL_OES},
* 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)}.
*
* The current approach has some issues, for example see {@link Issue514Workaround}.
*/
public class OverlayDrawer {
private static final String TAG = OverlayDrawer.class.getSimpleName();
@ -22,9 +42,10 @@ public class OverlayDrawer {
private int mTextureId;
private SurfaceTexture mSurfaceTexture;
private Surface mSurface;
private float[] mTransform = new float[16];
private EglViewport mViewport;
private Issue514Workaround mIssue514Workaround;
private float[] mTransform = new float[16];
private final Object mIssue514WorkaroundLock = new Object();
public OverlayDrawer(@NonNull Overlay overlay, @NonNull Size size, int cameraTextureId) {
mOverlay = overlay;
@ -46,8 +67,10 @@ public class OverlayDrawer {
} catch (Surface.OutOfResourcesException e) {
LOG.w("Got Surface.OutOfResourcesException while drawing video overlays", e);
}
mIssue514Workaround.beforeOverlayUpdateTexImage();
mSurfaceTexture.updateTexImage();
synchronized (mIssue514WorkaroundLock) {
mIssue514Workaround.beforeOverlayUpdateTexImage();
mSurfaceTexture.updateTexImage();
}
mSurfaceTexture.getTransformMatrix(mTransform);
}
@ -56,9 +79,11 @@ public class OverlayDrawer {
}
public void render() {
mIssue514Workaround.afterOverlayGlDrawn();
mViewport.drawFrame(mTextureId, mTransform);
mIssue514Workaround.afterOverlayGlDrawn();
synchronized (mIssue514WorkaroundLock) {
mViewport.drawFrame(mTextureId, mTransform);
}
// mIssue514Workaround.afterOverlayGlDrawn();
// mIssue514Workaround.afterOverlayGlDrawn();
}
public void release() {

Loading…
Cancel
Save