• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <GLES3/gl3.h>
17 #include <cstdint>
18 #include "gl_utils.h"
19 #include "third_party/externals/oboe/samples/RhythmGame/third_party/glm/gtc/matrix_transform.hpp"
20 
21 constexpr uint32_t MESSAGE_MAX_SIZE = 511;
22 
23 namespace OHOS {
24 namespace Media {
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_VIDEOEDITOR, "VideoEditorRender"};
27 }
CreateTexture2D(GLsizei width,GLsizei height,GLenum internalFormat,GLint minFilter,GLint magFilter)28 GLuint GLUtils::CreateTexture2D(GLsizei width, GLsizei height, GLenum internalFormat, GLint minFilter,
29     GLint magFilter)
30 {
31     GLuint textureId = 0;
32     glGenTextures(1, &textureId);
33     glBindTexture(GL_TEXTURE_2D, textureId);
34     glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, width, height);
35     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
36     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
37     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
38     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
39     glBindTexture(GL_TEXTURE_2D, GL_NONE);
40     return textureId;
41 }
42 
CreateTexture2DNoStorage(GLint minFilter,GLint magFilter,GLint wrapS,GLint wrapT)43 GLuint GLUtils::CreateTexture2DNoStorage(GLint minFilter, GLint magFilter, GLint wrapS, GLint wrapT)
44 {
45     GLuint tex;
46     glGenTextures(1, &tex);
47     glBindTexture(GL_TEXTURE_2D, tex);
48     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
49     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
50     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
51     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
52     GLUtils::CheckError(__FILE_NAME__, __LINE__);
53     return tex;
54 }
55 
CreateFramebuffer(GLuint textureId)56 GLuint GLUtils::CreateFramebuffer(GLuint textureId)
57 {
58     GLuint fboId;
59     glGenFramebuffers(1, &fboId);
60     if (textureId != 0) {
61         glBindFramebuffer(GL_FRAMEBUFFER, fboId);
62         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
63         glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
64     }
65     return fboId;
66 }
67 
DeleteTexture(GLuint texture)68 void GLUtils::DeleteTexture(GLuint texture)
69 {
70     if (texture == 0) {
71         return;
72     }
73     glDeleteTextures(1, &texture);
74 }
75 
DeleteFboOnly(GLuint fbo)76 void GLUtils::DeleteFboOnly(GLuint fbo)
77 {
78     glDeleteFramebuffers(1, &fbo);
79 }
80 
CopyTexture(GLuint srcTexId,GLuint dstTexId,GLint width,GLint height)81 void GLUtils::CopyTexture(GLuint srcTexId, GLuint dstTexId, GLint width, GLint height)
82 {
83     glBindTexture(GL_TEXTURE_2D, dstTexId);
84     GLuint tempFbo;
85     glGenFramebuffers(1, &tempFbo);
86     glBindFramebuffer(GL_FRAMEBUFFER, tempFbo);
87     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexId, 0);
88     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
89 
90     glBindTexture(GL_TEXTURE_2D, GL_NONE);
91     glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
92     glDeleteFramebuffers(1, &tempFbo);
93 }
94 
CreateTexNoStorage(GLenum target)95 GLuint GLUtils::CreateTexNoStorage(GLenum target)
96 {
97     GLuint tex;
98     glGenTextures(1, &tex);
99     glBindTexture(target, tex);
100     glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
101     glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
102     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
103     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
104     glBindTexture(target, 0);
105     return tex;
106 }
107 
GetInternalFormatPixelByteSize(GLenum internalFormat)108 size_t GLUtils::GetInternalFormatPixelByteSize(GLenum internalFormat)
109 {
110     size_t ret = 0;
111     const int32_t ARGS_TWO = 2;
112     const int32_t ARGS_EIGHT = 8;
113     const int32_t ARGS_FOUR = 4;
114     switch (internalFormat) {
115         case GL_RGBA8:
116         case GL_R32F:
117             ret = ARGS_FOUR;
118             break;
119         case GL_RGBA16F:
120             ret = ARGS_EIGHT;
121             break;
122         case GL_R8:
123             ret = 1;
124             break;
125         case GL_RGB565:
126             ret = ARGS_TWO;
127             break;
128         case GL_RGBA4:
129             ret = ARGS_TWO;
130             break;
131         default:
132             break;
133     }
134     return ret;
135 }
136 
LoadShader(const std::string & src,uint32_t shaderType)137 GLuint GLUtils::LoadShader(const std::string& src, uint32_t shaderType)
138 {
139     const char* tempSrc = src.c_str();
140     GLuint shader = glCreateShader(shaderType);
141     if (shader == 0) {
142         MEDIA_LOGE("Could Not Create Shader!");
143         return shader;
144     }
145     glShaderSource(shader, 1, &tempSrc, nullptr);
146     glCompileShader(shader);
147     GLint status = GL_FALSE;
148     glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
149     if (status == GL_FALSE) {
150         GLchar message[MESSAGE_MAX_SIZE + 1] = {0};
151         glGetShaderInfoLog(shader, MESSAGE_MAX_SIZE, nullptr, &message[0]);
152         MEDIA_LOGE("Load Shader Error: %{public}s", message);
153         glDeleteShader(shader);
154         shader = 0;
155     }
156     return shader;
157 }
158 
CreateProgram(const std::string & vss,const std::string & fss)159 GLuint GLUtils::CreateProgram(const std::string& vss, const std::string& fss)
160 {
161     GLuint vs = LoadShader(vss, GL_VERTEX_SHADER);
162     GLuint fs = LoadShader(fss, GL_FRAGMENT_SHADER);
163     if (vs == 0 || fs == 0) {
164         return 0;
165     }
166     GLuint program = glCreateProgram();
167     if (program == 0) {
168         MEDIA_LOGE("Could Not Create Program!");
169         return program;
170     }
171     glAttachShader(program, vs);
172     glAttachShader(program, fs);
173     glLinkProgram(program);
174     GLint linkStatus = GL_FALSE;
175     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
176     if (linkStatus == GL_FALSE) {
177         GLchar message[MESSAGE_MAX_SIZE + 1] = {0};
178         glGetShaderInfoLog(program, MESSAGE_MAX_SIZE, nullptr, &message[0]);
179         MEDIA_LOGE("Create Program Error: %{public}s", message);
180         glDeleteProgram(program);
181         program = 0;
182         return program;
183     }
184     if (vs > 0) {
185         glDetachShader(program, vs);
186         glDeleteShader(vs);
187     }
188     if (vs > 0) {
189         glDetachShader(program, fs);
190         glDeleteShader(fs);
191     }
192     return program;
193 }
194 
GetOesSamplingMatrix(Vec2 bufferWH,Vec2 displayWH,int32_t angle,bool flip)195 Mat4x4 GLUtils::GetOesSamplingMatrix(Vec2 bufferWH, Vec2 displayWH, int32_t angle, bool flip)
196 {
197     const float half = 0.5;
198     Mat4x4 result(1);
199     angle = angle / 90 * 90; // 默认旋转角度是90的整数倍
200     Vec2 dataWH = (angle == 90 || angle == 270) ? Vec2{ displayWH.y, displayWH.x } : displayWH;
201     Vec2 ratioWH = Vec2(dataWH.x / bufferWH.x, dataWH.y / bufferWH.y);
202     result = glm::translate(result, Vec3(half, half, 0.0));
203     result = glm::rotate(result, glm::radians(-(float)angle), Vec3(0.0, 0.0, 1.0));
204     result = glm::translate(result, Vec3(-half, -half, 0.0));
205     result[0][0] *= ratioWH.x;
206     result[1][1] *= ratioWH.y;
207     return result;
208 }
209 
CheckError(const char * file,int32_t line)210 void GLUtils::CheckError(const char* file, int32_t line)
211 {
212     GLenum status = glGetError();
213     if (status != GL_NO_ERROR) {
214         MEDIA_LOGE("[Render] GL Error: 0x%{public}x [%{public}s:%{public}d]\n", status, file, line);
215     }
216 }
217 
218 }
219 }