1 /*
2 * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 "rosen_context_impl.h"
17
18 #include "ui/rs_surface_extractor.h"
19 #include "backend/rs_surface_ohos_gl.h"
20
21 using namespace OHOS;
22 using namespace Rosen;
23
RosenContextImpl()24 RosenContextImpl::RosenContextImpl()
25 {
26 InitEgl();
27 InitProducer();
28 }
29
ShowConfig(EGLConfig cfg)30 void RosenContextImpl::ShowConfig(EGLConfig cfg)
31 {
32 EGLint red, green, blue, alpha, depth, stencil, samples, sft, rt;
33
34 eglGetConfigAttrib(eglDisplay_, cfg, EGL_RED_SIZE, &red);
35 eglGetConfigAttrib(eglDisplay_, cfg, EGL_GREEN_SIZE, &green);
36 eglGetConfigAttrib(eglDisplay_, cfg, EGL_BLUE_SIZE, &blue);
37 eglGetConfigAttrib(eglDisplay_, cfg, EGL_ALPHA_SIZE, &alpha);
38 eglGetConfigAttrib(eglDisplay_, cfg, EGL_DEPTH_SIZE, &depth);
39 eglGetConfigAttrib(eglDisplay_, cfg, EGL_STENCIL_SIZE, &stencil);
40 eglGetConfigAttrib(eglDisplay_, cfg, EGL_SAMPLES, &samples);
41 eglGetConfigAttrib(eglDisplay_, cfg, EGL_SURFACE_TYPE, &sft);
42 eglGetConfigAttrib(eglDisplay_, cfg, EGL_RENDERABLE_TYPE, &rt);
43
44 printf("%8d%8d%8d%8d%8d%8d%8d%8d%8d\n", red, green, blue, alpha, depth, stencil, samples, sft, rt);
45 }
46
InitProducer()47 void RosenContextImpl::InitProducer()
48 {
49 displayNode_ = RSDisplayNode::Create(RSDisplayNodeConfig());
50 surfaceNode_ = RSSurfaceNode::Create(RSSurfaceNodeConfig());
51 surfaceNode_->SetBounds(0, 0, 512, 512);
52 displayNode_->AddChild(surfaceNode_, -1);
53
54 std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode_);
55 std::shared_ptr<RSSurfaceOhosGl> rsSurfaceOhosGl = std::static_pointer_cast<RSSurfaceOhosGl>(rsSurface);
56 producer_ = rsSurfaceOhosGl->GetSurface();
57 }
58
InitEgl()59 bool RosenContextImpl::InitEgl()
60 {
61 eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
62 if (eglDisplay_ == EGL_NO_DISPLAY)
63 {
64 printf("Failed to create EGLDisplay gl errno : %x", eglGetError());
65 return false;
66 }
67
68 EGLint major, minor;
69 if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE)
70 {
71 printf("Failed to initialize EGLDisplay");
72 return false;
73 }
74
75 glDepthMask(GL_TRUE);
76
77 eglGetConfigs(eglDisplay_, NULL, 0, &configCount_);
78 allConfigs_ = new EGLConfig[configCount_];
79 eglGetConfigs(eglDisplay_, allConfigs_, configCount_, &configCount_);
80
81 printf("config count : %d\n", configCount_);
82 for (int i = 0; i < configCount_; i++)
83 {
84 ShowConfig(allConfigs_[i]);
85 }
86
87 return true;
88 }
89
SetConfig(int32_t w,int32_t h,RCI_GLES_VERSION ver,RCI_PIXEL_FORMAT pf,RCI_SURFACE_TYPE st,RCI_PROFILE tp,RCI_CONTEXT_FLAG flags)90 bool RosenContextImpl::SetConfig(int32_t w, int32_t h, RCI_GLES_VERSION ver, RCI_PIXEL_FORMAT pf, RCI_SURFACE_TYPE st, RCI_PROFILE tp, RCI_CONTEXT_FLAG flags)
91 {
92 glesVersion_ = ver;
93 typeProfile_ = tp;
94 contextFlags_ = flags;
95 surfaceType_ = st;
96 width_ = w;
97 height_ = h;
98 pixelFormat_ = pf;
99
100 EGLint eglApi;
101 switch (typeProfile_)
102 {
103 case RCI_PROFILE::ES:
104 eglApi = EGL_OPENGL_ES_API;
105 break;
106 case RCI_PROFILE::CORE:
107 eglApi = EGL_OPENGL_API;
108 break;
109 case RCI_PROFILE::COMPATIBILITY:
110 eglApi = EGL_OPENGL_API;
111 break;
112 default:
113 return false;
114 }
115 if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE)
116 {
117 printf("Failed to bind OpenGL ES API");
118 return false;
119 }
120
121 std::vector<EGLint> frameBufferAttribs;
122 frameBufferAttribs.push_back(EGL_RENDERABLE_TYPE);
123 switch (static_cast<int>(glesVersion_) / 10)
124 {
125 case 3:
126 frameBufferAttribs.push_back(EGL_OPENGL_ES3_BIT);
127 break;
128 case 2:
129 frameBufferAttribs.push_back(EGL_OPENGL_ES2_BIT);
130 break;
131 default:
132 frameBufferAttribs.push_back(EGL_OPENGL_ES_BIT);
133 }
134
135 frameBufferAttribs.push_back(EGL_SURFACE_TYPE);
136 switch (surfaceType_)
137 {
138 case RCI_SURFACE_TYPE::NONE:
139 frameBufferAttribs.push_back(EGL_DONT_CARE);
140 break;
141 case RCI_SURFACE_TYPE::PBUFFER:
142 frameBufferAttribs.push_back(EGL_PBUFFER_BIT);
143 break;
144 case RCI_SURFACE_TYPE::PIXMAP:
145 frameBufferAttribs.push_back(EGL_PIXMAP_BIT);
146 break;
147 case RCI_SURFACE_TYPE::WINDOW:
148 frameBufferAttribs.push_back(EGL_WINDOW_BIT);
149 break;
150 }
151
152 if (pixelFormat_.redBits != -1)
153 {
154 frameBufferAttribs.push_back(EGL_RED_SIZE);
155 frameBufferAttribs.push_back(pixelFormat_.redBits);
156 }
157 if (pixelFormat_.greenBits != -1)
158 {
159 frameBufferAttribs.push_back(EGL_GREEN_SIZE);
160 frameBufferAttribs.push_back(pixelFormat_.greenBits);
161 }
162 if (pixelFormat_.blueBits != -1)
163 {
164 frameBufferAttribs.push_back(EGL_BLUE_SIZE);
165 frameBufferAttribs.push_back(pixelFormat_.blueBits);
166 }
167 if (pixelFormat_.alphaBits != -1)
168 {
169 frameBufferAttribs.push_back(EGL_ALPHA_SIZE);
170 frameBufferAttribs.push_back(pixelFormat_.alphaBits);
171 }
172 if (pixelFormat_.depthBits != -1)
173 {
174 frameBufferAttribs.push_back(EGL_DEPTH_SIZE);
175 frameBufferAttribs.push_back(pixelFormat_.depthBits);
176 }
177 if (pixelFormat_.stencilBits != -1)
178 {
179 frameBufferAttribs.push_back(EGL_STENCIL_SIZE);
180 frameBufferAttribs.push_back(pixelFormat_.stencilBits);
181 }
182 if (pixelFormat_.numSamples != -1)
183 {
184 frameBufferAttribs.push_back(EGL_SAMPLES);
185 frameBufferAttribs.push_back(pixelFormat_.numSamples);
186 }
187 frameBufferAttribs.push_back(EGL_NONE);
188
189 unsigned int ret;
190 EGLint count;
191 ret = eglChooseConfig(eglDisplay_, &frameBufferAttribs[0], &config_, 1, &count);
192 printf("ret=%d,count=%d\n", ret, count);
193 if (!(ret && static_cast<unsigned int>(count) >= 1))
194 {
195 printf("Failed to eglChooseConfig\n");
196 return false;
197 }
198 EGLint red, green, blue, alpha, depth, stencil, samples;
199 eglGetConfigAttrib(eglDisplay_, config_, EGL_RED_SIZE, &red);
200 eglGetConfigAttrib(eglDisplay_, config_, EGL_GREEN_SIZE, &green);
201 eglGetConfigAttrib(eglDisplay_, config_, EGL_BLUE_SIZE, &blue);
202 eglGetConfigAttrib(eglDisplay_, config_, EGL_ALPHA_SIZE, &alpha);
203 eglGetConfigAttrib(eglDisplay_, config_, EGL_DEPTH_SIZE, &depth);
204 eglGetConfigAttrib(eglDisplay_, config_, EGL_STENCIL_SIZE, &stencil);
205 eglGetConfigAttrib(eglDisplay_, config_, EGL_SAMPLES, &samples);
206 ShowConfig(config_);
207 if (pixelFormat_.redBits == -1)
208 {
209 pixelFormat_.redBits = red;
210 }
211 else if (pixelFormat_.redBits != red)
212 {
213 printf("Failed to eglChooseConfig redBits %d != %d\n", pixelFormat_.redBits, red);
214 return false;
215 }
216
217 if (pixelFormat_.greenBits == -1)
218 {
219 pixelFormat_.greenBits = green;
220 }
221 else if (pixelFormat_.greenBits != green)
222 {
223 printf("Failed to eglChooseConfig redBits %d != %d\n", pixelFormat_.greenBits, green);
224 return false;
225 }
226
227 if (pixelFormat_.blueBits != blue)
228 {
229 if (pixelFormat_.blueBits != -1)
230 printf("Failed to eglChooseConfig blueBits %d != %d\n", pixelFormat_.blueBits, blue);
231 pixelFormat_.blueBits = blue;
232 }
233
234 if (pixelFormat_.alphaBits != alpha)
235 {
236 if (pixelFormat_.alphaBits != -1)
237 printf("Failed to eglChooseConfig alphaBits %d != %d\n", pixelFormat_.alphaBits, alpha);
238 pixelFormat_.alphaBits = alpha;
239 }
240
241 if (pixelFormat_.depthBits != depth)
242 {
243 if (pixelFormat_.depthBits != -1)
244 printf("Failed to eglChooseConfig depthBits %d != %d\n", pixelFormat_.depthBits, depth);
245 pixelFormat_.depthBits = depth;
246 }
247
248 if (pixelFormat_.stencilBits != stencil)
249 {
250 if (pixelFormat_.stencilBits != -1)
251 printf("Failed to eglChooseConfig stencilBits %d != %d\n", pixelFormat_.stencilBits, stencil);
252 pixelFormat_.stencilBits = stencil;
253 }
254
255 if (pixelFormat_.numSamples != samples)
256 {
257 if (pixelFormat_.numSamples != -1)
258 printf("Failed to eglChooseConfig numSamples %d != %d\n", pixelFormat_.numSamples, samples);
259 pixelFormat_.numSamples = samples;
260 }
261 printf("config ok\n");
262 return true;
263 }
264
InitNativeWindow()265 bool RosenContextImpl::InitNativeWindow()
266 {
267 if (nativeWindow_ == nullptr)
268 {
269 nativeWindow_ = CreateNativeWindowFromSurface(&producer_);
270 }
271 NativeWindowHandleOpt(nativeWindow_, SET_BUFFER_GEOMETRY, width_, height_);
272 if (pixelFormat_.stencilBits != -1)
273 {
274 NativeWindowHandleOpt(nativeWindow_, SET_STRIDE, pixelFormat_.stencilBits);
275 }
276 if (pixelFormat_.redBits == 8 && pixelFormat_.greenBits == 8 && pixelFormat_.blueBits == 8 && pixelFormat_.alphaBits == 8)
277 {
278 NativeWindowHandleOpt(nativeWindow_, SET_FORMAT, PIXEL_FMT_RGBA_8888);
279 }
280 else if (pixelFormat_.redBits == 5 && pixelFormat_.greenBits == 6 && pixelFormat_.blueBits == 5 && pixelFormat_.alphaBits == 0)
281 {
282 NativeWindowHandleOpt(nativeWindow_, SET_FORMAT, PIXEL_FMT_RGB_565);
283 }
284 else if (pixelFormat_.redBits == 4 && pixelFormat_.greenBits == 4 && pixelFormat_.blueBits == 4 && pixelFormat_.alphaBits == 4)
285 {
286 NativeWindowHandleOpt(nativeWindow_, SET_FORMAT, PIXEL_FMT_RGBA_4444);
287 }
288 printf("native window ok\n");
289 return true;
290 }
291
InitEglSurface()292 bool RosenContextImpl::InitEglSurface()
293 {
294 if(eglSurface_ != EGL_NO_SURFACE) {
295 eglDestroySurface(eglDisplay_, eglSurface_);
296 eglSurface_ = EGL_NO_SURFACE;
297 }
298
299 eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
300
301 std::vector<EGLint> surfaceAttribs;
302
303 switch (surfaceType_)
304 {
305 case RCI_SURFACE_TYPE::NONE:
306 break;
307 case RCI_SURFACE_TYPE::WINDOW:
308 // surfaceAttribs.push_back(EGL_GL_COLORSPACE_KHR);
309 //TODO: EGL_GL_COLORSPACE_LINEAR_KHR, EGL_GL_COLORSPACE_SRGB_KHR
310 // surfaceAttribs.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
311 surfaceAttribs.push_back(EGL_NONE);
312
313 eglSurface_ = eglCreateWindowSurface(eglDisplay_, config_, nativeWindow_, &surfaceAttribs[0]);
314 if (eglSurface_ == EGL_NO_SURFACE)
315 {
316 printf("Failed to create eglsurface!!! %x\n", eglGetError());
317 return false;
318 }
319 break;
320 case RCI_SURFACE_TYPE::PBUFFER:
321 case RCI_SURFACE_TYPE::PIXMAP:
322 surfaceAttribs.push_back(EGL_WIDTH);
323 surfaceAttribs.push_back(width_);
324 surfaceAttribs.push_back(EGL_HEIGHT);
325 surfaceAttribs.push_back(height_);
326 surfaceAttribs.push_back(EGL_NONE);
327 break;
328 }
329 printf("egl surface ok\n");
330 return true;
331 }
332
InitEglContext()333 bool RosenContextImpl::InitEglContext()
334 {
335 if(eglContext_ != EGL_NO_CONTEXT) {
336 eglDestroyContext(eglDisplay_, eglContext_);
337 eglContext_ = EGL_NO_CONTEXT;
338 }
339
340 std::vector<EGLint> contextAttribs;
341 contextAttribs.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
342 contextAttribs.push_back(static_cast<int>(glesVersion_) / 10);
343 contextAttribs.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
344 contextAttribs.push_back(static_cast<int>(glesVersion_) % 10);
345
346 switch (typeProfile_)
347 {
348 case RCI_PROFILE::ES:
349 break;
350 case RCI_PROFILE::CORE:
351 contextAttribs.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
352 contextAttribs.push_back(EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR);
353 break;
354 case RCI_PROFILE::COMPATIBILITY:
355 contextAttribs.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
356 contextAttribs.push_back(EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR);
357 break;
358 }
359
360 EGLint flags = 0;
361 if ((static_cast<int>(contextFlags_) & static_cast<int>(RCI_CONTEXT_FLAG::DEBUG)) != 0)
362 flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
363
364 if ((static_cast<int>(contextFlags_) & static_cast<int>(RCI_CONTEXT_FLAG::ROBUST)) != 0)
365 flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
366
367 if ((static_cast<int>(contextFlags_) & static_cast<int>(RCI_CONTEXT_FLAG::FORWARD_COMPATIBLE)) != 0)
368 flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
369
370 contextAttribs.push_back(EGL_CONTEXT_FLAGS_KHR);
371 contextAttribs.push_back(flags);
372
373 contextAttribs.push_back(EGL_NONE);
374
375 eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, &contextAttribs[0]);
376 if (eglContext_ == EGL_NO_CONTEXT)
377 {
378 printf("Failed to create egl context %x\n", eglGetError());
379 return false;
380 }
381 printf("context ok\n");
382 return true;
383 }
384
MakeCurrent()385 void RosenContextImpl::MakeCurrent()
386 {
387 if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_))
388 {
389 printf("eglMakeCurrent FAIL\n");
390 }
391 }
392
SwapBuffer()393 void RosenContextImpl::SwapBuffer()
394 {
395 eglSwapBuffers(eglDisplay_, eglSurface_);
396 RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
397 }
398
GetAttrib(int32_t attrType)399 int32_t RosenContextImpl::GetAttrib(int32_t attrType)
400 {
401 int32_t ret;
402 eglGetConfigAttrib(eglDisplay_, config_, attrType, &ret);
403 return ret;
404 }