Get hardware accelerated Canvas from TextureView on Android

Weston Lee
3 min readJan 7, 2024

SurfaceView and TextureView are high-level components provided by Android framework that support rendering from background thread. Although they both support asynchronous rendering, they are different in terms of usage and underlying implementation principles.

Internally, SurfaceView directly creates a Surface that is independent of the current Activity. This Surface is under the Activity Surface by default, and then digs a transparent hole of a corresponding size at the corresponding position on the Activity so that the content of the SurfaceView below can be displayed.
The content of TextureView is rendered normally to the Surface of the current Activity. It is implemented internally based on SurfaceTexture. When the rendering side completes its render procedure, SurfaceTexture will upload the rendering result to the GPU in the form of a texture, and then TextureView will render the texture into the view tree of the current Activity.
In terms of use, both SurfaceView and TextureView provide the Canvas interface for asynchronous rendering. By using SurfaceView, developer can specify whether the Canvas is hardware accelerated(lockHardwareCanvas is HW backed and lockCanvas is not), but the Canvas returned by TextureView.lockCanvas() and TextureView.lockCanvas(Rect dirty) provided by TextureView is never hardware accelerated.

When the Canvas is not hardware accelerated, the rendering instructions is completely executed by the CPU. Although the procedure is finished on asynchronous thread, when rendering complex graphics, the high time consumption of single frame rendering results in a low rendering frame rate, and on the other hand It will consume a lot of CPU time, causing problems such as overall application lag and device heating and power outage.

Solution

HwTextureView is a solution to obtain hardware accelerated Canvas from TextureView.

We can make our TextureView extends HwTextureView to get hardware accelerated Canvas.

The render procedure is same as the ordinary TextureView. The Canvas obtained by lockCanvas() is hardware accelerated on Android 28 and above. It should be noted that the lockCanvas(Rect dirty) method is not available (returns null directly).

The internal implementation is to create a Surface as a graphics producer, and the consumer side is connected to the SurfaceTexture of TextureView, This Surface is used to provide a hardware acceleration interface to the outside world.

implementation of HwTextureView

Performance test

rendering content

What to count:

  • Per frame time consumption of executing all drawing command(drawPath)
  • Average cpu usage during rendering

Result:

--

--