diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
index f3fd9de8..ea5a4a49 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
@@ -226,6 +226,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
int frameExecutors = a.getInteger(R.styleable.CameraView_cameraFrameProcessingExecutors,
DEFAULT_FRAME_PROCESSING_EXECUTORS);
+ boolean overlayHardwareCanvas = a.getBoolean(R.styleable.CameraView_cameraOverlayHardwareCanvas, false);
+
// Size selectors and gestures
SizeSelectorParser sizeSelectors = new SizeSelectorParser(a);
GestureParser gestures = new GestureParser(a);
@@ -259,6 +261,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setUseDeviceOrientation(useDeviceOrientation);
setGrid(controls.getGrid());
setGridColor(gridColor);
+ setOverlayHardwareCanvasEnabled(overlayHardwareCanvas);
// Apply camera engine params
// Adding new ones? See setEngine().
@@ -2148,6 +2151,25 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.isTakingPicture();
}
+ /**
+ * Sets the overlay layout hardware canvas capture mode to allow hardware
+ * accelerated views to be captured in snapshots
+ *
+ * @param on true if enabled
+ */
+ public void setOverlayHardwareCanvasEnabled(boolean on) {
+ mOverlayLayout.setHardwareCanvasEnabled(on);
+ }
+
+ /**
+ * Returns true if the overlay layout is set to capture the hardware canvas
+ * of child views
+ *
+ * @return boolean indicating hardware canvas capture is enabled
+ */
+ public boolean getOverlayHardwareCanvasEnabled() {
+ return mOverlayLayout.getHardwareCanvasEnabled();
+ }
//endregion
//region Callbacks and dispatching
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/Overlay.java b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/Overlay.java
index 44e1661d..038702af 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/Overlay.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/Overlay.java
@@ -30,4 +30,18 @@ public interface Overlay {
* @return true to draw on it
*/
boolean drawsOn(@NonNull Target target);
+
+ /**
+ * Sets the overlay renderer to lock and capture the hardware canvas in order
+ * to capture hardware accelerated views such as video players
+ *
+ * @param on enabled
+ */
+ void setHardwareCanvasEnabled(boolean on);
+
+ /**
+ * Returns true if hardware canvas capture is enabled, false by default
+ * @return true if capturing hardware surfaces
+ */
+ boolean getHardwareCanvasEnabled();
}
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayDrawer.java b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayDrawer.java
index 88f72668..940b80ba 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayDrawer.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayDrawer.java
@@ -6,6 +6,7 @@ import android.graphics.PorterDuff;
import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
+import android.os.Build;
import android.view.Surface;
import androidx.annotation.NonNull;
@@ -63,7 +64,12 @@ public class OverlayDrawer {
*/
public void draw(@NonNull Overlay.Target target) {
try {
- final Canvas surfaceCanvas = mSurface.lockCanvas(null);
+ final Canvas surfaceCanvas;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && mOverlay.getHardwareCanvasEnabled()) {
+ surfaceCanvas = mSurface.lockHardwareCanvas();
+ } else {
+ surfaceCanvas = mSurface.lockCanvas(null);
+ }
surfaceCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
mOverlay.drawOn(target, surfaceCanvas);
mSurface.unlockCanvasAndPost(surfaceCanvas);
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java
index 3b2bd782..ba5dec36 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java
@@ -26,6 +26,8 @@ public class OverlayLayout extends FrameLayout implements Overlay {
@VisibleForTesting Target currentTarget = Target.PREVIEW;
+ private boolean mHardwareCanvasEnabled;
+
/**
* We set {@link #setWillNotDraw(boolean)} to false even if we don't draw anything.
* This ensures that the View system will call {@link #draw(Canvas)} on us instead
@@ -99,6 +101,16 @@ public class OverlayLayout extends FrameLayout implements Overlay {
return false;
}
+ @Override
+ public void setHardwareCanvasEnabled(boolean on) {
+ mHardwareCanvasEnabled = on;
+ }
+
+ @Override
+ public boolean getHardwareCanvasEnabled() {
+ return mHardwareCanvasEnabled;
+ }
+
/**
* For {@link Target#PREVIEW}, this method is called by the View hierarchy. We will
* just forward the call to super.
@@ -132,7 +144,8 @@ public class OverlayLayout extends FrameLayout implements Overlay {
"canvas:", canvas.getWidth() + "x" + canvas.getHeight(),
"view:", getWidth() + "x" + getHeight(),
"widthScale:", widthScale,
- "heightScale:", heightScale
+ "heightScale:", heightScale,
+ "hardwareCanvasMode:", mHardwareCanvasEnabled
);
canvas.scale(widthScale, heightScale);
dispatchDraw(canvas);
diff --git a/cameraview/src/main/res/values/attrs.xml b/cameraview/src/main/res/values/attrs.xml
index 9a27f115..50b388c2 100644
--- a/cameraview/src/main/res/values/attrs.xml
+++ b/cameraview/src/main/res/values/attrs.xml
@@ -169,6 +169,8 @@
+
+