summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java89
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java7
3 files changed, 66 insertions, 36 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index e9eda4f5577b..9a0e9fc92af6 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -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() {
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
index 1744c4e5af19..d74112608491 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
@@ -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()));
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
index b615a5f32835..60ea1cdf6b22 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
@@ -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;
@@ -83,12 +82,6 @@ public interface GLWallpaperRenderer {
interface SurfaceProxy {
/**
- * Get surface holder.
- * @return surface holder.
- */
- SurfaceHolder getHolder();
-
- /**
* Ask proxy to start rendering frame to surface.
*/
void requestRender();