Loading packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl +45 −2 Original line number Diff line number Diff line 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 packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +38 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -66,8 +69,9 @@ public class ImageWallpaper extends WallpaperService { private Bitmap mMiniBitmap; @Inject public ImageWallpaper() { public ImageWallpaper(StatusBarStateController statusBarStateController) { super(); mStatusBarStateController = statusBarStateController; } @Override Loading @@ -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 Loading @@ -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() { } Loading @@ -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() { Loading Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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!"); Loading Loading @@ -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); } } } packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -83,6 +85,7 @@ class ImageGLWallpaper { private int mAttrPosition; private int mAttrTextureCoordinates; private int mUniTexture; private int mUniExposure; private int mTextureId; ImageGLWallpaper(ImageGLProgram program) { Loading Loading @@ -125,6 +128,7 @@ class ImageGLWallpaper { private void setupUniforms() { mUniTexture = mProgram.getUniformHandle(U_TEXTURE); mUniExposure = mProgram.getUniformHandle(U_EXPOSURE); } void draw() { Loading Loading @@ -171,6 +175,10 @@ class ImageGLWallpaper { glUniform1i(mUniTexture, 0); } void setExposureValue(float exposureValue) { glUniform1f(mUniExposure, exposureValue); } /** * Called to dump current state. * @param prefix prefix. Loading packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java +9 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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(); } Loading packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading
packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl +45 −2 Original line number Diff line number Diff line 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
packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +38 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -66,8 +69,9 @@ public class ImageWallpaper extends WallpaperService { private Bitmap mMiniBitmap; @Inject public ImageWallpaper() { public ImageWallpaper(StatusBarStateController statusBarStateController) { super(); mStatusBarStateController = statusBarStateController; } @Override Loading @@ -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 Loading @@ -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() { } Loading @@ -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() { Loading Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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!"); Loading Loading @@ -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); } } }
packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -83,6 +85,7 @@ class ImageGLWallpaper { private int mAttrPosition; private int mAttrTextureCoordinates; private int mUniTexture; private int mUniExposure; private int mTextureId; ImageGLWallpaper(ImageGLProgram program) { Loading Loading @@ -125,6 +128,7 @@ class ImageGLWallpaper { private void setupUniforms() { mUniTexture = mProgram.getUniformHandle(U_TEXTURE); mUniExposure = mProgram.getUniformHandle(U_EXPOSURE); } void draw() { Loading Loading @@ -171,6 +175,10 @@ class ImageGLWallpaper { glUniform1i(mUniTexture, 0); } void setExposureValue(float exposureValue) { glUniform1f(mUniExposure, exposureValue); } /** * Called to dump current state. * @param prefix prefix. Loading
packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java +9 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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(); } Loading
packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading