Revert "[Tizen] ecore-wl2: add zxdg_shell define"
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / tizen-wayland / window-render-surface-ecore-wl.cpp
1 /*
2  * Copyright (c) 2017 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/window-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 // INTERNAL INCLUDES
26 #include <dali/integration-api/wayland/wl-types.h>
27 #include <dali/internal/graphics/gles20/egl-implementation.h>
28 #include <dali/internal/adaptor/common/adaptor-impl.h>
29 #include <dali/integration-api/trigger-event-factory-interface.h>
30
31 namespace Dali
32 {
33
34 #if defined(DEBUG_ENABLED)
35 extern Debug::Filter* gRenderSurfaceLogFilter;
36 #endif
37
38 namespace ECore
39 {
40
41 namespace
42 {
43
44 const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
45
46 } // unnamed namespace
47
48 WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize,
49                                           Any surface,
50                                           const std::string& name,
51                                           bool isTransparent)
52 : EcoreWlRenderSurface( positionSize, surface, name, isTransparent ),
53   mWlWindow( NULL ),
54   mWlSurface( NULL ),
55   mEglWindow( NULL ),
56   mThreadSynchronization( NULL ),
57   mRotationTrigger( NULL ),
58   mRotationAngle( 0 ),
59   mScreenRotationAngle( 0 ),
60   mRotationSupported( false ),
61   mRotationFinished( true ),
62   mScreenRotationFinished( true ),
63   mResizeFinished( true )
64 {
65   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
66   Init( surface );
67 }
68
69 WindowRenderSurface::~WindowRenderSurface()
70 {
71   if( mEglWindow != NULL )
72   {
73     wl_egl_window_destroy(mEglWindow);
74     mEglWindow = NULL;
75   }
76
77   if( mOwnSurface )
78   {
79     ecore_wl_window_free( mWlWindow );
80   }
81
82   if( mRotationTrigger )
83   {
84     delete mRotationTrigger;
85   }
86
87 }
88
89 Ecore_Wl_Window* WindowRenderSurface::GetDrawable()
90 {
91   // already an e-core type
92   return mWlWindow;
93 }
94
95 Any WindowRenderSurface::GetSurface()
96 {
97   // already an e-core type
98   return Any( mWlWindow );
99 }
100
101 Ecore_Wl_Window* WindowRenderSurface::GetWlWindow()
102 {
103   return mWlWindow;
104 }
105
106 void WindowRenderSurface::RequestRotation( int angle, int width, int height )
107 {
108   if( !mRotationSupported )
109   {
110     DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: Rotation is not supported!\n" );
111     return;
112   }
113
114   if( !mRotationTrigger )
115   {
116     TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface();
117     mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
118   }
119
120   mPositionSize.width = width;
121   mPositionSize.height = height;
122
123   mRotationAngle = angle;
124   mRotationFinished = false;
125
126   ecore_wl_window_rotation_set( mWlWindow, mRotationAngle );
127
128   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
129 }
130
131 void WindowRenderSurface::OutputTransformed()
132 {
133   int transform;
134
135   if( ecore_wl_window_ignore_output_transform_get( mWlWindow ) )
136   {
137     transform = 0;
138   }
139   else
140   {
141     transform = ecore_wl_output_transform_get( ecore_wl_window_output_find( mWlWindow ) );
142   }
143
144   mScreenRotationAngle = transform * 90;
145   mScreenRotationFinished = false;
146
147   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
148 }
149
150 void WindowRenderSurface::SetTransparency( bool transparent )
151 {
152   ecore_wl_window_alpha_set( mWlWindow, transparent );
153 }
154
155 void WindowRenderSurface::InitializeEgl( EglInterface& eglIf )
156 {
157   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
158
159   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
160
161   eglImpl.ChooseConfig(true, mColorDepth);
162 }
163
164 void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf )
165 {
166   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
167
168   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
169
170   // create the EGL window
171   if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
172   {
173     mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height );
174   }
175   else
176   {
177     mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width );
178   }
179
180   EGLNativeWindowType windowType( mEglWindow );
181   eglImpl.CreateSurfaceWindow( windowType, mColorDepth );
182
183   // Check capability
184   wl_egl_window_capability capability = static_cast< wl_egl_window_capability >( wl_egl_window_get_capabilities( mEglWindow ) );
185   if( capability == WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED )
186   {
187     DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: capability = %d\n", capability );
188     mRotationSupported = true;
189   }
190
191   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle );
192 }
193
194 void WindowRenderSurface::DestroyEglSurface( EglInterface& eglIf )
195 {
196   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
197
198   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
199   eglImpl.DestroySurface();
200
201   if( mEglWindow != NULL )
202   {
203     wl_egl_window_destroy(mEglWindow);
204     mEglWindow = NULL;
205   }
206 }
207
208 bool WindowRenderSurface::ReplaceEGLSurface( EglInterface& egl )
209 {
210   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
211
212   if( mEglWindow != NULL )
213   {
214     wl_egl_window_destroy(mEglWindow);
215     mEglWindow = NULL;
216   }
217
218   if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
219   {
220     mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height );
221   }
222   else
223   {
224     mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width );
225   }
226
227   // Set screen rotation
228   mScreenRotationFinished = false;
229
230   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
231   EGLNativeWindowType windowType( mEglWindow );
232   return eglImpl.ReplaceSurfaceWindow( windowType );
233 }
234
235 void WindowRenderSurface::MoveResize( Dali::PositionSize positionSize )
236 {
237   bool needToMove = false;
238   bool needToResize = false;
239
240   // check moving
241   if( (fabs(positionSize.x - mPositionSize.x) > MINIMUM_DIMENSION_CHANGE) ||
242       (fabs(positionSize.y - mPositionSize.y) > MINIMUM_DIMENSION_CHANGE) )
243   {
244     needToMove = true;
245   }
246
247   // check resizing
248   if( (fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) ||
249       (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE) )
250   {
251     needToResize = true;
252   }
253
254   if( needToMove )
255   {
256     ecore_wl_window_position_set( mWlWindow, positionSize.x, positionSize.y );
257   }
258   if( needToResize )
259   {
260     ecore_wl_window_update_size( mWlWindow, positionSize.width, positionSize.height );
261     mResizeFinished = false;
262   }
263
264   mPositionSize = positionSize;
265
266   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height );
267 }
268
269 void WindowRenderSurface::Map()
270 {
271   ecore_wl_window_show(mWlWindow);
272 }
273
274 void WindowRenderSurface::StartRender()
275 {
276 }
277
278 bool WindowRenderSurface::PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface )
279 {
280   if( resizingSurface )
281   {
282 #ifdef OVER_TIZEN_VERSION_4
283     // Window rotate or screen rotate
284     if( !mRotationFinished || !mScreenRotationFinished )
285     {
286       wl_egl_window_rotation rotation;
287       wl_output_transform bufferTransform;
288       int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360;
289
290       switch( totalAngle )
291       {
292         case 0:
293         {
294           rotation = ROTATION_0;
295           bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL;
296           break;
297         }
298         case 90:
299         {
300           rotation = ROTATION_270;
301           bufferTransform = WL_OUTPUT_TRANSFORM_90;
302           break;
303         }
304         case 180:
305         {
306           rotation = ROTATION_180;
307           bufferTransform = WL_OUTPUT_TRANSFORM_180;
308           break;
309         }
310         case 270:
311         {
312           rotation = ROTATION_90;
313           bufferTransform = WL_OUTPUT_TRANSFORM_270;
314           break;
315         }
316         default:
317         {
318           rotation = ROTATION_0;
319           bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL;
320           break;
321         }
322       }
323
324       wl_egl_window_set_rotation( mEglWindow, rotation );
325
326       wl_egl_window_set_buffer_transform( mEglWindow, bufferTransform );
327
328       // Reset only screen rotation flag
329       mScreenRotationFinished = true;
330
331       DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set rotation [%d] [%d]\n", mRotationAngle, mScreenRotationAngle );
332     }
333
334     // Only window rotate
335     if( !mRotationFinished )
336     {
337       wl_output_transform windowTransform;
338
339       switch( mRotationAngle )
340       {
341         case 0:
342         {
343           windowTransform = WL_OUTPUT_TRANSFORM_NORMAL;
344           break;
345         }
346         case 90:
347         {
348           windowTransform = WL_OUTPUT_TRANSFORM_90;
349           break;
350         }
351         case 180:
352         {
353           windowTransform = WL_OUTPUT_TRANSFORM_180;
354           break;
355         }
356         case 270:
357         {
358           windowTransform = WL_OUTPUT_TRANSFORM_270;
359           break;
360         }
361         default:
362         {
363           windowTransform = WL_OUTPUT_TRANSFORM_NORMAL;
364           break;
365         }
366       }
367
368       wl_egl_window_set_window_transform( mEglWindow, windowTransform );
369     }
370 #endif
371
372     // Resize case
373     if( !mResizeFinished )
374     {
375       wl_egl_window_resize( mEglWindow, mPositionSize.width, mPositionSize.height, mPositionSize.x, mPositionSize.y );
376       mResizeFinished = true;
377
378       DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set resize\n" );
379     }
380   }
381
382   return true;
383 }
384
385 void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
386 {
387   if( resizingSurface )
388   {
389     if( !mRotationFinished )
390     {
391       DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PostRender: Trigger rotation event\n" );
392
393       mRotationTrigger->Trigger();
394
395       if( mThreadSynchronization )
396       {
397         // Wait until the event-thread complete the rotation event processing
398         mThreadSynchronization->PostRenderWaitForCompletion();
399       }
400     }
401   }
402
403   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
404   eglImpl.SwapBuffers();
405
406   if( mRenderNotification )
407   {
408     mRenderNotification->Trigger();
409   }
410 }
411
412 void WindowRenderSurface::StopRender()
413 {
414 }
415
416 void WindowRenderSurface::SetViewMode( ViewMode viewMode )
417 {
418   //FIXME
419 }
420
421 void WindowRenderSurface::CreateWlRenderable()
422 {
423    // if width or height are zero, go full screen.
424   if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) )
425   {
426     // Default window size == screen size
427     mPositionSize.x = 0;
428     mPositionSize.y = 0;
429
430     ecore_wl_screen_size_get( &mPositionSize.width, &mPositionSize.height );
431   }
432
433   mWlWindow = ecore_wl_window_new( 0, mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW );
434
435   if ( mWlWindow == 0 )
436   {
437     DALI_ASSERT_ALWAYS(0 && "Failed to create Wayland window");
438   }
439
440   mWlSurface = ecore_wl_window_surface_create( mWlWindow );
441
442   if( mColorDepth == COLOR_DEPTH_32 )
443   {
444     ecore_wl_window_alpha_set( mWlWindow, true );
445   }
446   else
447   {
448     ecore_wl_window_alpha_set( mWlWindow, false );
449   }
450
451   // Get output transform
452   if( !ecore_wl_window_ignore_output_transform_get( mWlWindow ) )
453   {
454     Ecore_Wl_Output* output = ecore_wl_window_output_find( mWlWindow );
455
456     int transform = ecore_wl_output_transform_get( output );
457
458     mScreenRotationAngle = transform * 90;
459     mScreenRotationFinished = false;
460   }
461 }
462
463 void WindowRenderSurface::UseExistingRenderable( unsigned int surfaceId )
464 {
465   mWlWindow = AnyCast< Ecore_Wl_Window* >( surfaceId );
466 }
467
468 void WindowRenderSurface::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
469 {
470   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::SetThreadSynchronization: called\n" );
471
472   mThreadSynchronization = &threadSynchronization;
473 }
474
475 void WindowRenderSurface::ReleaseLock()
476 {
477   // Nothing to do.
478 }
479
480 void WindowRenderSurface::ProcessRotationRequest()
481 {
482   mRotationFinished = true;
483
484   ecore_wl_window_rotation_change_done_send( mWlWindow );
485
486   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::ProcessRotationRequest: Rotation Done\n" );
487
488   if( mThreadSynchronization )
489   {
490     mThreadSynchronization->PostRenderComplete();
491   }
492 }
493
494 } // namespace ECore
495
496 } // namespace Dali