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