Add common enum type for Window
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / gl-window-impl.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/common/gl-window-impl.h>
20
21 // EXTERNAL HEADERS
22 #include <dali/integration-api/core.h>
23 #include <dali/devel-api/adaptor-framework/orientation.h>
24 #include <dali/devel-api/adaptor-framework/gl-window.h>
25 #include <dali/integration-api/events/touch-integ.h>
26 #include <dali/integration-api/events/key-event-integ.h>
27 #include <dali/devel-api/events/key-event-devel.h>
28
29 // INTERNAL HEADERS
30 #include <dali/internal/window-system/common/event-handler.h>
31 #include <dali/internal/window-system/common/orientation-impl.h>
32 #include <dali/internal/window-system/common/window-factory.h>
33 #include <dali/internal/window-system/common/window-base.h>
34 #include <dali/internal/window-system/common/window-system.h>
35 #include <dali/internal/window-system/common/window-impl.h>
36 #include <dali/internal/window-system/common/window-render-surface.h>
37 #include <dali/internal/window-system/common/window-visibility-observer.h>
38 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
39 #include <dali/internal/window-system/common/display-utils.h>
40
41 namespace Dali
42 {
43 namespace Internal
44 {
45 namespace Adaptor
46 {
47
48 namespace
49 {
50 const int MINIMUM_DIMENSION_CHANGE( 1 );
51
52 #if defined(DEBUG_ENABLED)
53 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
54 #endif
55
56 } // unnamed namespace
57
58 GlWindow* GlWindow::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
59 {
60   GlWindow* window = new GlWindow();
61   window->mIsTransparent = isTransparent;
62   window->Initialize( positionSize, name, className );
63   return window;
64 }
65
66 GlWindow::GlWindow()
67 : mWindowBase(),
68   mGraphics(),
69   mDisplayConnection( nullptr ),
70   mEventHandler( nullptr ),
71   mPositionSize(),
72   mColorDepth( COLOR_DEPTH_24 ),
73   mIsTransparent( false ),
74   mIsFocusAcceptable( false ),
75   mIconified( false ),
76   mOpaqueState( false ),
77   mResizeEnabled( false ),
78   mVisible( false ),
79   mIsRotated( false ),
80   mIsWindowRotated( false ),
81   mIsTouched( false ),
82   mAvailableAngles(),
83   mPreferredAngle( 0 ),
84   mTotalRotationAngle( 0 ),
85   mWindowRotationAngle( 0 ),
86   mScreenRotationAngle( 0 ),
87   mOrientationMode( 0 ),
88   mWindowWidth( 0 ),
89   mWindowHeight( 0 ),
90   mNativeWindowId( -1 ),
91   mKeyEventSignal(),
92   mTouchedSignal(),
93   mFocusChangeSignal(),
94   mResizeSignal(),
95   mVisibilityChangedSignal(),
96   mGLInitCallback(),
97   mGLRenderFrameCallback(),
98   mGLTerminateCallback(),
99   mGLRenderCallback( nullptr ),
100   mEGLSurface( nullptr ),
101   mEGLContext( nullptr ),
102   mGLESVersion( Dali::GlWindow::GlesVersion::VERSION_3_0 ),
103   mInitCallback( false ),
104   mDepth( false ),
105   mStencil( false ),
106   mIsEGLInitialize( false ),
107   mMSAA( 0 )
108 {
109 }
110
111 GlWindow::~GlWindow()
112 {
113   if( mEventHandler )
114   {
115     mEventHandler->RemoveObserver( *this );
116   }
117
118   if( mGLTerminateCallback )
119   {
120     CallbackBase::Execute(*mGLTerminateCallback);
121   }
122
123   if( mIsEGLInitialize )
124   {
125     GraphicsInterface* graphics = mGraphics.get();
126     EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
127     Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
128
129     if( mEGLSurface )
130     {
131       eglImpl.DestroySurface( mEGLSurface );
132       mEGLSurface = nullptr;
133     }
134
135     if( mEGLContext )
136     {
137       eglImpl.DestroyContext( mEGLContext );
138       mEGLContext = nullptr;
139     }
140
141     eglImpl.TerminateGles();
142
143     mGraphics->Destroy();
144   }
145 }
146
147 void GlWindow::Initialize( const PositionSize& positionSize, const std::string& name, const std::string& className )
148 {
149   int screenWidth, screenHeight;
150
151   mPositionSize = positionSize;
152   WindowSystem::GetScreenSize( screenWidth, screenHeight );
153   if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) )
154   {
155     mPositionSize.x = 0;
156     mPositionSize.y = 0;
157     mPositionSize.width = screenWidth;
158     mPositionSize.height = screenHeight;
159   }
160
161   if( screenWidth > screenHeight )
162   {
163     mOrientationMode = 1; // Default mode is landscape
164   }
165   else
166   {
167     mOrientationMode = 0; // Default mode is portrate
168   }
169
170   // Create a window base
171   auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
172   Any surface;
173   mWindowBase = windowFactory->CreateWindowBase( mPositionSize, surface, ( mIsTransparent ? true : false ) );
174   mWindowBase->IconifyChangedSignal().Connect( this, &GlWindow::OnIconifyChanged );
175   mWindowBase->FocusChangedSignal().Connect( this, &GlWindow::OnFocusChanged );
176
177   if( Dali::Adaptor::IsAvailable() )
178   {
179     SetEventHandler();
180   }
181
182   if( !mPositionSize.IsEmpty() )
183   {
184     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
185     mResizeEnabled = true;
186   }
187
188   mWindowBase->Show();
189
190   if( mIsTransparent )
191   {
192     mColorDepth = COLOR_DEPTH_32;
193   }
194   else
195   {
196     mColorDepth = COLOR_DEPTH_24;
197   }
198
199   SetClass( name, className );
200
201   // For Debugging
202   mNativeWindowId = mWindowBase->GetNativeWindowId();
203 }
204
205 void GlWindow::SetEventHandler()
206 {
207   mEventHandler = EventHandlerPtr( new EventHandler( mWindowBase.get(), *this ) );
208   mEventHandler->AddObserver( *this );
209 }
210
211 void GlWindow::SetClass( const std::string& name, const std::string className )
212 {
213   mName = name;
214   mClassName = className;
215   mWindowBase->SetClass( name, className );
216 }
217
218 void GlWindow::SetEglConfig( bool depth, bool stencil, int msaa, Dali::GlWindow::GlesVersion version )
219 {
220   // Init Graphics
221   mDepth = depth;
222   mStencil = stencil;
223   mMSAA = msaa;
224   mGLESVersion = version;
225
226   InitializeGraphics();
227 }
228
229 void GlWindow::Raise()
230 {
231   mWindowBase->Raise();
232   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Raise() \n", this, mNativeWindowId );
233 }
234
235 void GlWindow::Lower()
236 {
237   mWindowBase->Lower();
238   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Lower() \n", this, mNativeWindowId );
239 }
240
241 void GlWindow::Activate()
242 {
243   mWindowBase->Activate();
244   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Activate() \n", this, mNativeWindowId );
245 }
246
247 void GlWindow::Show()
248 {
249   mVisible = true;
250
251   mWindowBase->Show();
252
253   if( !mIconified )
254   {
255     Dali::GlWindow handle( this );
256     mVisibilityChangedSignal.Emit( handle, true );
257   }
258
259   if( mEventHandler )
260   {
261     mEventHandler->Resume();
262   }
263
264   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Show(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible );
265 }
266
267 void GlWindow::Hide()
268 {
269   mVisible = false;
270
271   mWindowBase->Hide();
272
273   if( !mIconified )
274   {
275     Dali::GlWindow handle( this );
276     mVisibilityChangedSignal.Emit( handle, false );
277   }
278
279   if( mEventHandler )
280   {
281     mEventHandler->Pause();
282   }
283
284   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Hide(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible );
285 }
286
287 unsigned int GlWindow::GetSupportedAuxiliaryHintCount() const
288 {
289   return mWindowBase->GetSupportedAuxiliaryHintCount();
290 }
291
292 std::string GlWindow::GetSupportedAuxiliaryHint( unsigned int index ) const
293 {
294   return mWindowBase->GetSupportedAuxiliaryHint( index );
295 }
296
297 unsigned int GlWindow::AddAuxiliaryHint( const std::string& hint, const std::string& value )
298 {
299   return mWindowBase->AddAuxiliaryHint( hint, value );
300 }
301
302 bool GlWindow::RemoveAuxiliaryHint( unsigned int id )
303 {
304   return mWindowBase->RemoveAuxiliaryHint( id );
305 }
306
307 bool GlWindow::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
308 {
309   return mWindowBase->SetAuxiliaryHintValue( id, value );
310 }
311
312 std::string GlWindow::GetAuxiliaryHintValue( unsigned int id ) const
313 {
314   return mWindowBase->GetAuxiliaryHintValue( id );
315 }
316
317 unsigned int GlWindow::GetAuxiliaryHintId( const std::string& hint ) const
318 {
319   return mWindowBase->GetAuxiliaryHintId( hint );
320 }
321
322 void GlWindow::SetInputRegion( const Rect< int >& inputRegion )
323 {
324   mWindowBase->SetInputRegion( inputRegion );
325
326   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "GlWindow::SetInputRegion: x = %d, y = %d, w = %d, h = %d\n", inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height );
327 }
328
329 void GlWindow::SetOpaqueState( bool opaque )
330 {
331   mOpaqueState = opaque;
332
333   mWindowBase->SetOpaqueState( opaque );
334
335   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "GlWindow::SetOpaqueState: opaque = %d\n", opaque );
336 }
337
338 bool GlWindow::IsOpaqueState() const
339 {
340   return mOpaqueState;
341 }
342
343 void GlWindow::SetPositionSize( PositionSize positionSize )
344 {
345   if( !mResizeEnabled )
346   {
347     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
348     mResizeEnabled = true;
349   }
350
351   bool needToMove = false;
352   bool needToResize = false;
353
354   // Check moving
355   if( (fabs(positionSize.x - mPositionSize.x) > MINIMUM_DIMENSION_CHANGE) ||
356       (fabs(positionSize.y - mPositionSize.y) > MINIMUM_DIMENSION_CHANGE) )
357   {
358     needToMove = true;
359   }
360
361   // Check resizing
362   if( (fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) ||
363       (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE) )
364   {
365     needToResize = true;
366   }
367
368   if( needToResize )
369   {
370     if( needToMove )
371     {
372       mWindowBase->MoveResize( positionSize );
373     }
374     else
375     {
376       mWindowBase->Resize( positionSize );
377     }
378     mPositionSize = positionSize;
379   }
380   else
381   {
382     if( needToMove )
383     {
384       mWindowBase->Move( positionSize );
385       mPositionSize = positionSize;
386     }
387   }
388
389   // If window's size or position is changed, the signal will be emitted to user.
390   if( ( needToMove ) || ( needToResize ) )
391   {
392     Uint16Pair newSize( mPositionSize.width, mPositionSize.height );
393     Dali::GlWindow handle( this );
394     mResizeSignal.Emit( newSize );
395   }
396 }
397
398 PositionSize GlWindow::GetPositionSize() const
399 {
400   PositionSize positionSize( mPositionSize );
401   if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
402   {
403     positionSize.height = mPositionSize.width;
404     positionSize.width = mPositionSize.height;
405   }
406
407   return positionSize;
408 }
409
410 void GlWindow::OnIconifyChanged( bool iconified )
411 {
412   if( iconified )
413   {
414     mIconified = true;
415
416     if( mVisible )
417     {
418       Dali::GlWindow handle( this );
419       mVisibilityChangedSignal.Emit( handle, false );
420     }
421
422     if( mEventHandler )
423     {
424       mEventHandler->Pause();
425     }
426
427     DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Iconified: visible = %d\n", this, mNativeWindowId, mVisible );
428   }
429   else
430   {
431     mIconified = false;
432
433     if( mVisible )
434     {
435       Dali::GlWindow handle( this );
436       mVisibilityChangedSignal.Emit( handle, true );
437     }
438
439     if( mEventHandler )
440     {
441       mEventHandler->Resume();
442     }
443
444     DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Deiconified: visible = %d\n", this, mNativeWindowId, mVisible );
445   }
446 }
447
448 void GlWindow::OnFocusChanged( bool focusIn )
449 {
450   Dali::GlWindow handle( this );
451   mFocusChangeSignal.Emit( handle, focusIn );
452 }
453
454 void GlWindow::OnOutputTransformed()
455 {
456   int screenRotationAngle = mWindowBase->GetScreenRotationAngle();
457   if( screenRotationAngle != mScreenRotationAngle )
458   {
459     mScreenRotationAngle = screenRotationAngle;
460     mTotalRotationAngle = (mWindowRotationAngle + mScreenRotationAngle) % 360;
461
462     if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
463     {
464       mWindowWidth = mPositionSize.height;
465       mWindowHeight = mPositionSize.width;
466     }
467     else
468     {
469       mWindowWidth = mPositionSize.width;
470       mWindowHeight = mPositionSize.height;
471     }
472
473     // Emit Resize signal
474     Dali::GlWindow handle( this );
475     mResizeSignal.Emit( Dali::Uint16Pair( mWindowWidth, mWindowHeight ) );
476   }
477 }
478
479 void GlWindow::OnTouchPoint( Dali::Integration::Point& point, int timeStamp )
480 {
481   PointState::Type state = point.GetState();
482
483   if( state == PointState::DOWN )
484   {
485     mIsTouched = true;
486   }
487
488   if( state == PointState::UP )
489   {
490     mIsTouched = false;
491   }
492
493   if( !mIsTouched && state == PointState::MOTION )
494   {
495     return;
496   }
497
498   RecalculateTouchPosition( point );
499   Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent( timeStamp, point );
500   Dali::GlWindow handle( this );
501   mTouchedSignal.Emit( touchEvent );
502 }
503
504 void GlWindow::OnWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
505 {
506   // TODO:
507   //FeedWheelEvent( wheelEvent );
508 }
509
510 void GlWindow::OnKeyEvent( Dali::Integration::KeyEvent& keyEvent )
511 {
512   Dali::KeyEvent event = Dali::DevelKeyEvent::New( keyEvent.keyName, keyEvent.logicalKey, keyEvent.keyString, keyEvent.keyCode,
513                                                    keyEvent.keyModifier, keyEvent.time, static_cast<Dali::KeyEvent::State>(keyEvent.state),
514                                                    keyEvent.compose, keyEvent.deviceName, keyEvent.deviceClass, keyEvent.deviceSubclass );
515   Dali::GlWindow handle( this );
516   mKeyEventSignal.Emit( event );
517 }
518
519 void GlWindow::OnRotation( const RotationEvent& rotation )
520 {
521   mWindowRotationAngle = rotation.angle;
522   mTotalRotationAngle = ( mWindowRotationAngle + mScreenRotationAngle ) % 360;
523   if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
524   {
525     mWindowWidth = mPositionSize.height;
526     mWindowHeight = mPositionSize.width;
527   }
528   else
529   {
530     mWindowWidth = mPositionSize.width;
531     mWindowHeight = mPositionSize.height;
532   }
533
534   mIsRotated = true;
535   mIsWindowRotated = true;
536   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), OnRotation(): resize signal emit [%d x %d]\n", this, mNativeWindowId, mWindowWidth, mWindowHeight );
537
538   // Emit Resize signal
539   Dali::GlWindow handle( this );
540   mResizeSignal.Emit( Dali::Uint16Pair( mWindowWidth, mWindowHeight ) );
541 }
542
543 void GlWindow::RecalculateTouchPosition( Integration::Point& point )
544 {
545   Vector2 position = point.GetScreenPosition();
546   Vector2 convertedPosition;
547
548   switch( mTotalRotationAngle )
549   {
550     case 90:
551     {
552       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.y;
553       convertedPosition.y = position.x;
554       break;
555     }
556     case 180:
557     {
558       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.x;
559       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.y;
560       break;
561     }
562     case 270:
563     {
564       convertedPosition.x = position.y;
565       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.x;
566       break;
567     }
568     default:
569     {
570       convertedPosition = position;
571       break;
572     }
573   }
574
575   point.SetScreenPosition( convertedPosition );
576 }
577
578 void GlWindow::SetAvailableAnlges( const std::vector< int >& angles )
579 {
580   if( angles.size() > 4 )
581   {
582     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableAnlges: Invalid vector size! [%d]\n", angles.size() );
583     return;
584   }
585
586   mWindowBase->SetAvailableAnlges( angles );
587 }
588
589 bool GlWindow::IsOrientationAvailable( WindowOrientation orientation ) const
590 {
591   if( orientation <= WindowOrientation::NO_ORIENTATION_PREFERENCE
592       || orientation > WindowOrientation::LANDSCAPE_INVERSE )
593   {
594     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::IsOrientationAvailable: Invalid input orientation [%d]\n", orientation );
595     return false;
596   }
597   return true;
598 }
599
600 int GlWindow::ConvertToAngle(  WindowOrientation  orientation )
601 {
602   int convertAngle = 0;
603   if ( mOrientationMode == 0 )
604   {
605     convertAngle = static_cast< int >( orientation );
606   }
607   else if( mOrientationMode == 1)
608   {
609     switch( orientation )
610     {
611       case WindowOrientation::LANDSCAPE:
612       {
613         convertAngle = 0;
614         break;
615       }
616       case WindowOrientation::PORTRAIT:
617       {
618         convertAngle = 90;
619         break;
620       }
621       case WindowOrientation::LANDSCAPE_INVERSE:
622       {
623         convertAngle = 180;
624         break;
625       }
626       case WindowOrientation::PORTRAIT_INVERSE:
627       {
628         convertAngle = 270;
629         break;
630       }
631       case WindowOrientation::NO_ORIENTATION_PREFERENCE:
632       {
633         convertAngle = -1;
634         break;
635       }
636     }
637   }
638   return convertAngle;
639 }
640
641 WindowOrientation GlWindow::ConvertToOrientation( int angle ) const
642 {
643   WindowOrientation orientation = WindowOrientation::NO_ORIENTATION_PREFERENCE;
644   if ( mOrientationMode == 0 ) // Portrate mode
645   {
646     orientation = static_cast< WindowOrientation >( angle );
647   }
648   else if( mOrientationMode == 1 ) // Landscape mode
649   {
650     switch( angle )
651     {
652       case 0:
653       {
654         orientation = WindowOrientation::LANDSCAPE;
655         break;
656       }
657       case 90:
658       {
659         orientation = WindowOrientation::PORTRAIT;
660         break;
661       }
662       case 180:
663       {
664         orientation = WindowOrientation::LANDSCAPE_INVERSE;
665         break;
666       }
667       case 270:
668       {
669         orientation = WindowOrientation::PORTRAIT_INVERSE;
670         break;
671       }
672       case -1:
673       {
674         orientation = WindowOrientation::NO_ORIENTATION_PREFERENCE;
675         break;
676       }
677     }
678   }
679   return orientation;
680 }
681
682 WindowOrientation GlWindow::GetCurrentOrientation() const
683 {
684   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), GetCurrentOrientation(): %d\n", this, mNativeWindowId, mTotalRotationAngle );
685   return ConvertToOrientation( mTotalRotationAngle );
686 }
687
688 void GlWindow::SetAvailableOrientations( const Dali::Vector< WindowOrientation >& orientations )
689 {
690   Dali::Vector<float>::SizeType count = orientations.Count();
691   for( Dali::Vector<float>::SizeType index = 0; index < count; ++index )
692   {
693     if( IsOrientationAvailable( orientations[index] ) == false )
694     {
695       DALI_LOG_ERROR("Window::SetAvailableRotationAngles, invalid angle: %d\n", orientations[index]);
696       continue;
697     }
698
699     bool found = false;
700     int angle = ConvertToAngle( orientations[index] );
701
702     for( std::size_t i = 0; i < mAvailableAngles.size(); i++ )
703     {
704       if( mAvailableAngles[i] == angle )
705       {
706         found = true;
707         break;
708       }
709     }
710
711     if( !found )
712     {
713       DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetAvailableOrientations: %d\n", this, mNativeWindowId, angle );
714       mAvailableAngles.push_back( angle );
715     }
716   }
717   SetAvailableAnlges( mAvailableAngles );
718 }
719
720 void GlWindow::SetPreferredOrientation( WindowOrientation orientation  )
721 {
722   if( IsOrientationAvailable( orientation ) == false )
723   {
724     DALI_LOG_ERROR( "Window::SetPreferredOrientation, invalid orientation: %d\n", orientation );
725     return;
726   }
727   mPreferredAngle = ConvertToAngle( orientation );
728   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetPreferredOrientation: %d\n", this, mNativeWindowId, mPreferredAngle );
729   mWindowBase->SetPreferredAngle( mPreferredAngle );
730 }
731
732 void GlWindow::SetChild( Dali::Window& child )
733 {
734   if( DALI_UNLIKELY( child ) )
735   {
736     mChildWindow = child;
737     Internal::Adaptor::Window& windowImpl = Dali::GetImplementation( mChildWindow );
738     WindowRenderSurface* renderSurface = static_cast<WindowRenderSurface*>( windowImpl.GetSurface() );
739     if( renderSurface )
740     {
741       WindowBase* childWindowBase = renderSurface->GetWindowBase();
742       if( childWindowBase )
743       {
744         childWindowBase->SetParent( mWindowBase.get() );
745       }
746     }
747   }
748 }
749
750 void GlWindow::RegisterGlCallback( CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback )
751 {
752   if( mIsEGLInitialize == false )
753   {
754     InitializeGraphics();
755   }
756   mGLInitCallback = std::unique_ptr< CallbackBase >(initCallback);
757   mGLRenderFrameCallback = std::unique_ptr< CallbackBase >( renderFrameCallback );
758   mGLTerminateCallback = std::unique_ptr< CallbackBase >( terminateCallback );
759
760   mInitCallback = false;
761
762   if( !mGLRenderCallback )
763   {
764     mGLRenderCallback = MakeCallback( this, &GlWindow::RunCallback );
765
766     if( Dali::Adaptor::IsAvailable() )
767     {
768       Dali::Adaptor::Get().AddIdle( mGLRenderCallback, true );
769     }
770     else
771     {
772       DALI_LOG_RELEASE_INFO( "RegisterGlCallback: Adaptor is not avaiable\n" );
773     }
774
775   }
776 }
777
778 bool GlWindow::RunCallback()
779 {
780   GraphicsInterface* graphics = mGraphics.get();
781   EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
782   Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
783
784   eglImpl.MakeContextCurrent( mEGLSurface, mEGLContext );
785
786   int renderFrameResult = 0;
787
788   if( mIsRotated )
789   {
790     mWindowBase->SetEglWindowBufferTransform( mTotalRotationAngle );
791     if( mIsWindowRotated )
792     {
793       mWindowBase->SetEglWindowTransform( mWindowRotationAngle );
794     }
795     mIsRotated = false;
796   }
797
798   if( !mInitCallback )
799   {
800     if( mGLInitCallback )
801     {
802       CallbackBase::Execute(*mGLInitCallback);
803     }
804     mInitCallback = true;
805   }
806
807   if( mGLRenderFrameCallback )
808   {
809     renderFrameResult = CallbackBase::ExecuteReturn<int>(*mGLRenderFrameCallback);
810   }
811
812   if( mIsWindowRotated )
813   {
814     mWindowBase->WindowRotationCompleted( mWindowRotationAngle, mPositionSize.width, mPositionSize.height );
815     mIsWindowRotated = false;
816   }
817
818   if(renderFrameResult)
819   {
820     eglImpl.SwapBuffers( mEGLSurface );
821   }
822
823   return true;
824 }
825
826 void GlWindow::RenderOnce()
827 {
828   RunCallback();
829 }
830
831 void GlWindow::InitializeGraphics()
832 {
833   if( !mIsEGLInitialize )
834   {
835     // Init Graphics
836     std::unique_ptr< GraphicsFactory > graphicsFactoryPtr = Utils::MakeUnique< GraphicsFactory >();
837     auto graphicsFactory = *graphicsFactoryPtr.get();
838
839     mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
840     GraphicsInterface* graphics = mGraphics.get();
841     EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
842     eglGraphics->Initialize( mDepth, mStencil, mMSAA );
843     eglGraphics->Create();
844
845     mDisplayConnection = std::unique_ptr< Dali::DisplayConnection >( Dali::DisplayConnection::New( *graphics, Dali::RenderSurfaceInterface::Type::WINDOW_RENDER_SURFACE ) );
846     mDisplayConnection->Initialize();
847
848     Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
849     if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_2_0 )
850     {
851       eglImpl.SetGlesVersion( 20 );
852     }
853     else if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
854     {
855       eglImpl.SetGlesVersion( 30 );
856     }
857
858     if( eglImpl.ChooseConfig(true, mColorDepth) == false )
859     {
860       if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
861       {
862         DALI_LOG_RELEASE_INFO( "InitializeGraphics: Fail to choose config with GLES30, retry with GLES20\n" );
863         eglImpl.SetGlesVersion( 20 );
864         mGLESVersion = Dali::GlWindow::GlesVersion::VERSION_2_0;
865         if( eglImpl.ChooseConfig(true, mColorDepth) == false )
866         {
867           DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
868           return;
869         }
870       }
871       else
872       {
873         DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
874         return;
875       }
876     }
877     eglImpl.CreateWindowContext( mEGLContext );
878
879    // Create the EGL window
880     EGLNativeWindowType window = mWindowBase->CreateEglWindow( mPositionSize.width, mPositionSize.height );
881     mEGLSurface = eglImpl.CreateSurfaceWindow( window, mColorDepth );
882
883     mIsEGLInitialize = true;
884   }
885 }
886
887 void GlWindow::OnDamaged(  const DamageArea& area )
888 {
889
890 }
891
892 } // Adaptor
893
894 } // Internal
895
896 } // Dali