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

am: 84ed5df87f

Change-Id: Id7b816deec2b048e5f6fd641ed44de1ca23c91ff
This commit is contained in:
Ahan Wu
2019-06-27 00:49:57 -07:00
committed by android-build-merger
3 changed files with 66 additions and 36 deletions

View File

@@ -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;
mRenderer.finish();
mRenderer = null;
mEglHelper.finish();
mEglHelper = null;
getSurfaceHolder().getSurface().hwuiDestroy();
mWorker.getThreadHandler().post(() -> {
mRenderer.finish();
mRenderer = null;
mEglHelper.finish();
mEglHelper = null;
getSurfaceHolder().getSurface().hwuiDestroy();
});
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
mEglHelper.init(holder);
mRenderer.onSurfaceCreated();
mWorker.getThreadHandler().post(() -> {
mEglHelper.init(holder);
mRenderer.onSurfaceCreated();
});
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mRenderer.onSurfaceChanged(width, height);
mNeedRedraw = true;
mWorker.getThreadHandler().post(() -> {
mRenderer.onSurfaceChanged(width, height);
mNeedRedraw = true;
});
}
@Override
public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
if (mNeedRedraw) {
preRender();
requestRender();
postRender();
mNeedRedraw = false;
}
}
@Override
public SurfaceHolder getHolder() {
return getSurfaceHolder();
mWorker.getThreadHandler().post(() -> {
if (mNeedRedraw) {
preRender();
requestRender();
postRender();
mNeedRedraw = false;
}
});
}
@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() {

View File

@@ -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()));

View File

@@ -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.
*/