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