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. 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. 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. 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() | -✗ | -✗ | -✗ | -✓ | -|||||
| clipRegion() | -✗ | -✗ | -✗ | -✓ | -|||||
| clipRect(Region.Op.XOR) | -✗ | -✗ | -✗ | -✓ | -|||||
| clipRect(Region.Op.Difference) | -✗ | -✗ | -✗ | -✓ | -|||||
| clipRect(Region.Op.ReverseDifference) | -✗ | -✗ | -✗ | -✓ | -|||||
| drawBitmapMesh() (colors array) | -✗ | -✗ | -✗ | -✓ | +✗ | +✗ | +✗ | +✓ | |
| drawPicture() | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
| drawPosText() | -✗ | -✓ | -✓ | -✓ | +✗ | +✓ | +✓ | +✓ | |
| drawTextOnPath() | -✗ | -✓ | -✓ | -✓ | +✗ | +✓ | +✓ | +✓ | |
| drawVertices() | -✗ | -✗ | -✗ | -✗ | +✗ | +✗ | +✗ | +✗ | |
| setDrawFilter() | -✗ | -✓ | -✓ | -✓ | +✗ | +✓ | +✓ | +✓ | +|
| clipPath() | +✗ | +✗ | +✗ | +✓ | +|||||
| clipRegion() | +✗ | +✗ | +✗ | +✓ | +|||||
| clipRect(Region.Op.XOR) | +✗ | +✗ | +✗ | +✓ | +|||||
| clipRect(Region.Op.Difference) | +✗ | +✗ | +✗ | +✓ | +|||||
| 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 | -✗ | -✗ | -✗ | -✓ | +✗ | +✗ | +✗ | +✓ | |
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 acceleratin everywhere else. See Controlling Hardware Acceleration for more information on how to enable and -disable hardware acceleration at different levels in your application. - - + 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.