Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / renderer / graphics-engine / FUiEffects_RendererGraphicsEngineRender.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FUiEffects_RendererGraphicsEngineRender.cpp
20  * @brief               Implementation of class for rendering scene tree
21  *
22  */
23
24 #include <renderer/engine-model/FUiEffects_RendererEngineModelDrawable.h>
25 #include <renderer/engine-model/FUiEffects_RendererEngineModelNode.h>
26 #include <renderer/engine-model/FUiEffects_RendererEngineModelGroup.h>
27 #include <renderer/engine-model/FUiEffects_RendererEngineModelCamera.h>
28 #include <renderer/engine-model/FUiEffects_RendererEngineModelBuffer.h>
29 #include <renderer/engine-model/FUiEffects_RendererEngineModelTexture2DProperty.h>
30 #include <renderer/engine-model/FUiEffects_RendererEngineModelStringShaderProperty.h>
31 #include <renderer/engine-model/FUiEffects_RendererEngineModelShaderHolderProgramProperty.h>
32
33 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineOpenGLImplementation.h>
34 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRender.h>
35 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRenderDrawableCache.h>
36 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRenderBufferCache.h>
37 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRenderTextureCache.h>
38 #include <renderer/graphics-engine/FUiEffects_RendererGraphicsEngineRenderShaderCache.h>
39
40 namespace Tizen { namespace Ui { namespace Effects { namespace _Renderer { namespace GraphicsEngine
41 {
42
43 Render::Render(void)
44         : __worldViewProjection()
45         , __externalRenderTargets()
46         , __drawables()
47         , __blendDrawables()
48         , __pCamera(null)
49         , __findCameraPass(false)
50         , __caches()
51         , __deadCaches()
52         , __alphaBlendSource(GL_SRC_ALPHA)
53         , __alphaBlendDestination(GL_ONE_MINUS_SRC_ALPHA)
54         , __depthTestState(false)
55         , __currentFrameBuffer(0)
56 {
57 }
58
59 Render::~Render(void)
60 {
61         const CacheListSizeType len = __caches.size();
62         for (CacheListSizeType i = 0; len > i; ++i)
63         {
64                 __caches[i]->InternalDestroyCache();
65         }
66 }
67
68 void
69 Render::SetDefaultDepthTestState(bool aIsEnable)
70 {
71         __depthTestState = aIsEnable;
72         return;
73 }
74
75 void
76 Render::Draw(Tizen::Ui::Effects::_Renderer::EngineModel::Node& root, EngineModel::Camera& camera)
77 {
78         InternalKillDeadCaches();
79
80         __pCamera = &camera;
81         if (null == __pCamera)
82         {
83                 ThrowJmp("Render::draw: Can`t render, no active camera");
84         }
85
86         InternalPreDraw();
87
88         InternalCollectInfo(root);
89
90         InternalDraw();
91
92         InternalPostDraw();
93         return;
94 }
95
96 void
97 Render::Draw(Tizen::Ui::Effects::_Renderer::EngineModel::Node& root)
98 {
99         InternalFindCameras(root);
100
101         Draw(root, *__pCamera);
102         return;
103 }
104
105 void
106 Render::OnGroup(Tizen::Ui::Effects::_Renderer::EngineModel::Group& prop)
107 {
108         const size_t len = prop.ChildrenCount();
109         for (size_t i = 0; len > i; ++i)
110         {
111                 prop.GetChild(i)->Visit(*this);
112         }
113         return;
114 }
115
116 void
117 Render::OnDrawable(Tizen::Ui::Effects::_Renderer::EngineModel::Drawable& prop)
118 {
119         EngineModel::Cache* pCache = System::GetImpl(prop.GetCache());
120         if (!pCache)
121         {
122                 BuildCache(prop);
123
124                 pCache = System::GetImpl(prop.GetCache());
125                 if (!pCache) { return; }
126         }
127
128         RenderDrawableCache* renderCache = dynamic_cast<RenderDrawableCache*>(pCache);
129         if (renderCache == null)
130         {
131                 return;
132         }
133
134         __drawables.push_back(renderCache);
135
136
137         const RenderDrawableCache::ExternalTexturesListSizeType numExternalTextures = renderCache->NumExternalTextures();
138
139         for (RenderDrawableCache::ExternalTexturesListSizeType i = 0; numExternalTextures > i; ++i)
140         {
141
142                 EngineModel::TextureAttachment* attachment = renderCache->GetExternalTexture(i);
143                 if (attachment == null)
144                 {
145                         return;
146                 }
147
148                 const EngineModel::TextureAttachment::RenderTargetListSizeType numRenderTargets = attachment->GetNumRenderTargets();
149
150                 for (Tizen::Ui::Effects::_Renderer::EngineModel::TextureAttachment::RenderTargetListSizeType rt = 0; numRenderTargets > rt; ++rt)
151                 {
152                         EngineModel::RenderTargetExternalRender* pRenderTarget = static_cast<Tizen::Ui::Effects::_Renderer::EngineModel::RenderTargetExternalRender*>(attachment->GetRenderTarget(rt));
153                         if (pRenderTarget == null)
154                         {
155                                 return;
156                         }
157
158                         RenderTargetExternalRenderCache* cache = static_cast<RenderTargetExternalRenderCache*>(System::GetImpl(pRenderTarget->GetCache()));
159                         if (!cache)
160                         {
161                                 BuildCache(*pRenderTarget);
162
163                                 cache = static_cast<RenderTargetExternalRenderCache*>(System::GetImpl(pRenderTarget->GetCache()));
164                         }
165                         __externalRenderTargets[cache] = cache;
166                 }
167         }
168
169         return;
170 }
171
172 void
173 Render::ManageCache(RenderCacheImplPtr pCache)
174 {
175         __caches.push_back(pCache);
176         pCache->__cacheIndex = __caches.size() - 1;
177         return;
178 }
179
180 void
181 Render::KillCache(RenderCacheImpl* pCache)
182 {
183         __deadCaches.push_back(pCache);
184         return;
185 }
186
187 void
188 Render::InternalKillDeadCaches(void)
189 {
190         const DeadCacheListSizeType len = __deadCaches.size();
191         for (DeadCacheListSizeType i = 0; len > i; ++i)
192         {
193                 __deadCaches[i]->InternalDestroyCache();
194                 const size_t cacheIndex = __deadCaches[i]->__cacheIndex;
195                 const CacheListSizeType cachesSize = __caches.size();
196                 __caches[cacheIndex] = __caches[cachesSize - 1];
197                 __caches[cacheIndex]->__cacheIndex = cacheIndex;
198                 __caches.resize(cachesSize - 1);
199         }
200         __deadCaches.clear();
201         return;
202 }
203
204 void
205 Render::ContextLost(void)
206 {
207         const CacheListSizeType len = __caches.size();
208         for (CacheListSizeType i = 0; len > i; ++i)
209         {
210                 __caches[i]->InternalDropCache();
211         }
212         return;
213 }
214
215 namespace
216 {
217         struct CameraFinder: public EngineModel::Visitor
218         {
219                 EngineModel::Camera* pCamera;
220                 CameraFinder(): pCamera(null) {}
221
222                 virtual void
223                 OnGroup(Tizen::Ui::Effects::_Renderer::EngineModel::Group& prop)
224                 {
225                         const size_t len = prop.ChildrenCount();
226                         for (size_t i = 0; len > i; ++i)
227                         {
228                                 prop.GetChild(i)->Visit(*this);
229                         }
230                         return;
231                 }
232
233                 virtual void
234                 OnCamera(Tizen::Ui::Effects::_Renderer::EngineModel::Camera& prop)
235                 {
236                         pCamera = &prop;
237                         return;
238                 }
239         };
240 }
241
242 void
243 Render::InternalFindCameras(Tizen::Ui::Effects::_Renderer::EngineModel::Node& prop)
244 {
245         __pCamera = null;
246         CameraFinder cameraFinder;
247         prop.Visit(cameraFinder);
248         __pCamera = cameraFinder.pCamera;
249         return;
250 }
251
252 void
253 Render::InternalPreDraw(void)
254 {
255         __drawables.clear();
256         __blendDrawables.clear();
257         __externalRenderTargets.clear();
258         return;
259 }
260
261 void
262 Render::InternalCollectInfo(Tizen::Ui::Effects::_Renderer::EngineModel::Node& prop)
263 {
264         prop.Visit(*this);
265         return;
266 }
267
268 void
269 Render::InternalDraw(void)
270 {
271         Math::Vector2f minPos = __pCamera->GetViewportMin();
272         Math::Vector2f maxPos = __pCamera->GetViewportMax();
273         glViewport(static_cast<GLint>(minPos.X()), static_cast<GLint>(minPos.Y()), static_cast<GLint>(maxPos.X()), static_cast<GLint>(maxPos.Y()));
274
275         Math::Matrix4f cameraWorld(__pCamera->GetWorld());
276         Math::Matrix4f cameraView(cameraWorld.GetInversed()); //__pCamera world matrix is inverted view matrix
277         Math::Matrix4f projection(__pCamera->GetProj());
278         Math::Matrix4f viewProjection = projection * cameraView;
279         if (__depthTestState)
280         {
281                 glEnable(GL_DEPTH_TEST);
282         }
283         else
284         {
285                 glDisable(GL_DEPTH_TEST);
286         }
287
288         //solid Draw
289         const size_t len = __drawables.size();
290         for (size_t i = 0; len > i; ++i)
291         {
292                 __worldViewProjection = viewProjection * __drawables[i]->GetWorld();
293                 __worldViewProjection.Transpose();
294                 if (static_cast<RenderDrawableCache*>(__drawables[i])->HasAlphaBlend(this))
295                 {
296                         glEnable(GL_BLEND);
297                 }
298                 else
299                 {
300                         glDisable(GL_BLEND);
301                 }
302
303                 static_cast<RenderDrawableCache*>(__drawables[i])->Draw(this);
304         }
305
306         return;
307 }
308
309 void
310 Render::InternalPostDraw(void)
311 {
312         return;
313 }
314
315 void
316 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::Drawable& prop)
317 {
318         RenderCachePtr cachePtr(new (std::nothrow) RenderDrawableCache(this, &prop));
319         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "cache = null");
320
321         prop.SetCache(cachePtr);
322
323         cachePtr->Validate(this);
324
325         ManageCache(cachePtr);
326         return;
327 }
328
329 void
330 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::VertexBuffer& prop)
331 {
332         RenderCachePtr cachePtr(new (std::nothrow) SolidVertexBufferCache(this, &prop));
333         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "cache = null");
334
335         prop.SetCache(cachePtr);
336         cachePtr->Validate(this);
337         ManageCache(cachePtr);
338         return;
339 }
340
341 void
342 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::IndexBuffer& prop)
343 {
344         RenderCachePtr cachePtr(new (std::nothrow) IndexBufferCache(this, &prop));
345         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "cache = null");
346
347         prop.SetCache(cachePtr);
348         cachePtr->Validate(this);
349         ManageCache(cachePtr);
350         return;
351 }
352
353 void
354 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::CompositeVertexBuffer& prop)
355 {
356         RenderCachePtr cachePtr(new (std::nothrow) CompositeVertexBufferCache(this, &prop));
357         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
358
359         prop.SetCache(cachePtr);
360         cachePtr->Validate(this);
361         ManageCache(cachePtr);
362         return;
363 }
364
365 void
366 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::PartVertexBuffer& prop)
367 {
368         RenderCachePtr cachePtr(new (std::nothrow) PartVertexBufferCache(this, &prop));
369         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
370
371         prop.SetCache(cachePtr);
372         cachePtr->Validate(this);
373         ManageCache(cachePtr);
374         return;
375 }
376
377 void
378 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::Texture2dProperty& prop, GLuint stage)
379 {
380         RenderCachePtr cachePtr(new (std::nothrow) RenderTexture2dCache(this, &prop));
381         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
382
383         prop.SetCache(cachePtr);
384         cachePtr.staticCast<RenderTexture2dCache>()->Validate(this, stage);
385         ManageCache(cachePtr);
386         return;
387 }
388
389 void
390 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::ShaderProperty& prop)
391 {
392         RenderCachePtr cachePtr(new (std::nothrow) RenderShaderCache(this, &prop));
393         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
394
395         prop.SetCache(cachePtr);
396         cachePtr->Validate(this);
397         ManageCache(cachePtr);
398         return;
399 }
400
401 void
402 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::ProgramProperty& prop)
403 {
404         RenderCachePtr cachePtr(new (std::nothrow) RenderProgramCache(this, &prop));
405         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
406
407         prop.SetCache(cachePtr);
408         cachePtr->Validate(this);
409         ManageCache(cachePtr);
410         return;
411 }
412
413 void
414 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::RenderTargetExternalRender& prop)
415 {
416         RenderCachePtr cachePtr(new (std::nothrow) RenderTargetExternalRenderCache(this, &prop));
417         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
418
419         prop.SetCache(cachePtr);
420         cachePtr->Validate(this);
421         ManageCache(cachePtr);
422         return;
423 }
424
425 void
426 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::Texture2dAttachmentProperty& prop, GLuint stage)
427 {
428         RenderCachePtr cachePtr(new (std::nothrow) Texture2dAttachmentCache(this, &prop));
429         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
430
431         prop.SetCache(cachePtr);
432         cachePtr.staticCast<Texture2dAttachmentCache>()->Validate(this, stage);
433         ManageCache(cachePtr);
434         return;
435 }
436
437 void
438 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::StubAttachment& o)
439 {
440         RenderCachePtr cachePtr(new (std::nothrow) StubAttachmentCache(this, &o));
441         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
442
443         o.SetCache(cachePtr);
444         cachePtr->Validate(this);
445         ManageCache(cachePtr);
446         return;
447 }
448
449 void
450 Render::BuildCache(Tizen::Ui::Effects::_Renderer::EngineModel::AlphaBlendProperty& prop)
451 {
452         RenderCachePtr cachePtr(new (std::nothrow) RenderAlphaBlendCache(this, &prop));
453         _TryJmp(GetImpl(cachePtr) != null, E_OUT_OF_MEMORY, "pCache = null");
454
455         prop.SetCache(cachePtr);
456         cachePtr->Validate(this);
457         ManageCache(cachePtr);
458         return;
459 }
460
461 RenderCommandPtr
462 Render::GetDefaultRenderCommand(const RenderProgramCache::UniformListValueType* pInfo)
463 {
464         if (pInfo->second == "WorldViewProjection")
465         {
466                 RenderCommandPtr result = RenderCommandPtr(new (std::nothrow) SetWorldViewProjection(pInfo->first.location));
467                 _TryJmp(System::GetImpl(result) != null, E_OUT_OF_MEMORY, "GetDefaultRenderCommand = null");
468
469                 return result;
470         }
471
472         return RenderCommandPtr();
473 }
474
475 SetWorldViewProjection::SetWorldViewProjection(GLuint location):
476         __location(location)
477 {
478 }
479
480 void
481 SetWorldViewProjection::Apply(Render* pRender)
482 {
483         glUniformMatrix4fv(__location, 1, GL_FALSE, pRender->GetWorldViewProjection().data[0].data);
484         return;
485 }
486
487 const Math::Matrix4f&
488 Render::GetWorldViewProjection(void)
489 {
490         return __worldViewProjection;
491 }
492
493 }}}}} //Tizen::Ui::Effects::_Renderer::GraphicsEngine