17

In order to improve app performance, I encounter GPU Overdraw problem. According to Romain Guy's Article, here are the basic Colors:


  • No color means there is no overdraw. The pixel was painted only once. In this example, you can see that the background is intact.

  • Blue indicates an overdraw of 1x. The pixel was painted twice. Large blue areas are acceptable (if the entire window is blue, you can get rid of one layer.)

  • Green indicates an overdraw of 2x. The pixel was painted three times. Medium-sized green areas are acceptable but you should try to optimize them away.

  • Light red indicates an overdraw of 3x. The pixel was painted four times. Small light red areas are acceptable.

  • Dark red indicates an overdraw of 4x or more. The pixel was painted 5 times or more. This is wrong. Fix it.`


To Test that, I create a simple project with XML as follows

XML Code

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"

    android:layout_margin="50dp"
    android:background="#fff">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"/>

</RelativeLayout>

and get result:
n00b Me

Then I tried Whatsapp's overdraw. To my suprise:
Awesome Whatsapp

So How Whatsapp is drawing background wallpaper with no overdraw (no blue tint) but in my simple xml, even coloring gives one overdraw??

PS: I have intentionally added background color to show that adding color gives overdraw but adding wallpaper doesn't

Community
  • 1
  • 1
Aexyn
  • 1,212
  • 2
  • 13
  • 30

3 Answers3

31

Every Activity has a default background Drawable coming from the Theme's android:windowBackground attribute.

WhatsApp is using a background image which can be repeated in both directions in order to fill up the whole screen. This way they don't need to hassle around with different images for different screen sizes - it's super responsive!

So let's say you have such a tiled image (e.g. drawable-nodpi/background_tile.png)

Just create a new xml Drawable (e.g. drawable/background.xml) which looks like this:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/background_tile"
    android:tileMode="repeat" />

Now simply set this Drawable as a background for your Activity's Theme:

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <item name="android:windowBackground">@drawable/background</item>
</style>

You can also set the background Drawable of an Activity at runtime with getWindow().setBackgroundDrawable or getWindow().setBackgroundDrawableResource

You can also set the background Drawable to null, for example if the whole Activity shows a MapView or something similar.

Also note that the Zygote will use the Theme's background Drawable during the app startup phase if the Activity is your main launcher Activity.

astuetz
  • 2,693
  • 2
  • 23
  • 22
3

Applying Bill Gates's hint, it turns out setting background in styles.xml in app actually saves one overdraw. This code saves one overDraw

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="android:windowBackground">@color/highlighted_text_material_dark</item>
    </style>

</resources>

Now Adding background doesn't take any overDraw so Relative Layout is Still One overDraw

BackGround with no OverDraw

UPDATE The Above method Works, and is good if you want same color background for all of your app. But in case you want different colors and still wanna save OverDraw, replace above line with

<item name="android:windowBackground">@null</item>

One Step Further
Boom.. You are good to go..

TIP: If your app has black color as background.. go for it save one more overdraw ;)

Community
  • 1
  • 1
Aexyn
  • 1,212
  • 2
  • 13
  • 30
  • 2
    I wouldn't recommend setting the windowBackground to @null if the root view of the layout doesn't have a solid background, as it doesn't set the background of the Activity to black. Instead, it will be "nothing" then, which can cause a lot of weird artifacts as soon as you animate or move around Views. – astuetz Apr 22 '15 at 14:40
  • "Instead, set it to the color/image you want or get rid of from onCreate() by calling getWindow().setBackgroundDrawable(null)", not in the theme for the root activity – superuser May 11 '16 at 06:51
1

I think the one overdraw you have is the background of your RelativeLayout. You can remove that android:background="#fff" the background will be once drawn depending upon the app theme.

null pointer
  • 5,874
  • 4
  • 36
  • 66
  • I have intentionally added background color to show that adding color gives overdraw but adding wallpaper doesn't – Aexyn Apr 22 '15 at 13:22
  • its just a wild guess may be my making the background of activity as transparent in theme we can reduce one overdraw. – null pointer Apr 22 '15 at 13:35