Render to Frame Buffer Object.
[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 }
84
85 void RenderHelper::ConsumeEvents()
86 {
87   mDisplayConnection->ConsumeEvents();
88 }
89
90 void RenderHelper::InitializeEgl()
91 {
92   mEGL = mEglFactory->Create();
93
94   DALI_ASSERT_ALWAYS( mSurface && "NULL surface" );
95
96   // Initialize EGL & OpenGL
97   mDisplayConnection->InitializeEgl( *mEGL );
98   mSurface->InitializeEgl( *mEGL );
99
100   // create the OpenGL context
101   mEGL->CreateContext();
102
103   // create the OpenGL surface
104   mSurface->CreateEglSurface(*mEGL);
105
106   // Make it current
107   mEGL->MakeContextCurrent();
108 }
109
110 void RenderHelper::ReplaceSurface( RenderSurface* newSurface )
111 {
112   mSurface->DestroyEglSurface(*mEGL);
113
114   // This is designed for replacing pixmap surfaces, but should work for window as well
115   // we need to delete the egl surface and renderable (pixmap / window)
116   // Then create a new pixmap/window and new egl surface
117   // If the new surface has a different display connection, then the context will be lost
118   DALI_ASSERT_ALWAYS(newSurface && "NULL surface");
119
120   mDisplayConnection->InitializeEgl(*mEGL);
121
122   newSurface->ReplaceEGLSurface(*mEGL);
123
124   // use the new surface from now on
125   mSurface = newSurface;
126   mSurfaceReplaced = true;
127 }
128
129 void RenderHelper::ResizeSurface()
130 {
131   mSurfaceResized = true;
132 }
133
134 void RenderHelper::ShutdownEgl()
135 {
136   if( mSurface )
137   {
138     // give a chance to destroy the OpenGL surface that created externally
139     mSurface->DestroyEglSurface( *mEGL );
140
141     mSurface = NULL;
142   }
143
144   // delete the GL context / egl surface
145   mEGL->TerminateGles();
146 }
147
148 bool RenderHelper::PreRender()
149 {
150   if( mSurface )
151   {
152     mSurface->PreRender( *mEGL, mGLES, mSurfaceResized );
153   }
154   mGLES.PreRender();
155   return true;
156 }
157
158 void RenderHelper::PostRender( bool renderToFbo )
159 {
160   // Inform the gl implementation that rendering has finished before informing the surface
161   mGLES.PostRender();
162
163   if( renderToFbo )
164   {
165     mGLES.Flush();
166     mGLES.Finish();
167   }
168   else
169   {
170     if( mSurface )
171     {
172       // Inform the surface that rendering this frame has finished.
173       mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced, mSurfaceResized );
174     }
175   }
176   mSurfaceReplaced = false;
177   mSurfaceResized = false;
178 }
179
180 } // namespace Adaptor
181
182 } // namespace Internal
183
184 } // namespace Dali