Fix to use OpenGL es 3.0
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / tizen / native-image-source-queue-impl-tizen.cpp
1 /*
2  * Copyright (c) 2018 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/imaging/tizen/native-image-source-queue-impl-tizen.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/gl-defines.h>
24 #include <tbm_surface_internal.h>
25
26 // INTERNAL INCLUDES
27 #include <dali/internal/graphics/common/egl-image-extensions.h>
28 #include <dali/internal/graphics/gles/egl-graphics.h>
29 #include <dali/internal/adaptor/common/adaptor-impl.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 namespace Adaptor
38 {
39
40 namespace
41 {
42 #define TBM_SURFACE_QUEUE_SIZE  3
43
44 const char* FRAGMENT_PREFIX = "#extension GL_OES_EGL_image_external:require\n";
45 const char* SAMPLER_TYPE = "samplerExternalOES";
46
47 int FORMATS_BLENDING_REQUIRED[] = {
48   TBM_FORMAT_ARGB4444, TBM_FORMAT_ABGR4444,
49   TBM_FORMAT_RGBA4444, TBM_FORMAT_BGRA4444,
50   TBM_FORMAT_RGBX5551, TBM_FORMAT_BGRX5551,
51   TBM_FORMAT_ARGB1555, TBM_FORMAT_ABGR1555,
52   TBM_FORMAT_RGBA5551, TBM_FORMAT_BGRA5551,
53   TBM_FORMAT_ARGB8888, TBM_FORMAT_ABGR8888,
54   TBM_FORMAT_RGBA8888, TBM_FORMAT_BGRA8888,
55   TBM_FORMAT_ARGB2101010, TBM_FORMAT_ABGR2101010,
56   TBM_FORMAT_RGBA1010102, TBM_FORMAT_BGRA1010102
57 };
58
59 const int NUM_FORMATS_BLENDING_REQUIRED = 18;
60
61 }
62
63 NativeImageSourceQueueTizen* NativeImageSourceQueueTizen::New( unsigned int width, unsigned int height, Dali::NativeImageSourceQueue::ColorDepth depth, Any nativeImageSourceQueue )
64 {
65   NativeImageSourceQueueTizen* image = new NativeImageSourceQueueTizen( width, height, depth, nativeImageSourceQueue );
66   DALI_ASSERT_DEBUG( image && "NativeImageSourceQueueTizen allocation failed." );
67
68   if( image )
69   {
70     image->Initialize( depth );
71   }
72
73   return image;
74 }
75
76 NativeImageSourceQueueTizen::NativeImageSourceQueueTizen( unsigned int width, unsigned int height, Dali::NativeImageSourceQueue::ColorDepth depth, Any nativeImageSourceQueue )
77 : mWidth( width ),
78   mHeight( height ),
79   mTbmQueue( NULL ),
80   mConsumeSurface( NULL ),
81   mEglImages(),
82   mEglGraphics( NULL ),
83   mEglImageExtensions( NULL ),
84   mOwnTbmQueue( false ),
85   mBlendingRequired( false )
86 {
87   DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() );
88
89   GraphicsInterface* graphics = &( Adaptor::GetImplementation( Adaptor::Get() ).GetGraphicsInterface() );
90   mEglGraphics = static_cast<EglGraphics *>(graphics);
91
92   mTbmQueue = GetSurfaceFromAny( nativeImageSourceQueue );
93
94   if( mTbmQueue != NULL )
95   {
96     mBlendingRequired = CheckBlending( tbm_surface_queue_get_format( mTbmQueue ) );
97     mWidth = tbm_surface_queue_get_width( mTbmQueue );
98     mHeight = tbm_surface_queue_get_height( mTbmQueue );
99   }
100 }
101
102 NativeImageSourceQueueTizen::~NativeImageSourceQueueTizen()
103 {
104   if( mOwnTbmQueue )
105   {
106     DestroyQueue();
107   }
108 }
109
110 void NativeImageSourceQueueTizen::Initialize( Dali::NativeImageSourceQueue::ColorDepth depth )
111 {
112   if( mTbmQueue != NULL || mWidth == 0 || mHeight == 0 )
113   {
114     return;
115   }
116
117   int format = TBM_FORMAT_ARGB8888;
118
119   switch( depth )
120   {
121     case Dali::NativeImageSourceQueue::COLOR_DEPTH_DEFAULT:
122     case Dali::NativeImageSourceQueue::COLOR_DEPTH_32:
123     {
124       format = TBM_FORMAT_ARGB8888;
125       mBlendingRequired = true;
126       break;
127     }
128     case Dali::NativeImageSourceQueue::COLOR_DEPTH_24:
129     {
130       format = TBM_FORMAT_RGB888;
131       mBlendingRequired = false;
132       break;
133     }
134     default:
135     {
136       DALI_LOG_WARNING( "Wrong color depth.\n" );
137       return;
138     }
139   }
140
141   mTbmQueue = tbm_surface_queue_create( TBM_SURFACE_QUEUE_SIZE, mWidth, mHeight, format, 0 );
142
143   mOwnTbmQueue = true;
144 }
145
146 tbm_surface_queue_h NativeImageSourceQueueTizen::GetSurfaceFromAny( Any source ) const
147 {
148   if( source.Empty() )
149   {
150     return NULL;
151   }
152
153   if( source.GetType() == typeid( tbm_surface_queue_h ) )
154   {
155     return AnyCast< tbm_surface_queue_h >( source );
156   }
157   else
158   {
159     return NULL;
160   }
161 }
162
163 Any NativeImageSourceQueueTizen::GetNativeImageSourceQueue() const
164 {
165   return Any( mTbmQueue );
166 }
167
168 void NativeImageSourceQueueTizen::SetSource( Any source )
169 {
170   if( mOwnTbmQueue )
171   {
172     DestroyQueue();
173   }
174
175   mTbmQueue = GetSurfaceFromAny( source );
176
177   if( mTbmQueue != NULL )
178   {
179     mBlendingRequired = CheckBlending( tbm_surface_queue_get_format( mTbmQueue ) );
180     mWidth = tbm_surface_queue_get_width( mTbmQueue );
181     mHeight = tbm_surface_queue_get_height( mTbmQueue );
182   }
183 }
184
185 bool NativeImageSourceQueueTizen::GlExtensionCreate()
186 {
187   mEglImageExtensions = mEglGraphics->GetImageExtensions();
188   DALI_ASSERT_DEBUG( mEglImageExtensions );
189
190   return true;
191 }
192
193 void NativeImageSourceQueueTizen::GlExtensionDestroy()
194 {
195   for( auto&& iter : mEglImages )
196   {
197     mEglImageExtensions->DestroyImageKHR( iter.second );
198
199     tbm_surface_internal_unref( iter.first );
200   }
201   mEglImages.clear();
202 }
203
204 unsigned int NativeImageSourceQueueTizen::TargetTexture()
205 {
206   return 0;
207 }
208
209 void NativeImageSourceQueueTizen::PrepareTexture()
210 {
211   tbm_surface_h oldSurface = mConsumeSurface;
212
213   if( tbm_surface_queue_can_acquire( mTbmQueue, 0 ) )
214   {
215     if( tbm_surface_queue_acquire( mTbmQueue, &mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
216     {
217       DALI_LOG_ERROR( "Failed to aquire a tbm_surface\n" );
218       return;
219     }
220
221     if( oldSurface )
222     {
223       if( tbm_surface_internal_is_valid( oldSurface ) )
224       {
225         tbm_surface_queue_release( mTbmQueue, oldSurface );
226       }
227     }
228
229     if( mConsumeSurface )
230     {
231       bool existing = false;
232       for( auto&& iter : mEglImages )
233       {
234         if( iter.first == mConsumeSurface )
235         {
236           // Find the surface in the existing list
237           existing = true;
238           mEglImageExtensions->TargetTextureKHR( iter.second );
239           break;
240         }
241       }
242
243       if( !existing )
244       {
245         // Push the surface
246         tbm_surface_internal_ref( mConsumeSurface );
247
248         void* eglImageKHR = mEglImageExtensions->CreateImageKHR( reinterpret_cast< EGLClientBuffer >( mConsumeSurface ) );
249         mEglImageExtensions->TargetTextureKHR( eglImageKHR );
250
251         mEglImages.push_back( EglImagePair( mConsumeSurface, eglImageKHR) );
252       }
253     }
254   }
255 }
256
257 const char* NativeImageSourceQueueTizen::GetCustomFragmentPreFix()
258 {
259   return FRAGMENT_PREFIX;
260 }
261
262 const char* NativeImageSourceQueueTizen::GetCustomSamplerTypename()
263 {
264   return SAMPLER_TYPE;
265 }
266
267 int NativeImageSourceQueueTizen::GetEglImageTextureTarget()
268 {
269   return GL_TEXTURE_EXTERNAL_OES;
270 }
271
272 void NativeImageSourceQueueTizen::DestroyQueue()
273 {
274   if( mConsumeSurface )
275   {
276     tbm_surface_internal_unref( mConsumeSurface );
277
278     if( tbm_surface_internal_is_valid( mConsumeSurface ) )
279     {
280       tbm_surface_queue_release( mTbmQueue, mConsumeSurface );
281     }
282   }
283
284   if( mTbmQueue != NULL )
285   {
286     tbm_surface_queue_destroy( mTbmQueue );
287   }
288
289   mTbmQueue = NULL;
290   mOwnTbmQueue = false;
291 }
292
293 bool NativeImageSourceQueueTizen::CheckBlending( int format )
294 {
295   for( int i = 0; i < NUM_FORMATS_BLENDING_REQUIRED; ++i )
296   {
297     if( format == FORMATS_BLENDING_REQUIRED[i] )
298     {
299       return true;
300     }
301   }
302
303   return false;
304 }
305
306 } // namespace Adaptor
307
308 } // namespace internal
309
310 } // namespace Dali