在Draw上使用自定义视图中的硬件层



因此,我试图了解如何在持续设置动画的自定义View中正确使用硬件加速(如果可用)。这是我的onDraw():的基本前提

canvas.drawColor(mBackgroundColor);
for (Layer layer : mLayers) {
    canvas.save();
    canvas.translate(layer.x, layer.y);
    //Draw that number of images in a grid, offset by -1
    for (int i = -1; i < layer.xCount - 1; i++) {
        for (int j = -1; j < layer.yCount - 1; j++) {
            canvas.drawBitmap(layer.bitmap, layer.w * i, layer.h * j, null);
        }
    }
    //If the layer's x has moved past its width, reset back to a seamless position
    layer.x += ((difference * layer.xSpeed) / 1000f);
    float xOverlap = layer.x % layer.w;
    if (xOverlap > 0) {
        layer.x = xOverlap;
    }
    //If the layer's y has moved past its height, reset back to a seamless position
    layer.y += ((difference * layer.ySpeed) / 1000f);
    float yOverlap = layer.y % layer.h;
    if (yOverlap > 0) {
        layer.y = yOverlap;
    }
    canvas.restore();
}
//Redraw the view
ViewCompat.postInvalidateOnAnimation(this);

我在onAttachedToWindow()中启用硬件层,在onDetachedFromWindow()中禁用硬件层,但我试图了解我是否真的在使用它。本质上,调用drawBitmap()i/j循环永远不会改变;唯一改变的是CCD_ 7翻译。Bitmap是作为幕后纹理自动保存到GPU中,还是需要手动操作?

您究竟在哪个视图上设置View.LAYER_TYPE_HARDWARE?如果在包含上面显示的图形代码的视图上设置硬件图层,则会导致系统所做的工作比所需的多得多。由于您只绘制位图,因此不需要在此处执行任何操作。如果您调用Canvas.drawBitmap(),框架将代表您缓存生成的OpenGL纹理。

但是,您可以对代码进行更多的优化。您可以使用子视图,而不是调用drawBitmap()。如果使用offset*()方法(或setX()/setY())移动这些子级,则框架将应用进一步的优化,以避免再次调用draw()方法。

一般来说,硬件层应该设置在绘制成本高昂且内容不会经常更改的视图上(这与您所做的几乎相反:)

您可以使用Android的Tracer for OpenGL ES来查看您的视图是否发出OpenGL命令。

来自developer.android.com

Tracer是一个用于分析Android应用程序中OpenGL for Embedded Systems(ES)代码的工具。该工具允许您捕获OpenGL ES命令和逐帧图像,以帮助您了解图形命令是如何执行的。

还有一个关于安卓性能研究的教程,由罗曼·盖伊介绍,它几乎是一步一步地使用。

最新更新