Revert "[Tizen] Add codes for Dali Windows Backend"
[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::SetViewMode( ViewMode viewMode )
201 {
202 }
203
204 void NativeRenderSurfaceEcoreWl::StartRender()
205 {
206 }
207
208 bool NativeRenderSurfaceEcoreWl::PreRender( bool )
209 {
210   // nothing to do for pixmaps
211   return true;
212 }
213
214 void NativeRenderSurfaceEcoreWl::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface )
215 {
216   auto eglGraphics = static_cast<Internal::Adaptor::EglGraphics *>(mGraphics);
217   Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
218
219   eglImpl.SwapBuffers();
220
221   if( mThreadSynchronization )
222   {
223     mThreadSynchronization->PostRenderStarted();
224   }
225
226   if( tbm_surface_queue_can_acquire( mTbmQueue, 1 ) )
227   {
228     if( tbm_surface_queue_acquire( mTbmQueue, &mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
229     {
230       DALI_LOG_ERROR( "Failed to acquire a tbm_surface\n" );
231       return;
232     }
233   }
234
235   tbm_surface_internal_ref( mConsumeSurface );
236
237   if( replacingSurface )
238   {
239     ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
240     mDrawableCompleted = true;
241     mTbmSurfaceCondition.Notify( lock );
242   }
243
244  // create damage for client applications which wish to know the update timing
245   if( !replacingSurface && mRenderNotification )
246   {
247     // use notification trigger
248     // Tell the event-thread to render the tbm_surface
249     mRenderNotification->Trigger();
250   }
251
252   if( mThreadSynchronization )
253   {
254     // wait until the event-thread completed to use the tbm_surface
255     mThreadSynchronization->PostRenderWaitForCompletion();
256   }
257
258   // release the consumed surface after post render was completed
259   ReleaseDrawable();
260 }
261
262 void NativeRenderSurfaceEcoreWl::StopRender()
263 {
264   ReleaseLock();
265 }
266
267 void NativeRenderSurfaceEcoreWl::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
268 {
269   mThreadSynchronization = &threadSynchronization;
270 }
271
272 RenderSurface::Type NativeRenderSurfaceEcoreWl::GetSurfaceType()
273 {
274   return RenderSurface::NATIVE_RENDER_SURFACE;
275 }
276
277 void NativeRenderSurfaceEcoreWl::ReleaseLock()
278 {
279   if( mThreadSynchronization )
280   {
281     mThreadSynchronization->PostRenderComplete();
282   }
283 }
284
285 void NativeRenderSurfaceEcoreWl::CreateNativeRenderable()
286 {
287   // check we're creating one with a valid size
288   DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "tbm_surface size is invalid" );
289
290   mTbmQueue = tbm_surface_queue_create( 3, mPosition.width, mPosition.height, mTbmFormat, TBM_BO_DEFAULT );
291
292   if( mTbmQueue )
293   {
294     mOwnSurface = true;
295   }
296   else
297   {
298     mOwnSurface = false;
299   }
300 }
301
302 void NativeRenderSurfaceEcoreWl::ReleaseDrawable()
303 {
304   if( mConsumeSurface )
305   {
306     tbm_surface_internal_unref( mConsumeSurface );
307
308     if( tbm_surface_internal_is_valid( mConsumeSurface ) )
309     {
310       tbm_surface_queue_release( mTbmQueue, mConsumeSurface );
311     }
312     mConsumeSurface = NULL;
313   }
314 }
315
316 } // namespace Dali