Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-adaptor.git] / adaptors / base / render-helper.cpp
1 /*
2  * Copyright (c) 2017 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 "render-helper.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 // INTERNAL INCLUDES
25 #include <base/interfaces/adaptor-internal-services.h>
26 #include <base/display-connection.h>
27
28 namespace Dali
29 {
30
31 namespace Internal
32 {
33
34 namespace Adaptor
35 {
36
37 RenderHelper::RenderHelper( AdaptorInternalServices& adaptorInterfaces )
38 : mGLES( adaptorInterfaces.GetGlesInterface() ),
39   mEglFactory( &adaptorInterfaces.GetEGLFactoryInterface()),
40   mEGL( NULL ),
41   mSurfaceReplaced( false ),
42   mSurfaceResized( false )
43 {
44   // set the initial values before render thread starts
45   mSurface = adaptorInterfaces.GetRenderSurfaceInterface();
46
47   if( mSurface )
48   {
49     mDisplayConnection = Dali::DisplayConnection::New( mSurface->GetSurfaceType() );
50   }
51   else
52   {
53     mDisplayConnection = Dali::DisplayConnection::New();
54   }
55 }
56
57 RenderHelper::~RenderHelper()
58 {
59   if (mDisplayConnection)
60   {
61     delete mDisplayConnection;
62     mDisplayConnection = NULL;
63   }
64
65   mEglFactory->Destroy();
66 }
67
68 void RenderHelper::Start()
69 {
70   if( mSurface )
71   {
72     mSurface->StartRender();
73   }
74 }
75
76 void RenderHelper::Stop()
77 {
78   if( mSurface )
79   {
80     // Tell surface we have stopped rendering
81     mSurface->StopRender();
82
83     // The surface will be destroyed soon; this pointer will become invalid
84     mSurface = NULL;
85   }
86 }
87
88 void RenderHelper::ConsumeEvents()
89 {
90   mDisplayConnection->ConsumeEvents();
91 }
92
93 void RenderHelper::InitializeEgl()
94 {
95   mEGL = mEglFactory->Create();
96
97   DALI_ASSERT_ALWAYS( mSurface && "NULL surface" );
98
99   // Initialize EGL & OpenGL
100   mDisplayConnection->InitializeEgl( *mEGL );
101   mSurface->InitializeEgl( *mEGL );
102
103   // create the OpenGL context
104   mEGL->CreateContext();
105
106   // create the OpenGL surface
107   mSurface->CreateEglSurface(*mEGL);
108
109   // Make it current
110   mEGL->MakeContextCurrent();
111 }
112
113 void RenderHelper::ReplaceSurface( RenderSurface* newSurface )
114 {
115   mSurface->DestroyEglSurface(*mEGL);
116
117   // This is designed for replacing pixmap surfaces, but should work for window as well
118   // we need to delete the egl surface and renderable (pixmap / window)
119   // Then create a new pixmap/window and new egl surface
120   // If the new surface has a different display connection, then the context will be lost
121   DALI_ASSERT_ALWAYS(newSurface && "NULL surface");
122
123   mDisplayConnection->InitializeEgl(*mEGL);
124
125   newSurface->ReplaceEGLSurface(*mEGL);
126
127   // use the new surface from now on
128   mSurface = newSurface;
129   mSurfaceReplaced = true;
130 }
131
132 void RenderHelper::ResizeSurface()
133 {
134   mSurfaceResized = true;
135 }
136
137 void RenderHelper::ShutdownEgl()
138 {
139   if( mSurface )
140   {
141     // give a chance to destroy the OpenGL surface that created externally
142     mSurface->DestroyEglSurface( *mEGL );
143   }
144
145   // delete the GL context / egl surface
146   mEGL->TerminateGles();
147 }
148
149 bool RenderHelper::PreRender()
150 {
151   if( mSurface )
152   {
153     mSurface->PreRender( *mEGL, mGLES, mSurfaceResized );
154   }
155   mGLES.PreRender();
156   return true;
157 }
158
159 void RenderHelper::PostRender()
160 {
161   // Inform the gl implementation that rendering has finished before informing the surface
162   mGLES.PostRender();
163
164   if( mSurface )
165   {
166     // Inform the surface that rendering this frame has finished.
167     mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced, mSurfaceResized );
168   }
169   mSurfaceReplaced = false;
170   mSurfaceResized = false;
171 }
172
173 } // namespace Adaptor
174
175 } // namespace Internal
176
177 } // namespace Dali