blob: 1a0356c4446d66264a37ebd51f52fe281bbabb7d [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;
Ahan Wu67e7f102019-01-14 20:38:14 +080022import static android.opengl.GLES20.glViewport;
23
24import android.app.WallpaperManager;
25import android.content.Context;
26import android.graphics.Bitmap;
27import android.graphics.Rect;
Ahan Wu67e7f102019-01-14 20:38:14 +080028import android.util.Log;
Ahan Wufa42c512019-05-15 19:52:51 +080029import android.util.Size;
Ahan Wu67e7f102019-01-14 20:38:14 +080030
Ahan Wu67e7f102019-01-14 20:38:14 +080031import com.android.systemui.R;
32
Ahan Wu76884242019-05-22 20:04:23 +080033import java.io.FileDescriptor;
34import java.io.PrintWriter;
Ahan Wu3222d3f2020-03-11 20:24:00 +080035import java.util.concurrent.atomic.AtomicInteger;
36import java.util.function.Consumer;
Ahan Wu76884242019-05-22 20:04:23 +080037
Ahan Wu67e7f102019-01-14 20:38:14 +080038/**
39 * A GL renderer for image wallpaper.
40 */
Ahan Wu4a297792020-04-16 03:00:14 +080041public class ImageWallpaperRenderer implements GLWallpaperRenderer {
Ahan Wu67e7f102019-01-14 20:38:14 +080042 private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
Ahan Wu4a297792020-04-16 03:00:14 +080043 private static final boolean DEBUG = false;
Ahan Wu67e7f102019-01-14 20:38:14 +080044
Ahan Wu67e7f102019-01-14 20:38:14 +080045 private final ImageGLProgram mProgram;
46 private final ImageGLWallpaper mWallpaper;
Ahan Wue16e1fa2019-05-29 18:39:33 +080047 private final Rect mSurfaceSize = new Rect();
Ahan Wu3222d3f2020-03-11 20:24:00 +080048 private final WallpaperTexture mTexture;
Ahan Wu48ebbd72019-03-12 20:59:13 +080049
Ahan Wu4a297792020-04-16 03:00:14 +080050 public ImageWallpaperRenderer(Context context) {
Ahan Wu3222d3f2020-03-11 20:24:00 +080051 final WallpaperManager wpm = context.getSystemService(WallpaperManager.class);
52 if (wpm == null) {
Ahan Wu67e7f102019-01-14 20:38:14 +080053 Log.w(TAG, "WallpaperManager not available");
54 }
55
Ahan Wu3222d3f2020-03-11 20:24:00 +080056 mTexture = new WallpaperTexture(wpm);
Ahan Wu67e7f102019-01-14 20:38:14 +080057 mProgram = new ImageGLProgram(context);
58 mWallpaper = new ImageGLWallpaper(mProgram);
Ahan Wu67e7f102019-01-14 20:38:14 +080059 }
60
61 @Override
Ahan Wu287d8282019-12-17 16:23:17 +080062 public boolean isWcgContent() {
Ahan Wu3222d3f2020-03-11 20:24:00 +080063 return mTexture.isWcgContent();
Ahan Wu287d8282019-12-17 16:23:17 +080064 }
65
66 @Override
Ahan Wufa42c512019-05-15 19:52:51 +080067 public void onSurfaceCreated() {
Ahan Wu67e7f102019-01-14 20:38:14 +080068 glClearColor(0f, 0f, 0f, 1.0f);
69 mProgram.useGLProgram(
70 R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
Ahan Wufa42c512019-05-15 19:52:51 +080071
Ahan Wu3222d3f2020-03-11 20:24:00 +080072 mTexture.use(bitmap -> {
73 if (bitmap == null) {
74 Log.w(TAG, "reload texture failed!");
Ahan Wufa42c512019-05-15 19:52:51 +080075 }
Ahan Wu3222d3f2020-03-11 20:24:00 +080076 mWallpaper.setup(bitmap);
77 });
Ahan Wu67e7f102019-01-14 20:38:14 +080078 }
79
80 @Override
Ahan Wufa42c512019-05-15 19:52:51 +080081 public void onSurfaceChanged(int width, int height) {
82 glViewport(0, 0, width, height);
83 }
84
85 @Override
86 public void onDrawFrame() {
Ahan Wue16e1fa2019-05-29 18:39:33 +080087 glClear(GL_COLOR_BUFFER_BIT);
Ahan Wu4a297792020-04-16 03:00:14 +080088 glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
Ahan Wu67e7f102019-01-14 20:38:14 +080089 mWallpaper.useTexture();
90 mWallpaper.draw();
91 }
92
Ahan Wufa42c512019-05-15 19:52:51 +080093 @Override
Ahan Wufa42c512019-05-15 19:52:51 +080094 public Size reportSurfaceSize() {
Ahan Wu4a297792020-04-16 03:00:14 +080095 mTexture.use(null /* consumer */);
Ahan Wu3222d3f2020-03-11 20:24:00 +080096 mSurfaceSize.set(mTexture.getTextureDimensions());
Ahan Wufa42c512019-05-15 19:52:51 +080097 return new Size(mSurfaceSize.width(), mSurfaceSize.height());
98 }
99
100 @Override
101 public void finish() {
Ahan Wu67e7f102019-01-14 20:38:14 +0800102 }
Ahan Wu76884242019-05-22 20:04:23 +0800103
104 @Override
105 public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
Ahan Wu76884242019-05-22 20:04:23 +0800106 out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
Ahan Wu3222d3f2020-03-11 20:24:00 +0800107 out.print(prefix); out.print("mWcgContent="); out.print(isWcgContent());
Ahan Wue16e1fa2019-05-29 18:39:33 +0800108 mWallpaper.dump(prefix, fd, out, args);
Ahan Wu76884242019-05-22 20:04:23 +0800109 }
Ahan Wu3222d3f2020-03-11 20:24:00 +0800110
111 static class WallpaperTexture {
112 private final AtomicInteger mRefCount;
113 private final Rect mDimensions;
114 private final WallpaperManager mWallpaperManager;
115 private Bitmap mBitmap;
116 private boolean mWcgContent;
117
118 private WallpaperTexture(WallpaperManager wallpaperManager) {
119 mWallpaperManager = wallpaperManager;
120 mRefCount = new AtomicInteger();
121 mDimensions = new Rect();
122 }
123
124 public void use(Consumer<Bitmap> consumer) {
125 mRefCount.incrementAndGet();
126 synchronized (mRefCount) {
127 if (mBitmap == null) {
128 mBitmap = mWallpaperManager.getBitmap(false /* hardware */);
129 mWcgContent = mWallpaperManager.wallpaperSupportsWcg(
130 WallpaperManager.FLAG_SYSTEM);
131 mWallpaperManager.forgetLoadedWallpaper();
132 if (mBitmap != null) {
133 mDimensions.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
134 } else {
135 Log.w(TAG, "Can't get bitmap");
136 }
137 }
138 }
139 if (consumer != null) {
140 consumer.accept(mBitmap);
141 }
142 synchronized (mRefCount) {
143 final int count = mRefCount.decrementAndGet();
144 if (count == 0 && mBitmap != null) {
145 if (DEBUG) {
146 Log.v(TAG, "WallpaperTexture: release 0x" + getHash()
147 + ", refCount=" + count);
148 }
149 mBitmap.recycle();
150 mBitmap = null;
151 }
152 }
153 }
154
155 private boolean isWcgContent() {
156 return mWcgContent;
157 }
158
159 private String getHash() {
160 return mBitmap != null ? Integer.toHexString(mBitmap.hashCode()) : "null";
161 }
162
163 private Rect getTextureDimensions() {
164 return mDimensions;
165 }
166
167 @Override
168 public String toString() {
169 return "{" + getHash() + ", " + mRefCount.get() + "}";
170 }
171 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800172}