I am currently having problems with multiple surface views and the clipping of one of the single views to get it to appear as a circle. It is best described in images:
So in this view i have 2 surface views, the full screen one which is showing a preview of the camera and then the top which is playing back a file with a MediaPlayer. I have gotten the top one to be above the preview with the following line:
surfaceView.setZOrderMediaOverlay(true);
Now as you can see i have attempted to mask this to a circle with the following code:
@Override
protected void dispatchDraw(Canvas canvas) {
Path clipPath = new Path();
clipPath.addCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, Path.Direction.CCW);
canvas.clipPath(clipPath);
super.dispatchDraw(canvas);
}
But it doesn't appear to have quite worked out. I initially thought this was a problem with my masking code but turns out the if i remove the preview surface view, like in the following image, the masking works fine
Anyone have any ideas as to why this is occurring or how to fix it at all :S?
Thanks for your help
Bear in mind that a SurfaceView has two parts, the Surface and the View, and that the Android graphics system uses multiple layers.
All of your Views live on a single layer, usually referred to simply as "the View UI layer". Views can be placed on top of or below each other because they're all being rendered into the same buffer of pixels.
Surfaces appear on their own layers. By default, the SurfaceView's Surface is below (behind) the View UI layer. The SurfaceView's View part is just a transparent rectangle that the View system uses for layout. If you draw on that View (by subclassing SurfaceView and overriding a draw method), you're rendering pixels that overlap the Surface, making them opaque. This is an easy way to mask the Surface.
Your mini-player Surface uses setZOrderOnTop()
, which sets the layer for that SurfaceView's Surface to be on top (in front) of the View UI. This is handy if your Surface is partially transparent, as it lets you see the Views behind it. However, anything you draw on the SurfaceView's View will also appear behind it, so it will no longer work as a mask.
The trouble with what you're trying to do is that you want to have the lower Surface visible through the upper Surface at the corners. You can't simply mask those pixels off with another layer -- you need to make them transparent on the video playback layer itself. This is a bit tricky, as you will need to feed the video into a GLES texture and then render it.
See also the graphics architecture doc.