47925222e7ba55996a977f64af995a7ced40b13b
[platform/core/uifw/dali-adaptor.git] / adaptors / common / 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 "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
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   EGLImageKHR eglImage  = eglCreateImageKHRProc( mEglImplementation->GetDisplay(),
91                                              EGL_NO_CONTEXT,
92                                              EGL_NATIVE_PIXMAP_KHR,
93                                              clientBuffer,
94                                              attribs );
95
96   DALI_ASSERT_DEBUG( EGL_NO_IMAGE_KHR != eglImage && "X11Image::GlExtensionCreate eglCreateImageKHR failed!\n");
97   if( EGL_NO_IMAGE_KHR == eglImage )
98   {
99     switch( eglGetError() )
100     {
101       case EGL_SUCCESS :
102       {
103         break;
104       }
105       case EGL_BAD_DISPLAY:
106       {
107         DALI_LOG_ERROR( "EGL_BAD_DISPLAY: Invalid EGLDisplay object\n" );
108         break;
109       }
110       case EGL_BAD_CONTEXT:
111       {
112         DALI_LOG_ERROR( "EGL_BAD_CONTEXT: Invalid EGLContext object\n" );
113         break;
114       }
115       case EGL_BAD_PARAMETER:
116       {
117         DALI_LOG_ERROR( "EGL_BAD_PARAMETER: Invalid target parameter or attribute in attrib_list\n" );
118         break;
119       }
120       case EGL_BAD_MATCH:
121       {
122         DALI_LOG_ERROR( "EGL_BAD_MATCH: attrib_list does not match target\n" );
123         break;
124       }
125       case EGL_BAD_ACCESS:
126       {
127         DALI_LOG_ERROR( "EGL_BAD_ACCESS: Previously bound off-screen, or EGLImage sibling error\n" );
128         break;
129       }
130       case EGL_BAD_ALLOC:
131       {
132         DALI_LOG_ERROR( "EGL_BAD_ALLOC: Insufficient memory is available\n" );
133         break;
134       }
135       default:
136       {
137         break;
138       }
139     }
140   }
141
142   return eglImage;
143 }
144
145 void EglImageExtensions::DestroyImageKHR(void* eglImageKHR)
146 {
147   DALI_ASSERT_DEBUG( mImageKHRInitialized );
148
149   if( ! mImageKHRInitialized )
150   {
151     return;
152   }
153
154   if( eglImageKHR == NULL )
155   {
156     return;
157   }
158
159   EGLImageKHR eglImage = static_cast<EGLImageKHR>(eglImageKHR);
160
161   EGLBoolean result = eglDestroyImageKHRProc(mEglImplementation->GetDisplay(), eglImage);
162
163   if( EGL_FALSE == result )
164   {
165     switch( eglGetError() )
166     {
167       case EGL_BAD_DISPLAY:
168       {
169         DALI_LOG_ERROR( "EGL_BAD_DISPLAY: Invalid EGLDisplay object\n" );
170         break;
171       }
172       case EGL_BAD_PARAMETER:
173       {
174         DALI_LOG_ERROR( "EGL_BAD_PARAMETER: eglImage is not a valid EGLImageKHR object created with respect to EGLDisplay\n" );
175         break;
176       }
177       case EGL_BAD_ACCESS:
178       {
179         DALI_LOG_ERROR( "EGL_BAD_ACCESS: EGLImage sibling error\n" );
180         break;
181       }
182       default:
183       {
184         break;
185       }
186     }
187   }
188 }
189
190 void EglImageExtensions::TargetTextureKHR(void* eglImageKHR)
191 {
192   DALI_ASSERT_DEBUG( mImageKHRInitialized );
193
194   if( eglImageKHR != NULL )
195   {
196     EGLImageKHR eglImage = static_cast<EGLImageKHR>(eglImageKHR);
197
198 #ifdef EGL_ERROR_CHECKING
199     GLint glError = glGetError();
200 #endif
201
202     glEGLImageTargetTexture2DOESProc(GL_TEXTURE_2D, reinterpret_cast< GLeglImageOES >( eglImage ) );
203
204 #ifdef EGL_ERROR_CHECKING
205     glError = glGetError();
206     if( GL_NO_ERROR != glError )
207     {
208       DALI_LOG_ERROR(" glEGLImageTargetTexture2DOES returned error %0x04x\n", glError );
209     }
210 #endif
211   }
212 }
213
214 void EglImageExtensions::InitializeEglImageKHR()
215 {
216   // avoid trying to reload extended KHR functions, if it fails the first time
217   if( ! mImageKHRInitializeFailed )
218   {
219     eglCreateImageKHRProc  = reinterpret_cast< PFNEGLCREATEIMAGEKHRPROC >( eglGetProcAddress("eglCreateImageKHR") );
220     eglDestroyImageKHRProc = reinterpret_cast< PFNEGLDESTROYIMAGEKHRPROC >( eglGetProcAddress("eglDestroyImageKHR") );
221     glEGLImageTargetTexture2DOESProc = reinterpret_cast< PFNGLEGLIMAGETARGETTEXTURE2DOESPROC >( eglGetProcAddress("glEGLImageTargetTexture2DOES") );
222   }
223
224   if (eglCreateImageKHRProc && eglDestroyImageKHRProc && glEGLImageTargetTexture2DOESProc)
225   {
226     mImageKHRInitialized = true;
227   }
228   else
229   {
230     mImageKHRInitializeFailed = true;
231   }
232 }
233
234 } // namespace Adaptor
235
236 } // namespace Internal
237
238 } // namespace Dali