Home » Android » android – When should we use LAYER_TYPE_HARDWARE

android – When should we use LAYER_TYPE_HARDWARE

Posted by: admin May 14, 2020 Leave a comment

Questions:

After reading on http://developer.android.com/guide/topics/graphics/hardware-accel.html , my understanding on 3 different type of layering techniques are (Assume the device has GPU)

  • LAYER_TYPE_SOFTWAREDraw is performed by software on software’s off-screen bitmap memory. Software’s off-screen bitmap will then transferred to GPU. GPU render the bitmap on screen.
  • LAYER_TYPE_NONE – GPU will draw directly on screen.
  • LAYER_TYPE_HARDWAREDraw is performed by GPU on GPU’s off-screen bitmap memory. GPU’s off-screen bitmap will then render to screen by GPU.

When to use LAYER_TYPE_SOFTWARE

My understanding certain draw operation isn’t supported by GPU like setShadowLayer. Hence, we need to switch to LAYER_TYPE_SOFTWARE, so that draw will be performed by software.

However, since there’s software’s off-screen bitmap memory transferred to GPU operation, things may appear slower.

When to use LAYER_TYPE_NONE

I think this is the default settings in most of the devices. So, I assume we should use this technique most of the time.

When to use LAYER_TYPE_HARDWARE

I have no idea when to use this technique. Any example will be very much appreciated, on when we should apply LAYER_TYPE_HARDWARE technique.

p/s Also, my understanding on LAYER_TYPE_… may appear wrong. Kindly correct me, if you find any mistake. Thank you.

How to&Answers:

When to use LAYER_TYPE_HARDWARE

When I want to draw a text that cutout the parent view (allowing you to see through it) I use:

setLayerType(View.LAYER_TYPE_HARDWARE, null)

For example in my custom view:

init {
    setLayerType(View.LAYER_TYPE_HARDWARE, null)
}

private val textPaint = TextPaint(ANTI_ALIAS_FLAG).apply {
    textSize = size
    xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    createTextLayout(MeasureSpec.getSize(widthMeasureSpec))
    setMeasuredDimension(widthMeasureSpec, heightMeasureSpec)
}

private fun createTextLayout(textWidth: Int) {
    textLayout = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        StaticLayout.Builder
                .obtain(text, 0, text.length, textPaint, textWidth)
                .setAlignment(Layout.Alignment.ALIGN_CENTER)
                .build()
    } else {
        StaticLayout(text, textPaint, textWidth, Layout.Alignment.ALIGN_CENTER, 1f, 0f, true)
    }
}

...

override fun onDraw(canvas: Canvas?) {
    canvas?.drawCircle(width / 2f, height / 2f, width / 2f, circlePaint)

    canvas?.withTranslation(
            x = width / 2f - textLayout.width / 2f,
            y = height / 2f - textLayout.height / 2f
    ) {
        textLayout.draw(canvas)
    }
}

The result:

enter image description here

And without setting LAYER_TYPE_HARDWARE:

enter image description here

Answer:

Basically its like a drawing cache. if your custom view is expensive to render/draw but the content doesn’t change too much often then i’d use the flag. otherwise your just stressing out the device to cache for no reason.