Home | History | Annotate | Download | only in rendering
      1 page.title=Reducing Overdraw
      2 page.metaDescription=Improve performance by reducing unnecessary rendering.
      3 
      4 meta.tags="performance"
      5 page.tags="performance"
      6 
      7 @jd:body
      8 
      9 <div id="qv-wrapper">
     10 <div id="qv">
     11 
     12 <h2>In this document</h2>
     13     <ol>
     14 
     15       <li>
     16         <a href="#understanding">Understanding Overdraw</a>
     17       </li>
     18       <li>
     19         <a href="#finding">Finding Overdraw Problems</a>
     20       </li>
     21       <li>
     22         <a href="#fixing">Fixing Overdraw</a>
     23       </li>
     24     </ol>
     25   </div>
     26 </div>
     27 
     28 <p>
     29 An app may draw the same pixel more than once within a single frame, an event
     30 called <em>overdraw</em>. Overdraw is usually unnecessary, and best
     31 eliminated. It manifests itself as a performance problem by wasting GPU time to
     32 render pixels that don't contribute to what the user sees on the screen.
     33 </p>
     34 
     35 <p>
     36 This document explains overdraw: what it is, how to diagnose it, and actions you
     37 can take to eliminate or mitigate it.
     38 </p>
     39 
     40 <h2 name="understanding">Understanding Overdraw</h2>
     41 
     42 <p>
     43 Overdraw refers to the system's drawing a pixel on the screen multiple times
     44 in a single frame of rendering. For example, if we have a bunch of stacked UI
     45 cards, each card hides a portion of the one below it.
     46 </p>
     47 
     48 <p>
     49 However, the system still needs to draw even the hidden portions of the cards
     50 in the stack. This is because stacked cards are rendered according to the
     51 <a class="external-link"
     52 href="https://en.wikipedia.org/wiki/Painter%27s_algorithm">painter's
     53 algorithm</a>: that is, in back-to-front order.
     54 This sequence of rendering allows the system to apply proper alpha blending to
     55 translucent objects such as shadows.
     56 </p>
     57 
     58 <h2 name="finding">Finding Overdraw Problems</h2>
     59 
     60 <p>
     61 The platform offers several tools to help you determine if overdraw is
     62 affecting your app's performance. These tools are available right on the device,
     63 and accessible by turning on <strong>Developer Settings</strong></a> under
     64 <em>Settings</em>. For more information about device developer settings, see
     65 <a href="/studio/run/device.html#developer-device-options">Run Apps on a
     66 Hardware Device</a>.
     67 </p>
     68 
     69 <h3 id="dgot">Debug GPU overdraw tool</h3>
     70 
     71 <p>
     72 The Debug GPU Overdraw tool uses color-coding to show the number of times your
     73 app draws each pixel on the screen. The higher this count, the
     74 more likely it is that overdraw affects your app's performance.
     75 </p>
     76 
     77 <p>
     78 For more information on how to use the tool, refer to the related
     79 <a href="/studio/profile/dev-options-overdraw.html">walkthrough</a>
     80 and
     81 <a href="https://io2015codelabs.appspot.com/codelabs/android-performance-debug-gpu-overdraw#1">
     82 codelab</a>.
     83 </p>
     84 
     85 <h3 id="pgrt">Profile GPU rendering tool</h3>
     86 
     87 <p>
     88 The Profile GPU Rendering tool displays, as a scrolling histogram, the time
     89 each stage of the rendering pipeline takes to display a single frame. The
     90 <em>Process</em> part of each bar, indicated in orange, shows when the system
     91 is swapping buffers; this metric provides important clues about overdraw.
     92 </p>
     93 
     94 <p>
     95 On less performant GPUs, available fill-rate (the speed at which the GPU can
     96 fill the frame buffer) can be quite low. As the number of
     97 pixels required to draw a frame increases, the GPU may take longer to process
     98 new commands, and ask the rest of the system to wait until it can catch up.
     99 The <em>Process</em> bar shows that this spike happens as the GPU gets
    100 overwhelmed trying to draw pixels as fast as possible. Issues other than
    101 raw numbers of pixels may also cause this metric to spike. For example,
    102 if the Debug GPU Overdraw tool shows heavy overdraw and <em>Process</em> spikes,
    103 there's likely an issue with overdraw.
    104 </p>
    105 
    106 <p class="note"><strong>Note: </strong>The
    107 <a href="https://developer.android.com/studio/profile/dev-options-rendering.html">
    108 Profile GPU Rendering</a> tool does not
    109 work with apps that use the NDK. This is because the system pushes framework
    110 messages to the background whenever OpenGL takes a full-screen context. In
    111 such cases, you may find a profiling tool provided by the GPU manufacturer
    112 helpful.</p>
    113 
    114 <h2 name="fixing">Fixing Overdraw</h2>
    115 
    116 <p>
    117 There are several strategies you can pursue to reduce or eliminate overdraw:
    118 </p>
    119 
    120 <ul>
    121    <li>Removing unneeded backgrounds in layouts.</li>
    122    <li>Flattening the view hierarchy.</li>
    123    <li>Reducing transparency.</li>
    124 </ul>
    125 
    126 <p>
    127 This section provides information about each of these approaches.
    128 </p>
    129 
    130 <h3 id="rubil">Removing unneeded backgrounds in layouts</h3>
    131 
    132 <p>
    133 By default, a layout does not have a background, which means it does not render
    134 anything directly by itself. When layouts do have backgrounds, however, they may
    135 contribute to overdraw.
    136 </p>
    137 
    138 <p>
    139 Removing unnecessary backgrounds is a quick way of improving rendering
    140 performance. An unnecessary background may never be visible because it's
    141 completely covered by everything else the app is drawing on top of that
    142 view. For example, the system may entirely cover up a parent's
    143 background when it draws child views on top of it.
    144 </p>
    145 
    146 <p>
    147 To find out why you're overdrawing, walk through the hierarchy in
    148 the <a href="/studio/profile/hierarchy-viewer.html">Hierarchy Viewer</a> tool.
    149 As you do so, look out for any backgrounds you can eliminate because
    150 they are not visible to the user. Cases where many containers share a
    151 common background color offer another opportunity to eliminate unneeded
    152 backgrounds: You can set the window background to the main background color
    153 of your app, and leave all of the containers above it with no background values
    154 defined.
    155 </p>
    156 
    157 <h3 id="fvh">Flattening view hierarchy</h3>
    158 
    159 <p>
    160 Modern layouts make it easy to stack and layer views to produce beautiful
    161 design. However, doing so can degrade performance by resulting in overdraw,
    162 especially in scenarios where each stacked view object is opaque, requiring the
    163 drawing of both seen and unseen pixels to the screen.
    164 </p>
    165 
    166 <p>
    167 If you encounter this sort of issue, you may be able to improve performance by
    168 optimizing your view hierarchy to reduce the number of overlapping UI objects.
    169 For more information about how to accomplish this, see
    170 <a href="/topic/performance/optimizing-view-hierarchies.html">Optimizing View
    171 Hierarchies</a>.
    172 </p>
    173 
    174 <h3 id="rt">Reducing transparency</h3>
    175 
    176 <p>
    177 Rendering of transparent pixels on screen, known as alpha rendering, is a key
    178 contributor to overdraw. Unlike standard overdraw,
    179 in which the system completely hides existing drawn pixels by drawing
    180 opaque pixels on top of them, transparent
    181 objects require existing pixels to be drawn first, so that the right blending
    182 equation can occur.  Visual effects like transparent animations, fade-outs, and
    183 drop shadows all involve some sort of transparency, and can therefore contribute
    184 significantly to overdraw. You can improve overdraw in these situations by
    185 reducing the number of transparent objects you render. For example, you can get
    186 gray text by drawing black text in a {@link android.widget.TextView} with a
    187 translucent alpha value set on it. But you can get the same effect with far
    188 better performance by simply drawing the text in gray.
    189 </p>
    190 
    191 <p>
    192 To learn more about performance costs that transparency imposes throughout the
    193 entire drawing pipeline, watch the video
    194 <a href="https://www.youtube.com/watch?v=wIy8g8yNhNk&index=46&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">
    195 Hidden Costs of Transparency</a>.
    196 </p>
    197 
    198