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