• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }