Revert "[Tizen] Sync for libds"
[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   RecalculateTouchPosition( point );
498   Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent( timeStamp, point );
499   mTouchSignal.Emit( touchEvent );
500 }
501
502 void GlWindow::OnWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
503 {
504   // TODO:
505   //FeedWheelEvent( wheelEvent );
506 }
507
508 void GlWindow::OnKeyEvent( Dali::Integration::KeyEvent& keyEvent )
509 {
510   Dali::KeyEvent event = Dali::DevelKeyEvent::New( keyEvent.keyName, keyEvent.logicalKey, keyEvent.keyString, keyEvent.keyCode,
511                                                    keyEvent.keyModifier, keyEvent.time, static_cast<Dali::KeyEvent::State>(keyEvent.state),
512                                                    keyEvent.compose, keyEvent.deviceName, keyEvent.deviceClass, keyEvent.deviceSubclass );
513   mKeyEventSignal.Emit( event );
514 }
515
516 void GlWindow::OnRotation( const RotationEvent& rotation )
517 {
518   mWindowRotationAngle = rotation.angle;
519   mTotalRotationAngle = ( mWindowRotationAngle + mScreenRotationAngle ) % 360;
520   if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
521   {
522     mWindowWidth = mPositionSize.height;
523     mWindowHeight = mPositionSize.width;
524   }
525   else
526   {
527     mWindowWidth = mPositionSize.width;
528     mWindowHeight = mPositionSize.height;
529   }
530
531   mIsRotated = true;
532   mIsWindowRotated = true;
533   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), OnRotation(): resized signal emit [%d x %d]\n", this, mNativeWindowId, mWindowWidth, mWindowHeight );
534
535   // Emit Resized signal
536   mResizedSignal.Emit( Dali::Uint16Pair( mWindowWidth, mWindowHeight ) );
537 }
538
539 void GlWindow::RecalculateTouchPosition( Integration::Point& point )
540 {
541   Vector2 position = point.GetScreenPosition();
542   Vector2 convertedPosition;
543
544   switch( mTotalRotationAngle )
545   {
546     case 90:
547     {
548       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.y;
549       convertedPosition.y = position.x;
550       break;
551     }
552     case 180:
553     {
554       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.x;
555       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.y;
556       break;
557     }
558     case 270:
559     {
560       convertedPosition.x = position.y;
561       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.x;
562       break;
563     }
564     default:
565     {
566       convertedPosition = position;
567       break;
568     }
569   }
570
571   point.SetScreenPosition( convertedPosition );
572 }
573
574 void GlWindow::SetAvailableAnlges( const std::vector< int >& angles )
575 {
576   if( angles.size() > 4 )
577   {
578     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableAnlges: Invalid vector size! [%d]\n", angles.size() );
579     return;
580   }
581
582   mWindowBase->SetAvailableAnlges( angles );
583 }
584
585 bool GlWindow::IsOrientationAvailable( Dali::GlWindow::GlWindowOrientation orientation ) const
586 {
587   if( orientation <= Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE
588       || orientation > Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE )
589   {
590     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::IsOrientationAvailable: Invalid input orientation [%d]\n", orientation );
591     return false;
592   }
593   return true;
594 }
595
596 int GlWindow::ConvertToAngle(  Dali::GlWindow::GlWindowOrientation  orientation )
597 {
598   int convertAngle = 0;
599   if ( mOrientationMode == 0 )
600   {
601     convertAngle = ( static_cast< int >( orientation ) ) * 90;
602   }
603   else if( mOrientationMode == 1)
604   {
605     switch( orientation )
606     {
607       case Dali::GlWindow::GlWindowOrientation::LANDSCAPE:
608       {
609         convertAngle = 0;
610         break;
611       }
612       case Dali::GlWindow::GlWindowOrientation::PORTRAIT:
613       {
614         convertAngle = 90;
615         break;
616       }
617       case Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE:
618       {
619         convertAngle = 180;
620         break;
621       }
622       case Dali::GlWindow::GlWindowOrientation::PORTRAIT_INVERSE:
623       {
624         convertAngle = 270;
625         break;
626       }
627       case Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE:
628       {
629         convertAngle = -1;
630         break;
631       }
632     }
633   }
634   return convertAngle;
635 }
636
637 Dali::GlWindow::GlWindowOrientation GlWindow::ConvertToOrientation( int angle ) const
638 {
639   Dali::GlWindow::GlWindowOrientation orientation = Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE;
640   if ( mOrientationMode == 0 ) // Portrate mode
641   {
642     orientation = static_cast< Dali::GlWindow::GlWindowOrientation >( angle / 90 );
643   }
644   else if( mOrientationMode == 1 ) // Landscape mode
645   {
646     switch( angle )
647     {
648       case 0:
649       {
650         orientation = Dali::GlWindow::GlWindowOrientation::LANDSCAPE;
651         break;
652       }
653       case 90:
654       {
655         orientation = Dali::GlWindow::GlWindowOrientation::PORTRAIT;
656         break;
657       }
658       case 180:
659       {
660         orientation = Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE;
661         break;
662       }
663       case 270:
664       {
665         orientation = Dali::GlWindow::GlWindowOrientation::PORTRAIT_INVERSE;
666         break;
667       }
668       case -1:
669       {
670         orientation = Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE;
671         break;
672       }
673     }
674   }
675   return orientation;
676 }
677
678 Dali::GlWindow::GlWindowOrientation GlWindow::GetCurrentOrientation() const
679 {
680   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), GetCurrentOrientation(): %d\n", this, mNativeWindowId, mTotalRotationAngle );
681   return ConvertToOrientation( mTotalRotationAngle );
682 }
683
684 void GlWindow::SetAvailableOrientations( const Dali::Vector< Dali::GlWindow::GlWindowOrientation >& orientations )
685 {
686   Dali::Vector<float>::SizeType count = orientations.Count();
687   for( Dali::Vector<float>::SizeType index = 0; index < count; ++index )
688   {
689     if( IsOrientationAvailable( orientations[index] ) == false )
690     {
691       DALI_LOG_ERROR("Window::SetAvailableRotationAngles, invalid angle: %d\n", orientations[index]);
692       continue;
693     }
694
695     bool found = false;
696     int angle = ConvertToAngle( orientations[index] );
697
698     for( std::size_t i = 0; i < mAvailableAngles.size(); i++ )
699     {
700       if( mAvailableAngles[i] == angle )
701       {
702         found = true;
703         break;
704       }
705     }
706
707     if( !found )
708     {
709       DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetAvailableOrientations: %d\n", this, mNativeWindowId, angle );
710       mAvailableAngles.push_back( angle );
711     }
712   }
713   SetAvailableAnlges( mAvailableAngles );
714 }
715
716 void GlWindow::SetPreferredOrientation( Dali::GlWindow::GlWindowOrientation orientation  )
717 {
718   if( IsOrientationAvailable( orientation ) == false )
719   {
720     DALI_LOG_ERROR( "Window::SetPreferredOrientation, invalid orientation: %d\n", orientation );
721     return;
722   }
723   mPreferredAngle = ConvertToAngle( orientation );
724   DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetPreferredOrientation: %d\n", this, mNativeWindowId, mPreferredAngle );
725   mWindowBase->SetPreferredAngle( mPreferredAngle );
726 }
727
728 void GlWindow::SetChild( Dali::Window& child )
729 {
730   if( DALI_UNLIKELY( child ) )
731   {
732     mChildWindow = child;
733     Internal::Adaptor::Window& windowImpl = Dali::GetImplementation( mChildWindow );
734     WindowRenderSurface* renderSurface = static_cast<WindowRenderSurface*>( windowImpl.GetSurface() );
735     WindowBase* childWindowBase = renderSurface->GetWindowBase();
736     childWindowBase->SetParent( mWindowBase.get() );
737   }
738 }
739
740 void GlWindow::RegisterGlCallback( GlInitialize glInit, GlRenderFrame glRenderFrame, GlTerminate glTerminate )
741 {
742   if( mIsEGLInitialize == false )
743   {
744     InitializeGraphics();
745   }
746   mGLInitCallback = glInit;
747   mGLRenderFrameCallback = glRenderFrame;
748   mGLTerminateCallback = glTerminate;
749
750   mInitCallback = false;
751
752   if( !mGLRenderCallback )
753   {
754     mGLRenderCallback = MakeCallback( this, &GlWindow::RunCallback );
755
756     Dali::Adaptor::Get().AddIdle( mGLRenderCallback, true );
757   }
758 }
759
760 bool GlWindow::RunCallback()
761 {
762   GraphicsInterface* graphics = mGraphics.get();
763   EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
764   Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
765
766   eglImpl.MakeContextCurrent( mEGLSurface, mEGLContext );
767
768   if( mIsRotated )
769   {
770     mWindowBase->SetEglWindowBufferTransform( mTotalRotationAngle );
771     if( mIsWindowRotated )
772     {
773       mWindowBase->SetEglWindowTransform( mWindowRotationAngle );
774     }
775     mIsRotated = false;
776   }
777
778   if( !mInitCallback )
779   {
780     if( mGLInitCallback )
781     {
782       mGLInitCallback();
783     }
784     mInitCallback = true;
785   }
786
787   if( mGLRenderFrameCallback )
788   {
789     mGLRenderFrameCallback();
790   }
791
792   if( mIsWindowRotated )
793   {
794     mWindowBase->WindowRotationCompleted( mWindowRotationAngle, mPositionSize.width, mPositionSize.height );
795     mIsWindowRotated = false;
796   }
797
798   eglImpl.SwapBuffers( mEGLSurface );
799
800   return true;
801 }
802
803 void GlWindow::RenderOnce()
804 {
805   RunCallback();
806 }
807
808 int32_t GlWindow::GetNativeId() const
809 {
810   return mWindowBase->GetNativeWindowId();
811 }
812
813 void GlWindow::InitializeGraphics()
814 {
815   if( !mIsEGLInitialize )
816   {
817     // Init Graphics
818     std::unique_ptr< GraphicsFactory > graphicsFactoryPtr = Utils::MakeUnique< GraphicsFactory >();
819     auto graphicsFactory = *graphicsFactoryPtr.get();
820
821     mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
822     GraphicsInterface* graphics = mGraphics.get();
823     EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
824     eglGraphics->Initialize( mDepth, mStencil, mMSAA );
825     eglGraphics->Create();
826
827     mDisplayConnection = Dali::DisplayConnection::New( *graphics, Dali::RenderSurfaceInterface::Type::WINDOW_RENDER_SURFACE );
828     mDisplayConnection->Initialize();
829
830     Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
831     if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_2_0 )
832     {
833       eglImpl.SetGlesVersion( 20 );
834     }
835     else if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
836     {
837       eglImpl.SetGlesVersion( 30 );
838     }
839
840     if( eglImpl.ChooseConfig(true, mColorDepth) == false )
841     {
842       if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
843       {
844         DALI_LOG_RELEASE_INFO( "InitializeGraphics: Fail to choose config with GLES30, retry with GLES20\n" );
845         eglImpl.SetGlesVersion( 20 );
846         mGLESVersion = Dali::GlWindow::GlesVersion::VERSION_2_0;
847         if( eglImpl.ChooseConfig(true, mColorDepth) == false )
848         {
849           DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
850           return;
851         }
852       }
853       else
854       {
855         DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
856         return;
857       }
858     }
859     eglImpl.CreateWindowContext( mEGLContext );
860
861    // Create the EGL window
862     EGLNativeWindowType window = mWindowBase->CreateEglWindow( mPositionSize.width, mPositionSize.height );
863     mEGLSurface = eglImpl.CreateSurfaceWindow( window, mColorDepth );
864
865     mIsEGLInitialize = true;
866   }
867 }
868
869 void GlWindow::OnDamaged(  const DamageArea& area )
870 {
871
872 }
873
874 } // Adaptor
875
876 } // Internal
877
878 } // Dali