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/common/window-render-surface.h>
22 #include <dali/integration-api/gl-abstraction.h>
23 #include <dali/integration-api/debug.h>
26 #include <dali/integration-api/trigger-event-factory-interface.h>
27 #include <dali/integration-api/thread-synchronization-interface.h>
28 #include <dali/internal/graphics/gles20/egl-implementation.h>
29 #include <dali/internal/adaptor/common/adaptor-impl.h>
30 #include <dali/internal/window-system/common/window-base.h>
31 #include <dali/internal/window-system/common/window-factory.h>
32 #include <dali/internal/window-system/common/window-system.h>
44 const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
46 #if defined(DEBUG_ENABLED)
47 Debug::Filter* gWindowRenderSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_WINDOW_RENDER_SURFACE");
50 } // unnamed namespace
52 WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent )
53 : mPositionSize( positionSize ),
55 mThreadSynchronization( NULL ),
56 mRenderNotification( NULL ),
57 mRotationTrigger( NULL ),
58 mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ),
60 mScreenRotationAngle( 0 ),
62 mRotationSupported( false ),
63 mRotationFinished( true ),
64 mScreenRotationFinished( true ),
65 mResizeFinished( true )
67 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
68 Initialize( surface );
71 WindowRenderSurface::~WindowRenderSurface()
73 if( mRotationTrigger )
75 delete mRotationTrigger;
79 void WindowRenderSurface::Initialize( Any surface )
81 // if width or height are zero, go full screen.
82 if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) )
84 // Default window size == screen size
88 WindowSystem::GetScreenSize( mPositionSize.width, mPositionSize.height );
91 // Create a window base
92 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
93 mWindowBase = windowFactory->CreateWindowBase( mPositionSize, surface, ( mColorDepth == COLOR_DEPTH_32 ? true : false ) );
96 mWindowBase->OutputTransformedSignal().Connect( this, &WindowRenderSurface::OutputTransformed );
98 // Check screen rotation
99 mScreenRotationAngle = mWindowBase->GetScreenRotationAngle();
100 if( mScreenRotationAngle != 0 )
102 mScreenRotationFinished = false;
106 Any WindowRenderSurface::GetNativeWindow()
108 return mWindowBase->GetNativeWindow();
111 int WindowRenderSurface::GetNativeWindowId()
113 return mWindowBase->GetNativeWindowId();
116 void WindowRenderSurface::Map()
121 void WindowRenderSurface::SetRenderNotification( TriggerEventInterface* renderNotification )
123 mRenderNotification = renderNotification;
126 void WindowRenderSurface::SetTransparency( bool transparent )
128 mWindowBase->SetTransparency( transparent );
131 void WindowRenderSurface::RequestRotation( int angle, int width, int height )
133 if( !mRotationSupported )
135 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: Rotation is not supported!\n" );
139 if( !mRotationTrigger )
141 TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface();
142 mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
145 mPositionSize.width = width;
146 mPositionSize.height = height;
148 mRotationAngle = angle;
149 mRotationFinished = false;
151 mWindowBase->SetWindowRotationAngle( mRotationAngle );
153 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
156 WindowBase* WindowRenderSurface::GetWindowBase()
158 return mWindowBase.get();
161 PositionSize WindowRenderSurface::GetPositionSize() const
163 return mPositionSize;
166 void WindowRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
168 mWindowBase->GetDpi( dpiHorizontal, dpiVertical );
171 void WindowRenderSurface::InitializeEgl( EglInterface& eglIf )
173 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
175 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
177 eglImpl.ChooseConfig(true, mColorDepth);
180 void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf )
182 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
185 if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
187 width = mPositionSize.width;
188 height = mPositionSize.height;
192 width = mPositionSize.height;
193 height = mPositionSize.width;
196 // create the EGL window
197 EGLNativeWindowType window = mWindowBase->CreateEglWindow( width, height );
199 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
200 eglImpl.CreateSurfaceWindow( window, mColorDepth );
202 // Check rotation capability
203 mRotationSupported = mWindowBase->IsEglWindowRotationSupported();
205 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle );
208 void WindowRenderSurface::DestroyEglSurface( EglInterface& eglIf )
210 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
212 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
213 eglImpl.DestroySurface();
215 mWindowBase->DestroyEglWindow();
218 bool WindowRenderSurface::ReplaceEGLSurface( EglInterface& egl )
220 DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter );
222 // Destroy the old one
223 mWindowBase->DestroyEglWindow();
226 if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
228 width = mPositionSize.width;
229 height = mPositionSize.height;
233 width = mPositionSize.height;
234 height = mPositionSize.width;
237 // create the EGL window
238 EGLNativeWindowType window = mWindowBase->CreateEglWindow( width, height );
240 // Set screen rotation
241 mScreenRotationFinished = false;
243 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
244 return eglImpl.ReplaceSurfaceWindow( window );
247 void WindowRenderSurface::MoveResize( Dali::PositionSize positionSize )
249 bool needToMove = false;
250 bool needToResize = false;
253 if( (fabs(positionSize.x - mPositionSize.x) > MINIMUM_DIMENSION_CHANGE) ||
254 (fabs(positionSize.y - mPositionSize.y) > MINIMUM_DIMENSION_CHANGE) )
260 if( (fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) ||
261 (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE) )
270 mWindowBase->MoveResize( positionSize );
274 mWindowBase->Resize( positionSize );
277 mResizeFinished = false;
278 mPositionSize = positionSize;
284 mWindowBase->Move( positionSize );
286 mPositionSize = positionSize;
290 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height );
293 void WindowRenderSurface::SetViewMode( ViewMode viewMode )
295 mWindowBase->SetViewMode( viewMode );
298 void WindowRenderSurface::StartRender()
302 bool WindowRenderSurface::PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface )
304 if( resizingSurface )
306 #ifdef OVER_TIZEN_VERSION_4
307 // Window rotate or screen rotate
308 if( !mRotationFinished || !mScreenRotationFinished )
310 int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360;
312 mWindowBase->SetEglWindowRotation( totalAngle );
313 mWindowBase->SetEglWindowBufferTransform( totalAngle );
315 // Reset only screen rotation flag
316 mScreenRotationFinished = true;
318 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set rotation [%d] [%d]\n", mRotationAngle, mScreenRotationAngle );
321 // Only window rotate
322 if( !mRotationFinished )
324 mWindowBase->SetEglWindowTransform( mRotationAngle );
329 if( !mResizeFinished )
331 mWindowBase->ResizeEglWindow( mPositionSize );
332 mResizeFinished = true;
334 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set resize\n" );
341 void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, Dali::DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
343 if( resizingSurface )
345 if( !mRotationFinished )
347 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PostRender: Trigger rotation event\n" );
349 mRotationTrigger->Trigger();
351 if( mThreadSynchronization )
353 // Wait until the event-thread complete the rotation event processing
354 mThreadSynchronization->PostRenderWaitForCompletion();
359 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
360 eglImpl.SwapBuffers();
362 if( mRenderNotification )
364 mRenderNotification->Trigger();
368 void WindowRenderSurface::StopRender()
372 void WindowRenderSurface::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
374 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::SetThreadSynchronization: called\n" );
376 mThreadSynchronization = &threadSynchronization;
379 void WindowRenderSurface::ReleaseLock()
384 RenderSurface::Type WindowRenderSurface::GetSurfaceType()
386 return RenderSurface::WINDOW_RENDER_SURFACE;
389 void WindowRenderSurface::OutputTransformed()
391 mScreenRotationAngle = mWindowBase->GetScreenRotationAngle();
392 mScreenRotationFinished = false;
394 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
397 void WindowRenderSurface::ProcessRotationRequest()
399 mRotationFinished = true;
401 mWindowBase->WindowRotationCompleted( mRotationAngle, mPositionSize.width, mPositionSize.height );
403 DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::ProcessRotationRequest: Rotation Done\n" );
405 if( mThreadSynchronization )
407 mThreadSynchronization->PostRenderComplete();
411 } // namespace Adaptor
413 } // namespace internal