• 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 #ifdef USE_M133_SKIA
20 #include "samples/RhythmGame/third_party/glm/gtc/matrix_transform.hpp"
21 #else
22 #include "third_party/externals/oboe/samples/RhythmGame/third_party/glm/gtc/matrix_transform.hpp"
23 #endif
24 
25 constexpr uint32_t MESSAGE_MAX_SIZE = 511;
26 
27 namespace OHOS {
28 namespace Media {
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_VIDEOEDITOR, "VideoEditorRender"};
31 }
CreateTexture2D(GLsizei width,GLsizei height,GLenum internalFormat,GLint minFilter,GLint magFilter)32 GLuint GLUtils::CreateTexture2D(GLsizei width, GLsizei height, GLenum internalFormat, GLint minFilter,
33     GLint magFilter)
34 {
35     GLuint textureId = 0;
36     glGenTextures(1, &textureId);
37     glBindTexture(GL_TEXTURE_2D, textureId);
38     glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, width, height);
39     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
40     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
41     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
42     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
43     glBindTexture(GL_TEXTURE_2D, GL_NONE);
44     return textureId;
45 }
46 
CreateTexture2DNoStorage(GLint minFilter,GLint magFilter,GLint wrapS,GLint wrapT)47 GLuint GLUtils::CreateTexture2DNoStorage(GLint minFilter, GLint magFilter, GLint wrapS, GLint wrapT)
48 {
49     GLuint tex;
50     glGenTextures(1, &tex);
51     glBindTexture(GL_TEXTURE_2D, tex);
52     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
53     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
54     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
55     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
56     GLUtils::CheckError(__FILE_NAME__, __LINE__);
57     return tex;
58 }
59 
CreateFramebuffer(GLuint textureId)60 GLuint GLUtils::CreateFramebuffer(GLuint textureId)
61 {
62     GLuint fboId;
63     glGenFramebuffers(1, &fboId);
64     if (textureId != 0) {
65         glBindFramebuffer(GL_FRAMEBUFFER, fboId);
66         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
67         glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
68     }
69     return fboId;
70 }
71 
DeleteTexture(GLuint texture)72 void GLUtils::DeleteTexture(GLuint texture)
73 {
74     if (texture == 0) {
75         return;
76     }
77     glDeleteTextures(1, &texture);
78 }
79 
DeleteFboOnly(GLuint fbo)80 void GLUtils::DeleteFboOnly(GLuint fbo)
81 {
82     glDeleteFramebuffers(1, &fbo);
83 }
84 
CopyTexture(GLuint srcTexId,GLuint dstTexId,GLint width,GLint height)85 void GLUtils::CopyTexture(GLuint srcTexId, GLuint dstTexId, GLint width, GLint height)
86 {
87     glBindTexture(GL_TEXTURE_2D, dstTexId);
88     GLuint tempFbo;
89     glGenFramebuffers(1, &tempFbo);
90     glBindFramebuffer(GL_FRAMEBUFFER, tempFbo);
91     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexId, 0);
92     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
93 
94     glBindTexture(GL_TEXTURE_2D, GL_NONE);
95     glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
96     glDeleteFramebuffers(1, &tempFbo);
97 }
98 
CreateTexNoStorage(GLenum target)99 GLuint GLUtils::CreateTexNoStorage(GLenum target)
100 {
101     GLuint tex;
102     glGenTextures(1, &tex);
103     glBindTexture(target, tex);
104     glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
105     glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
106     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
107     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
108     glBindTexture(target, 0);
109     return tex;
110 }
111 
GetInternalFormatPixelByteSize(GLenum internalFormat)112 size_t GLUtils::GetInternalFormatPixelByteSize(GLenum internalFormat)
113 {
114     size_t ret = 0;
115     const int32_t ARGS_TWO = 2;
116     const int32_t ARGS_EIGHT = 8;
117     const int32_t ARGS_FOUR = 4;
118     switch (internalFormat) {
119         case GL_RGBA8:
120         case GL_R32F:
121             ret = ARGS_FOUR;
122             break;
123         case GL_RGBA16F:
124             ret = ARGS_EIGHT;
125             break;
126         case GL_R8:
127             ret = 1;
128             break;
129         case GL_RGB565:
130             ret = ARGS_TWO;
131             break;
132         case GL_RGBA4:
133             ret = ARGS_TWO;
134             break;
135         default:
136             break;
137     }
138     return ret;
139 }
140 
LoadShader(const std::string & src,uint32_t shaderType)141 GLuint GLUtils::LoadShader(const std::string& src, uint32_t shaderType)
142 {
143     const char* tempSrc = src.c_str();
144     GLuint shader = glCreateShader(shaderType);
145     if (shader == 0) {
146         MEDIA_LOGE("Could Not Create Shader!");
147         return shader;
148     }
149     glShaderSource(shader, 1, &tempSrc, nullptr);
150     glCompileShader(shader);
151     GLint status = GL_FALSE;
152     glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
153     if (status == GL_FALSE) {
154         GLchar message[MESSAGE_MAX_SIZE + 1] = {0};
155         glGetShaderInfoLog(shader, MESSAGE_MAX_SIZE, nullptr, &message[0]);
156         MEDIA_LOGE("Load Shader Error: %{public}s", message);
157         glDeleteShader(shader);
158         shader = 0;
159     }
160     return shader;
161 }
162 
CreateProgram(const std::string & vss,const std::string & fss)163 GLuint GLUtils::CreateProgram(const std::string& vss, const std::string& fss)
164 {
165     GLuint vs = LoadShader(vss, GL_VERTEX_SHADER);
166     GLuint fs = LoadShader(fss, GL_FRAGMENT_SHADER);
167     if (vs == 0 || fs == 0) {
168         return 0;
169     }
170     GLuint program = glCreateProgram();
171     if (program == 0) {
172         MEDIA_LOGE("Could Not Create Program!");
173         return program;
174     }
175     glAttachShader(program, vs);
176     glAttachShader(program, fs);
177     glLinkProgram(program);
178     GLint linkStatus = GL_FALSE;
179     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
180     if (linkStatus == GL_FALSE) {
181         GLchar message[MESSAGE_MAX_SIZE + 1] = {0};
182         glGetShaderInfoLog(program, MESSAGE_MAX_SIZE, nullptr, &message[0]);
183         MEDIA_LOGE("Create Program Error: %{public}s", message);
184         glDeleteProgram(program);
185         program = 0;
186         return program;
187     }
188     if (vs > 0) {
189         glDetachShader(program, vs);
190         glDeleteShader(vs);
191     }
192     if (vs > 0) {
193         glDetachShader(program, fs);
194         glDeleteShader(fs);
195     }
196     return program;
197 }
198 
GetOesSamplingMatrix(Vec2 bufferWH,Vec2 displayWH,int32_t angle,bool flip)199 Mat4x4 GLUtils::GetOesSamplingMatrix(Vec2 bufferWH, Vec2 displayWH, int32_t angle, bool flip)
200 {
201     const float half = 0.5;
202     Mat4x4 result(1);
203     angle = angle / 90 * 90; // 默认旋转角度是90的整数倍
204     Vec2 dataWH = (angle == 90 || angle == 270) ? Vec2{ displayWH.y, displayWH.x } : displayWH;
205     Vec2 ratioWH = Vec2(dataWH.x / bufferWH.x, dataWH.y / bufferWH.y);
206     result = glm::translate(result, Vec3(half, half, 0.0));
207     result = glm::rotate(result, glm::radians(-(float)angle), Vec3(0.0, 0.0, 1.0));
208     result = glm::translate(result, Vec3(-half, -half, 0.0));
209     result[0][0] *= ratioWH.x;
210     result[1][1] *= ratioWH.y;
211     return result;
212 }
213 
CheckError(const char * file,int32_t line)214 void GLUtils::CheckError(const char* file, int32_t line)
215 {
216     GLenum status = glGetError();
217     if (status != GL_NO_ERROR) {
218         MEDIA_LOGE("[Render] GL Error: 0x%{public}x [%{public}s:%{public}d]\n", status, file, line);
219     }
220 }
221 
222 }
223 }