| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.systemui.glwallpaper; |
| |
| import static android.opengl.GLES20.GL_FRAGMENT_SHADER; |
| import static android.opengl.GLES20.GL_VERTEX_SHADER; |
| import static android.opengl.GLES20.glAttachShader; |
| import static android.opengl.GLES20.glCompileShader; |
| import static android.opengl.GLES20.glCreateProgram; |
| import static android.opengl.GLES20.glCreateShader; |
| import static android.opengl.GLES20.glGetAttribLocation; |
| import static android.opengl.GLES20.glGetUniformLocation; |
| import static android.opengl.GLES20.glLinkProgram; |
| import static android.opengl.GLES20.glShaderSource; |
| import static android.opengl.GLES20.glUseProgram; |
| |
| import android.content.Context; |
| import android.content.res.Resources; |
| import android.util.Log; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| |
| /** |
| * This class takes charge of linking shader codes and then return a handle for OpenGL ES program. |
| */ |
| class ImageGLProgram { |
| private static final String TAG = ImageGLProgram.class.getSimpleName(); |
| |
| private Context mContext; |
| private int mProgramHandle; |
| |
| ImageGLProgram(Context context) { |
| mContext = context.getApplicationContext(); |
| } |
| |
| private int loadShaderProgram(int vertexId, int fragmentId) { |
| final String vertexSrc = getShaderResource(vertexId); |
| final String fragmentSrc = getShaderResource(fragmentId); |
| final int vertexHandle = getShaderHandle(GL_VERTEX_SHADER, vertexSrc); |
| final int fragmentHandle = getShaderHandle(GL_FRAGMENT_SHADER, fragmentSrc); |
| return getProgramHandle(vertexHandle, fragmentHandle); |
| } |
| |
| private String getShaderResource(int shaderId) { |
| Resources res = mContext.getResources(); |
| StringBuilder code = new StringBuilder(); |
| |
| try (BufferedReader reader = new BufferedReader( |
| new InputStreamReader(res.openRawResource(shaderId)))) { |
| String nextLine; |
| while ((nextLine = reader.readLine()) != null) { |
| code.append(nextLine).append("\n"); |
| } |
| } catch (IOException | Resources.NotFoundException ex) { |
| Log.d(TAG, "Can not read the shader source", ex); |
| code = null; |
| } |
| |
| return code == null ? "" : code.toString(); |
| } |
| |
| private int getShaderHandle(int type, String src) { |
| final int shader = glCreateShader(type); |
| if (shader == 0) { |
| Log.d(TAG, "Create shader failed, type=" + type); |
| return 0; |
| } |
| glShaderSource(shader, src); |
| glCompileShader(shader); |
| return shader; |
| } |
| |
| private int getProgramHandle(int vertexHandle, int fragmentHandle) { |
| final int program = glCreateProgram(); |
| if (program == 0) { |
| Log.d(TAG, "Can not create OpenGL ES program"); |
| return 0; |
| } |
| |
| glAttachShader(program, vertexHandle); |
| glAttachShader(program, fragmentHandle); |
| glLinkProgram(program); |
| return program; |
| } |
| |
| boolean useGLProgram(int vertexResId, int fragmentResId) { |
| mProgramHandle = loadShaderProgram(vertexResId, fragmentResId); |
| glUseProgram(mProgramHandle); |
| return true; |
| } |
| |
| int getAttributeHandle(String name) { |
| return glGetAttribLocation(mProgramHandle, name); |
| } |
| |
| int getUniformHandle(String name) { |
| return glGetUniformLocation(mProgramHandle, name); |
| } |
| } |