57d0c08af9623c9656e7b2073dbfceed114bb872
[platform/core/uifw/dali-adaptor.git] / adaptors / tizen / gl / egl-image-extensions-tizen.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 <gl/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 <gl/egl-implementation.h>
39
40 // TBM surface support
41 #ifndef EGL_NATIVE_SURFACE_TIZEN
42 #define EGL_NATIVE_SURFACE_TIZEN 0x32A1
43 #endif
44
45 namespace
46 {
47 // function pointers assigned in InitializeEglImageKHR
48 PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHRProc = 0;
49 PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHRProc = 0;
50 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOESProc = 0;
51 } // unnamed namespace
52
53
54 namespace Dali
55 {
56
57 namespace Internal
58 {
59
60 namespace Adaptor
61 {
62
63 EglImageExtensions::EglImageExtensions(EglImplementation* eglImpl)
64 : mEglImplementation(eglImpl),
65   mImageKHRInitialized(false),
66   mImageKHRInitializeFailed(false)
67 {
68   DALI_ASSERT_ALWAYS( eglImpl && "EGL Implementation not instantiated" );
69 }
70
71 EglImageExtensions::~EglImageExtensions()
72 {
73 }
74
75 void* EglImageExtensions::CreateImageKHR(EGLClientBuffer clientBuffer)
76 {
77   if (mImageKHRInitialized == false)
78   {
79     InitializeEglImageKHR();
80   }
81
82   if (mImageKHRInitialized == false)
83   {
84     return NULL;
85   }
86
87   // Use the EGL image extension
88   const EGLint attribs[] =
89   {
90     EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
91     EGL_NONE
92   };
93
94   EGLImageKHR eglImage  = eglCreateImageKHRProc( mEglImplementation->GetDisplay(),
95                                              EGL_NO_CONTEXT,
96                                              EGL_NATIVE_SURFACE_TIZEN,
97                                              clientBuffer,
98                                              attribs );
99
100   DALI_ASSERT_DEBUG( EGL_NO_IMAGE_KHR != eglImage && "X11Image::GlExtensionCreate eglCreateImageKHR failed!\n");
101   if( EGL_NO_IMAGE_KHR == eglImage )
102   {
103     switch( eglGetError() )
104     {
105       case EGL_SUCCESS :
106       {
107         break;
108       }
109       case EGL_BAD_DISPLAY:
110       {
111         DALI_LOG_ERROR( "EGL_BAD_DISPLAY: Invalid EGLDisplay object\n" );
112         break;
113       }
114       case EGL_BAD_CONTEXT:
115       {
116         DALI_LOG_ERROR( "EGL_BAD_CONTEXT: Invalid EGLContext object\n" );
117         break;
118       }
119       case EGL_BAD_PARAMETER:
120       {
121         DALI_LOG_ERROR( "EGL_BAD_PARAMETER: Invalid target parameter or attribute in attrib_list\n" );
122         break;
123       }
124       case EGL_BAD_MATCH:
125       {
126         DALI_LOG_ERROR( "EGL_BAD_MATCH: attrib_list does not match target\n" );
127         break;
128       }
129       case EGL_BAD_ACCESS:
130       {
131         DALI_LOG_ERROR( "EGL_BAD_ACCESS: Previously bound off-screen, or EGLImage sibling error\n" );
132         break;
133       }
134       case EGL_BAD_ALLOC:
135       {
136         DALI_LOG_ERROR( "EGL_BAD_ALLOC: Insufficient memory is available\n" );
137         break;
138       }
139       default:
140       {
141         break;
142       }
143     }
144   }
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_EXTERNAL_OES, 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