Add option to capture hardware accelerated overlays

pull/1066/head
Ryan Loebs 4 years ago
parent a219073468
commit 28576f6569
  1. 22
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  2. 14
      cameraview/src/main/java/com/otaliastudios/cameraview/overlay/Overlay.java
  3. 8
      cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayDrawer.java
  4. 15
      cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java
  5. 2
      cameraview/src/main/res/values/attrs.xml

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

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

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

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

@ -169,6 +169,8 @@
<attr name="cameraRequestPermissions" format="boolean|reference"/>
<attr name="cameraExperimental" format="boolean|reference" />
<attr name="cameraOverlayHardwareCanvas" format="boolean"/>
</declare-styleable>
<declare-styleable name="CameraView_Layout">

Loading…
Cancel
Save