2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/window-system/tizen-wayland/ecore-wl/window-render-surface-ecore-wl.h>
22 #include <dali/integration-api/gl-abstraction.h>
23 #include <dali/integration-api/debug.h>
26 #include <dali/internal/graphics/gles20/egl-implementation.h>
27 #include <dali/internal/adaptor/common/adaptor-impl.h>
28 #include <dali/integration-api/trigger-event-factory-interface.h>
40 const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
42 #if defined(DEBUG_ENABLED)
43 Debug::Filter* gWindowRenderSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_WINDOW_RENDER_SURFACE_ECORE_WL");
46 } // unnamed namespace
48 WindowRenderSurfaceEcoreWl::WindowRenderSurfaceEcoreWl( Dali::PositionSize positionSize,
50 const std::string& name,
53 mPositionSize( positionSize ),
57 mThreadSynchronization( NULL ),
58 mRenderNotification( NULL ),
59 mRotationTrigger( NULL ),
60 mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ),
62 mScreenRotationAngle( 0 ),
64 mRotationSupported( false ),
65 mRotationFinished( true ),
66 mScreenRotationFinished( true ),
67 mResizeFinished( true )
69 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
70 Initialize( surface );
73 WindowRenderSurfaceEcoreWl::~WindowRenderSurfaceEcoreWl()
75 if( mEglWindow != NULL )
77 wl_egl_window_destroy(mEglWindow);
83 ecore_wl_window_free( mWlWindow );
86 if( mRotationTrigger )
88 delete mRotationTrigger;
97 void WindowRenderSurfaceEcoreWl::Initialize( Any surface )
99 // see if there is a surface in Any surface
100 unsigned int surfaceId = GetSurfaceId( surface );
102 // if the surface is empty, create a new one.
105 // we own the surface about to created
106 ecore_wl_init( NULL );
112 // XLib should already be initialized so no point in calling XInitThreads
113 UseExistingRenderable( surfaceId );
117 Ecore_Wl_Window* WindowRenderSurfaceEcoreWl::GetWlWindow()
122 void WindowRenderSurfaceEcoreWl::OutputTransformed()
126 if( ecore_wl_window_ignore_output_transform_get( mWlWindow ) )
132 transform = ecore_wl_output_transform_get( ecore_wl_window_output_find( mWlWindow ) );
135 mScreenRotationAngle = transform * 90;
136 mScreenRotationFinished = false;
138 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
141 Any WindowRenderSurfaceEcoreWl::GetWindow()
146 void WindowRenderSurfaceEcoreWl::Map()
148 ecore_wl_window_show( mWlWindow );
151 void WindowRenderSurfaceEcoreWl::SetRenderNotification( TriggerEventInterface* renderNotification )
153 mRenderNotification = renderNotification;
156 void WindowRenderSurfaceEcoreWl::SetTransparency( bool transparent )
158 ecore_wl_window_alpha_set( mWlWindow, transparent );
161 void WindowRenderSurfaceEcoreWl::RequestRotation( int angle, int width, int height )
163 if( !mRotationSupported )
165 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::Rotate: Rotation is not supported!\n" );
169 if( !mRotationTrigger )
171 TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface();
172 mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurfaceEcoreWl::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
175 mPositionSize.width = width;
176 mPositionSize.height = height;
178 mRotationAngle = angle;
179 mRotationFinished = false;
181 ecore_wl_window_rotation_set( mWlWindow, mRotationAngle );
183 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::Rotate: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
186 PositionSize WindowRenderSurfaceEcoreWl::GetPositionSize() const
188 return mPositionSize;
191 void WindowRenderSurfaceEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
196 // 1 inch = 25.4 millimeters
197 xres = ecore_wl_dpi_get();
198 yres = ecore_wl_dpi_get();
200 dpiHorizontal = int( xres + 0.5f ); // rounding
201 dpiVertical = int( yres + 0.5f );
204 void WindowRenderSurfaceEcoreWl::InitializeEgl( EglInterface& eglIf )
206 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
208 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
210 eglImpl.ChooseConfig(true, mColorDepth);
213 void WindowRenderSurfaceEcoreWl::CreateEglSurface( EglInterface& eglIf )
215 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
217 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
219 // create the EGL window
220 if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
222 mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height );
226 mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width );
229 EGLNativeWindowType windowType( mEglWindow );
230 eglImpl.CreateSurfaceWindow( windowType, mColorDepth );
233 wl_egl_window_capability capability = static_cast< wl_egl_window_capability >( wl_egl_window_get_capabilities( mEglWindow ) );
234 if( capability == WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED )
236 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::CreateEglSurface: capability = %d\n", capability );
237 mRotationSupported = true;
240 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::CreateEglSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle );
243 void WindowRenderSurfaceEcoreWl::DestroyEglSurface( EglInterface& eglIf )
245 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
247 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
248 eglImpl.DestroySurface();
250 if( mEglWindow != NULL )
252 wl_egl_window_destroy(mEglWindow);
257 bool WindowRenderSurfaceEcoreWl::ReplaceEGLSurface( EglInterface& egl )
259 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
261 if( mEglWindow != NULL )
263 wl_egl_window_destroy(mEglWindow);
267 if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
269 mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height );
273 mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width );
276 // Set screen rotation
277 mScreenRotationFinished = false;
279 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
280 EGLNativeWindowType windowType( mEglWindow );
281 return eglImpl.ReplaceSurfaceWindow( windowType );
284 void WindowRenderSurfaceEcoreWl::MoveResize( Dali::PositionSize positionSize )
286 bool needToMove = false;
287 bool needToResize = false;
290 if( (fabs(positionSize.x - mPositionSize.x) > MINIMUM_DIMENSION_CHANGE) ||
291 (fabs(positionSize.y - mPositionSize.y) > MINIMUM_DIMENSION_CHANGE) )
297 if( (fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) ||
298 (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE) )
305 ecore_wl_window_position_set( mWlWindow, positionSize.x, positionSize.y );
309 ecore_wl_window_update_size( mWlWindow, positionSize.width, positionSize.height );
310 mResizeFinished = false;
313 mPositionSize = positionSize;
315 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height );
318 void WindowRenderSurfaceEcoreWl::SetViewMode( ViewMode viewMode )
322 void WindowRenderSurfaceEcoreWl::StartRender()
326 bool WindowRenderSurfaceEcoreWl::PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface )
328 if( resizingSurface )
330 #ifdef OVER_TIZEN_VERSION_4
331 // Window rotate or screen rotate
332 if( !mRotationFinished || !mScreenRotationFinished )
334 wl_egl_window_rotation rotation;
335 wl_output_transform bufferTransform;
336 int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360;
342 rotation = ROTATION_0;
343 bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL;
348 rotation = ROTATION_270;
349 bufferTransform = WL_OUTPUT_TRANSFORM_90;
354 rotation = ROTATION_180;
355 bufferTransform = WL_OUTPUT_TRANSFORM_180;
360 rotation = ROTATION_90;
361 bufferTransform = WL_OUTPUT_TRANSFORM_270;
366 rotation = ROTATION_0;
367 bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL;
372 wl_egl_window_set_rotation( mEglWindow, rotation );
374 wl_egl_window_set_buffer_transform( mEglWindow, bufferTransform );
376 // Reset only screen rotation flag
377 mScreenRotationFinished = true;
379 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::PreRender: Set rotation [%d] [%d]\n", mRotationAngle, mScreenRotationAngle );
382 // Only window rotate
383 if( !mRotationFinished )
385 wl_output_transform windowTransform;
387 switch( mRotationAngle )
391 windowTransform = WL_OUTPUT_TRANSFORM_NORMAL;
396 windowTransform = WL_OUTPUT_TRANSFORM_90;
401 windowTransform = WL_OUTPUT_TRANSFORM_180;
406 windowTransform = WL_OUTPUT_TRANSFORM_270;
411 windowTransform = WL_OUTPUT_TRANSFORM_NORMAL;
416 wl_egl_window_set_window_transform( mEglWindow, windowTransform );
421 if( !mResizeFinished )
423 wl_egl_window_resize( mEglWindow, mPositionSize.width, mPositionSize.height, mPositionSize.x, mPositionSize.y );
424 mResizeFinished = true;
426 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::PreRender: Set resize\n" );
433 void WindowRenderSurfaceEcoreWl::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
435 if( resizingSurface )
437 if( !mRotationFinished )
439 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::PostRender: Trigger rotation event\n" );
441 mRotationTrigger->Trigger();
443 if( mThreadSynchronization )
445 // Wait until the event-thread complete the rotation event processing
446 mThreadSynchronization->PostRenderWaitForCompletion();
451 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
452 eglImpl.SwapBuffers();
454 if( mRenderNotification )
456 mRenderNotification->Trigger();
460 void WindowRenderSurfaceEcoreWl::StopRender()
464 void WindowRenderSurfaceEcoreWl::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
466 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::SetThreadSynchronization: called\n" );
468 mThreadSynchronization = &threadSynchronization;
471 void WindowRenderSurfaceEcoreWl::ReleaseLock()
476 RenderSurface::Type WindowRenderSurfaceEcoreWl::GetSurfaceType()
478 return RenderSurface::WINDOW_RENDER_SURFACE;
481 void WindowRenderSurfaceEcoreWl::CreateRenderable()
483 // if width or height are zero, go full screen.
484 if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) )
486 // Default window size == screen size
490 ecore_wl_screen_size_get( &mPositionSize.width, &mPositionSize.height );
493 mWlWindow = ecore_wl_window_new( 0, mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW );
495 if ( mWlWindow == 0 )
497 DALI_ASSERT_ALWAYS(0 && "Failed to create Wayland window");
500 mWlSurface = ecore_wl_window_surface_create( mWlWindow );
502 if( mColorDepth == COLOR_DEPTH_32 )
504 ecore_wl_window_alpha_set( mWlWindow, true );
508 ecore_wl_window_alpha_set( mWlWindow, false );
511 // Get output transform
512 if( !ecore_wl_window_ignore_output_transform_get( mWlWindow ) )
514 Ecore_Wl_Output* output = ecore_wl_window_output_find( mWlWindow );
516 int transform = ecore_wl_output_transform_get( output );
518 mScreenRotationAngle = transform * 90;
519 mScreenRotationFinished = false;
523 void WindowRenderSurfaceEcoreWl::UseExistingRenderable( unsigned int surfaceId )
525 mWlWindow = AnyCast< Ecore_Wl_Window* >( surfaceId );
528 unsigned int WindowRenderSurfaceEcoreWl::GetSurfaceId( Any surface ) const
530 unsigned int surfaceId = 0;
532 if( surface.Empty() == false )
534 // check we have a valid type
535 DALI_ASSERT_ALWAYS( ( (surface.GetType() == typeid (Ecore_Wl_Window *) ) )
536 && "Surface type is invalid" );
538 surfaceId = AnyCast<unsigned int>( surface );
543 void WindowRenderSurfaceEcoreWl::ProcessRotationRequest()
545 mRotationFinished = true;
547 ecore_wl_window_rotation_change_done_send( mWlWindow );
549 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::ProcessRotationRequest: Rotation Done\n" );
551 if( mThreadSynchronization )
553 mThreadSynchronization->PostRenderComplete();
557 } // namespace Adaptor
559 } // namespace internal