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