Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f20081f authored by Chet Haase's avatar Chet Haase
Browse files

Avoid redundant wallpaper loading/drawing

Switching users causes wallpapers to get recreated 3 times. Other operations
like startup and rotation cause similar redundant load/draw operations. This change
tracks the various attributes that tell us when we really need to reload
and redraw, causing only one of these expensive operation per one of these
switches.

Issue #7334664 Wallpaper draws several times when switching users

Change-Id: Ic3072ef3a7eaf622d8632e87e34f50999f716c39
parent a3d5b688
Loading
Loading
Loading
Loading
+53 −50
Original line number Diff line number Diff line
@@ -31,8 +31,10 @@ import android.os.SystemProperties;
import android.renderscript.Matrix4f;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.WindowManager;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
@@ -108,6 +110,7 @@ public class ImageWallpaper extends WallpaperService {

        Bitmap mBackground;
        int mBackgroundWidth = -1, mBackgroundHeight = -1;
        int mLastRotation = -1;
        float mXOffset;
        float mYOffset;

@@ -156,7 +159,7 @@ public class ImageWallpaper extends WallpaperService {
                    mBackgroundWidth = mBackgroundHeight = -1;
                    mBackground = null;
                    mRedrawNeeded = true;
                    drawFrameLocked(false);
                    drawFrameLocked();
                }
            }
        }
@@ -225,7 +228,7 @@ public class ImageWallpaper extends WallpaperService {
        @Override
        public void onVisibilityChanged(boolean visible) {
            if (DEBUG) {
                Log.d(TAG, "onVisibilityChanged: visible=" + visible);
                Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible);
            }

            synchronized (mLock) {
@@ -234,7 +237,7 @@ public class ImageWallpaper extends WallpaperService {
                        Log.d(TAG, "Visibility changed to visible=" + visible);
                    }
                    mVisible = visible;
                    drawFrameLocked(false);
                    drawFrameLocked();
                }
            }
        }
@@ -263,7 +266,7 @@ public class ImageWallpaper extends WallpaperService {
                    mYOffset = yOffset;
                    mOffsetsChanged = true;
                }
                drawFrameLocked(false);
                drawFrameLocked();
            }
        }

@@ -276,80 +279,81 @@ public class ImageWallpaper extends WallpaperService {
            super.onSurfaceChanged(holder, format, width, height);

            synchronized (mLock) {
                mRedrawNeeded = true;
                drawFrameLocked();
            }
        }

        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mBackgroundWidth = mBackgroundHeight = -1;
                drawFrameLocked(true);
        }

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
            mBackgroundWidth = mBackgroundHeight = -1;
        }

        @Override
        public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
            if (DEBUG) {
                Log.d(TAG, "onSurfaceRedrawNeeded:");
                Log.d(TAG, "onSurfaceRedrawNeeded");
            }
            super.onSurfaceRedrawNeeded(holder);

            synchronized (mLock) {
                mRedrawNeeded = true;
                drawFrameLocked(false);
                drawFrameLocked();
            }
        }

        void drawFrameLocked(boolean force) {
            if (!force) {
                if (!mVisible) {
                    if (DEBUG) {
                        Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible.");
                    }
                    return;
                }
                if (!mRedrawNeeded && !mOffsetsChanged) {
        void drawFrameLocked() {
            SurfaceHolder sh = getSurfaceHolder();
            final Rect frame = sh.getSurfaceFrame();
            final int dw = frame.width();
            final int dh = frame.height();
            int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)).
                    getDefaultDisplay().getRotation();

            boolean redrawNeeded = dw != mBackgroundWidth || dh != mBackgroundHeight ||
                    newRotation != mLastRotation;
            if (!redrawNeeded && !mOffsetsChanged) {
                if (DEBUG) {
                    Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
                            + "and offsets have not changed.");
                }
                return;
            }
            }
            // If we don't yet know the size of the wallpaper bitmap,
            // we need to get it now.
            boolean updateWallpaper = mBackgroundWidth < 0 || mBackgroundHeight < 0 ;

            // If we somehow got to this point after we have last flushed
            // the wallpaper, well we really need it to draw again.  So
            // seems like we need to reload it.  Ouch.
            updateWallpaper = updateWallpaper || mBackground == null;
            mLastRotation = newRotation;

            if (updateWallpaper) {
            // Load bitmap if it is not yet loaded or if it was loaded at a different size
            if (mBackground == null || dw != mBackgroundWidth || dw != mBackgroundHeight) {
                if (DEBUG) {
                    Log.d(TAG, "Reloading bitmap");
                }
                mWallpaperManager.forgetLoadedWallpaper();
                updateWallpaperLocked();
            }

            SurfaceHolder sh = getSurfaceHolder();
            final Rect frame = sh.getSurfaceFrame();
            final int dw = frame.width();
            final int dh = frame.height();
            final int availw = dw - mBackgroundWidth;
            final int availh = dh - mBackgroundHeight;
            int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2);
            int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);

            mOffsetsChanged = false;
            if (!force && !mRedrawNeeded
                    && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
            mRedrawNeeded = false;
            mLastXTranslation = xPixels;
            mLastYTranslation = yPixels;
            if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
                if (DEBUG) {
                    Log.d(TAG, "Suppressed drawFrame since the image has not "
                            + "actually moved an integral number of pixels.");
                }
                return;
            }
            mRedrawNeeded = false;
            mLastXTranslation = xPixels;
            mLastYTranslation = yPixels;

            if (DEBUG) {
                Log.d(TAG, "drawFrameUnlocked(" + force + "): mBackgroundWxH=" + mBackgroundWidth + "x"
                        + mBackgroundHeight + " SurfaceFrame=" + frame.toShortString()
                        + " X,YOffset=" + mXOffset + "," + mYOffset);
                Log.d(TAG, "Redrawing wallpaper");
            }
            if (mIsHwAccelerated) {
                if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
@@ -429,7 +433,6 @@ public class ImageWallpaper extends WallpaperService {
            final float bottom = top + mBackgroundHeight;

            final Rect frame = sh.getSurfaceFrame();

            final Matrix4f ortho = new Matrix4f();
            ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f);