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