• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "pixel_map_gl_context.h"
17 
18 #undef LOG_DOMAIN
19 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
20 #undef LOG_TAG
21 #define LOG_TAG "PixelMapGlContext"
22 
23 namespace OHOS {
24 namespace Media {
25 
26 static bool displayInitFlag = false;
27 EGLDisplay PixelMapGlContext::eglDisplay_ = EGL_NO_DISPLAY;
28 EGLConfig PixelMapGlContext::config_ = nullptr;
29 
PixelMapGlContext()30 PixelMapGlContext::PixelMapGlContext()
31 {
32 }
33 
PixelMapGlContext(bool init)34 PixelMapGlContext::PixelMapGlContext(bool init)
35 {
36     if (init) {
37         InitEGLContext();
38     }
39 }
40 
~PixelMapGlContext()41 PixelMapGlContext::~PixelMapGlContext() noexcept
42 {
43     Clear();
44 }
45 
Init()46 bool PixelMapGlContext::Init()
47 {
48     if (!InitEGLContext()) {
49         return false;
50     }
51 
52     if (!InitGrContext()) {
53         return false;
54     }
55 
56     return true;
57 }
58 
InitEGLContext()59 bool PixelMapGlContext::InitEGLContext()
60 {
61     ImageTrace imageTrace("PixelMapGlContext::InitEGLContext");
62     if (!displayInitFlag) {
63         eglDisplay_ = eglGetPlatformDisplay(EGL_PLATFORM_OHOS_KHR, EGL_DEFAULT_DISPLAY, nullptr);
64         if (eglDisplay_ == EGL_NO_DISPLAY) {
65             IMAGE_LOGE("PixelMapGlContext::Init: eglGetDisplay error: ");
66             return false;
67         }
68         EGLint major = 0;
69         EGLint minor = 0;
70         if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) {
71             IMAGE_LOGE("Failed to initialize EGLDisplay");
72             return false;
73         }
74         if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
75             IMAGE_LOGE("Failed to bind OpenGL ES API");
76             return false;
77         }
78         unsigned int ret;
79         EGLint count;
80         EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8,
81             EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_RENDERABLE_TYPE,
82             EGL_OPENGL_ES3_BIT, EGL_NONE };
83         ret = eglChooseConfig(eglDisplay_, configAttribs, &config_, 1, &count);
84         if (!(ret && static_cast<unsigned int>(count) >= 1)) {
85             IMAGE_LOGE("Failed to eglChooseConfig");
86             return false;
87         }
88         IMAGE_LOGE("PixelMapGlContext::Init");
89         displayInitFlag = true;
90     }
91 
92     if (eglDisplay_ == EGL_NO_DISPLAY) {
93         return false;
94     }
95 
96     static const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
97     eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, contextAttribs);
98     if (eglContext_ == EGL_NO_CONTEXT) {
99         IMAGE_LOGE("Failed to create egl context %{public}x", eglGetError());
100         return false;
101     }
102 
103     if (!CreatePbufferSurface()) {
104         return false;
105     }
106     MakeCurrent(pbufferSurface_);
107 
108     return true;
109 }
110 
CreatePbufferSurface()111 bool PixelMapGlContext::CreatePbufferSurface()
112 {
113     if (pbufferSurface_ == EGL_NO_SURFACE) {
114         EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
115         pbufferSurface_ = eglCreatePbufferSurface(eglDisplay_, config_, attribs);
116         if (pbufferSurface_ == EGL_NO_SURFACE) {
117             IMAGE_LOGE(
118                 "PixelMapGlContext::CreatePbufferSurface failed, error is %{public}x",
119                 eglGetError());
120             return false;
121         }
122     }
123     return true;
124 }
125 
MakeCurrentSimple(bool needCurrent)126 bool PixelMapGlContext::MakeCurrentSimple(bool needCurrent)
127 {
128     EGLSurface currSurfaceDraw = pbufferSurface_;
129     EGLSurface currSurfaceRead = pbufferSurface_;
130     EGLContext currContext = eglContext_;
131     if (!needCurrent) {
132         currSurfaceDraw = oldEglSurfaceDraw_;
133         currSurfaceRead = oldEglSurfaceRead_;
134         currContext = oldEglContext_;
135     } else {
136         EGLSurface oldSurface = eglGetCurrentSurface(EGL_DRAW);
137         EGLContext oldContext = eglGetCurrentContext();
138         if (oldSurface == currSurfaceDraw && oldContext == currContext) {
139             IMAGE_LOGI("PixelGPU::MakeCurrentSimple with same context");
140             return true;
141         }
142         oldEglSurfaceDraw_ = oldSurface;
143         oldEglSurfaceRead_ = eglGetCurrentSurface(EGL_READ);
144         oldEglContext_ = oldContext;
145     }
146 
147     if (eglMakeCurrent(eglDisplay_, currSurfaceDraw, currSurfaceRead, currContext) != EGL_TRUE) {
148         EGLint surfaceId = -1;
149         eglQuerySurface(eglDisplay_, currSurfaceDraw, EGL_CONFIG_ID, &surfaceId);
150         IMAGE_LOGE(
151             "PixelMapGlContext::MakeCurrent failed %{public}d, error is %{public}x needCurrent %{public}d",
152             surfaceId,
153             eglGetError(), needCurrent);
154         return false;
155     }
156     return true;
157 }
158 
MakeCurrent(EGLSurface surface) const159 void PixelMapGlContext::MakeCurrent(EGLSurface surface) const
160 {
161     EGLSurface currSurface = surface;
162     if (currSurface == EGL_NO_SURFACE) {
163         currSurface = pbufferSurface_;
164     }
165 
166     if (eglMakeCurrent(eglDisplay_, currSurface, currSurface, eglContext_) != EGL_TRUE) {
167         EGLint surfaceId = -1;
168         eglQuerySurface(eglDisplay_, surface, EGL_CONFIG_ID, &surfaceId);
169         IMAGE_LOGE(
170             "PixelMapGlContext::MakeCurrent failed for eglSurface %{public}d, error is %{public}x",
171             surfaceId,
172             eglGetError());
173     }
174 }
175 
InitGrContext()176 bool PixelMapGlContext::InitGrContext()
177 {
178 #ifdef USE_M133_SKIA
179     sk_sp<const GrGLInterface> glInterface(GrGLMakeNativeInterface());
180 #else
181     sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
182 #endif
183     if (glInterface == nullptr) {
184         IMAGE_LOGE("SetUpGrContext failed to make native interface");
185         return false;
186     }
187 
188     GrContextOptions options;
189     options.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
190     options.fPreferExternalImagesOverES3 = true;
191     options.fDisableDistanceFieldPaths = true;
192 #ifdef USE_M133_SKIA
193     grContext_ = GrDirectContexts::MakeGL(std::move(glInterface), options);
194 #else
195     grContext_ = GrDirectContext::MakeGL(std::move(glInterface), options);
196 #endif
197     return grContext_ != nullptr;
198 }
199 
Clear()200 void PixelMapGlContext::Clear() noexcept
201 {
202     if (eglDisplay_ == EGL_NO_DISPLAY) {
203         return;
204     }
205 
206     grContext_ = nullptr;
207 
208     if (pbufferSurface_ != EGL_NO_SURFACE) {
209         EGLBoolean ret = eglDestroySurface(eglDisplay_, pbufferSurface_);
210         if (ret != EGL_TRUE) {
211             IMAGE_LOGE("PixelMapGlContext::Clear() failed error is %{public}x.", eglGetError());
212         }
213         pbufferSurface_ = EGL_NO_SURFACE;
214     }
215 
216     (void)eglDestroyContext(eglDisplay_, eglContext_);
217     eglContext_ = EGL_NO_CONTEXT;
218 }
219 } // namespace Media
220 } // namespace OHOS
221