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