summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl47
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java3
5 files changed, 102 insertions, 8 deletions
diff --git a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
index e4b6e0778664..e9c838999dda 100644
--- a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
+++ b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
@@ -1,11 +1,54 @@
precision mediump float;
+#define GAMMA 2.2
+#define INV_GAMMA 1.0 / GAMMA
// The actual wallpaper texture.
uniform sampler2D uTexture;
+uniform float uExposure;
varying vec2 vTextureCoordinates;
+// Following the Rec. ITU-R BT.709.
+float relativeLuminance(vec3 color) {
+ return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
+}
+
+// Adjusts the exposure of some luminance value.
+float relativeExposureCompensation(in float lum, in float ev) {
+ return lum * pow(2.0, ev);
+}
+
+vec4 srgbToLinear(in vec4 color) {
+ vec4 linearColor = vec4(color);
+ linearColor.rgb = pow(linearColor.rgb, vec3(GAMMA));
+ return linearColor;
+}
+
+vec4 linearToSrgb(in vec4 color) {
+ vec4 srgbColor = vec4(color);
+ srgbColor.rgb = pow(srgbColor.rgb, vec3(INV_GAMMA));
+ return srgbColor;
+}
+
+/*
+ * Normalizes a value inside a range to a normalized range [0,1].
+ */
+float normalizedRange(in float value, in float inMin, in float inMax) {
+ float valueClamped = clamp(value, inMin, inMax);
+ return (value - inMin) / (inMax - inMin);
+}
+
void main() {
- // gets the pixel value of the wallpaper for this uv coordinates on screen.
- gl_FragColor = texture2D(uTexture, vTextureCoordinates);
+ // Gets the pixel value of the wallpaper for this uv coordinates on screen.
+ vec4 color = srgbToLinear(texture2D(uTexture, vTextureCoordinates));
+ float lum = relativeLuminance(color.rgb);
+
+ // Transform it using the S curve created by the smoothstep. This will increase the contrast.
+ lum = smoothstep(0., 1., lum) + 0.001;
+
+ lum = relativeExposureCompensation(lum, mix(-15., 10., uExposure));
+ lum = mix(clamp(lum, 0.0, 1.0), 1.0, normalizedRange(uExposure, 0.55, 1.0));
+ color.rgb *= lum;
+
+ gl_FragColor = linearToSrgb(color);
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 7966b388bc4f..8b68ae959ebf 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -29,6 +29,7 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.MathUtils;
import android.util.Size;
+import android.view.Choreographer;
import android.view.SurfaceHolder;
import android.view.WindowManager;
@@ -37,6 +38,7 @@ import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.glwallpaper.EglHelper;
import com.android.systemui.glwallpaper.ImageWallpaperRenderer;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -53,10 +55,11 @@ public class ImageWallpaper extends WallpaperService {
private static final String TAG = ImageWallpaper.class.getSimpleName();
// 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 static final int DELAY_FINISH_RENDERING = 3000;
private static final @android.annotation.NonNull RectF LOCAL_COLOR_BOUNDS =
new RectF(0, 0, 1, 1);
private static final boolean DEBUG = false;
+ private final StatusBarStateController mStatusBarStateController;
private final ArrayList<RectF> mLocalColorsToAdd = new ArrayList<>();
private final ArraySet<RectF> mColorAreas = new ArraySet<>();
private float mShift;
@@ -66,8 +69,9 @@ public class ImageWallpaper extends WallpaperService {
private Bitmap mMiniBitmap;
@Inject
- public ImageWallpaper() {
+ public ImageWallpaper(StatusBarStateController statusBarStateController) {
super();
+ mStatusBarStateController = statusBarStateController;
}
@Override
@@ -90,7 +94,9 @@ public class ImageWallpaper extends WallpaperService {
mMiniBitmap = null;
}
- class GLEngine extends Engine {
+
+ class GLEngine extends Engine implements StatusBarStateController.StateListener,
+ Choreographer.FrameCallback {
// 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.
@VisibleForTesting
@@ -101,11 +107,12 @@ public class ImageWallpaper extends WallpaperService {
private ImageWallpaperRenderer mRenderer;
private EglHelper mEglHelper;
private final Runnable mFinishRenderingTask = this::finishRendering;
- private boolean mNeedRedraw;
private int mWidth = 1;
private int mHeight = 1;
private int mImgWidth = 1;
private int mImgHeight = 1;
+ private volatile float mDozeAmount;
+ private volatile boolean mNewDozeValue = false;
GLEngine() {
}
@@ -130,8 +137,14 @@ public class ImageWallpaper extends WallpaperService {
mWidth = window.width();
mMiniBitmap = null;
if (mWorker != null && mWorker.getThreadHandler() != null) {
- mWorker.getThreadHandler().post(this::updateMiniBitmap);
+ mWorker.getThreadHandler().post(() -> {
+ updateMiniBitmap();
+ Choreographer.getInstance().postFrameCallback(GLEngine.this);
+ });
}
+
+ mDozeAmount = mStatusBarStateController.getDozeAmount();
+ mStatusBarStateController.addCallback(this);
}
EglHelper getEglHelperInstance() {
@@ -210,11 +223,14 @@ public class ImageWallpaper extends WallpaperService {
public void onDestroy() {
mMiniBitmap = null;
mWorker.getThreadHandler().post(() -> {
+ Choreographer.getInstance().removeFrameCallback(this);
mRenderer.finish();
mRenderer = null;
mEglHelper.finish();
mEglHelper = null;
});
+
+ mStatusBarStateController.removeCallback(this);
}
@Override
@@ -323,9 +339,16 @@ public class ImageWallpaper extends WallpaperService {
@Override
public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
if (mWorker == null) return;
+ mDozeAmount = mStatusBarStateController.getDozeAmount();
mWorker.getThreadHandler().post(this::drawFrame);
}
+ @Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ mDozeAmount = linear;
+ mNewDozeValue = true;
+ }
+
private void drawFrame() {
preRender();
requestRender();
@@ -381,6 +404,7 @@ public class ImageWallpaper extends WallpaperService {
&& frame.width() > 0 && frame.height() > 0;
if (readyToRender) {
+ mRenderer.setExposureValue(1 - mDozeAmount);
mRenderer.onDrawFrame();
if (!mEglHelper.swapBuffer()) {
Log.e(TAG, "drawFrame failed!");
@@ -438,5 +462,14 @@ public class ImageWallpaper extends WallpaperService {
mEglHelper.dump(prefix, fd, out, args);
mRenderer.dump(prefix, fd, out, args);
}
+
+ @Override
+ public void doFrame(long frameTimeNanos) {
+ if (mNewDozeValue) {
+ drawFrame();
+ mNewDozeValue = false;
+ }
+ Choreographer.getInstance().postFrameCallback(this);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 1a53c28c0fc5..58c41d582413 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -29,6 +29,7 @@ import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGenTextures;
import static android.opengl.GLES20.glTexParameteri;
+import static android.opengl.GLES20.glUniform1f;
import static android.opengl.GLES20.glUniform1i;
import static android.opengl.GLES20.glVertexAttribPointer;
@@ -52,6 +53,7 @@ class ImageGLWallpaper {
private static final String A_POSITION = "aPosition";
private static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
private static final String U_TEXTURE = "uTexture";
+ private static final String U_EXPOSURE = "uExposure";
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int TEXTURE_COMPONENT_COUNT = 2;
private static final int BYTES_PER_FLOAT = 4;
@@ -83,6 +85,7 @@ class ImageGLWallpaper {
private int mAttrPosition;
private int mAttrTextureCoordinates;
private int mUniTexture;
+ private int mUniExposure;
private int mTextureId;
ImageGLWallpaper(ImageGLProgram program) {
@@ -125,6 +128,7 @@ class ImageGLWallpaper {
private void setupUniforms() {
mUniTexture = mProgram.getUniformHandle(U_TEXTURE);
+ mUniExposure = mProgram.getUniformHandle(U_EXPOSURE);
}
void draw() {
@@ -171,6 +175,10 @@ class ImageGLWallpaper {
glUniform1i(mUniTexture, 0);
}
+ void setExposureValue(float exposureValue) {
+ glUniform1f(mUniExposure, exposureValue);
+ }
+
/**
* Called to dump current state.
* @param prefix prefix.
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 01a353ce8f1f..cdf88f3898bb 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -46,6 +46,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer {
private final ImageGLWallpaper mWallpaper;
private final Rect mSurfaceSize = new Rect();
private final WallpaperTexture mTexture;
+ private float mExposureValue;
public ImageWallpaperRenderer(Context context) {
final WallpaperManager wpm = context.getSystemService(WallpaperManager.class);
@@ -66,6 +67,13 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer {
mTexture.use(c);
}
+ /**
+ * @hide
+ */
+ public void setExposureValue(float exposureValue) {
+ mExposureValue = exposureValue;
+ }
+
@Override
public boolean isWcgContent() {
return mTexture.isWcgContent();
@@ -94,6 +102,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer {
public void onDrawFrame() {
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
+ mWallpaper.setExposureValue(mExposureValue);
mWallpaper.useTexture();
mWallpaper.draw();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
index e1ddaada44cf..daa896cc6a8b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
@@ -41,6 +41,7 @@ import android.view.DisplayInfo;
import android.view.SurfaceHolder;
import com.android.systemui.glwallpaper.ImageWallpaperRenderer;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import org.junit.Before;
import org.junit.Ignore;
@@ -99,7 +100,7 @@ public class ImageWallpaperTest extends SysuiTestCase {
}
private ImageWallpaper createImageWallpaper() {
- return new ImageWallpaper() {
+ return new ImageWallpaper(mock(StatusBarStateController.class)) {
@Override
public Engine onCreateEngine() {
return new GLEngine(mHandler) {