[dali_2.3.32] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / generic / egl-image-extensions-generic.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/graphics/common/egl-image-extensions.h>
20
21 // EXTERNAL INCLUDES
22 #include <GLES2/gl2.h>
23 #include <GLES2/gl2ext.h>
24 #include <GLES3/gl3.h>
25
26 #include <EGL/eglext.h>
27
28 #include <dali/integration-api/debug.h>
29
30 // INTERNAL INCLUDES
31 #include <dali/internal/graphics/gles/egl-implementation.h>
32
33 namespace
34 {
35 // function pointers assigned in InitializeEglImageKHR
36 PFNEGLCREATEIMAGEKHRPROC            eglCreateImageKHRProc            = 0;
37 PFNEGLDESTROYIMAGEKHRPROC           eglDestroyImageKHRProc           = 0;
38 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOESProc = 0;
39 } // unnamed namespace
40
41 namespace Dali
42 {
43 namespace Internal
44 {
45 namespace Adaptor
46 {
47 EglImageExtensions::EglImageExtensions(EglImplementation* eglImpl)
48 : mEglImplementation(eglImpl),
49   mImageKHRInitialized(false),
50   mImageKHRInitializeFailed(false)
51 {
52   DALI_ASSERT_ALWAYS(eglImpl && "EGL Implementation not instantiated");
53 }
54
55 EglImageExtensions::~EglImageExtensions()
56 {
57 }
58
59 void* EglImageExtensions::CreateImageKHR(EGLClientBuffer clientBuffer)
60 {
61   if(mImageKHRInitialized == false)
62   {
63     InitializeEglImageKHR();
64   }
65
66   if(mImageKHRInitialized == false)
67   {
68     return NULL;
69   }
70
71   // Use the EGL image extension
72   const EGLint attribs[] =
73     {
74       EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
75
76   EGLImageKHR eglImage = eglCreateImageKHRProc(mEglImplementation->GetDisplay(),
77                                                EGL_NO_CONTEXT,
78                                                EGL_NATIVE_PIXMAP_KHR,
79                                                clientBuffer,
80                                                attribs);
81
82   DALI_ASSERT_DEBUG(EGL_NO_IMAGE_KHR != eglImage && "X11Image::GlExtensionCreate eglCreateImageKHR failed!\n");
83   if(EGL_NO_IMAGE_KHR == eglImage)
84   {
85     switch(eglGetError())
86     {
87       case EGL_SUCCESS:
88       {
89         break;
90       }
91       case EGL_BAD_DISPLAY:
92       {
93         DALI_LOG_ERROR("EGL_BAD_DISPLAY: Invalid EGLDisplay object\n");
94         break;
95       }
96       case EGL_BAD_CONTEXT:
97       {
98         DALI_LOG_ERROR("EGL_BAD_CONTEXT: Invalid EGLContext object\n");
99         break;
100       }
101       case EGL_BAD_PARAMETER:
102       {
103         DALI_LOG_ERROR("EGL_BAD_PARAMETER: Invalid target parameter or attribute in attrib_list\n");
104         break;
105       }
106       case EGL_BAD_MATCH:
107       {
108         DALI_LOG_ERROR("EGL_BAD_MATCH: attrib_list does not match target\n");
109         break;
110       }
111       case EGL_BAD_ACCESS:
112       {
113         DALI_LOG_ERROR("EGL_BAD_ACCESS: Previously bound off-screen, or EGLImage sibling error\n");
114         break;
115       }
116       case EGL_BAD_ALLOC:
117       {
118         DALI_LOG_ERROR("EGL_BAD_ALLOC: Insufficient memory is available\n");
119         break;
120       }
121       default:
122       {
123         break;
124       }
125     }
126   }
127
128   return eglImage;
129 }
130
131 void EglImageExtensions::DestroyImageKHR(void* eglImageKHR)
132 {
133   DALI_ASSERT_DEBUG(mImageKHRInitialized);
134
135   if(!mImageKHRInitialized)
136   {
137     return;
138   }
139
140   if(eglImageKHR == NULL)
141   {
142     return;
143   }
144
145   EGLImageKHR eglImage = static_cast<EGLImageKHR>(eglImageKHR);
146
147   EGLBoolean result = eglDestroyImageKHRProc(mEglImplementation->GetDisplay(), eglImage);
148
149   if(EGL_FALSE == result)
150   {
151     switch(eglGetError())
152     {
153       case EGL_BAD_DISPLAY:
154       {
155         DALI_LOG_ERROR("EGL_BAD_DISPLAY: Invalid EGLDisplay object\n");
156         break;
157       }
158       case EGL_BAD_PARAMETER:
159       {
160         DALI_LOG_ERROR("EGL_BAD_PARAMETER: eglImage is not a valid EGLImageKHR object created with respect to EGLDisplay\n");
161         break;
162       }
163       case EGL_BAD_ACCESS:
164       {
165         DALI_LOG_ERROR("EGL_BAD_ACCESS: EGLImage sibling error\n");
166         break;
167       }
168       default:
169       {
170         break;
171       }
172     }
173   }
174 }
175
176 void EglImageExtensions::TargetTextureKHR(void* eglImageKHR)
177 {
178   DALI_ASSERT_DEBUG(mImageKHRInitialized);
179
180   if(eglImageKHR != NULL)
181   {
182     EGLImageKHR eglImage = static_cast<EGLImageKHR>(eglImageKHR);
183
184 #ifdef EGL_ERROR_CHECKING
185     GLint glError = glGetError();
186 #endif
187
188     glEGLImageTargetTexture2DOESProc(GL_TEXTURE_2D, reinterpret_cast<GLeglImageOES>(eglImage));
189
190 #ifdef EGL_ERROR_CHECKING
191     glError = glGetError();
192     if(GL_NO_ERROR != glError)
193     {
194       DALI_LOG_ERROR(" glEGLImageTargetTexture2DOES returned error %0x04x\n", glError);
195     }
196 #endif
197   }
198 }
199
200 void EglImageExtensions::InitializeEglImageKHR()
201 {
202   // avoid trying to reload extended KHR functions, if it fails the first time
203   if(!mImageKHRInitializeFailed)
204   {
205     eglCreateImageKHRProc            = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
206     eglDestroyImageKHRProc           = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
207     glEGLImageTargetTexture2DOESProc = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
208   }
209
210   if(eglCreateImageKHRProc && eglDestroyImageKHRProc && glEGLImageTargetTexture2DOESProc)
211   {
212     mImageKHRInitialized = true;
213   }
214   else
215   {
216     mImageKHRInitializeFailed = true;
217   }
218 }
219
220 } // namespace Adaptor
221
222 } // namespace Internal
223
224 } // namespace Dali