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 "offscreen_context_helper.h"
17 #include <EGL/egl.h>
18 #include <EGL/eglext.h>
19 #include <GLES/gl.h>
20 #include <window.h>
21
22 #include <3d_widget_adapter_log.h>
23
24
25 namespace OHOS::Render3D {
AutoRestore()26 AutoRestore::AutoRestore()
27 {
28 c_ = eglGetCurrentContext();
29 rs_ = eglGetCurrentSurface(EGL_READ);
30 ws_ = eglGetCurrentSurface(EGL_DRAW);
31 d_ = eglGetCurrentDisplay();
32 if (d_ == EGL_NO_DISPLAY) {
33 d_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
34 }
35 if (!eglMakeCurrent(d_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
36 WIDGET_LOGE("AutoRestore make current error %d", eglGetError());
37 }
38 }
39
~AutoRestore()40 AutoRestore::~AutoRestore()
41 {
42 if (!eglMakeCurrent(d_, ws_, rs_, c_)) {
43 WIDGET_LOGE("~AutoRestore make current error %d", eglGetError());
44 }
45 }
46
~OffScreenContextHelper()47 OffScreenContextHelper::~OffScreenContextHelper()
48 {
49 DestroyOffScreenContext();
50 }
51
CreateOffScreenContext(EGLContext eglContext)52 EGLContext OffScreenContextHelper::CreateOffScreenContext(EGLContext eglContext)
53 {
54 if (localThreadContext_ != EGL_NO_CONTEXT) {
55 return localThreadContext_;
56 }
57
58 eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
59 if (eglContext == EGL_NO_CONTEXT) {
60 EGLint major = 0;
61 EGLint minor = 0;
62 if (!eglInitialize(eglDisplay_, &major, &minor)) {
63 WIDGET_LOGW("Initialize egl fail");
64 }
65 if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
66 WIDGET_LOGW("faile to bind gles api");
67 }
68 }
69
70 EGLint contextAttrs[] = {
71 EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2,
72 EGL_NONE, EGL_NONE,
73 };
74 EGLint configAttribs[] = {
75 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, EGL_RED_SIZE, 8,
76 EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0,
77 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_CONFORMANT, EGL_OPENGL_ES3_BIT_KHR, EGL_NONE, EGL_NONE,
78 };
79 EGLint count = -1;
80 EGLConfig config;
81
82 if (!eglChooseConfig(eglDisplay_, configAttribs, &config, 1, &count)) {
83 WIDGET_LOGE("eglChooseConfig error %d", eglGetError());
84 return EGL_NO_CONTEXT;
85 }
86
87 localThreadContext_ = eglCreateContext(eglDisplay_, config, eglContext, contextAttrs);
88 auto error = eglGetError();
89 if (error != EGL_SUCCESS) {
90 WIDGET_LOGE("create context fail %d", error);
91 return EGL_NO_CONTEXT;
92 }
93
94 EGLint pbufferAttribs[] = {
95 EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE,
96 };
97 pBufferSurface_ = eglCreatePbufferSurface(eglDisplay_, config, pbufferAttribs);
98 return localThreadContext_;
99 }
100
GetOffScreenContext()101 EGLContext OffScreenContextHelper::GetOffScreenContext()
102 {
103 return localThreadContext_;
104 }
105
BindOffScreenContext()106 void OffScreenContextHelper::BindOffScreenContext()
107 {
108 if (!eglMakeCurrent(eglDisplay_, pBufferSurface_, pBufferSurface_, localThreadContext_)) {
109 WIDGET_LOGE("%s, eglMakecurrent error %d", __func__, eglGetError());
110 }
111 }
112
DestroyOffScreenContext()113 void OffScreenContextHelper::DestroyOffScreenContext()
114 {
115 WIDGET_LOGI("DestroyOffScreenContext");
116 if (pBufferSurface_ != EGL_NO_SURFACE) {
117 eglDestroySurface(eglDisplay_, pBufferSurface_);
118 pBufferSurface_ = EGL_NO_SURFACE;
119 }
120
121 if (localThreadContext_ != EGL_NO_CONTEXT) {
122 eglDestroyContext(eglDisplay_, localThreadContext_);
123 localThreadContext_ = EGL_NO_CONTEXT;
124 }
125 }
126 } // namespace OHOS::Render3D
127