From 0f7ade766678779182f66bdbc6e85d09df4c791f Mon Sep 17 00:00:00 2001
From: Chris Craik Beginning in Android 3.0 (API level 11), the Android 2D rendering pipeline is designed to
- better support hardware acceleration. Hardware acceleration carries out all drawing operations
- that are performed on a {@link android.view.View}'s canvas using the GPU. Because of the
- increased resources required to enable hardware acceleration, your app will consume more RAM. The easiest way to enable hardware acceleration is to turn it on
- globally for your entire application. If your application uses only standard views and {@link
- android.graphics.drawable.Drawable}s, turning it on globally should not cause any adverse
- drawing effects. However, because hardware acceleration is not supported for all of the 2D drawing
- operations, turning it on might affect some of your applications that use custom views or drawing
- calls. Problems usually manifest themselves as invisible elements, exceptions, or wrongly
- rendered pixels. To remedy this, Android gives you the option to enable or disable hardware
- acceleration at the following levels: If your application performs custom drawing, test your application on actual hardware
-devices with hardware acceleration turned on to find any problems. The Unsupported drawing operations section describes known issues with
-drawing operations that cannot be hardware accelerated and how to work around them. Beginning in Android 3.0 (API level 11), the Android 2D rendering pipeline supports hardware
+ acceleration, meaning that all drawing operations that are performed on a {@link
+ android.view.View}'s canvas use the GPU. Because of the increased resources required to enable
+ hardware acceleration, your app will consume more RAM. Hardware acceleration is enabled by default if your Target API level is >=14, but can also
+ be explicitly enabled. If your application uses only standard views and {@link
+ android.graphics.drawable.Drawable}s, turning it on globally should not cause any adverse drawing
+ effects. However, because hardware acceleration is not supported for all of the 2D drawing
+ operations, turning it on might affect some of your custom views or drawing calls. Problems
+ usually manifest themselves as invisible elements, exceptions, or wrongly rendered pixels. To
+ remedy this, Android gives you the option to enable or disable hardware acceleration at multiple
+ levels. See Controlling Hardware Acceleration. If your application performs custom drawing, test your application on actual hardware devices
+ with hardware acceleration turned on to find any problems. The Unsupported drawing operations section describes known issues with
+ hardware acceleration and how to work around them. You can control hardware acceleration at the following levels: If your application does not behave properly with hardware acceleration turned on globally,
- you can control it for individual activities as well. To enable or disable hardware acceleration
- at the activity level, you can use the If your application does not behave properly with hardware acceleration turned on globally, you
+ can control it for individual activities as well. To enable or disable hardware acceleration at
+ the activity level, you can use the With this model, you cannot rely on a view intersecting the dirty region to have its {@link
android.view.View#draw draw()} method executed. To ensure that the Android system records a
viewâs display list, you must call {@link android.view.View#invalidate invalidate()}. Forgetting
- to do so causes a view to look the same even after changing it, which is an easier bug to find if
- it happens.
-
-
- Controlling Hardware Acceleration
Activity level
- android:hardwareAccelerated
- attribute for the
- <activity>
element. The following example enables hardware acceleration
-for the entire application but disables it for one activity:android:hardwareAccelerated
attribute for
+ the
+ <activity>
element. The following example enables hardware acceleration for
+ the entire application but disables it for one activity:
<application android:hardwareAccelerated="true">
@@ -228,8 +217,7 @@ changed.
Using display lists also benefits animation performance because setting specific properties, such as alpha or rotation, does not require invalidating the targeted view (it is done @@ -275,7 +263,7 @@ changed.
The following table describes the support level of various operations across API levels:
< 16 | 16 | -17 | +17 | 18 | |||||
Canvas | |||||||||
clipPath() | -✗ | -✗ | -✗ | -✓ | +drawBitmapMesh() (colors array) | +✗ | +✗ | +✗ | +✓ |
clipRegion() | -✗ | -✗ | -✗ | -✓ | +drawPicture() | +✗ | +✗ | +✗ | +✗ |
clipRect(Region.Op.XOR) | -✗ | -✗ | -✗ | -✓ | +drawPosText() | +✗ | +✓ | +✓ | +✓ |
clipRect(Region.Op.Difference) | -✗ | -✗ | -✗ | -✓ | +drawTextOnPath() | +✗ | +✓ | +✓ | +✓ |
clipRect(Region.Op.ReverseDifference) | -✗ | -✗ | -✗ | -✓ | +drawVertices() | +✗ | +✗ | +✗ | +✗ |
drawBitmapMesh() (colors array) | -✗ | -✗ | -✗ | -✓ | +setDrawFilter() | +✗ | +✓ | +✓ | +✓ |
drawPicture() | -✗ | -✗ | -✗ | -✗ | +clipPath() | +✗ | +✗ | +✗ | +✓ |
drawPosText() | -✗ | -✓ | -✓ | -✓ | +clipRegion() | +✗ | +✗ | +✗ | +✓ |
drawTextOnPath() | -✗ | -✓ | -✓ | -✓ | +clipRect(Region.Op.XOR) | +✗ | +✗ | +✗ | +✓ |
drawVertices() | -✗ | -✗ | -✗ | -✗ | +clipRect(Region.Op.Difference) | +✗ | +✗ | +✗ | +✓ |
setDrawFilter() | -✗ | -✓ | -✓ | -✓ | +clipRect(Region.Op.ReverseDifference) | +✗ | +✗ | +✗ | +✓ | +
clipRect() with rotation/perspective | +✗ | +✗ | +✗ | +✓ | |||||
Paint | |||||||||
setAntiAlias() (for text) | -✗ | -✗ | -✗ | -✓ | +setAntiAlias() (for text) | +✗ | +✗ | +✗ | +✓ |
setAntiAlias() (for lines) | -✗ | -✓ | -✓ | -✓ | +setAntiAlias() (for lines) | +✗ | +✓ | +✓ | +✓ |
setFilterBitmap() | -✗ | -✗ | -✓ | -✓ | +setFilterBitmap() | +✗ | +✗ | +✓ | +✓ |
setLinearText() | -✗ | -✗ | -✗ | -✗ | +setLinearText() | +✗ | +✗ | +✗ | +✗ |
setMaskFilter() | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
setPathEffect() (for lines) | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
setRasterizer() | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
setShadowLayer() (other than text) | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
setStrokeCap() (for lines) | -✗ | -✗ | -✗ | -✓ | +✗ | +✗ | +✗ | +✓ | |
setStrokeCap() (for points) | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
setSubpixelText() | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
Xfermode | |||||||||
AvoidXfermode | -✗ | -✗ | -✗ | -✗ | +AvoidXfermode | +✗ | +✗ | +✗ | +✗ |
PixelXorXfermode | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
PorterDuff.Mode.DARKEN (framebuffer) | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
PorterDuff.Mode.LIGHTEN (framebuffer) | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
PorterDuff.Mode.OVERLAY (framebuffer) | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
Shader | |||||||||
ComposeShader inside ComposeShader | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
Same type shaders inside ComposeShader | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
Local matrix on ComposeShader | -✗ | -✗ | -✗ | -✓ | +✗ | +✗ | +✗ | +✓ |
If your application is affected by any of these missing features or limitations, you can turn - off hardware acceleration for just the affected portion of your application by calling - {@link android.view.View#setLayerType setLayerType(View.LAYER_TYPE_SOFTWARE, null)}. This way, -you can still take advantage of hardware acceleratin everywhere else. See Controlling Hardware Acceleration for more information on how to enable and -disable hardware acceleration at different levels in your application. +
The hardware accelerated 2D rendering pipeline was built first to support unscaled drawing, + with some drawing operations degrading quality significantly at higher scale values. These + operations are implemented as textures drawn at scale 1.0, transformed by the GPU. In API level + <17, using these operations will result in scaling artifacts increasing with scale.
+ + The following table shows when implementation was changed to correctly handle large scales: ++ | + | + | + | |
+ | API level | +|||
< 17 | +17 | +18 | +||
Support for large scale factors | +||||
drawText() | +✗ | +✗ | +✓ | +|
drawPosText() | +✗ | +✗ | +✗ | +|
drawTextOnPath() | +✗ | +✗ | +✗ | +|
Simple Shapes* | +✗ | +✓ | +✓ | +|
Complex Shapes* | +✗ | +✗ | +✗ | +|
drawPath() | +✗ | +✗ | +✗ | +|
Shadow layer | +✗ | +✗ | +✗ | +
Note: 'Simple' shapes are drawRect()
,
+ drawCircle()
, drawOval()
, drawRoundRect()
, and
+ drawArc()
(with useCenter=false) commands issued with a Paint that doesn't have a
+ PathEffect, and doesn't contain non-default joins (via setStrokeJoin()
/
+ setStrokeMiter()
). Other instances of those draw commands fall under 'Complex,' in
+ the above chart.
If your application is affected by any of these missing features or limitations, you can turn + off hardware acceleration for just the affected portion of your application by calling {@link + android.view.View#setLayerType setLayerType(View.LAYER_TYPE_SOFTWARE, null)}. This way, you can + still take advantage of hardware acceleration everywhere else. See Controlling Hardware Acceleration for more information on how to enable + and disable hardware acceleration at different levels in your application.