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