ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * 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);
    }
}