blob: 7b22a49fc88a6447a273b5d3e4f3ee3e49c21698 [file] [log] [blame]
Ahan Wu67e7f102019-01-14 20:38:14 +08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.glwallpaper;
18
19import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
20import static android.opengl.GLES20.glClear;
21import static android.opengl.GLES20.glClearColor;
22import static android.opengl.GLES20.glUniform1f;
23import static android.opengl.GLES20.glViewport;
24
25import android.app.WallpaperManager;
26import android.content.Context;
Ahan Wu23ac8e62019-07-23 20:41:52 +080027import android.content.res.Configuration;
Ahan Wu67e7f102019-01-14 20:38:14 +080028import android.graphics.Bitmap;
29import android.graphics.Rect;
Ahan Wu67e7f102019-01-14 20:38:14 +080030import android.util.Log;
Ahan Wuc8363352019-03-07 17:35:27 +080031import android.util.MathUtils;
Ahan Wufa42c512019-05-15 19:52:51 +080032import android.util.Size;
Ahan Wue16e1fa2019-05-29 18:39:33 +080033import android.view.DisplayInfo;
34import android.view.WindowManager;
Ahan Wu67e7f102019-01-14 20:38:14 +080035
Ahan Wu67e7f102019-01-14 20:38:14 +080036import com.android.systemui.R;
37
Ahan Wu76884242019-05-22 20:04:23 +080038import java.io.FileDescriptor;
39import java.io.PrintWriter;
40
Ahan Wu67e7f102019-01-14 20:38:14 +080041/**
42 * A GL renderer for image wallpaper.
43 */
Ahan Wufa42c512019-05-15 19:52:51 +080044public class ImageWallpaperRenderer implements GLWallpaperRenderer,
45 ImageRevealHelper.RevealStateListener {
Ahan Wu67e7f102019-01-14 20:38:14 +080046 private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
Ahan Wue16e1fa2019-05-29 18:39:33 +080047 private static final float SCALE_VIEWPORT_MIN = 1f;
48 private static final float SCALE_VIEWPORT_MAX = 1.1f;
Ahan Wu67e7f102019-01-14 20:38:14 +080049
50 private final WallpaperManager mWallpaperManager;
51 private final ImageGLProgram mProgram;
52 private final ImageGLWallpaper mWallpaper;
53 private final ImageProcessHelper mImageProcessHelper;
54 private final ImageRevealHelper mImageRevealHelper;
Ahan Wu67e7f102019-01-14 20:38:14 +080055
Ahan Wufa42c512019-05-15 19:52:51 +080056 private SurfaceProxy mProxy;
Ahan Wue16e1fa2019-05-29 18:39:33 +080057 private final Rect mScissor;
58 private final Rect mSurfaceSize = new Rect();
59 private final Rect mViewport = new Rect();
Ahan Wu48ebbd72019-03-12 20:59:13 +080060 private Bitmap mBitmap;
Ahan Wue16e1fa2019-05-29 18:39:33 +080061 private boolean mScissorMode;
62 private float mXOffset;
63 private float mYOffset;
Ahan Wu48ebbd72019-03-12 20:59:13 +080064
Ahan Wufa42c512019-05-15 19:52:51 +080065 public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
Ahan Wu67e7f102019-01-14 20:38:14 +080066 mWallpaperManager = context.getSystemService(WallpaperManager.class);
67 if (mWallpaperManager == null) {
68 Log.w(TAG, "WallpaperManager not available");
69 }
70
Ahan Wue16e1fa2019-05-29 18:39:33 +080071 DisplayInfo displayInfo = new DisplayInfo();
72 WindowManager wm = context.getSystemService(WindowManager.class);
73 wm.getDefaultDisplay().getDisplayInfo(displayInfo);
Ahan Wu23ac8e62019-07-23 20:41:52 +080074
75 // We only do transition in portrait currently, b/137962047.
76 int orientation = context.getResources().getConfiguration().orientation;
77 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
78 mScissor = new Rect(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
79 } else {
80 mScissor = new Rect(0, 0, displayInfo.logicalHeight, displayInfo.logicalWidth);
81 }
Ahan Wue16e1fa2019-05-29 18:39:33 +080082
Ahan Wufa42c512019-05-15 19:52:51 +080083 mProxy = proxy;
Ahan Wu67e7f102019-01-14 20:38:14 +080084 mProgram = new ImageGLProgram(context);
85 mWallpaper = new ImageGLWallpaper(mProgram);
86 mImageProcessHelper = new ImageProcessHelper();
87 mImageRevealHelper = new ImageRevealHelper(this);
Ahan Wu67e7f102019-01-14 20:38:14 +080088
Ahan Wufa42c512019-05-15 19:52:51 +080089 if (loadBitmap()) {
Ahan Wu330bc602019-04-25 15:04:39 +080090 // Compute threshold of the image, this is an async work.
91 mImageProcessHelper.start(mBitmap);
Ahan Wu67e7f102019-01-14 20:38:14 +080092 }
93 }
94
95 @Override
Ahan Wufa42c512019-05-15 19:52:51 +080096 public void onSurfaceCreated() {
Ahan Wu67e7f102019-01-14 20:38:14 +080097 glClearColor(0f, 0f, 0f, 1.0f);
98 mProgram.useGLProgram(
99 R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
Ahan Wufa42c512019-05-15 19:52:51 +0800100
101 if (!loadBitmap()) {
102 Log.w(TAG, "reload bitmap failed!");
103 }
104
Ahan Wu48ebbd72019-03-12 20:59:13 +0800105 mWallpaper.setup(mBitmap);
106 mBitmap = null;
Ahan Wu67e7f102019-01-14 20:38:14 +0800107 }
108
Ahan Wufa42c512019-05-15 19:52:51 +0800109 private boolean loadBitmap() {
110 if (mWallpaperManager != null && mBitmap == null) {
111 mBitmap = mWallpaperManager.getBitmap();
112 mWallpaperManager.forgetLoadedWallpaper();
113 if (mBitmap != null) {
Ahan Wue16e1fa2019-05-29 18:39:33 +0800114 mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
Ahan Wufa42c512019-05-15 19:52:51 +0800115 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800116 }
Ahan Wufa42c512019-05-15 19:52:51 +0800117 return mBitmap != null;
Ahan Wu67e7f102019-01-14 20:38:14 +0800118 }
119
120 @Override
Ahan Wufa42c512019-05-15 19:52:51 +0800121 public void onSurfaceChanged(int width, int height) {
122 glViewport(0, 0, width, height);
123 }
124
125 @Override
126 public void onDrawFrame() {
Ahan Wu330bc602019-04-25 15:04:39 +0800127 float threshold = mImageProcessHelper.getThreshold();
Ahan Wu67e7f102019-01-14 20:38:14 +0800128 float reveal = mImageRevealHelper.getReveal();
129
Ahan Wu67e7f102019-01-14 20:38:14 +0800130 glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
Ahan Wu330bc602019-04-25 15:04:39 +0800131 glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
Ahan Wu67e7f102019-01-14 20:38:14 +0800132 glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
133
Ahan Wue16e1fa2019-05-29 18:39:33 +0800134 glClear(GL_COLOR_BUFFER_BIT);
135 // We only need to scale viewport while doing transition.
136 if (mScissorMode) {
137 scaleViewport(reveal);
138 } else {
139 glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
140 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800141 mWallpaper.useTexture();
142 mWallpaper.draw();
143 }
144
Ahan Wufa42c512019-05-15 19:52:51 +0800145 @Override
146 public void updateAmbientMode(boolean inAmbientMode, long duration) {
147 mImageRevealHelper.updateAwake(!inAmbientMode, duration);
148 }
149
150 @Override
Ahan Wue16e1fa2019-05-29 18:39:33 +0800151 public void updateOffsets(float xOffset, float yOffset) {
152 mXOffset = xOffset;
153 mYOffset = yOffset;
154 int left = (int) ((mSurfaceSize.width() - mScissor.width()) * xOffset);
155 int right = left + mScissor.width();
156 mScissor.set(left, mScissor.top, right, mScissor.bottom);
157 }
158
159 @Override
Ahan Wufa42c512019-05-15 19:52:51 +0800160 public Size reportSurfaceSize() {
161 return new Size(mSurfaceSize.width(), mSurfaceSize.height());
162 }
163
164 @Override
165 public void finish() {
166 mProxy = null;
167 }
168
Ahan Wuc8363352019-03-07 17:35:27 +0800169 private void scaleViewport(float reveal) {
Ahan Wue16e1fa2019-05-29 18:39:33 +0800170 int left = mScissor.left;
171 int top = mScissor.top;
172 int width = mScissor.width();
173 int height = mScissor.height();
Ahan Wuc8363352019-03-07 17:35:27 +0800174 // Interpolation between SCALE_VIEWPORT_MAX and SCALE_VIEWPORT_MIN by reveal.
Ahan Wue16e1fa2019-05-29 18:39:33 +0800175 float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MIN, SCALE_VIEWPORT_MAX, reveal);
Ahan Wuc8363352019-03-07 17:35:27 +0800176 // Calculate the offset amount from the lower left corner.
Ahan Wue16e1fa2019-05-29 18:39:33 +0800177 float offset = (SCALE_VIEWPORT_MIN - vpScaled) / 2;
Ahan Wuc8363352019-03-07 17:35:27 +0800178 // Change the viewport.
Ahan Wue16e1fa2019-05-29 18:39:33 +0800179 mViewport.set((int) (left + width * offset), (int) (top + height * offset),
Ahan Wufa42c512019-05-15 19:52:51 +0800180 (int) (width * vpScaled), (int) (height * vpScaled));
Ahan Wue16e1fa2019-05-29 18:39:33 +0800181 glViewport(mViewport.left, mViewport.top, mViewport.right, mViewport.bottom);
Ahan Wu67e7f102019-01-14 20:38:14 +0800182 }
183
184 @Override
185 public void onRevealStateChanged() {
Ahan Wufa42c512019-05-15 19:52:51 +0800186 mProxy.requestRender();
Ahan Wu67e7f102019-01-14 20:38:14 +0800187 }
188
Ahan Wufa42c512019-05-15 19:52:51 +0800189 @Override
Ahan Wu23ac8e62019-07-23 20:41:52 +0800190 public void onRevealStart(boolean animate) {
191 if (animate) {
192 mScissorMode = true;
193 // Use current display area of texture.
194 mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
195 }
Ahan Wufa42c512019-05-15 19:52:51 +0800196 mProxy.preRender();
197 }
198
199 @Override
200 public void onRevealEnd() {
Ahan Wu23ac8e62019-07-23 20:41:52 +0800201 if (mScissorMode) {
202 mScissorMode = false;
203 // reset texture coordinates to use full texture.
204 mWallpaper.adjustTextureCoordinates(null, null, 0, 0);
205 // We need draw full texture back before finishing render.
206 mProxy.requestRender();
207 }
Ahan Wufa42c512019-05-15 19:52:51 +0800208 mProxy.postRender();
Ahan Wu67e7f102019-01-14 20:38:14 +0800209 }
Ahan Wu76884242019-05-22 20:04:23 +0800210
211 @Override
212 public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
213 out.print(prefix); out.print("mProxy="); out.print(mProxy);
214 out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
Ahan Wue16e1fa2019-05-29 18:39:33 +0800215 out.print(prefix); out.print("mScissor="); out.print(mScissor);
216 out.print(prefix); out.print("mViewport="); out.print(mViewport);
217 out.print(prefix); out.print("mScissorMode="); out.print(mScissorMode);
218 out.print(prefix); out.print("mXOffset="); out.print(mXOffset);
219 out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
Ahan Wu76884242019-05-22 20:04:23 +0800220 out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
Ahan Wue16e1fa2019-05-29 18:39:33 +0800221 mWallpaper.dump(prefix, fd, out, args);
Ahan Wu76884242019-05-22 20:04:23 +0800222 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800223}