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

Commit c0a94341 authored by Ahan Wu's avatar Ahan Wu Committed by android-build-merger
Browse files

Merge "Move image wallpaper rendering works to background thread." into qt-dev

am: 84ed5df8

Change-Id: Ie45506fe06d6fa5fba4563c2774a08ac8b5732d1
parents 4f7a7290 84ed5df8
Loading
Loading
Loading
Loading
+61 −28
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.HandlerThread;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.util.Size;
@@ -45,12 +46,27 @@ public class ImageWallpaper extends WallpaperService {
    // We delayed destroy render context that subsequent render requests have chance to cancel it.
    // This is to avoid destroying then recreating render context in a very short time.
    private static final int DELAY_FINISH_RENDERING = 1000;
    private HandlerThread mWorker;

    @Override
    public void onCreate() {
        super.onCreate();
        mWorker = new HandlerThread(TAG);
        mWorker.start();
    }

    @Override
    public Engine onCreateEngine() {
        return new GLEngine(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mWorker.quitSafely();
        mWorker = null;
    }

    class GLEngine extends Engine implements GLWallpaperRenderer.SurfaceProxy, StateListener {
        // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
        // set min to 64 px (CTS covers this), please refer to ag/4867989 for detail.
@@ -98,13 +114,14 @@ public class ImageWallpaper extends WallpaperService {
        @Override
        public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
                float yOffsetStep, int xPixelOffset, int yPixelOffset) {
            mRenderer.updateOffsets(xOffset, yOffset);
            mWorker.getThreadHandler().post(() -> mRenderer.updateOffsets(xOffset, yOffset));
        }

        @Override
        public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
            mRenderer.updateAmbientMode(inAmbientMode,
                    (mNeedTransition || animationDuration != 0) ? animationDuration : 0);
            long duration = mNeedTransition || animationDuration != 0 ? animationDuration : 0;
            mWorker.getThreadHandler().post(
                    () -> mRenderer.updateAmbientMode(inAmbientMode, duration));
        }

        @Override
@@ -113,53 +130,61 @@ public class ImageWallpaper extends WallpaperService {
                mController.removeCallback(this /* StateListener */);
            }
            mController = null;

            mWorker.getThreadHandler().post(() -> {
                mRenderer.finish();
                mRenderer = null;
                mEglHelper.finish();
                mEglHelper = null;
                getSurfaceHolder().getSurface().hwuiDestroy();
            });
        }

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            mWorker.getThreadHandler().post(() -> {
                mEglHelper.init(holder);
                mRenderer.onSurfaceCreated();
            });
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            mWorker.getThreadHandler().post(() -> {
                mRenderer.onSurfaceChanged(width, height);
                mNeedRedraw = true;
            });
        }

        @Override
        public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
            mWorker.getThreadHandler().post(() -> {
                if (mNeedRedraw) {
                    preRender();
                    requestRender();
                    postRender();
                    mNeedRedraw = false;
                }
        }

        @Override
        public SurfaceHolder getHolder() {
            return getSurfaceHolder();
            });
        }

        @Override
        public void onStatePostChange() {
            // When back to home, we try to release EGL, which is preserved in lock screen or aod.
            if (mController.getState() == StatusBarState.SHADE) {
                scheduleFinishRendering();
                mWorker.getThreadHandler().post(this::scheduleFinishRendering);
            }
        }

        @Override
        public void preRender() {
            mWorker.getThreadHandler().post(this::preRenderInternal);
        }

        private void preRenderInternal() {
            boolean contextRecreated = false;
            Rect frame = getSurfaceHolder().getSurfaceFrame();
            getMainThreadHandler().removeCallbacks(mFinishRenderingTask);
            cancelFinishRenderingTask();

            // Check if we need to recreate egl context.
            if (!mEglHelper.hasEglContext()) {
@@ -187,6 +212,10 @@ public class ImageWallpaper extends WallpaperService {

        @Override
        public void requestRender() {
            mWorker.getThreadHandler().post(this::requestRenderInternal);
        }

        private void requestRenderInternal() {
            Rect frame = getSurfaceHolder().getSurfaceFrame();
            boolean readyToRender = mEglHelper.hasEglContext() && mEglHelper.hasEglSurface()
                    && frame.width() > 0 && frame.height() > 0;
@@ -205,12 +234,16 @@ public class ImageWallpaper extends WallpaperService {

        @Override
        public void postRender() {
            scheduleFinishRendering();
            mWorker.getThreadHandler().post(this::scheduleFinishRendering);
        }

        private void cancelFinishRenderingTask() {
            mWorker.getThreadHandler().removeCallbacks(mFinishRenderingTask);
        }

        private void scheduleFinishRendering() {
            getMainThreadHandler().removeCallbacks(mFinishRenderingTask);
            getMainThreadHandler().postDelayed(mFinishRenderingTask, DELAY_FINISH_RENDERING);
            cancelFinishRenderingTask();
            mWorker.getThreadHandler().postDelayed(mFinishRenderingTask, DELAY_FINISH_RENDERING);
        }

        private void finishRendering() {
+5 −1
Original line number Diff line number Diff line
@@ -60,6 +60,9 @@ import java.io.PrintWriter;
 */
public class EglHelper {
    private static final String TAG = EglHelper.class.getSimpleName();
    // Below two constants make drawing at low priority, so other things can preempt our drawing.
    private static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100;
    private static final int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;

    private EGLDisplay mEglDisplay;
    private EGLConfig mEglConfig;
@@ -181,7 +184,8 @@ public class EglHelper {
     * @return true if EglContext is ready.
     */
    public boolean createEglContext() {
        int[] attrib_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
        int[] attrib_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2,
                EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_NONE};
        mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0);
        if (mEglContext == EGL_NO_CONTEXT) {
            Log.w(TAG, "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError()));
+0 −7
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.systemui.glwallpaper;

import android.util.Size;
import android.view.SurfaceHolder;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -82,12 +81,6 @@ public interface GLWallpaperRenderer {
     */
    interface SurfaceProxy {

        /**
         * Get surface holder.
         * @return surface holder.
         */
        SurfaceHolder getHolder();

        /**
         * Ask proxy to start rendering frame to surface.
         */