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