Support Ecore-Wayland2
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / tizen-wayland / native-render-surface-ecore-wl.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/window-system/tizen-wayland/native-render-surface-ecore-wl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/gl-abstraction.h>
23 #include <dali/integration-api/debug.h>
24
25 #ifdef ECORE_WAYLAND2
26 #include <Ecore_Wl2.h>
27 #else
28 #include <Ecore_Wayland.h>
29 #endif
30
31 #include <tbm_bufmgr.h>
32 #include <tbm_surface_internal.h>
33
34 // INTERNAL INCLUDES
35 #include <dali/internal/system/common/trigger-event.h>
36 #include <dali/internal/graphics/gles20/egl-implementation.h>
37 #include <dali/internal/window-system/common/display-connection.h>
38 #include <dali/internal/window-system/common/window-system.h>
39 #include <dali/integration-api/thread-synchronization-interface.h>
40
41 namespace Dali
42 {
43
44 namespace
45 {
46
47 #if defined(DEBUG_ENABLED)
48 Debug::Filter* gNativeSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_NATIVE_RENDER_SURFACE");
49 #endif
50
51 } // unnamed namespace
52
53 NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl( Dali::PositionSize positionSize, bool isTransparent )
54 : mPosition( positionSize ),
55   mRenderNotification( NULL ),
56   mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ),
57   mTbmFormat( isTransparent ? TBM_FORMAT_ARGB8888 : TBM_FORMAT_RGB888 ),
58   mOwnSurface( false ),
59   mDrawableCompleted( false ),
60   mTbmQueue( NULL ),
61   mConsumeSurface( NULL ),
62   mThreadSynchronization( NULL )
63 {
64   Dali::Internal::Adaptor::WindowSystem::Initialize();
65
66   CreateNativeRenderable();
67   setenv( "EGL_PLATFORM", "tbm", 1 );
68 }
69
70 NativeRenderSurfaceEcoreWl::~NativeRenderSurfaceEcoreWl()
71 {
72   // release the surface if we own one
73   if( mOwnSurface )
74   {
75     ReleaseDrawable();
76
77     if( mTbmQueue )
78     {
79       tbm_surface_queue_destroy( mTbmQueue );
80     }
81
82     DALI_LOG_INFO( gNativeSurfaceLogFilter, Debug::General, "Own tbm surface queue destroy\n" );
83   }
84
85   Dali::Internal::Adaptor::WindowSystem::Shutdown();
86 }
87
88 Any NativeRenderSurfaceEcoreWl::GetDrawable()
89 {
90   return mConsumeSurface;
91 }
92
93 void NativeRenderSurfaceEcoreWl::SetRenderNotification( TriggerEventInterface* renderNotification )
94 {
95   mRenderNotification = renderNotification;
96 }
97
98 void NativeRenderSurfaceEcoreWl::WaitUntilSurfaceReplaced()
99 {
100   ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
101   while( !mDrawableCompleted )
102   {
103     mTbmSurfaceCondition.Wait( lock );
104   }
105
106   mDrawableCompleted = false;
107 }
108
109 PositionSize NativeRenderSurfaceEcoreWl::GetPositionSize() const
110 {
111   return mPosition;
112 }
113
114 void NativeRenderSurfaceEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
115 {
116   // calculate DPI
117   float xres, yres;
118
119   // 1 inch = 25.4 millimeters
120 #ifdef ECORE_WAYLAND2
121   // TODO: Application should set dpi value in wayland2
122   xres = 96;
123   yres = 96;
124 #else
125   xres = ecore_wl_dpi_get();
126   yres = ecore_wl_dpi_get();
127 #endif
128
129   dpiHorizontal = int( xres + 0.5f );  // rounding
130   dpiVertical   = int( yres + 0.5f );
131 }
132
133 void NativeRenderSurfaceEcoreWl::InitializeEgl( EglInterface& egl )
134 {
135   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
136   unsetenv( "EGL_PLATFORM" );
137
138   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
139
140   eglImpl.ChooseConfig( true, mColorDepth );
141 }
142
143 void NativeRenderSurfaceEcoreWl::CreateEglSurface( EglInterface& egl )
144 {
145   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
146
147   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
148
149   eglImpl.CreateSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ), mColorDepth );
150 }
151
152 void NativeRenderSurfaceEcoreWl::DestroyEglSurface( EglInterface& egl )
153 {
154   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
155
156   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
157   eglImpl.DestroySurface();
158 }
159
160 bool NativeRenderSurfaceEcoreWl::ReplaceEGLSurface( EglInterface& egl )
161 {
162   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
163
164   if( !mTbmQueue )
165   {
166     return false;
167   }
168
169   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
170
171   return eglImpl.ReplaceSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ) );
172 }
173
174 void NativeRenderSurfaceEcoreWl::MoveResize( Dali::PositionSize positionSize )
175 {
176 }
177
178 void NativeRenderSurfaceEcoreWl::SetViewMode( ViewMode viewMode )
179 {
180 }
181
182 void NativeRenderSurfaceEcoreWl::StartRender()
183 {
184 }
185
186 bool NativeRenderSurfaceEcoreWl::PreRender( EglInterface&, Integration::GlAbstraction&, bool )
187 {
188   // nothing to do for pixmaps
189   return true;
190 }
191
192 void NativeRenderSurfaceEcoreWl::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
193 {
194   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
195   eglImpl.SwapBuffers();
196
197   if( mThreadSynchronization )
198   {
199     mThreadSynchronization->PostRenderStarted();
200   }
201
202   if( tbm_surface_queue_can_acquire( mTbmQueue, 1 ) )
203   {
204     if( tbm_surface_queue_acquire( mTbmQueue, &mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
205     {
206       DALI_LOG_ERROR( "Failed to aquire a tbm_surface\n" );
207       return;
208     }
209   }
210
211   tbm_surface_internal_ref( mConsumeSurface );
212
213   if( replacingSurface )
214   {
215     ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
216     mDrawableCompleted = true;
217     mTbmSurfaceCondition.Notify( lock );
218   }
219
220  // create damage for client applications which wish to know the update timing
221   if( !replacingSurface && mRenderNotification )
222   {
223     // use notification trigger
224     // Tell the event-thread to render the tbm_surface
225     mRenderNotification->Trigger();
226   }
227
228   if( mThreadSynchronization )
229   {
230     // wait until the event-thread completed to use the tbm_surface
231     mThreadSynchronization->PostRenderWaitForCompletion();
232   }
233
234   // release the consumed surface after post render was completed
235   ReleaseDrawable();
236 }
237
238 void NativeRenderSurfaceEcoreWl::StopRender()
239 {
240   ReleaseLock();
241 }
242
243 void NativeRenderSurfaceEcoreWl::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
244 {
245   mThreadSynchronization = &threadSynchronization;
246 }
247
248 RenderSurface::Type NativeRenderSurfaceEcoreWl::GetSurfaceType()
249 {
250   return RenderSurface::NATIVE_RENDER_SURFACE;
251 }
252
253 void NativeRenderSurfaceEcoreWl::ReleaseLock()
254 {
255   if( mThreadSynchronization )
256   {
257     mThreadSynchronization->PostRenderComplete();
258   }
259 }
260
261 void NativeRenderSurfaceEcoreWl::CreateNativeRenderable()
262 {
263   // check we're creating one with a valid size
264   DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "tbm_surface size is invalid" );
265
266   mTbmQueue = tbm_surface_queue_create( 3, mPosition.width, mPosition.height, mTbmFormat, TBM_BO_DEFAULT );
267
268   if( mTbmQueue )
269   {
270     mOwnSurface = true;
271   }
272   else
273   {
274     mOwnSurface = false;
275   }
276 }
277
278 void NativeRenderSurfaceEcoreWl::ReleaseDrawable()
279 {
280   if( mConsumeSurface )
281   {
282     tbm_surface_internal_unref( mConsumeSurface );
283
284     if( tbm_surface_internal_is_valid( mConsumeSurface ) )
285     {
286       tbm_surface_queue_release( mTbmQueue, mConsumeSurface );
287     }
288     mConsumeSurface = NULL;
289   }
290 }
291
292 } // namespace Dali