1 /*
2 * Copyright (c) 2021-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 "context/webgl_rendering_context_basic_base.h"
17
18 #include "context/webgl2_rendering_context.h"
19 #include "context/webgl_rendering_context.h"
20 #include "napi/n_class.h"
21 #include "util/egl_manager.h"
22 #include "util/log.h"
23 #include "util/object_manager.h"
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 using namespace std;
30 namespace OHOS {
31 namespace Rosen {
32
~WebGLRenderingContextBasicBase()33 WebGLRenderingContextBasicBase::~WebGLRenderingContextBasicBase()
34 {
35 if (eglSurface_ != nullptr) {
36 eglDestroySurface(EglManager::GetInstance().GetEGLDisplay(), eglSurface_);
37 eglSurface_ = nullptr;
38 }
39 }
40
SetEglWindow(void * window)41 void WebGLRenderingContextBasicBase::SetEglWindow(void* window)
42 {
43 LOGD("WebGLRenderingContextBasicBase::SetEglWindow.");
44 eglWindow_ = reinterpret_cast<NativeWindow*>(window);
45 }
46
Create(void * context)47 void WebGLRenderingContextBasicBase::Create(void* context)
48 {
49 LOGD("WebGLRenderingContextBasicBase::Create.");
50 }
51
Init()52 void WebGLRenderingContextBasicBase::Init()
53 {
54 LOGD("WebGLRenderingContextBasicBase::Init. %{public}p", this);
55 EglManager::GetInstance().Init();
56 if (eglSurface_ == nullptr) {
57 eglSurface_ = EglManager::GetInstance().CreateSurface(eglWindow_);
58 }
59 }
60
SetBitMapPtr(char * bitMapPtr,int bitMapWidth,int bitMapHeight)61 void WebGLRenderingContextBasicBase::SetBitMapPtr(char* bitMapPtr, int bitMapWidth, int bitMapHeight)
62 {
63 LOGD("WebGLRenderingContextBasicBase::SetBitMapPtr. %{public}p", this);
64 LOGD("WebGLRenderingContextBasicBase SetBitMapPtr [%{public}d %{public}d]", bitMapWidth, bitMapHeight);
65 bitMapPtr_ = bitMapPtr;
66 bitMapWidth_ = bitMapWidth;
67 bitMapHeight_ = bitMapHeight;
68 EglManager::GetInstance().SetPbufferAttributes(bitMapWidth, bitMapHeight);
69 }
70
CreateTexture()71 uint64_t WebGLRenderingContextBasicBase::CreateTexture()
72 {
73 return 0;
74 }
75
SetUpdateCallback(std::function<void ()> callback)76 void WebGLRenderingContextBasicBase::SetUpdateCallback(std::function<void()> callback)
77 {
78 updateCallback_ = callback;
79 }
80
SetTexture(uint64_t id)81 void WebGLRenderingContextBasicBase::SetTexture(uint64_t id) {}
82
Attach(uint64_t textureId)83 void WebGLRenderingContextBasicBase::Attach(uint64_t textureId) {}
84
Update()85 void WebGLRenderingContextBasicBase::Update()
86 {
87 if (eglWindow_) {
88 LOGD("eglSwapBuffers");
89 EGLDisplay eglDisplay = EglManager::GetInstance().GetEGLDisplay();
90 eglSwapBuffers(eglDisplay, eglSurface_);
91 } else {
92 LOGD("glReadPixels packAlignment %{public}d", packAlignment_);
93 glPixelStorei(GL_PACK_ALIGNMENT, 4); // 4 alignment
94 glReadPixels(0, 0, bitMapWidth_, bitMapHeight_, GL_RGBA, GL_UNSIGNED_BYTE, bitMapPtr_);
95 glPixelStorei(GL_PACK_ALIGNMENT, packAlignment_);
96 LOGD("glReadPixels result %{public}u", glGetError());
97 }
98 if (updateCallback_) {
99 LOGD("mUpdateCallback");
100 updateCallback_();
101 } else {
102 LOGE("mUpdateCallback is null");
103 }
104 }
105
Detach()106 void WebGLRenderingContextBasicBase::Detach() {}
107
CreateSurface()108 bool WebGLRenderingContextBasicBase::CreateSurface()
109 {
110 if (eglSurface_ == nullptr) {
111 eglSurface_ = EglManager::GetInstance().CreateSurface(eglWindow_);
112 if (eglSurface_ == nullptr) {
113 return false;
114 }
115 }
116 return true;
117 }
118
GetContextAttr(const std::string & str,const std::string & key,int keyLength,int value)119 string WebGLRenderingContextBasicBase::GetContextAttr(
120 const std::string& str, const std::string& key, int keyLength, int value)
121 {
122 size_t item = str.find(key);
123 if (item != string::npos) {
124 string itemVar = str.substr(item + keyLength, value);
125 return itemVar;
126 }
127 return "false";
128 }
129
SetWebGLContextAttributes(const std::vector<std::string> & vec)130 bool WebGLRenderingContextBasicBase::SetWebGLContextAttributes(const std::vector<std::string>& vec)
131 {
132 if (vec.size() <= 1) {
133 return true;
134 }
135 if (webGlContextAttributes_ == nullptr) {
136 webGlContextAttributes_ = std::make_shared<WebGLContextAttributes>();
137 if (webGlContextAttributes_ == nullptr) {
138 return false;
139 }
140 }
141 for (size_t i = 1; i < vec.size(); i++) {
142 if (GetContextAttr(vec[i], "alpha", 7, 4) == "true") { // 7 alpha length 4 true
143 webGlContextAttributes_->alpha_ = true;
144 }
145 if (GetContextAttr(vec[i], "depth", 7, 4) == "true") { // 7 depth length 4 true
146 webGlContextAttributes_->depth_ = true;
147 }
148 if (GetContextAttr(vec[i], "stencil", 9, 4) == "true") { // 9 stencil length 4 true
149 webGlContextAttributes_->stencil_ = true;
150 }
151 if (GetContextAttr(vec[i], "premultipliedAlpha", 23, 4) == "true") { // 23 premultipliedAlpha length 4 true
152 webGlContextAttributes_->premultipliedAlpha_ = true;
153 }
154 // 18 preserveDrawingBuffer length 4 true
155 if (GetContextAttr(vec[i], "preserveDrawingBuffer", 18, 4) == "true") {
156 webGlContextAttributes_->preserveDrawingBuffer_ = true;
157 }
158 // 30 failIfMajorPerformanceCaveat length 4 true
159 if (GetContextAttr(vec[i], "failIfMajorPerformanceCaveat", 30, 4) == "true") {
160 webGlContextAttributes_->failIfMajorPerformanceCaveat_ = true;
161 }
162 if (GetContextAttr(vec[i], "desynchronized", 16, 4) == "true") { // 16 desynchronized length 4 true
163 webGlContextAttributes_->desynchronized_ = true;
164 }
165 string highPerformance = GetContextAttr(vec[i], "powerPreference", 18, 16); // 18 16 powerPreference length
166 if (highPerformance == "high-performance") {
167 webGlContextAttributes_->powerPreference_ = highPerformance;
168 return true;
169 }
170 string lowPower = GetContextAttr(vec[i], "powerPreference", 18, 9); // 18 9 powerPreference length
171 if (lowPower == "low-power") {
172 webGlContextAttributes_->powerPreference_ = lowPower;
173 } else {
174 if (GetContextAttr(vec[i], "powerPreference", 18, 7) == "default") { // 18 7 powerPreference length
175 webGlContextAttributes_->powerPreference_ = "default";
176 }
177 }
178 }
179 return true;
180 }
181
GetContextInstance(napi_env env,std::string className,napi_callback constructor,napi_finalize finalize_cb)182 napi_value WebGLRenderingContextBasicBase::GetContextInstance(napi_env env,
183 std::string className, napi_callback constructor, napi_finalize finalize_cb)
184 {
185 napi_value instanceValue = nullptr;
186 napi_status status;
187 if (contextRef_ == nullptr) {
188 napi_value contextClass = nullptr;
189 napi_define_class(env, className.c_str(), NAPI_AUTO_LENGTH, constructor, nullptr, 0, nullptr, &contextClass);
190 status = napi_new_instance(env, contextClass, 0, nullptr, &instanceValue);
191 if (status != napi_ok) {
192 return NVal::CreateNull(env).val_;
193 }
194 status = napi_wrap(env, instanceValue, static_cast<void*>(this), finalize_cb, nullptr, nullptr);
195 if (status != napi_ok) {
196 return NVal::CreateNull(env).val_;
197 }
198 status = napi_create_reference(env, instanceValue, 1, &contextRef_);
199 if (status != napi_ok) {
200 return NVal::CreateNull(env).val_;
201 }
202 } else {
203 status = napi_get_reference_value(env, contextRef_, &instanceValue);
204 if (status != napi_ok) {
205 return NVal::CreateNull(env).val_;
206 }
207 }
208 return instanceValue;
209 }
210 } // namespace Rosen
211 } // namespace OHOS
212 #ifdef __cplusplus
213 }
214 #endif
215