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