[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
29 // INTERNAL HEADERS
30 //#include <dali/internal/graphics/gles/egl-graphics.h>
31 #include <dali/internal/window-system/common/event-handler.h>
32 #include <dali/internal/window-system/common/orientation-impl.h>
33 #include <dali/internal/window-system/common/window-factory.h>
34 #include <dali/internal/window-system/common/window-base.h>
35 #include <dali/internal/window-system/common/window-system.h>
36 #include <dali/internal/window-system/common/window-impl.h>
37 #include <dali/internal/window-system/common/window-render-surface.h>
38 #include <dali/internal/window-system/common/window-visibility-observer.h>
39 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
40 #include <dali/internal/window-system/common/display-utils.h>
41
42 namespace Dali
43 {
44 namespace Internal
45 {
46 namespace Adaptor
47 {
48
49 namespace
50 {
51 const int MINIMUM_DIMENSION_CHANGE( 1 );
52
53 #if defined(DEBUG_ENABLED)
54 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
55 #endif
56
57 } // unnamed namespace
58
59 GlWindow* GlWindow::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
60 {
61   GlWindow* window = new GlWindow();
62   window->mIsTransparent = isTransparent;
63   window->Initialize( positionSize, name, className );
64   return window;
65 }
66
67 GlWindow::GlWindow()
68 : mWindowBase(),
69   mGraphics(),
70   mDisplayConnection( nullptr ),
71   mEventHandler( nullptr ),
72   mPositionSize(),
73   mColorDepth( COLOR_DEPTH_24 ),
74   mIsTransparent( false ),
75   mIsFocusAcceptable( false ),
76   mIconified( false ),
77   mOpaqueState( false ),
78   mResizedEnabled( false ),
79   mVisible( false ),
80   mIsRotated( false ),
81   mIsWindowRotated( false ),
82   mIsTouched( false ),
83   mAvailableAngles(),
84   mPreferredAngle( 0 ),
85   mTotalRotationAngle( 0 ),
86   mWindowRotationAngle( 0 ),
87   mScreenRotationAngle( 0 ),
88   mOrientationMode( 0 ),
89   mWindowWidth( 0 ),
90   mWindowHeight( 0 ),
91   mNativeWindowId( -1 ),
92   mKeyEventSignal(),
93   mTouchSignal(),
94   mFocusChangeSignal(),
95   mResizedSignal(),
96   mVisibilityChangedSignal(),
97   mGLInitCallback( 0 ),
98   mGLRenderFrameCallback( 0 ),
99   mGLTerminateCallback( 0 ),
100   mGLRenderCallback( nullptr ),
101   mEGLSurface( nullptr ),
102   mEGLContext( nullptr ),
103   mGLESVersion( Dali::GlWindow::GlesVersion::VERSION_3_0 ),
104   mInitCallback( false ),
105   mDepth( false ),
106   mStencil( false ),
107   mIsEGLInitialize( false ),
108   mMSAA( 0 )
109 {
110 }
111
112 GlWindow::~GlWindow()
113 {
114   if ( mEventHandler )
115   {
116     mEventHandler->RemoveObserver( *this );
117   }
118
119   if( mGLTerminateCallback )
120   {
121     mGLTerminateCallback();
122   }
123
124   if( mIsEGLInitialize )
125   {
126     GraphicsInterface* graphics = mGraphics.get();
127     EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
128     Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
129
130     if( mEGLSurface )
131     {
132       eglImpl.DestroySurface( mEGLSurface );
133       mEGLSurface = nullptr;
134     }
135
136     if( mEGLContext )
137     {
138       eglImpl.DestroyContext( mEGLContext );
139       mEGLContext = nullptr;
140     }
141
142     eglImpl.TerminateGles();
143
144     mGraphics->Destroy();
145   }
146
147   delete mDisplayConnection;
148 }
149
150 void GlWindow::Initialize( const PositionSize& positionSize, const std::string& name, const std::string& className )
151 {
152   int screenWidth, screenHeight;
153
154   mPositionSize = positionSize;
155   WindowSystem::GetScreenSize( screenWidth, screenHeight );
156   if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) )
157   {
158     mPositionSize.x = 0;
159     mPositionSize.y = 0;
160     mPositionSize.width = screenWidth;
161     mPositionSize.height = screenHeight;
162   }
163
164   if( screenWidth > screenHeight )
165   {
166     mOrientationMode = 1; // Default mode is landscape
167   }
168   else
169   {
170     mOrientationMode = 0; // Default mode is portrate
171   }
172
173   // Create a window base
174   auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
175   Any surface;
176   mWindowBase = windowFactory->CreateWindowBase( mPositionSize, surface, ( mIsTransparent ? true : false ) );
177   mWindowBase->IconifyChangedSignal().Connect( this, &GlWindow::OnIconifyChanged );
178   mWindowBase->FocusChangedSignal().Connect( this, &GlWindow::OnFocusChanged );
179
180   SetEventHandler();
181
182   if( !mPositionSize.IsEmpty() )
183   {
184     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
185     mResizedEnabled = 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( !mResizedEnabled )
346   {
347     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
348     mResizedEnabled = 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     mResizedSignal.Emit( newSize );
394   }
395 }
396
397 PositionSize GlWindow::GetPositionSize() const
398 {
399   PositionSize positionSize( mPositionSize );
400   if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
401   {
402     positionSize.height = mPositionSize.width;
403     positionSize.width = mPositionSize.height;
404   }
405
406   return positionSize;
407 }
408
409 void GlWindow::OnIconifyChanged( bool iconified )
410 {
411   if( iconified )
412   {
413     mIconified = true;
414
415     if( mVisible )
416     {
417       Dali::GlWindow handle( this );
418       mVisibilityChangedSignal.Emit( handle, false );
419     }
420
421     if( mEventHandler )
422     {
423       mEventHandler->Pause();
424     }
425
426     DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Iconified: visible = %d\n", this, mNativeWindowId, mVisible );
427   }
428   else
429   {
430     mIconified = false;
431
432     if( mVisible )
433     {
434       Dali::GlWindow handle( this );
435       mVisibilityChangedSignal.Emit( handle, true );
436     }
437
438     if( mEventHandler )
439     {
440       mEventHandler->Resume();
441     }
442
443     DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Deiconified: visible = %d\n", this, mNativeWindowId, mVisible );
444   }
445 }
446
447 void GlWindow::OnFocusChanged( bool focusIn )
448 {
449   Dali::GlWindow handle( this );
450   mFocusChangeSignal.Emit( handle, focusIn );
451 }
452
453 void GlWindow::OnOutputTransformed()
454 {
455   int screenRotationAngle = mWindowBase->GetScreenRotationAngle();
456   if( screenRotationAngle != mScreenRotationAngle )
457   {
458     mScreenRotationAngle = screenRotationAngle;
459     mTotalRotationAngle = (mWindowRotationAngle + mScreenRotationAngle) % 360;
460
461     if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
462     {
463       mWindowWidth = mPositionSize.height;
464       mWindowHeight = mPositionSize.width;
465     }
466     else
467     {
468       mWindowWidth = mPositionSize.width;
469       mWindowHeight = mPositionSize.height;
470     }
471
472     // Emit Resized signal
473     mResizedSignal.Emit( Dali::Uint16Pair( mWindowWidth, mWindowHeight ) );
474   }
475 }
476
477 void GlWindow::OnTouchPoint( Dali::Integration::Point& point, int timeStamp )
478 {
479   PointState::Type state = point.GetState();
480
481   if( state == PointState::DOWN )
482   {
483     mIsTouched = true;
484   }
485
486   if( state == PointState::UP )
487   {
488     mIsTouched = false;
489   }
490
491   if( !mIsTouched && state == PointState::MOTION )
492   {
493     return;
494   }
495
496   Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent( timeStamp, point );
497   mTouchSignal.Emit( touchEvent );
498 }
499
500 void GlWindow::OnWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
501 {
502   // TODO:
503   //FeedWheelEvent( wheelEvent );
504 }
505
506 void GlWindow::OnKeyEvent( Dali::Integration::KeyEvent& keyEvent )
507 {
508   Dali::KeyEvent event = Dali::Integration::KeyEvent::Convert( keyEvent );
509   mKeyEventSignal.Emit( event );
510 }
511
512 void GlWindow::OnRotation( const RotationEvent& rotation )
513 {
514   mWindowRotationAngle = rotation.angle;
515   mTotalRotationAngle = ( mWindowRotationAngle + mScreenRotationAngle ) % 360;
516   if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
517   {
518     mWindowWidth = mPositionSize.height;
519     mWindowHeight = mPositionSize.width;
520   }
521   else
522   {
523     mWindowWidth = mPositionSize.width;
524     mWindowHeight = mPositionSize.height;
525   }
526
527   mIsRotated = true;
528   mIsWindowRotated = true;
529   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), OnRotation(): resized signal emit [%d x %d]\n", this, mNativeWindowId, mWindowWidth, mWindowHeight );
530
531   // Emit Resized signal
532   mResizedSignal.Emit( Dali::Uint16Pair( mWindowWidth, mWindowHeight ) );
533 }
534
535 void GlWindow::RecalculateTouchPosition( Integration::Point& point )
536 {
537   Vector2 position = point.GetScreenPosition();
538   Vector2 convertedPosition;
539
540   switch( mTotalRotationAngle )
541   {
542     case 90:
543     {
544       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.y;
545       convertedPosition.y = position.x;
546       break;
547     }
548     case 180:
549     {
550       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.x;
551       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.y;
552       break;
553     }
554     case 270:
555     {
556       convertedPosition.x = position.y;
557       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.x;
558       break;
559     }
560     default:
561     {
562       convertedPosition = position;
563       break;
564     }
565   }
566
567   point.SetScreenPosition( convertedPosition );
568 }
569
570 void GlWindow::SetAvailableAnlges( const std::vector< int >& angles )
571 {
572   if( angles.size() > 4 )
573   {
574     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableAnlges: Invalid vector size! [%d]\n", angles.size() );
575     return;
576   }
577
578   mWindowBase->SetAvailableAnlges( angles );
579 }
580
581 bool GlWindow::IsOrientationAvailable( Dali::GlWindow::GlWindowOrientation orientation ) const
582 {
583   if( orientation <= Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE
584       || orientation > Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE )
585   {
586     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::IsOrientationAvailable: Invalid input orientation [%d]\n", orientation );
587     return false;
588   }
589   return true;
590 }
591
592 int GlWindow::ConvertToAngle(  Dali::GlWindow::GlWindowOrientation  orientation )
593 {
594   int convertAngle = 0;
595   if ( mOrientationMode == 0 )
596   {
597     convertAngle = ( static_cast< int >( orientation ) ) * 90;
598   }
599   else if( mOrientationMode == 1)
600   {
601     switch( orientation )
602     {
603       case Dali::GlWindow::GlWindowOrientation::LANDSCAPE:
604       {
605         convertAngle = 0;
606         break;
607       }
608       case Dali::GlWindow::GlWindowOrientation::PORTRAIT:
609       {
610         convertAngle = 90;
611         break;
612       }
613       case Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE:
614       {
615         convertAngle = 180;
616         break;
617       }
618       case Dali::GlWindow::GlWindowOrientation::PORTRAIT_INVERSE:
619       {
620         convertAngle = 270;
621         break;
622       }
623       case Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE:
624       {
625         convertAngle = -1;
626         break;
627       }
628     }
629   }
630   return convertAngle;
631 }
632
633 Dali::GlWindow::GlWindowOrientation GlWindow::ConvertToOrientation( int angle ) const
634 {
635   Dali::GlWindow::GlWindowOrientation orientation = Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE;
636   if ( mOrientationMode == 0 ) // Portrate mode
637   {
638     orientation = static_cast< Dali::GlWindow::GlWindowOrientation >( angle / 90 );
639   }
640   else if( mOrientationMode == 1 ) // Landscape mode
641   {
642     switch( angle )
643     {
644       case 0:
645       {
646         orientation = Dali::GlWindow::GlWindowOrientation::LANDSCAPE;
647         break;
648       }
649       case 90:
650       {
651         orientation = Dali::GlWindow::GlWindowOrientation::PORTRAIT;
652         break;
653       }
654       case 180:
655       {
656         orientation = Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE;
657         break;
658       }
659       case 270:
660       {
661         orientation = Dali::GlWindow::GlWindowOrientation::PORTRAIT_INVERSE;
662         break;
663       }
664       case -1:
665       {
666         orientation = Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE;
667         break;
668       }
669     }
670   }
671   return orientation;
672 }
673
674 Dali::GlWindow::GlWindowOrientation GlWindow::GetCurrentOrientation() const
675 {
676   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), GetCurrentOrientation(): %d\n", this, mNativeWindowId, mTotalRotationAngle );
677   return ConvertToOrientation( mTotalRotationAngle );
678 }
679
680 void GlWindow::SetAvailableOrientations( const Dali::Vector< Dali::GlWindow::GlWindowOrientation >& orientations )
681 {
682   Dali::Vector<float>::SizeType count = orientations.Count();
683   for( Dali::Vector<float>::SizeType index = 0; index < count; ++index )
684   {
685     if( IsOrientationAvailable( orientations[index] ) == false )
686     {
687       DALI_LOG_ERROR("Window::SetAvailableRotationAngles, invalid angle: %d\n", orientations[index]);
688       continue;
689     }
690
691     bool found = false;
692     int angle = ConvertToAngle( orientations[index] );
693
694     for( std::size_t i = 0; i < mAvailableAngles.size(); i++ )
695     {
696       if( mAvailableAngles[i] == angle )
697       {
698         found = true;
699         break;
700       }
701     }
702
703     if( !found )
704     {
705       DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetAvailableOrientations: %d\n", this, mNativeWindowId, angle );
706       mAvailableAngles.push_back( angle );
707     }
708   }
709   SetAvailableAnlges( mAvailableAngles );
710 }
711
712 void GlWindow::SetPreferredOrientation( Dali::GlWindow::GlWindowOrientation orientation  )
713 {
714   if( IsOrientationAvailable( orientation ) == false )
715   {
716     DALI_LOG_ERROR( "Window::SetPreferredOrientation, invalid orientation: %d\n", orientation );
717     return;
718   }
719   mPreferredAngle = ConvertToAngle( orientation );
720   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetPreferredOrientation: %d\n", this, mNativeWindowId, mPreferredAngle );
721   mWindowBase->SetPreferredAngle( mPreferredAngle );
722 }
723
724 void GlWindow::SetChild( Dali::Window& child )
725 {
726   if( DALI_UNLIKELY( child ) )
727   {
728     mChildWindow = child;
729     Internal::Adaptor::Window& windowImpl = Dali::GetImplementation( mChildWindow );
730     WindowRenderSurface* renderSurface = static_cast<WindowRenderSurface*>( windowImpl.GetSurface() );
731     WindowBase* childWindowBase = renderSurface->GetWindowBase();
732     childWindowBase->SetParent( mWindowBase.get() );
733   }
734 }
735
736 void GlWindow::RegisterGlCallback( GlInitialize glInit, GlRenderFrame glRenderFrame, GlTerminate glTerminate )
737 {
738   if( mIsEGLInitialize == false )
739   {
740     InitializeGraphics();
741   }
742   mGLInitCallback = glInit;
743   mGLRenderFrameCallback = glRenderFrame;
744   mGLTerminateCallback = glTerminate;
745
746   mInitCallback = false;
747
748   if( !mGLRenderCallback )
749   {
750     mGLRenderCallback = MakeCallback( this, &GlWindow::RunCallback );
751
752     Dali::Adaptor::Get().AddIdle( mGLRenderCallback, true );
753   }
754 }
755
756 bool GlWindow::RunCallback()
757 {
758   GraphicsInterface* graphics = mGraphics.get();
759   EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
760   Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
761
762   eglImpl.MakeContextCurrent( mEGLSurface, mEGLContext );
763
764   if( mIsRotated )
765   {
766     mWindowBase->SetEglWindowBufferTransform( mTotalRotationAngle );
767     if( mIsWindowRotated )
768     {
769       mWindowBase->SetEglWindowTransform( mWindowRotationAngle );
770     }
771     mIsRotated = false;
772   }
773
774   if( !mInitCallback )
775   {
776     if( mGLInitCallback )
777     {
778       mGLInitCallback();
779     }
780     mInitCallback = true;
781   }
782
783   if( mGLRenderFrameCallback )
784   {
785     mGLRenderFrameCallback();
786   }
787
788   if( mIsWindowRotated )
789   {
790     mWindowBase->WindowRotationCompleted( mWindowRotationAngle, mPositionSize.width, mPositionSize.height );
791     mIsWindowRotated = false;
792   }
793
794   eglImpl.SwapBuffers( mEGLSurface );
795
796   return true;
797 }
798
799 void GlWindow::RenderOnce()
800 {
801   RunCallback();
802 }
803
804 int32_t GlWindow::GetNativeId() const
805 {
806   return mWindowBase->GetNativeWindowId();
807 }
808
809 void GlWindow::InitializeGraphics()
810 {
811   if( !mIsEGLInitialize )
812   {
813     // Init Graphics
814     std::unique_ptr< GraphicsFactory > graphicsFactoryPtr = Utils::MakeUnique< GraphicsFactory >();
815     auto graphicsFactory = *graphicsFactoryPtr.get();
816
817     mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
818     GraphicsInterface* graphics = mGraphics.get();
819     EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
820     eglGraphics->Initialize( mDepth, mStencil, mMSAA );
821     eglGraphics->Create();
822
823     mDisplayConnection = Dali::DisplayConnection::New( *graphics, Dali::RenderSurfaceInterface::Type::WINDOW_RENDER_SURFACE );
824     mDisplayConnection->Initialize();
825
826     Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
827     if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_2_0 )
828     {
829       eglImpl.SetGlesVersion( 20 );
830     }
831     else if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
832     {
833       eglImpl.SetGlesVersion( 30 );
834     }
835
836     if( eglImpl.ChooseConfig(true, mColorDepth) == false )
837     {
838       if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
839       {
840         DALI_LOG_RELEASE_INFO( "InitializeGraphics: Fail to choose config with GLES30, retry with GLES20\n" );
841         eglImpl.SetGlesVersion( 20 );
842         mGLESVersion = Dali::GlWindow::GlesVersion::VERSION_2_0;
843         if( eglImpl.ChooseConfig(true, mColorDepth) == false )
844         {
845           DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
846           return;
847         }
848       }
849       else
850       {
851         DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
852         return;
853       }
854     }
855     eglImpl.CreateWindowContext( mEGLContext );
856
857    // Create the EGL window
858     EGLNativeWindowType window = mWindowBase->CreateEglWindow( mPositionSize.width, mPositionSize.height );
859     mEGLSurface = eglImpl.CreateSurfaceWindow( window, mColorDepth );
860
861     mIsEGLInitialize = true;
862   }
863 }
864
865 void GlWindow::OnDamaged(  const DamageArea& area )
866 {
867
868 }
869
870 } // Adaptor
871
872 } // Internal
873
874 } // Dali