• 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 #define GL_GLEXT_PROTOTYPES
17 #define EGL_EGLEXT_PROTOTYPES
18 
19 #include "gl_utils.h"
20 #include "surface_buffer.h"
21 #include "native_window.h"
22 #include "effect_trace.h"
23 #include "effect_log.h"
24 
25 #include <GLES2/gl2ext.h>
26 
27 #include <cmath>
28 #include <string>
29 #include <cstdlib>
30 #include "effect_log.h"
31 
32 namespace OHOS {
33 namespace Media {
34 namespace Effect {
35 constexpr const int MSG_SIZE = 512;
36 constexpr const int BYTES_OF_RGBA16F = 8;
37 constexpr const int BYTES_OF_R32F = 4;
38 constexpr const int BYTES_OF_R8 = 1;
39 constexpr const int BYTES_OF_RGB565 = 2;
40 constexpr const int BYTES_OF_RGBA4 = 2;
41 
CreateTexture2D(GLsizei width,GLsizei height,GLsizei levels,GLenum internalFormat,GLint minFilter,GLint magFilter,GLint wrapS,GLint wrapT)42 GLuint GLUtils::CreateTexture2D(GLsizei width, GLsizei height, GLsizei levels, GLenum internalFormat, GLint minFilter,
43     GLint magFilter, GLint wrapS, GLint wrapT)
44 {
45     GLuint textureId = 0;
46     glGenTextures(1, &textureId);
47     glBindTexture(GL_TEXTURE_2D, textureId);
48     glTexStorage2D(GL_TEXTURE_2D, levels, internalFormat, width, height);
49     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
50     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
51     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
52     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
53     glBindTexture(GL_TEXTURE_2D, GL_NONE);
54     CheckError(__FILE__, __LINE__);
55     return textureId;
56 }
57 
CreateFramebuffer(unsigned int textureId)58 unsigned int GLUtils::CreateFramebuffer(unsigned int textureId)
59 {
60     GLuint fboId;
61     glGenFramebuffers(1, &fboId);
62     if (textureId != 0) {
63         glBindFramebuffer(GL_FRAMEBUFFER, fboId);
64         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
65         glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
66     }
67     return fboId;
68 }
69 
CreateFramebufferWithTarget(unsigned int textureId,GLenum target)70 unsigned int GLUtils::CreateFramebufferWithTarget(unsigned int textureId, GLenum target)
71 {
72     GLuint fboId;
73     glGenFramebuffers(1, &fboId);
74     if (textureId != 0) {
75         glBindFramebuffer(GL_FRAMEBUFFER, fboId);
76         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, textureId, 0);
77         glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
78     }
79     return fboId;
80 }
81 
DeleteFboOnly(unsigned int fbo)82 void GLUtils::DeleteFboOnly(unsigned int fbo)
83 {
84     glDeleteFramebuffers(1, &fbo);
85 }
86 
DeleteTexture(unsigned int textureId)87 void GLUtils::DeleteTexture(unsigned int textureId)
88 {
89     if (textureId == 0) {
90         return;
91     }
92     glDeleteTextures(1, &textureId);
93 }
94 
CreateTexWithStorage(GLenum target,int levels,GLenum internalFormat,int width,int height)95 GLuint GLUtils::CreateTexWithStorage(GLenum target, int levels, GLenum internalFormat,
96     int width, int height)
97 {
98     GLuint textureId = 0;
99     glGenTextures(1, &textureId);
100     glBindTexture(target, textureId);
101     glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
102     glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
103     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
104     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
105     glTexStorage2D(target, levels, internalFormat, width, height);
106     glBindTexture(target, 0);
107     return textureId;
108 }
109 
CheckError(const char * file,int line)110 void GLUtils::CheckError(const char *file, int line)
111 {
112     GLenum status = glGetError();
113     if (status != GL_NO_ERROR) {
114         EFFECT_LOGE("GL Error: 0x%{public}x, [%{public}s : %{public}d]", status, file, line);
115     }
116 }
117 
GetInternalFormatPixelByteSize(GLenum internalFormat)118 size_t GLUtils::GetInternalFormatPixelByteSize(GLenum internalFormat)
119 {
120     int ret = 0;
121     switch (internalFormat) {
122         case GL_RGBA8:
123         case GL_R32F:
124             ret = BYTES_OF_R32F;
125             break;
126         case GL_RGBA16F:
127             ret = BYTES_OF_RGBA16F;
128             break;
129         case GL_R8:
130             ret = BYTES_OF_R8;
131             break;
132         case GL_RGB565:
133             ret = BYTES_OF_RGB565;
134             break;
135         case GL_RGBA4:
136             ret = BYTES_OF_RGBA4;
137             break;
138         default:
139             break;
140     }
141     return ret;
142 }
143 
LoadShader(const std::string & src,unsigned int shaderType)144 unsigned int GLUtils::LoadShader(const std::string &src, unsigned int shaderType)
145 {
146     const char* tempSrc = src.c_str();
147     unsigned int shader = glCreateShader(shaderType);
148     if (shader == 0) {
149         EFFECT_LOGE("Could Not Create Shader");
150     }
151     glShaderSource(shader, 1, &tempSrc, nullptr);
152     glCompileShader(shader);
153     int status = GL_FALSE;
154     glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
155     if (status == GL_FALSE) {
156         GLchar message[MSG_SIZE] = {0};
157         glGetShaderInfoLog(shader, MSG_SIZE - 1, nullptr, &message[0]);
158         EFFECT_LOGE("LoadShader Error: %{public}s", message);
159         glDeleteShader(shader);
160         shader = 0;
161     }
162     CheckError(__FILE__, __LINE__);
163     return shader;
164 }
165 
CreateProgram(const std::string & vss,const std::string & fss)166 unsigned int GLUtils::CreateProgram(const std::string &vss, const std::string &fss)
167 {
168     unsigned int vs = LoadShader(vss, GL_VERTEX_SHADER);
169     unsigned int fs = LoadShader(fss, GL_FRAGMENT_SHADER);
170     if (vs == 0 || fs == 0) {
171         return 0;
172     }
173     unsigned int program = glCreateProgram();
174     if (program == 0) {
175         EFFECT_LOGE("CreateProgram Failed");
176     }
177     glAttachShader(program, vs);
178     glAttachShader(program, fs);
179     glLinkProgram(program);
180     CheckError(__FILE__, __LINE__);
181     int status = GL_FALSE;
182     glGetProgramiv(program, GL_LINK_STATUS, &status);
183     if (status == GL_FALSE) {
184         GLchar message[MSG_SIZE] = {0};
185         glGetShaderInfoLog(program, MSG_SIZE - 1, nullptr, &message[0]);
186         EFFECT_LOGE("LoadShader Error: %{public}s", message);
187         glDeleteProgram(program);
188         program = 0;
189     }
190     if (vs > 0) {
191         glDetachShader(program, vs);
192         glDeleteShader(vs);
193     }
194     if (fs > 0) {
195         glDetachShader(program, fs);
196         glDeleteShader(fs);
197     }
198     return program;
199 }
200 
CreateEGLImage(EGLDisplay display,SurfaceBuffer * buffer)201 EGLImageKHR GLUtils::CreateEGLImage(EGLDisplay display, SurfaceBuffer *buffer)
202 {
203     NativeWindowBuffer *nBuffer = CreateNativeWindowBufferFromSurfaceBuffer(&buffer);
204     EGLint attrsList[] = {
205         EGL_IMAGE_PRESERVED,
206         EGL_TRUE,
207         EGL_NONE,
208     };
209     EGLint *attrs = attrsList;
210     EGLImageKHR img = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nBuffer, attrs);
211     if (img == EGL_NO_IMAGE_KHR) {
212         EGLint error = eglGetError();
213         EFFECT_LOGE("CreateEGLImage Error: %{public}d", error);
214         eglTerminate(display);
215     }
216     CheckError(__FILE__, __LINE__);
217     DestroyNativeWindowBuffer(nBuffer);
218     return img;
219 }
220 
CreateTextureFromImage(EGLImageKHR img)221 GLuint GLUtils::CreateTextureFromImage(EGLImageKHR img)
222 {
223     GLuint textureId = 0;
224     glGenTextures(1, &textureId);
225     glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
226     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, static_cast<GLeglImageOES>(img));
227     glBindTexture(GL_TEXTURE_EXTERNAL_OES, GL_NONE);
228     CheckError(__FILE__, __LINE__);
229     return textureId;
230 }
231 
DestroyImage(EGLImageKHR img)232 void GLUtils::DestroyImage(EGLImageKHR img)
233 {
234     eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), img);
235 }
236 
CreateTextureFromSurfaceBuffer(SurfaceBuffer * buffer)237 GLuint GLUtils::CreateTextureFromSurfaceBuffer(SurfaceBuffer *buffer)
238 {
239     if (buffer == nullptr) {
240         return 0;
241     }
242     EGLImageKHR img = CreateEGLImage(eglGetDisplay(EGL_DEFAULT_DISPLAY), buffer);
243     GLuint tex = CreateTextureFromImage(img);
244     return tex;
245 }
246 } // namespace Effect
247 } // namespace Media
248 } // namespace OHOS