Merge "Changes needed for https://review.tizen.org/gerrit/#/c/191202/" into devel...
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / ubuntu-gl / egl-image-extensions.cpp
1 /*
2  * Copyright (c) 2017 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
19 // CLASS HEADER
20 #include <dali/internal/graphics/common/egl-image-extensions.h>
21
22 // EXTERNAL INCLUDES
23 #if DALI_GLES_VERSION >= 30
24 #include <GLES3/gl3.h>
25 #include <GLES3/gl3ext.h>
26
27 #else
28 #include <GLES2/gl2.h>
29 #endif // DALI_GLES_VERSION >= 30
30
31 #include <GLES2/gl2ext.h>
32
33 #include <EGL/eglext.h>
34
35 #include <dali/integration-api/debug.h>
36
37 // INTERNAL INCLUDES
38 #include <dali/internal/graphics/gles20/egl-implementation.h>
39
40
41 namespace
42 {
43 // function pointers assigned in InitializeEglImageKHR
44 PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHRProc = 0;
45 PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHRProc = 0;
46 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOESProc = 0;
47 } // unnamed namespace
48
49
50 namespace Dali
51 {
52
53 namespace Internal
54 {
55
56 namespace Adaptor
57 {
58
59 EglImageExtensions::EglImageExtensions(EglImplementation* eglImpl)
60 : mEglImplementation(eglImpl),
61   mImageKHRInitialized(false),
62   mImageKHRInitializeFailed(false)
63 {
64   DALI_ASSERT_ALWAYS( eglImpl && "EGL Implementation not instantiated" );
65 }
66
67 EglImageExtensions::~EglImageExtensions()
68 {
69 }
70
71 void* EglImageExtensions::CreateImageKHR(EGLClientBuffer clientBuffer)
72 {
73   if (mImageKHRInitialized == false)
74   {
75     InitializeEglImageKHR();
76   }
77
78   if (mImageKHRInitialized == false)
79   {
80     return NULL;
81   }
82
83   // Use the EGL image extension
84   const EGLint attribs[] =
85   {
86     EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
87     EGL_NONE
88   };
89
90 // EGL constants use C casts
91 #pragma GCC diagnostic push
92 #pragma GCC diagnostic ignored "-Wold-style-cast"
93   EGLImageKHR eglImage  = eglCreateImageKHRProc( mEglImplementation->GetDisplay(),
94                                              EGL_NO_CONTEXT,
95                                              EGL_NATIVE_PIXMAP_KHR,
96                                              clientBuffer,
97                                              attribs );
98
99   DALI_ASSERT_DEBUG( EGL_NO_IMAGE_KHR != eglImage && "X11Image::GlExtensionCreate eglCreateImageKHR failed!\n");
100   if( EGL_NO_IMAGE_KHR == eglImage )
101   {
102     switch( eglGetError() )
103     {
104       case EGL_SUCCESS :
105       {
106         break;
107       }
108       case EGL_BAD_DISPLAY:
109       {
110         DALI_LOG_ERROR( "EGL_BAD_DISPLAY: Invalid EGLDisplay object\n" );
111         break;
112       }
113       case EGL_BAD_CONTEXT:
114       {
115         DALI_LOG_ERROR( "EGL_BAD_CONTEXT: Invalid EGLContext object\n" );
116         break;
117       }
118       case EGL_BAD_PARAMETER:
119       {
120         DALI_LOG_ERROR( "EGL_BAD_PARAMETER: Invalid target parameter or attribute in attrib_list\n" );
121         break;
122       }
123       case EGL_BAD_MATCH:
124       {
125         DALI_LOG_ERROR( "EGL_BAD_MATCH: attrib_list does not match target\n" );
126         break;
127       }
128       case EGL_BAD_ACCESS:
129       {
130         DALI_LOG_ERROR( "EGL_BAD_ACCESS: Previously bound off-screen, or EGLImage sibling error\n" );
131         break;
132       }
133       case EGL_BAD_ALLOC:
134       {
135         DALI_LOG_ERROR( "EGL_BAD_ALLOC: Insufficient memory is available\n" );
136         break;
137       }
138       default:
139       {
140         break;
141       }
142     }
143   }
144 #pragma GCC diagnostic pop
145
146   return eglImage;
147 }
148
149 void EglImageExtensions::DestroyImageKHR(void* eglImageKHR)
150 {
151   DALI_ASSERT_DEBUG( mImageKHRInitialized );
152
153   if( ! mImageKHRInitialized )
154   {
155     return;
156   }
157
158   if( eglImageKHR == NULL )
159   {
160     return;
161   }
162
163   EGLImageKHR eglImage = static_cast<EGLImageKHR>(eglImageKHR);
164
165   EGLBoolean result = eglDestroyImageKHRProc(mEglImplementation->GetDisplay(), eglImage);
166
167   if( EGL_FALSE == result )
168   {
169     switch( eglGetError() )
170     {
171       case EGL_BAD_DISPLAY:
172       {
173         DALI_LOG_ERROR( "EGL_BAD_DISPLAY: Invalid EGLDisplay object\n" );
174         break;
175       }
176       case EGL_BAD_PARAMETER:
177       {
178         DALI_LOG_ERROR( "EGL_BAD_PARAMETER: eglImage is not a valid EGLImageKHR object created with respect to EGLDisplay\n" );
179         break;
180       }
181       case EGL_BAD_ACCESS:
182       {
183         DALI_LOG_ERROR( "EGL_BAD_ACCESS: EGLImage sibling error\n" );
184         break;
185       }
186       default:
187       {
188         break;
189       }
190     }
191   }
192 }
193
194 void EglImageExtensions::TargetTextureKHR(void* eglImageKHR)
195 {
196   DALI_ASSERT_DEBUG( mImageKHRInitialized );
197
198   if( eglImageKHR != NULL )
199   {
200     EGLImageKHR eglImage = static_cast<EGLImageKHR>(eglImageKHR);
201
202 #ifdef EGL_ERROR_CHECKING
203     GLint glError = glGetError();
204 #endif
205
206     glEGLImageTargetTexture2DOESProc(GL_TEXTURE_2D, reinterpret_cast< GLeglImageOES >( eglImage ) );
207
208 #ifdef EGL_ERROR_CHECKING
209     glError = glGetError();
210     if( GL_NO_ERROR != glError )
211     {
212       DALI_LOG_ERROR(" glEGLImageTargetTexture2DOES returned error %0x04x\n", glError );
213     }
214 #endif
215   }
216 }
217
218 void EglImageExtensions::InitializeEglImageKHR()
219 {
220   // avoid trying to reload extended KHR functions, if it fails the first time
221   if( ! mImageKHRInitializeFailed )
222   {
223     eglCreateImageKHRProc  = reinterpret_cast< PFNEGLCREATEIMAGEKHRPROC >( eglGetProcAddress("eglCreateImageKHR") );
224     eglDestroyImageKHRProc = reinterpret_cast< PFNEGLDESTROYIMAGEKHRPROC >( eglGetProcAddress("eglDestroyImageKHR") );
225     glEGLImageTargetTexture2DOESProc = reinterpret_cast< PFNGLEGLIMAGETARGETTEXTURE2DOESPROC >( eglGetProcAddress("glEGLImageTargetTexture2DOES") );
226   }
227
228   if (eglCreateImageKHRProc && eglDestroyImageKHRProc && glEGLImageTargetTexture2DOESProc)
229   {
230     mImageKHRInitialized = true;
231   }
232   else
233   {
234     mImageKHRInitializeFailed = true;
235   }
236 }
237
238 } // namespace Adaptor
239
240 } // namespace Internal
241
242 } // namespace Dali