2 * Copyright (c) 2017 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 <window-render-surface.h>
22 #include <dali/integration-api/gl-abstraction.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/gl-defines.h>
28 #include <gl/egl-implementation.h>
29 #include <base/display-connection.h>
30 #include <adaptors/common/adaptor-impl.h>
31 #include <integration-api/trigger-event-factory-interface.h>
36 #if defined(DEBUG_ENABLED)
37 extern Debug::Filter* gRenderSurfaceLogFilter;
46 const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
48 } // unnamed namespace
50 WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize,
52 const std::string& name,
54 : EcoreWlRenderSurface( positionSize, surface, name, isTransparent ),
57 mThreadSynchronization( NULL ),
58 mRotationTrigger( NULL ),
59 mRotationSupported( false ),
62 DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
66 WindowRenderSurface::~WindowRenderSurface()
68 if( mEglWindow != NULL )
70 wl_egl_window_destroy(mEglWindow);
76 ecore_wl_window_free( mWlWindow );
79 if( mRotationTrigger )
81 delete mRotationTrigger;
85 Ecore_Wl_Window* WindowRenderSurface::GetDrawable()
87 // already an e-core type
91 Any WindowRenderSurface::GetSurface()
93 // already an e-core type
94 return Any( mWlWindow );
97 Ecore_Wl_Window* WindowRenderSurface::GetWlWindow()
102 void WindowRenderSurface::RequestRotation( Dali::Window::WindowOrientation orientation, int width, int height )
104 if( !mRotationSupported )
106 DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: Rotation is not supported!\n" );
110 DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: orientation = %d\n", orientation );
112 if( !mRotationTrigger )
114 TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface();
115 mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
118 mPosition.width = width;
119 mPosition.height = height;
124 wl_egl_window_rotation rotation;
126 switch( orientation )
128 case Dali::Window::PORTRAIT:
131 rotation = ROTATION_0;
134 case Dali::Window::LANDSCAPE:
137 rotation = ROTATION_270;
140 case Dali::Window::PORTRAIT_INVERSE:
143 rotation = ROTATION_180;
146 case Dali::Window::LANDSCAPE_INVERSE:
149 rotation = ROTATION_90;
155 rotation = ROTATION_0;
160 ecore_wl_window_rotation_set( mWlWindow, angle );
162 wl_egl_window_set_rotation( mEglWindow, rotation );
165 void WindowRenderSurface::InitializeEgl( EglInterface& eglIf )
167 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
169 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
171 eglImpl.ChooseConfig(true, mColorDepth);
174 void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf )
176 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
178 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
180 // Temporary code for opaque window. We have to modify it after wayland team finish the work.
181 if( mColorDepth == COLOR_DEPTH_32 )
183 ecore_wl_window_alpha_set( mWlWindow, true );
187 ecore_wl_window_alpha_set( mWlWindow, false );
190 // create the EGL surface
191 ecore_wl_window_surface_create(mWlWindow);
192 mEglWindow = wl_egl_window_create(ecore_wl_window_surface_get(mWlWindow), mPosition.width, mPosition.height);
193 EGLNativeWindowType windowType( mEglWindow );
194 eglImpl.CreateSurfaceWindow( windowType, mColorDepth );
197 wl_egl_window_capability capability = static_cast< wl_egl_window_capability >( wl_egl_window_get_capabilities( mEglWindow ) );
198 if( capability == WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED )
200 DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: capability = %d\n", capability );
201 mRotationSupported = true;
205 void WindowRenderSurface::DestroyEglSurface( EglInterface& eglIf )
207 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
209 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
210 eglImpl.DestroySurface();
212 if( mEglWindow != NULL )
214 wl_egl_window_destroy(mEglWindow);
219 bool WindowRenderSurface::ReplaceEGLSurface( EglInterface& egl )
221 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
223 if( mEglWindow != NULL )
225 wl_egl_window_destroy(mEglWindow);
229 // Temporary code for opaque window. We have to modify it after wayland team finish the work.
230 if( mColorDepth == COLOR_DEPTH_32 )
232 ecore_wl_window_alpha_set( mWlWindow, true );
236 ecore_wl_window_alpha_set( mWlWindow, false );
239 mEglWindow = wl_egl_window_create(ecore_wl_window_surface_get(mWlWindow), mPosition.width, mPosition.height);
241 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
242 EGLNativeWindowType windowType( mEglWindow );
243 return eglImpl.ReplaceSurfaceWindow( windowType );
246 void WindowRenderSurface::MoveResize( Dali::PositionSize positionSize )
248 bool needToMove = false;
249 bool needToResize = false;
252 if( (fabs(positionSize.x - mPosition.x) > MINIMUM_DIMENSION_CHANGE) ||
253 (fabs(positionSize.y - mPosition.y) > MINIMUM_DIMENSION_CHANGE) )
259 if( (fabs(positionSize.width - mPosition.width) > MINIMUM_DIMENSION_CHANGE) ||
260 (fabs(positionSize.height - mPosition.height) > MINIMUM_DIMENSION_CHANGE) )
267 ecore_wl_window_move(mWlWindow, positionSize.x, positionSize.y);
268 mPosition = positionSize;
272 ecore_wl_window_resize(mWlWindow, positionSize.width, positionSize.height, 0);
273 mPosition = positionSize;
278 void WindowRenderSurface::Map()
280 ecore_wl_window_show(mWlWindow);
283 void WindowRenderSurface::StartRender()
287 bool WindowRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
289 // nothing to do for windows
293 void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface )
297 // Check viewport size
298 Dali::Vector< GLint > viewportSize;
299 viewportSize.Resize( 4 );
301 glAbstraction.GetIntegerv( GL_VIEWPORT, &viewportSize[0] );
303 if( viewportSize[2] == mPosition.width && viewportSize[3] == mPosition.height )
305 DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PostRender: Trigger rotation event\n" );
307 mRotationTrigger->Trigger();
309 if( mThreadSynchronization )
311 // Wait until the event-thread complete the rotation event processing
312 mThreadSynchronization->PostRenderWaitForCompletion();
317 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
318 eglImpl.SwapBuffers();
320 if( mRenderNotification )
322 mRenderNotification->Trigger();
326 void WindowRenderSurface::StopRender()
330 void WindowRenderSurface::SetViewMode( ViewMode viewMode )
335 void WindowRenderSurface::CreateWlRenderable()
337 // if width or height are zero, go full screen.
338 if ( (mPosition.width == 0) || (mPosition.height == 0) )
340 // Default window size == screen size
344 ecore_wl_screen_size_get( &mPosition.width, &mPosition.height );
347 mWlWindow = ecore_wl_window_new( 0, mPosition.x, mPosition.y, mPosition.width, mPosition.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW );
349 if ( mWlWindow == 0 )
351 DALI_ASSERT_ALWAYS(0 && "Failed to create Wayland window");
355 void WindowRenderSurface::UseExistingRenderable( unsigned int surfaceId )
357 mWlWindow = AnyCast< Ecore_Wl_Window* >( surfaceId );
360 void WindowRenderSurface::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
362 DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::SetThreadSynchronization: called\n" );
364 mThreadSynchronization = &threadSynchronization;
367 void WindowRenderSurface::ReleaseLock()
372 void WindowRenderSurface::ProcessRotationRequest()
376 ecore_wl_window_rotation_change_done_send( mWlWindow );
378 DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::ProcessRotationRequest: Rotation Done\n" );
380 if( mThreadSynchronization )
382 mThreadSynchronization->PostRenderComplete();