blob: fa45ea1acb95046ec72a8d23208a5703f1cc61e4 [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_FLOAT;
20import static android.opengl.GLES20.GL_LINEAR;
21import static android.opengl.GLES20.GL_TEXTURE0;
22import static android.opengl.GLES20.GL_TEXTURE_2D;
23import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
24import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
25import static android.opengl.GLES20.GL_TRIANGLES;
26import static android.opengl.GLES20.glActiveTexture;
27import static android.opengl.GLES20.glBindTexture;
28import static android.opengl.GLES20.glDrawArrays;
29import static android.opengl.GLES20.glEnableVertexAttribArray;
30import static android.opengl.GLES20.glGenTextures;
31import static android.opengl.GLES20.glTexParameteri;
32import static android.opengl.GLES20.glUniform1i;
33import static android.opengl.GLES20.glVertexAttribPointer;
34
35import android.graphics.Bitmap;
36import android.opengl.GLUtils;
Ahan Wu67e7f102019-01-14 20:38:14 +080037import android.util.Log;
38
Ahan Wue16e1fa2019-05-29 18:39:33 +080039import java.io.FileDescriptor;
40import java.io.PrintWriter;
Ahan Wu67e7f102019-01-14 20:38:14 +080041import java.nio.ByteBuffer;
42import java.nio.ByteOrder;
43import java.nio.FloatBuffer;
44
45/**
46 * This class takes charge of the geometry data like vertices and texture coordinates.
47 * It delivers these data to opengl runtime and triggers draw calls if necessary.
48 */
49class ImageGLWallpaper {
50 private static final String TAG = ImageGLWallpaper.class.getSimpleName();
51
Ahan Wu4a297792020-04-16 03:00:14 +080052 private static final String A_POSITION = "aPosition";
53 private static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
54 private static final String U_TEXTURE = "uTexture";
Ahan Wu67e7f102019-01-14 20:38:14 +080055 private static final int POSITION_COMPONENT_COUNT = 2;
56 private static final int TEXTURE_COMPONENT_COUNT = 2;
57 private static final int BYTES_PER_FLOAT = 4;
58
59 // Vertices to define the square with 2 triangles.
60 private static final float[] VERTICES = {
61 -1.0f, -1.0f,
62 +1.0f, -1.0f,
63 +1.0f, +1.0f,
64 +1.0f, +1.0f,
65 -1.0f, +1.0f,
66 -1.0f, -1.0f
67 };
68
69 // Texture coordinates that maps to vertices.
70 private static final float[] TEXTURES = {
71 0f, 1f,
72 1f, 1f,
73 1f, 0f,
74 1f, 0f,
75 0f, 0f,
76 0f, 1f
77 };
78
79 private final FloatBuffer mVertexBuffer;
80 private final FloatBuffer mTextureBuffer;
81 private final ImageGLProgram mProgram;
82
83 private int mAttrPosition;
84 private int mAttrTextureCoordinates;
Ahan Wu67e7f102019-01-14 20:38:14 +080085 private int mUniTexture;
86 private int mTextureId;
87
88 ImageGLWallpaper(ImageGLProgram program) {
89 mProgram = program;
90
91 // Create an float array in opengles runtime (native) and put vertex data.
92 mVertexBuffer = ByteBuffer.allocateDirect(VERTICES.length * BYTES_PER_FLOAT)
93 .order(ByteOrder.nativeOrder())
94 .asFloatBuffer();
95 mVertexBuffer.put(VERTICES);
96 mVertexBuffer.position(0);
97
98 // Create an float array in opengles runtime (native) and put texture data.
99 mTextureBuffer = ByteBuffer.allocateDirect(TEXTURES.length * BYTES_PER_FLOAT)
100 .order(ByteOrder.nativeOrder())
101 .asFloatBuffer();
102 mTextureBuffer.put(TEXTURES);
103 mTextureBuffer.position(0);
104 }
105
Ahan Wu48ebbd72019-03-12 20:59:13 +0800106 void setup(Bitmap bitmap) {
Ahan Wu67e7f102019-01-14 20:38:14 +0800107 setupAttributes();
108 setupUniforms();
Ahan Wu48ebbd72019-03-12 20:59:13 +0800109 setupTexture(bitmap);
Ahan Wu67e7f102019-01-14 20:38:14 +0800110 }
111
112 private void setupAttributes() {
113 mAttrPosition = mProgram.getAttributeHandle(A_POSITION);
114 mVertexBuffer.position(0);
115 glVertexAttribPointer(mAttrPosition, POSITION_COMPONENT_COUNT, GL_FLOAT,
116 false, 0, mVertexBuffer);
117 glEnableVertexAttribArray(mAttrPosition);
118
119 mAttrTextureCoordinates = mProgram.getAttributeHandle(A_TEXTURE_COORDINATES);
120 mTextureBuffer.position(0);
121 glVertexAttribPointer(mAttrTextureCoordinates, TEXTURE_COMPONENT_COUNT, GL_FLOAT,
122 false, 0, mTextureBuffer);
123 glEnableVertexAttribArray(mAttrTextureCoordinates);
124 }
125
126 private void setupUniforms() {
Ahan Wu67e7f102019-01-14 20:38:14 +0800127 mUniTexture = mProgram.getUniformHandle(U_TEXTURE);
128 }
129
Ahan Wu67e7f102019-01-14 20:38:14 +0800130 void draw() {
131 glDrawArrays(GL_TRIANGLES, 0, VERTICES.length / 2);
132 }
133
Ahan Wu48ebbd72019-03-12 20:59:13 +0800134 private void setupTexture(Bitmap bitmap) {
Ahan Wu67e7f102019-01-14 20:38:14 +0800135 final int[] tids = new int[1];
136
137 if (bitmap == null) {
138 Log.w(TAG, "setupTexture: invalid bitmap");
139 return;
140 }
141
142 // Generate one texture object and store the id in tids[0].
143 glGenTextures(1, tids, 0);
144 if (tids[0] == 0) {
145 Log.w(TAG, "setupTexture: glGenTextures() failed");
146 return;
147 }
148
Ahan Wu48ebbd72019-03-12 20:59:13 +0800149 // Bind a named texture to a target.
Ahan Wu67e7f102019-01-14 20:38:14 +0800150 glBindTexture(GL_TEXTURE_2D, tids[0]);
151 // Load the bitmap data and copy it over into the texture object that is currently bound.
152 GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
153 // Use bilinear texture filtering when minification.
154 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
155 // Use bilinear texture filtering when magnification.
156 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
157
158 mTextureId = tids[0];
159 }
160
161 void useTexture() {
162 // Set the active texture unit to texture unit 0.
163 glActiveTexture(GL_TEXTURE0);
164 // Bind the texture to this unit.
165 glBindTexture(GL_TEXTURE_2D, mTextureId);
166 // Let the texture sampler in fragment shader to read form this texture unit.
167 glUniform1i(mUniTexture, 0);
168 }
169
Ahan Wue16e1fa2019-05-29 18:39:33 +0800170 /**
Ahan Wue16e1fa2019-05-29 18:39:33 +0800171 * Called to dump current state.
172 * @param prefix prefix.
173 * @param fd fd.
174 * @param out out.
175 * @param args args.
176 */
177 public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
Ahan Wue16e1fa2019-05-29 18:39:33 +0800178 }
Ahan Wu67e7f102019-01-14 20:38:14 +0800179}