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 }
113 return true;
114 }
115
GetContextAttr(const std::string & str,const std::string & key,int keyLength,int value)116 string WebGLRenderingContextBasicBase::GetContextAttr(
117 const std::string& str, const std::string& key, int keyLength, int value)
118 {
119 size_t item = str.find(key);
120 if (item != string::npos) {
121 string itemVar = str.substr(item + keyLength, value);
122 return itemVar;
123 }
124 return "false";
125 }
126
SetWebGLContextAttributes(const std::vector<std::string> & vec)127 bool WebGLRenderingContextBasicBase::SetWebGLContextAttributes(const std::vector<std::string>& vec)
128 {
129 if (vec.size() <= 1) {
130 return true;
131 }
132 if (webGlContextAttributes_ == nullptr) {
133 webGlContextAttributes_ = std::make_shared<WebGLContextAttributes>();
134 if (webGlContextAttributes_ == nullptr) {
135 return false;
136 }
137 }
138 for (size_t i = 1; i < vec.size(); i++) {
139 if (GetContextAttr(vec[i], "alpha", 7, 4) == "true") { // 7 alpha length 4 true
140 webGlContextAttributes_->alpha_ = true;
141 }
142 if (GetContextAttr(vec[i], "depth", 7, 4) == "true") { // 7 depth length 4 true
143 webGlContextAttributes_->depth_ = true;
144 }
145 if (GetContextAttr(vec[i], "stencil", 9, 4) == "true") { // 9 stencil length 4 true
146 webGlContextAttributes_->stencil_ = true;
147 }
148 if (GetContextAttr(vec[i], "premultipliedAlpha", 23, 4) == "true") { // 23 premultipliedAlpha length 4 true
149 webGlContextAttributes_->premultipliedAlpha_ = true;
150 }
151 // 18 preserveDrawingBuffer length 4 true
152 if (GetContextAttr(vec[i], "preserveDrawingBuffer", 18, 4) == "true") {
153 webGlContextAttributes_->preserveDrawingBuffer_ = true;
154 }
155 // 30 failIfMajorPerformanceCaveat length 4 true
156 if (GetContextAttr(vec[i], "failIfMajorPerformanceCaveat", 30, 4) == "true") {
157 webGlContextAttributes_->failIfMajorPerformanceCaveat_ = true;
158 }
159 if (GetContextAttr(vec[i], "desynchronized", 16, 4) == "true") { // 16 desynchronized length 4 true
160 webGlContextAttributes_->desynchronized_ = true;
161 }
162 string highPerformance = GetContextAttr(vec[i], "powerPreference", 18, 16); // 18 16 powerPreference length
163 if (highPerformance == "high-performance") {
164 webGlContextAttributes_->powerPreference_ = highPerformance;
165 return true;
166 }
167 string lowPower = GetContextAttr(vec[i], "powerPreference", 18, 9); // 18 9 powerPreference length
168 if (lowPower == "low-power") {
169 webGlContextAttributes_->powerPreference_ = lowPower;
170 } else {
171 if (GetContextAttr(vec[i], "powerPreference", 18, 7) == "default") { // 18 7 powerPreference length
172 webGlContextAttributes_->powerPreference_ = "default";
173 }
174 }
175 }
176 return true;
177 }
178
GetContextInstance(napi_env env,std::string className,napi_callback constructor,napi_finalize finalize_cb)179 napi_value WebGLRenderingContextBasicBase::GetContextInstance(napi_env env,
180 std::string className, napi_callback constructor, napi_finalize finalize_cb)
181 {
182 napi_value instanceValue = nullptr;
183 napi_status status;
184 if (contextRef_ == nullptr) {
185 napi_value contextClass = nullptr;
186 napi_define_class(env, className.c_str(), NAPI_AUTO_LENGTH, constructor, nullptr, 0, nullptr, &contextClass);
187 status = napi_new_instance(env, contextClass, 0, nullptr, &instanceValue);
188 if (status != napi_ok) {
189 return NVal::CreateNull(env).val_;
190 }
191 status = napi_wrap(env, instanceValue, static_cast<void*>(this), finalize_cb, nullptr, nullptr);
192 if (status != napi_ok) {
193 return NVal::CreateNull(env).val_;
194 }
195 status = napi_create_reference(env, instanceValue, 1, &contextRef_);
196 if (status != napi_ok) {
197 return NVal::CreateNull(env).val_;
198 }
199 } else {
200 status = napi_get_reference_value(env, contextRef_, &instanceValue);
201 if (status != napi_ok) {
202 return NVal::CreateNull(env).val_;
203 }
204 }
205 return instanceValue;
206 }
207 } // namespace Rosen
208 } // namespace OHOS
209 #ifdef __cplusplus
210 }
211 #endif
212