按机器上查看启用与硬件加速的矩形覆盖的孔(Punch a hole in a rectangle o

2019-07-04 02:10发布

我有做一些基本的绘图视图。 这之后,我想画有孔矩形拳打在这样只有以前绘制的区域是可见的。 我想和我的最佳性能视图启用硬件加速来做到这一点。

目前,我有两个方法来工作,但只能当禁用硬件加速,另一个是太慢了。

方法1:SW加速(慢)

final int saveCount = canvas.save();

// Clip out a circle.
circle.reset();
circle.addCircle(cx, cy, radius, Path.Direction.CW);
circle.close();
canvas.clipPath(circle, Region.Op.DIFFERENCE);

// Draw the rectangle color.
canvas.drawColor(backColor);

canvas.restoreToCount(saveCount);

这不会对视图启用硬件加速工作,因为“canvas.clipPath”在这种模式下不支持(我知道我可以强制SW渲染,但我想避免这种情况)。

方法2:HW加速(V.慢)

// Create a new canvas.
final Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(b);

// Draw the rectangle colour.
c.drawColor(backColor);

// Erase a circle.
c.drawCircle(cx, cy, radius, eraser);

// Draw the bitmap on our views  canvas.
canvas.drawBitmap(b, 0, 0, null);

当橡皮创建为

eraser = new Paint()
eraser.setColor(0xFFFFFFFF);
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

这显然是缓慢的-一个新的Bitmap视图的大小时,创建每个描绘通话。

方法3:硬件加速(快速,不会对某些设备)

canvas.drawColor(backColor);
canvas.drawCircle(cx, cy, radius, eraser);

一样的硬件加速兼容的方法,但是不需要额外的画布。 没有与此的一个主要问题,但 - 它的工作原理与SW渲染用力,但在HTC One X的(安卓4.0.4 - 也许其他一些设备)至少与硬件渲染启用离开圈完全是黑色的。 这可能涉及到22361 。

方法4:硬件加速(可接受的,适用于所有设备)

按照一月的建议,为改善方法2,我避免创造了每次调用位图onDraw ,而不是这样做的onSizeChanged

if (w != oldw || h != oldh) {
    b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    c = new Canvas(b);
}

然后就是用这些在onDraw

if (overlayBitmap == null) {
   b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
   c = new Canvas(b);
}
b.eraseColor(Color.TRANSPARENT);
c.drawColor(backColor);
c.drawCircle(cx, cy, radius, eraser);
canvas.drawBitmap(b, 0, 0, null);

性能不如方法3,但比2更好,比1略胜一筹一样好。

问题

我怎样才能达到同样的效果,但与硬件加速兼容的方式做到这一点(和一贯的工作设备上)? 这增加了SW渲染性能的方法,也将是可接受的。

注意:当移动一圈,我只是一个无效区域 - 而不是整个画布 - 所以没有余地的性能改善那里。

Answer 1:

而不是分配每个重绘新的画布,你应该能够分配一次,然后再用每个重绘画布。

在初始化和调整大小:

Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);

上重绘:

b.eraseColor(Color.TRANSPARENT);
    // needed if backColor is not opaque; thanks @JosephEarl
c.drawColor(backColor);
c.drawCircle(cx, cy, radius, eraser);

canvas.drawBitmap(b, 0, 0, null);


文章来源: Punch a hole in a rectangle overlay with HW acceleration enabled on View