blob: 93d8dd6146a6077f7b118bac376d56581ec675d7 [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;
27import android.graphics.Bitmap;
28import android.graphics.Rect;
Ahan Wu67e7f102019-01-14 20:38:14 +080029import android.util.Log;
Ahan Wuc8363352019-03-07 17:35:27 +080030import android.util.MathUtils;
Ahan Wufa42c512019-05-15 19:52:51 +080031import android.util.Size;
Ahan Wue16e1fa2019-05-29 18:39:33 +080032import android.view.DisplayInfo;
33import android.view.WindowManager;
Ahan Wu67e7f102019-01-14 20:38:14 +080034
Ahan Wu67e7f102019-01-14 20:38:14 +080035import com.android.systemui.R;
36
Ahan Wu76884242019-05-22 20:04:23 +080037import java.io.FileDescriptor;
38import java.io.PrintWriter;
39
Ahan Wu67e7f102019-01-14 20:38:14 +080040/**
41 * A GL renderer for image wallpaper.
42 */
Ahan Wufa42c512019-05-15 19:52:51 +080043public class ImageWallpaperRenderer implements GLWallpaperRenderer,
44 ImageRevealHelper.RevealStateListener {
Ahan Wu67e7f102019-01-14 20:38:14 +080045 private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
Ahan Wue16e1fa2019-05-29 18:39:33 +080046 private static final float SCALE_VIEWPORT_MIN = 1f;
47 private static final float SCALE_VIEWPORT_MAX = 1.1f;
Ahan Wu67e7f102019-01-14 20:38:14 +080048
49 private final WallpaperManager mWallpaperManager;
50 private final ImageGLProgram mProgram;
51 private final ImageGLWallpaper mWallpaper;
52 private final ImageProcessHelper mImageProcessHelper;
53 private final ImageRevealHelper mImageRevealHelper;
Ahan Wu67e7f102019-01-14 20:38:14 +080054
Ahan Wufa42c512019-05-15 19:52:51 +080055 private SurfaceProxy mProxy;
Ahan Wue16e1fa2019-05-29 18:39:33 +080056 private final Rect mScissor;
57 private final Rect mSurfaceSize = new Rect();
58 private final Rect mViewport = new Rect();
Ahan Wu48ebbd72019-03-12 20:59:13 +080059 private Bitmap mBitmap;
Ahan Wue16e1fa2019-05-29 18:39:33 +080060 private boolean mScissorMode;
61 private float mXOffset;
62 private float mYOffset;
Ahan Wu48ebbd72019-03-12 20:59:13 +080063
Ahan Wufa42c512019-05-15 19:52:51 +080064 public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
Ahan Wu67e7f102019-01-14 20:38:14 +080065 mWallpaperManager = context.getSystemService(WallpaperManager.class);
66 if (mWallpaperManager == null) {
67 Log.w(TAG, "WallpaperManager not available");
68 }
69
Ahan Wue16e1fa2019-05-29 18:39:33 +080070 DisplayInfo displayInfo = new DisplayInfo();
71 WindowManager wm = context.getSystemService(WindowManager.class);
72 wm.getDefaultDisplay().getDisplayInfo(displayInfo);
73 mScissor = new Rect(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
74
Ahan Wufa42c512019-05-15 19:52:51 +080075 mProxy = proxy;
Ahan Wu67e7f102019-01-14 20:38:14 +080076 mProgram = new ImageGLProgram(context);
77 mWallpaper = new ImageGLWallpaper(mProgram);
78 mImageProcessHelper = new ImageProcessHelper();
79 mImageRevealHelper = new ImageRevealHelper(this);
Ahan Wu67e7f102019-01-14 20:38:14 +080080
Ahan Wufa42c512019-05-15 19:52:51 +080081 if (loadBitmap()) {
Ahan Wu330bc602019-04-25 15:04:39 +080082 // Compute threshold of the image, this is an async work.
83 mImageProcessHelper.start(mBitmap);
Ahan Wu67e7f102019-01-14 20:38:14 +080084 }
85 }
86
87 @Override
Ahan Wufa42c512019-05-15 19:52:51 +080088 public void onSurfaceCreated() {
Ahan Wu67e7f102019-01-14 20:38:14 +080089 glClearColor(0f, 0f, 0f, 1.0f);
90 mProgram.useGLProgram(
91 R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
Ahan Wufa42c512019-05-15 19:52:51 +080092
93 if (!loadBitmap()) {
94 Log.w(TAG, "reload bitmap failed!");
95 }
96
Ahan Wu48ebbd72019-03-12 20:59:13 +080097 mWallpaper.setup(mBitmap);
98 mBitmap = null;
Ahan Wu67e7f102019-01-14 20:38:14 +080099 }
100
Ahan Wufa42c512019-05-15 19:52:51 +0800101 private boolean loadBitmap() {
102 if (mWallpaperManager != null && mBitmap == null) {
103 mBitmap = mWallpaperManager.getBitmap();
104 mWallpaperManager.forgetLoadedWallpaper();
105 if (mBitmap != null) {
Ahan Wue16e1fa2019-05-29 18:39:33 +0800106 mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
Ahan Wufa42c512019-05-15 19:52:51 +0800107 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800108 }
Ahan Wufa42c512019-05-15 19:52:51 +0800109 return mBitmap != null;
Ahan Wu67e7f102019-01-14 20:38:14 +0800110 }
111
112 @Override
Ahan Wufa42c512019-05-15 19:52:51 +0800113 public void onSurfaceChanged(int width, int height) {
114 glViewport(0, 0, width, height);
115 }
116
117 @Override
118 public void onDrawFrame() {
Ahan Wu330bc602019-04-25 15:04:39 +0800119 float threshold = mImageProcessHelper.getThreshold();
Ahan Wu67e7f102019-01-14 20:38:14 +0800120 float reveal = mImageRevealHelper.getReveal();
121
Ahan Wu67e7f102019-01-14 20:38:14 +0800122 glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
Ahan Wu330bc602019-04-25 15:04:39 +0800123 glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
Ahan Wu67e7f102019-01-14 20:38:14 +0800124 glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
125
Ahan Wue16e1fa2019-05-29 18:39:33 +0800126 glClear(GL_COLOR_BUFFER_BIT);
127 // We only need to scale viewport while doing transition.
128 if (mScissorMode) {
129 scaleViewport(reveal);
130 } else {
131 glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
132 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800133 mWallpaper.useTexture();
134 mWallpaper.draw();
135 }
136
Ahan Wufa42c512019-05-15 19:52:51 +0800137 @Override
138 public void updateAmbientMode(boolean inAmbientMode, long duration) {
139 mImageRevealHelper.updateAwake(!inAmbientMode, duration);
140 }
141
142 @Override
Ahan Wue16e1fa2019-05-29 18:39:33 +0800143 public void updateOffsets(float xOffset, float yOffset) {
144 mXOffset = xOffset;
145 mYOffset = yOffset;
146 int left = (int) ((mSurfaceSize.width() - mScissor.width()) * xOffset);
147 int right = left + mScissor.width();
148 mScissor.set(left, mScissor.top, right, mScissor.bottom);
149 }
150
151 @Override
Ahan Wufa42c512019-05-15 19:52:51 +0800152 public Size reportSurfaceSize() {
153 return new Size(mSurfaceSize.width(), mSurfaceSize.height());
154 }
155
156 @Override
157 public void finish() {
158 mProxy = null;
159 }
160
Ahan Wuc8363352019-03-07 17:35:27 +0800161 private void scaleViewport(float reveal) {
Ahan Wue16e1fa2019-05-29 18:39:33 +0800162 int left = mScissor.left;
163 int top = mScissor.top;
164 int width = mScissor.width();
165 int height = mScissor.height();
Ahan Wuc8363352019-03-07 17:35:27 +0800166 // Interpolation between SCALE_VIEWPORT_MAX and SCALE_VIEWPORT_MIN by reveal.
Ahan Wue16e1fa2019-05-29 18:39:33 +0800167 float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MIN, SCALE_VIEWPORT_MAX, reveal);
Ahan Wuc8363352019-03-07 17:35:27 +0800168 // Calculate the offset amount from the lower left corner.
Ahan Wue16e1fa2019-05-29 18:39:33 +0800169 float offset = (SCALE_VIEWPORT_MIN - vpScaled) / 2;
Ahan Wuc8363352019-03-07 17:35:27 +0800170 // Change the viewport.
Ahan Wue16e1fa2019-05-29 18:39:33 +0800171 mViewport.set((int) (left + width * offset), (int) (top + height * offset),
Ahan Wufa42c512019-05-15 19:52:51 +0800172 (int) (width * vpScaled), (int) (height * vpScaled));
Ahan Wue16e1fa2019-05-29 18:39:33 +0800173 glViewport(mViewport.left, mViewport.top, mViewport.right, mViewport.bottom);
Ahan Wu67e7f102019-01-14 20:38:14 +0800174 }
175
176 @Override
177 public void onRevealStateChanged() {
Ahan Wufa42c512019-05-15 19:52:51 +0800178 mProxy.requestRender();
Ahan Wu67e7f102019-01-14 20:38:14 +0800179 }
180
Ahan Wufa42c512019-05-15 19:52:51 +0800181 @Override
182 public void onRevealStart() {
Ahan Wue16e1fa2019-05-29 18:39:33 +0800183 mScissorMode = true;
184 // Use current display area of texture.
185 mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
Ahan Wufa42c512019-05-15 19:52:51 +0800186 mProxy.preRender();
187 }
188
189 @Override
190 public void onRevealEnd() {
Ahan Wue16e1fa2019-05-29 18:39:33 +0800191 mScissorMode = false;
192 // reset texture coordinates to use full texture.
193 mWallpaper.adjustTextureCoordinates(null, null, 0, 0);
194 // We need draw full texture back before finishing render.
195 mProxy.requestRender();
Ahan Wufa42c512019-05-15 19:52:51 +0800196 mProxy.postRender();
Ahan Wu67e7f102019-01-14 20:38:14 +0800197 }
Ahan Wu76884242019-05-22 20:04:23 +0800198
199 @Override
200 public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
201 out.print(prefix); out.print("mProxy="); out.print(mProxy);
202 out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
Ahan Wue16e1fa2019-05-29 18:39:33 +0800203 out.print(prefix); out.print("mScissor="); out.print(mScissor);
204 out.print(prefix); out.print("mViewport="); out.print(mViewport);
205 out.print(prefix); out.print("mScissorMode="); out.print(mScissorMode);
206 out.print(prefix); out.print("mXOffset="); out.print(mXOffset);
207 out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
Ahan Wu76884242019-05-22 20:04:23 +0800208 out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
Ahan Wue16e1fa2019-05-29 18:39:33 +0800209 mWallpaper.dump(prefix, fd, out, args);
Ahan Wu76884242019-05-22 20:04:23 +0800210 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800211}