Move GetDpi implementation to RenderSurface
[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   ecore_wl_shutdown();
80 }
81
82 Any NativeRenderSurfaceEcoreWl::GetDrawable()
83 {
84   return mConsumeSurface;
85 }
86
87 void NativeRenderSurfaceEcoreWl::SetRenderNotification( TriggerEventInterface* renderNotification )
88 {
89   mRenderNotification = renderNotification;
90 }
91
92 void NativeRenderSurfaceEcoreWl::WaitUntilSurfaceReplaced()
93 {
94   ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
95   while( !mDrawableCompleted )
96   {
97     mTbmSurfaceCondition.Wait( lock );
98   }
99
100   mDrawableCompleted = false;
101 }
102
103 PositionSize NativeRenderSurfaceEcoreWl::GetPositionSize() const
104 {
105   return mPosition;
106 }
107
108 void NativeRenderSurfaceEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
109 {
110   // calculate DPI
111   float xres, yres;
112
113   // 1 inch = 25.4 millimeters
114   xres = ecore_wl_dpi_get();
115   yres = ecore_wl_dpi_get();
116
117   dpiHorizontal = int( xres + 0.5f );  // rounding
118   dpiVertical   = int( yres + 0.5f );
119 }
120
121 void NativeRenderSurfaceEcoreWl::InitializeEgl( EglInterface& egl )
122 {
123   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
124   unsetenv( "EGL_PLATFORM" );
125
126   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
127
128   eglImpl.ChooseConfig( true, mColorDepth );
129 }
130
131 void NativeRenderSurfaceEcoreWl::CreateEglSurface( EglInterface& egl )
132 {
133   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
134
135   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
136
137   eglImpl.CreateSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ), mColorDepth );
138 }
139
140 void NativeRenderSurfaceEcoreWl::DestroyEglSurface( EglInterface& egl )
141 {
142   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
143
144   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
145   eglImpl.DestroySurface();
146 }
147
148 bool NativeRenderSurfaceEcoreWl::ReplaceEGLSurface( EglInterface& egl )
149 {
150   DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
151
152   if( !mTbmQueue )
153   {
154     return false;
155   }
156
157   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
158
159   return eglImpl.ReplaceSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ) );
160 }
161
162 void NativeRenderSurfaceEcoreWl::MoveResize( Dali::PositionSize positionSize )
163 {
164 }
165
166 void NativeRenderSurfaceEcoreWl::SetViewMode( ViewMode viewMode )
167 {
168 }
169
170 void NativeRenderSurfaceEcoreWl::StartRender()
171 {
172 }
173
174 bool NativeRenderSurfaceEcoreWl::PreRender( EglInterface&, Integration::GlAbstraction&, bool )
175 {
176   // nothing to do for pixmaps
177   return true;
178 }
179
180 void NativeRenderSurfaceEcoreWl::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
181 {
182   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
183   eglImpl.SwapBuffers();
184
185   if( mThreadSynchronization )
186   {
187     mThreadSynchronization->PostRenderStarted();
188   }
189
190   if( tbm_surface_queue_can_acquire( mTbmQueue, 1 ) )
191   {
192     if( tbm_surface_queue_acquire( mTbmQueue, &mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
193     {
194       DALI_LOG_ERROR( "Failed to aquire a tbm_surface\n" );
195       return;
196     }
197   }
198
199   tbm_surface_internal_ref( mConsumeSurface );
200
201   if( replacingSurface )
202   {
203     ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
204     mDrawableCompleted = true;
205     mTbmSurfaceCondition.Notify( lock );
206   }
207
208  // create damage for client applications which wish to know the update timing
209   if( !replacingSurface && mRenderNotification )
210   {
211     // use notification trigger
212     // Tell the event-thread to render the tbm_surface
213     mRenderNotification->Trigger();
214   }
215
216   if( mThreadSynchronization )
217   {
218     // wait until the event-thread completed to use the tbm_surface
219     mThreadSynchronization->PostRenderWaitForCompletion();
220   }
221
222   // release the consumed surface after post render was completed
223   ReleaseDrawable();
224 }
225
226 void NativeRenderSurfaceEcoreWl::StopRender()
227 {
228   ReleaseLock();
229 }
230
231 void NativeRenderSurfaceEcoreWl::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
232 {
233   mThreadSynchronization = &threadSynchronization;
234 }
235
236 RenderSurface::Type NativeRenderSurfaceEcoreWl::GetSurfaceType()
237 {
238   return RenderSurface::NATIVE_RENDER_SURFACE;
239 }
240
241 void NativeRenderSurfaceEcoreWl::ReleaseLock()
242 {
243   if( mThreadSynchronization )
244   {
245     mThreadSynchronization->PostRenderComplete();
246   }
247 }
248
249 void NativeRenderSurfaceEcoreWl::CreateNativeRenderable()
250 {
251   // check we're creating one with a valid size
252   DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "tbm_surface size is invalid" );
253
254   mTbmQueue = tbm_surface_queue_create( 3, mPosition.width, mPosition.height, mTbmFormat, TBM_BO_DEFAULT );
255
256   if( mTbmQueue )
257   {
258     mOwnSurface = true;
259   }
260   else
261   {
262     mOwnSurface = false;
263   }
264 }
265
266 void NativeRenderSurfaceEcoreWl::ReleaseDrawable()
267 {
268   if( mConsumeSurface )
269   {
270     tbm_surface_internal_unref( mConsumeSurface );
271
272     if( tbm_surface_internal_is_valid( mConsumeSurface ) )
273     {
274       tbm_surface_queue_release( mTbmQueue, mConsumeSurface );
275     }
276     mConsumeSurface = NULL;
277   }
278 }
279
280 } // namespace Dali