diff options
| author | 2013-04-19 16:07:23 -0700 | |
|---|---|---|
| committer | 2013-04-19 18:19:31 -0700 | |
| commit | 0f7ade766678779182f66bdbc6e85d09df4c791f (patch) | |
| tree | 75e633a4d9cfef6dbebbf4f25da5f060446ef6a0 | |
| parent | 5584737fff6350ab09fb53e6a73bbff770930727 (diff) | |
Expand hardware accel doc
bug:8321992
Adds information to Unsupported Drawing Operations, and updates intro
Change-Id: I2b61a70f86f2d1a6ee50c06902f9af4ce0dc6da4
| -rw-r--r-- | docs/html/guide/topics/graphics/hardware-accel.jd | 437 |
1 files changed, 256 insertions, 181 deletions
diff --git a/docs/html/guide/topics/graphics/hardware-accel.jd b/docs/html/guide/topics/graphics/hardware-accel.jd index 9859c2840136..8ba6676bf11c 100644 --- a/docs/html/guide/topics/graphics/hardware-accel.jd +++ b/docs/html/guide/topics/graphics/hardware-accel.jd @@ -47,35 +47,24 @@ parent.link=index.html </div> </div> - <p>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.</p> - - <p>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:</p> - - <ul> - <li>Application</li> - - <li>Activity</li> - - <li>Window</li> - - <li>View</li> - </ul> - - <p>If your application performs custom drawing, test your application on actual hardware -devices with hardware acceleration turned on to find any problems. The <a -href="#drawing-support">Unsupported drawing operations</a> section describes known issues with -drawing operations that cannot be hardware accelerated and how to work around them.</p> - + <p>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.</p> + + <p>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 <a href="#controlling">Controlling Hardware Acceleration</a>.</p> + + <p>If your application performs custom drawing, test your application on actual hardware devices + with hardware acceleration turned on to find any problems. The <a + href="#drawing-support">Unsupported drawing operations</a> section describes known issues with + hardware acceleration and how to work around them.</p> <h2 id="controlling">Controlling Hardware Acceleration</h2> <p>You can control hardware acceleration at the following levels:</p> @@ -100,12 +89,12 @@ drawing operations that cannot be hardware accelerated and how to work around th </pre> <h4>Activity level</h4> - <p>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 <code>android:hardwareAccelerated</code> - attribute for the <a href="{@docRoot}guide/topics/manifest/activity-element.html"> - <code><activity></code></a> element. The following example enables hardware acceleration -for the entire application but disables it for one activity:</p> + <p>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 <code>android:hardwareAccelerated</code> attribute for + the <a href="{@docRoot}guide/topics/manifest/activity-element.html"> + <code><activity></code></a> element. The following example enables hardware acceleration for + the entire application but disables it for one activity:</p> <pre> <application android:hardwareAccelerated="true"> @@ -228,8 +217,7 @@ changed.</li> <p>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.</p> + to do so causes a view to look the same even after it has been changed.</p> <p>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.</li> <p>The following table describes the support level of various operations across API levels:</p> <style type="text/css"> - .tblGenFixed,.tblGeneric{font-size:15px}.tblGenFixed td {padding:0 3px;letter-spacing:0;word-spacing:0;background-color:#fff;z-index:1;border-top:0px none;border-left:0px none;border-bottom:1px solid #CCC;border-right:1px solid #CCC;} .dn {display:none} .tblGenFixed td.s0 {background-color:white;border-top:1px solid #CCC;border-left:1px solid #CCC;} .tblGenFixed td.s2 {background-color:#d9d9d9;color:#000000;text-align:center;} .tblGenFixed td.s1 {background-color:#434343;color:#ffffff;text-align:center;border-top:1px solid #CCC;} .tblGenFixed td.s9 {background-color:;color:#6aa84f;text-align:center;} .tblGenFixed td.s12 {background-color:white;color:#6aa84f;text-align:center;} .tblGenFixed td.s13 {background-color:#d9d9d9;color:#6aa84f;text-align:center;} .tblGenFixed td.s7 {background-color:#d9d9d9;color:#980000;text-align:center;} .tblGenFixed td.s8 {background-color:;color:#980000;text-align:center;} .tblGenFixed td.s5 {background-color:#434343;color:#ffffff;text-align:left;border-left:1px solid #CCC;} .tblGenFixed td.s6 {background-color:;font-family:courier new,monospace;color:;text-align:right;border-left:1px solid #CCC;} .tblGenFixed td.s10 {background-color:white;font-family:courier new,monospace;color:#000000;text-align:right;border-left:1px solid #CCC;} .tblGenFixed td.s3 {background-color:white;color:#000000;text-align:center;} .tblGenFixed td.s11 {background-color:white;color:#980000;text-align:center;} .tblGenFixed td.s4 {background-color:#d9d9d9;color:#000000;text-align:center;} + .tblGenFixed, .tblGeneric{font-size:15px}.tblGenFixed td {padding:0 3px;letter-spacing:0;word-spacing:0;background-color:#fff;z-index:1;border-top:0px none;border-left:0px none;border-bottom:1px solid #CCC;border-right:1px solid #CCC;} .dn {display:none} .tblGenFixed td.s0 {background-color:white;border-top:1px solid #CCC;border-left:1px solid #CCC;} .tblGenFixed td.s1 {background-color:#434343;color:#ffffff;text-align:center;border-top:1px solid #CCC;} .tblGenFixed td.s2 {background-color:#d9d9d9;color:#000000;text-align:center;} .tblGenFixed td.s3 {background-color:white;color:#000000;text-align:center;} .tblGenFixed td.s5 {background-color:#434343;color:#ffffff;text-align:left;border-left:1px solid #CCC;} .tblGenFixed td.s10 {background-color:white;font-family:courier new,monospace;color:#000000;text-align:right;border-left:1px solid #CCC;} .tblGenFixed td.g_pos {background-color:#d9d9d9;color:#6aa84f;text-align:center;} .tblGenFixed td.g_neg {background-color:#d9d9d9;color:#980000;text-align:center;} .tblGenFixed td.w_pos {background-color:white;color:#6aa84f;text-align:center;} .tblGenFixed td.w_neg {background-color:white;color:#980000;text-align:center;} </style> <table border="0" cellpadding="0" cellspacing="0" class="tblGenFixed" id="tblMain"> <tbody> @@ -294,242 +282,329 @@ changed.</li> <td style="display:none;"></td> <td class="s2">< 16</td> <td class="s3">16</td> - <td class="s4">17</td> + <td class="s2">17</td> <td class="s3">18</td> </tr> <tr> <td colspan="5" class="s5">Canvas</td> </tr> <tr> - <td class="s6">clipPath()</td> - <td class="s7">✗</td> - <td class="s8">✗</td> - <td class="s7">✗</td> - <td class="s9">✓</td> + <td class="s10">drawBitmapMesh() (colors array)</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">clipRegion()</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s12">✓</td> + <td class="s10">drawPicture()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> - <td class="s10">clipRect(Region.Op.XOR)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s12">✓</td> + <td class="s10">drawPosText()</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> + <td class="g_pos">✓</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">clipRect(Region.Op.Difference)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s12">✓</td> + <td class="s10">drawTextOnPath()</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> + <td class="g_pos">✓</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">clipRect(Region.Op.ReverseDifference)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s12">✓</td> + <td class="s10">drawVertices()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> - <td class="s10">drawBitmapMesh() (colors array)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s12">✓</td> + <td class="s10">setDrawFilter()</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> + <td class="g_pos">✓</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">drawPicture()</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="s10">clipPath()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">drawPosText()</td> - <td class="s7">✗</td> - <td class="s12">✓</td> - <td class="s13">✓</td> - <td class="s12">✓</td> + <td class="s10">clipRegion()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">drawTextOnPath()</td> - <td class="s7">✗</td> - <td class="s12">✓</td> - <td class="s13">✓</td> - <td class="s12">✓</td> + <td class="s10">clipRect(Region.Op.XOR)</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">drawVertices()</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="s10">clipRect(Region.Op.Difference)</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s10">setDrawFilter()</td> - <td class="s7">✗</td> - <td class="s12">✓</td> - <td class="s13">✓</td> - <td class="s12">✓</td> + <td class="s10">clipRect(Region.Op.ReverseDifference)</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> + </tr> + <tr> + <td class="s10">clipRect() with rotation/perspective</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> <td colspan="5" class="s5">Paint</td> </tr> <tr> - <td class="s6">setAntiAlias() (for text)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s12">✓</td> + <td class="s10">setAntiAlias() (for text)</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s6">setAntiAlias() (for lines)</td> - <td class="s7">✗</td> - <td class="s12">✓</td> - <td class="s13">✓</td> - <td class="s12">✓</td> + <td class="s10">setAntiAlias() (for lines)</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> + <td class="g_pos">✓</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s6">setFilterBitmap()</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s13">✓</td> - <td class="s12">✓</td> + <td class="s10">setFilterBitmap()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_pos">✓</td> + <td class="w_pos">✓</td> </tr> <tr> - <td class="s6">setLinearText()</td> - <td class="s7">✗</td> - <td class="s8">✗</td> - <td class="s7">✗</td> - <td class="s8">✗</td> + <td class="s10">setLinearText()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">setMaskFilter()</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">setPathEffect() (for lines)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">setRasterizer()</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">setShadowLayer() (other than text)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">setStrokeCap() (for lines)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s12">✓</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> <tr> <td class="s10">setStrokeCap() (for points)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">setSubpixelText()</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td colspan="5" class="s5">Xfermode</td> </tr> <tr> - <td class="s6">AvoidXfermode</td> - <td class="s7">✗</td> - <td class="s8">✗</td> - <td class="s7">✗</td> - <td class="s8">✗</td> + <td class="s10">AvoidXfermode</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">PixelXorXfermode</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">PorterDuff.Mode.DARKEN (framebuffer)</td> - <td class="s7">✗</td> - <td class="s8">✗</td> - <td class="s7">✗</td> - <td class="s8">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">PorterDuff.Mode.LIGHTEN (framebuffer)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">PorterDuff.Mode.OVERLAY (framebuffer)</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td colspan="5" class="s5">Shader</td> </tr> <tr> <td class="s10">ComposeShader inside ComposeShader</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">Same type shaders inside ComposeShader</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> </tr> <tr> <td class="s10">Local matrix on ComposeShader</td> - <td class="s7">✗</td> - <td class="s11">✗</td> - <td class="s7">✗</td> - <td class="s11">✓</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> </tr> </tbody> </table> - <p>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 <a -href="#controlling">Controlling Hardware Acceleration</a> for more information on how to enable and -disable hardware acceleration at different levels in your application. + <h3 id="scaling">Canvas Scaling</h3> + + <p>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.</p> + + The following table shows when implementation was changed to correctly handle large scales: + <table border="0" cellpadding="0" cellspacing="0" class="tblGenFixed" id="tblMain"> + <tbody> + <tr class="rShim"> + <td class="rShim" style="width:380px;"></td> + <td class="rShim" style="width:120px;"></td> + <td class="rShim" style="width:120px;"></td> + <td class="rShim" style="width:120px;"></td> + </tr> + <tr> + <td rowspan="2" class="s0"></td> + <td colspan="4" class="s1">API level</td> + </tr> + <tr> + <td style="display:none;"></td> + <td class="s2">< 17</td> + <td class="s3">17</td> + <td class="s2">18</td> + </tr> + <tr> + <td colspan="5" class="s5">Support for large scale factors</td> + </tr> + <tr> + <td class="s10">drawText()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_pos">✓</td> + </tr> + <tr> + <td class="s10">drawPosText()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + </tr> + <tr> + <td class="s10">drawTextOnPath()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + </tr> + <tr> + <td class="s10">Simple Shapes*</td> + <td class="g_neg">✗</td> + <td class="w_pos">✓</td> + <td class="g_pos">✓</td> + </tr> + <tr> + <td class="s10">Complex Shapes*</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + </tr> + <tr> + <td class="s10">drawPath()</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + </tr> + <tr> + <td class="s10">Shadow layer</td> + <td class="g_neg">✗</td> + <td class="w_neg">✗</td> + <td class="g_neg">✗</td> + </tr> + </tbody> + </table> + <p class="note"><strong>Note</strong>: 'Simple' shapes are <code>drawRect()</code>, + <code>drawCircle()</code>, <code>drawOval()</code>, <code>drawRoundRect()</code>, and + <code>drawArc()</code> (with useCenter=false) commands issued with a Paint that doesn't have a + PathEffect, and doesn't contain non-default joins (via <code>setStrokeJoin()</code> / + <code>setStrokeMiter()</code>). Other instances of those draw commands fall under 'Complex,' in + the above chart.</p> + + <p>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 <a + href="#controlling">Controlling Hardware Acceleration</a> for more information on how to enable + and disable hardware acceleration at different levels in your application. <h2 id="layers">View Layers</h2> |