Detecting and Fixing Overdraw

Fortunately, we can detect overdraws in android phones by selecting “Show overdraw areas” in “Debug GPU overdraw” under “Developer options” in phone settings.

The debug GPU overdraw tool colors the screen with red, green, blue; Red being the areas with highest overdraw and blue being the least overdraw regions of the screen.

In the screenshot attached, I have two LinearLayout vertically oriented. The first LinearLayout has unneeded backgrounds on a few widgets like EditText and ImageView and also on the layout. All the red areas in the image suggests that the views are redrawn on one top of another, therefore contributing to overdraw.

An example of Views being overdrawn

Let’s take a look at the first LinearLayout and figure out what’s wrong.

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/white">



<LinearLayout

android:id="@+id/unwanted_background_layout"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@color/white"

android:orientation="vertical"

android:padding="@dimen/button_margin">



<TextView

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@color/grey"

android:padding="8dp"

android:text="@string/layout_with_unwanted_backgrounds"

android:textSize="17sp" />



<ImageView

android:id="@+id/image_view"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_gravity="center"

android:layout_marginTop="8dp"

android:src="@mipmap/ic_launcher_round" />



<EditText

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_marginTop="8dp"

android:inputType="text"

android:padding="16dp" />



</LinearLayout> <LinearLayout

....

android:id="@+id/fixed_background_layout"

....>

....

</LinearLayout> </LinearLayout>

The XML code in bold shows the obvious mistake.

We have declared background colors for each children in the first LinearLayout ViewGroup. We have also set a background color in the parent ViewGroup. Note that setting the background color to the View adds to Overdraw and doesn’t depend on which color is used. Overdraw occurs for same colors and differnt colors too.

First the topmost LinearLayout is drawn on the screen. The background is set to white. The child LinearLayout is drawn next which also have a background color white. The system at this point doesn’t know that the color is the same as before. All it knows is there is new color and the pixels are redrawn again with the new color. The child TextView and ImageView have backgrounds set to each of them which makes the sytem to redraw pixels with new colors. Drawing and redrawing the same pixels wastes GPU cycles. Redrawing on the same pixels with same data that was previously there will prove to be costly for rendering performance.

How do we reduce overdraw and improve performance?

We know that the same color is drawn a multiple times in child views. Let’s get rid of that first as it is not a design constraint.

<LinearLayout

android:id=”@+id/fixed_background_layout”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:orientation=”vertical”

android:padding=”@dimen/button_margin”>

Getting rid of the white background on the child LinearLayout shows a lot less overdraw -

Reduced overdraw shown by less red marks

If the design allows, you could even remove the background for the TextView and improve the performance.

The red marks are invisible suggesting that there’s very less or nil overdraw. This view is more faster to render by the GPU, less time consumed and helps overall user experience to be much more smoother and faster.

To increase performance even further, use flat layouts as much as possible. Nesting several instances of Views can be very expensive as the children Views should be measured twice. Since, this is out of scope of this story, you can research on Optimizing Layout Hierarchies in the official Android Developers website.