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