Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / renderer / FUiEffects_RendererEffectRenderer.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_RendererEffectRenderer.cpp
20  * @brief               This is the source file for the EffectRenderer class
21  */
22
23 #include <FUiEffects_RendererEffectRenderer.h>
24
25 #include <limits>
26 #include <unique_ptr.h>
27
28 #include <FBaseSysLog.h>
29 #include <FUi_CoordinateSystemUtils.h>
30 #include <FGrp_BitmapImpl.h>
31
32 #include "FUiEffects_RendererEffectShader.h"
33 #include <FUiEffects_RuntimePointLight.h>
34 #include <FUiEffects_RuntimeSpotLight.h>
35 #include <FUiEffects_RuntimeDirectionalLight.h>
36 #include "../FUiEffects_EffectErrorMessages.h"
37 #include <FUiEffects_LoggingProfiler.h>
38
39 using namespace Tizen::Ui::Effects::_Runtime;
40 using namespace Tizen::Ui::Effects::_Renderer::EngineModel;
41 using namespace Tizen::Ui::Effects::_Renderer::Math;
42 using namespace Tizen::Ui::Effects::_Renderer::GraphicsEngine;
43 using namespace Tizen::Graphics;
44 using namespace Tizen::Ui;
45 using std::string;
46
47 namespace Tizen { namespace Ui { namespace Effects { namespace _Renderer
48 {
49
50 EGLDisplay EffectRenderer::__eglDisplay = EGL_NO_DISPLAY;
51 EGLConfig EffectRenderer::__eglConfig = 0;
52 EGLint EffectRenderer::__glMajorVer = 0;
53 EGLint EffectRenderer::__glMinorVer = 0;
54 bool EffectRenderer::__OpenGLInitialized = false;
55
56 const EGLint RENDERER_EGL_DEFAULT_CONFIG_ATTRIBS[] =
57 {
58         EGL_RED_SIZE,   8,
59         EGL_GREEN_SIZE, 8,
60         EGL_BLUE_SIZE,  8,
61         EGL_ALPHA_SIZE, 8,
62         EGL_DEPTH_SIZE, 0,
63         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
64         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
65         EGL_NONE
66 };
67
68 static const EGLint RENDERER_EGL_DEFAULT_CONTEXT_ATTRIBS[] =
69 {
70         EGL_CONTEXT_CLIENT_VERSION, 2,
71         EGL_NONE
72 };
73
74 bool
75 EffectRenderer::InitOpenGL(const EGLint* pConfig)
76 {
77         //if already initialized
78         if (__OpenGLInitialized)
79         {
80                 SysLog(NID_UI_EFFECT, "OpenGL already initialized.");
81
82                 return true;
83         }
84
85         int nconfigs = 0;
86         eglBindAPI(EGL_OPENGL_ES_API);
87
88         __eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
89         SysTryReturn(NID_UI_EFFECT,  __eglDisplay != EGL_NO_DISPLAY, false, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Effects. There was an error while performing function eglGetDisplay");
90
91
92         SysTryCatchLabel(NID_UI_EFFECT, eglInitialize(__eglDisplay, &__glMajorVer, &__glMinorVer) == EGL_TRUE, , INIT_ERROR, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Effects. There was an error while performing function eglInitialize");
93         //SysLog(NID_UI_EFFECT, "Effects. GL version %d.%d", __glMajorVer, __glMinorVer);
94
95         SysTryCatchLabel(NID_UI_EFFECT, eglChooseConfig(__eglDisplay, pConfig, &__eglConfig, 1, &nconfigs) == EGL_TRUE, , INIT_ERROR, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Effects. There was an error while performing function eglChooseConfig");
96
97
98         SysTryCatchLabel(NID_UI_EFFECT, nconfigs == 1, , INIT_ERROR, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Effects. There is eglChooseConfig matching configurations count error (OpenGL)");
99
100 //INIT_SUCCESS:
101         __OpenGLInitialized = CheckEglNoErrors();
102
103         SysTryReturn(NID_UI_EFFECT, __OpenGLInitialized, false, E_OPERATION_FAILED, "[E_OPERATION_FAILED] There are OpenGL errors during initialization");
104
105         SysLog(NID_UI_EFFECT, "OpenGL initialized successfully.");
106         return true;
107
108
109 INIT_ERROR:
110         __OpenGLInitialized = false;
111         eglTerminate(__eglDisplay);
112         __eglDisplay = EGL_NO_DISPLAY;
113         SysLogException(NID_UI_EFFECT, E_OPERATION_FAILED, "[E_OPERATION_FAILED] OpenGL errors were appeared during initialization");
114
115         return false;
116 }
117
118 void
119 EffectRenderer::CloseOpenGL(void)
120 {
121         SysLog(NID_UI_EFFECT, "Effects. OpenGL is closing...");
122
123         //if already initialized
124         if (!__OpenGLInitialized)
125         {
126                 SysLog(NID_UI_EFFECT, "OpenGL not initialized.");
127
128                 return;
129         }
130
131         if (__eglDisplay != EGL_NO_DISPLAY)
132         {
133                 eglTerminate(__eglDisplay);
134                 __eglDisplay = EGL_NO_DISPLAY;
135         }
136
137         __OpenGLInitialized = false;
138
139         SysLog(NID_UI_EFFECT, "OpenGL closed!");
140
141         return;
142 }
143
144 bool
145 EffectRenderer::CheckOpenGlesInitialized(void)
146 {
147         return __OpenGLInitialized;
148 }
149
150 EGLSurface
151 EffectRenderer::CreateSurface(EGLNativeWindowType wnd)
152 {
153         EGLSurface newsurface = eglCreateWindowSurface(__eglDisplay, __eglConfig, wnd, 0);
154
155         EGL_ASSERT_NOERRORS
156
157         SysTryReturn(NID_UI_EFFECT, newsurface != EGL_NO_SURFACE && CheckEglNoErrors(), EGL_NO_SURFACE, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Effects. There was an error while performing function eglCreateWindowSurface (EGL_NO_SURFACE)");
158
159         EGL_ASSERT_NOERRORS
160         return newsurface;
161 }
162
163 void
164 EffectRenderer::DeleteSurface(EGLSurface surface)
165 {
166         SysTryReturnVoidResult(NID_UI_EFFECT,  surface != EGL_NO_SURFACE, E_OPERATION_FAILED, "DeleteSurface EGL_NO_SURFACE");
167
168         eglDestroySurface(__eglDisplay, surface);
169
170         return;
171 }
172
173 EGLContext
174 EffectRenderer::CreateContext(EGLContext shareContext)
175 {
176         EGLContext newContext = eglCreateContext(__eglDisplay, __eglConfig, EGL_NO_CONTEXT, RENDERER_EGL_DEFAULT_CONTEXT_ATTRIBS);
177
178         SysTryReturn(NID_UI_EFFECT, newContext != EGL_NO_CONTEXT && CheckEglNoErrors(), EGL_NO_CONTEXT, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Effects. There was an error while performing function eglCreateContext (EGL_NO_CONTEXT)");
179         EGL_ASSERT_NOERRORS
180
181         return newContext;
182 }
183
184 void
185 EffectRenderer::DeleteContext(EGLContext context)
186 {
187         //SysTryLog(NID_UI_EFFECT,  context != EGL_NO_CONTEXT, "DeleteContext EGL_NO_CONTEXT");
188
189         eglDestroyContext(__eglDisplay, context);
190
191         return;
192 }
193
194 EffectRenderer::EffectRenderer(void)
195         : __previousContext(EGL_NO_CONTEXT)
196         , __previousContextSaved(false)
197         , __FOV_Y_deg(0.f)
198         , __perspectiveProjection(false)
199         , __renderDataScene(null)
200         , __pRenderDataSurfaceCollection(null)
201         , __dimensionPreviousControl()
202 {
203         result r = GetLastResult();
204         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
205
206         surface = EGL_NO_SURFACE;
207         __context = CreateContext();
208         r = GetLastResult();
209         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
210
211         __renderer = RenderPtr(new (std::nothrow) Render);
212         r = GetLastResult();
213         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
214         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(__renderer) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
215
216         __root = GroupPtr(new (std::nothrow) Group);
217         r = GetLastResult();
218         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
219         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(__root) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
220
221         __camera = CameraPtr(new (std::nothrow) Camera);
222         r = GetLastResult();
223         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
224         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(__camera) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
225
226         __camera->SetWorld(Math::Matrix4f().Identity());
227
228         StringShaderPropertyPtr vertex(new (std::nothrow) StringShaderProperty(ShaderProperty::ShaderType::VERTEX, EFFECT_VERTEX_SHADER_STR));
229         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(vertex) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
230
231         StringShaderPropertyPtr fragment(new (std::nothrow) StringShaderProperty(ShaderProperty::ShaderType::FRAGMENT, EFFECT_DUMMY_FRAGMENT_SHADER_STR));
232         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(fragment) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
233
234         __program = ShaderHolderProgramPropertyPtr(new (std::nothrow) ShaderHolderProgramProperty(vertex, fragment));
235         r = GetLastResult();
236         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
237         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(__program) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
238
239         __renderer->SetDefaultDepthTestState(true);
240 }
241
242 EffectRenderer::~EffectRenderer(void)
243 {
244         ReleaseCache();
245         DeleteContext(__context);
246 }
247
248 void
249 EffectRenderer::MakeCurrent(void)
250 {
251         SysAssertf(__eglDisplay != EGL_NO_DISPLAY, _UiEffectError::INTERNAL_ERROR);
252         SysAssertf(surface != EGL_NO_SURFACE, _UiEffectError::INTERNAL_ERROR);
253
254         if (!__previousContextSaved)
255         {
256                 __previousContext = eglGetCurrentContext();
257                 __previousContextSaved = true;
258         }
259
260         eglMakeCurrent(__eglDisplay, surface, surface, __context);
261
262         return;
263 }
264
265 void
266 EffectRenderer::RestorePreviousContext(void)
267 {
268         if (__previousContextSaved && __eglDisplay != EGL_NO_DISPLAY)
269         {
270                 if (__previousContext != EGL_NO_CONTEXT && surface != EGL_NO_SURFACE)
271                 {
272                         eglMakeCurrent(__eglDisplay, surface, surface, __previousContext);
273                 }
274                 else
275                 {
276                         eglMakeCurrent(__eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
277                 }
278         }
279
280         __previousContextSaved = false;
281
282         return;
283 }
284
285 MemoryTexture2DPropertyPtr
286 EffectRenderer::FindTexture(long bitmapID)
287 {
288         TexturesMap::const_iterator it = __textures.find(bitmapID);
289
290         if (it != __textures.end())
291         {
292                         return it->second;
293         }
294
295         //else (not found)
296         // create empty placeholder for further texture upload
297         MemoryTexture2DPropertyPtr tex = MemoryTexture2DPropertyPtr(new (std::nothrow) MemoryTexture2DProperty);
298
299         result r = GetLastResult();
300         SysTryReturn(NID_UI_EFFECT,  r == E_SUCCESS, tex, r, "[%s] Propagating.", GetErrorMessage(r));
301         SysTryReturn(NID_UI_EFFECT,  System::GetImpl(tex) != null, tex, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
302
303         __textures.insert(TexturesMap::value_type(bitmapID, tex));
304         return tex;
305 }
306
307 void
308 EffectRenderer::InitializeContext(void) const
309 {
310         glClearColor(0,0,0,1);
311         glDisable(GL_CULL_FACE);
312
313         return;
314 }
315
316 void
317 EffectRenderer::Construct(RenderDataScene &renderDataCollection)
318 {
319         __renderDataScene = &renderDataCollection;
320         __pRenderDataSurfaceCollection = &renderDataCollection.GetRenderDataSurfaceCollection();
321
322         Tizen::Ui::Effects::_Runtime::RenderDataSurfaceCollection::size_type objcount = __pRenderDataSurfaceCollection->size();
323
324         __root->Clear();// no deletion of children? check destructors
325         __root->AddChild(__camera);
326         __objects.clear();
327
328         ConstructLighting();
329         result r = GetLastResult();
330         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
331
332         __objects.resize(objcount);
333         for (RenderDataSurfaceCollection::size_type i = 0; i < objcount; ++i)
334         {
335                 __objects[i] = RendererObjectPtr(new (std::nothrow) RendererObject);
336
337                 result r = GetLastResult();
338                 SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
339                 SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(__objects[i]) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
340         }
341
342         for (RenderDataSurfaceCollection::size_type i = 0; i < objcount; ++i)
343         {
344                 InitRObjectFromData(i, *(*__pRenderDataSurfaceCollection)[i]);
345         }
346
347         return;
348 }
349
350 void
351 EffectRenderer::ConstructLighting()
352 {
353         SysAssertf(__renderDataScene != null, _UiEffectError::INTERNAL_ERROR);
354
355         __lightingParameters.SetAmbientColor(__renderDataScene->GetLightAmbientColour());
356         __lightingParameters.SetAmbientIntensity(__renderDataScene->GetLightIntensity());
357         __lightingParameters.SetAttenuation(__renderDataScene->GetLightAttenuation());
358
359         if (__renderDataScene->LockUnitsLightContainer())
360         {
361                 do
362                 {
363                         switch (__renderDataScene->GetTypeOfCurrentUnitLight())
364                         {
365                         case TYPE_UNIT_LIGHT_POINT:
366                         {
367                                 const _Runtime::PointLight* pModelPointLight = __renderDataScene->GetCurrentUnitLight<_Runtime::PointLight>();
368                                 if (pModelPointLight != null)
369                                 {
370                                         PointLightPtr pointLight = PointLightPtr(new (std::nothrow) PointLight(__lightingParameters.GetAttenuation()));
371                                         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(pointLight) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
372                                         __pointLights[pModelPointLight->GetName()] = pointLight;
373
374                                         pointLight->SetPosition(pModelPointLight->GetPosition());
375                                         pointLight->SetColor(pModelPointLight->GetColour());
376                                         pointLight->SetIntensity(pModelPointLight->GetIntensity());
377                                         pointLight->SetEnabled(pModelPointLight->GetEnabled());
378                                 }
379                         }
380                         break;
381                         case TYPE_UNIT_LIGHT_SPOT:
382                         {
383                                 const _Runtime::SpotLight* pModelSpotLight = __renderDataScene->GetCurrentUnitLight<_Runtime::SpotLight>();
384                                 if (pModelSpotLight != null)
385                                 {
386                                         SpotLightPtr spotLight = SpotLightPtr(new (std::nothrow) SpotLight(__lightingParameters.GetAttenuation()));
387                                         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(spotLight) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
388                                         __spotLights[pModelSpotLight->GetName()] = spotLight;
389
390                                         spotLight->SetPosition(pModelSpotLight->GetPosition());
391                                         spotLight->SetTarget(pModelSpotLight->GetTarget());
392                                         spotLight->SetOpeningAngle(pModelSpotLight->GetAngleOpening());
393                                         spotLight->SetFadeOutAngle(pModelSpotLight->GetAngleFadeOut());
394                                         spotLight->SetColor(pModelSpotLight->GetColour());
395                                         spotLight->SetIntensity(pModelSpotLight->GetIntensity());
396                                         spotLight->SetEnabled(pModelSpotLight->GetEnabled());
397                                 }
398                         }
399                         break;
400                         case TYPE_UNIT_LIGHT_DIRECTIONAL:
401                         {
402                                 const _Runtime::DirectionalLight* pModelDirectionalLight = __renderDataScene->GetCurrentUnitLight<_Runtime::DirectionalLight>();
403                                 if (pModelDirectionalLight != null)
404                                 {
405                                         DirectionalLightPtr directionalLight = DirectionalLightPtr(new (std::nothrow) DirectionalLight);
406                                         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(directionalLight) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
407                                         __directionalLights[pModelDirectionalLight->GetName()] = directionalLight;
408
409                                 directionalLight->SetDirection(pModelDirectionalLight->GetDirection());
410                                 directionalLight->SetColor(pModelDirectionalLight->GetColour());
411                                 directionalLight->SetIntensity(pModelDirectionalLight->GetIntensity());
412                                 directionalLight->SetEnabled(pModelDirectionalLight->GetEnabled());
413                                 }
414                         }
415                         break;
416                         default:
417                                 break;
418                         }
419                 }
420                 while (__renderDataScene->GoToNextUnitLight());
421         }
422
423         CreateShader();
424
425         return;
426 }
427
428 void
429 EffectRenderer::UpdateLighting(void)
430 {
431         SysAssertf(__renderDataScene != null, _UiEffectError::INTERNAL_ERROR);
432
433         bool updated = false;
434         bool needShaderCompilation = false;
435
436         if (__renderDataScene->isSomethingChanged)
437         {
438                 updated = true;
439
440                 if (__renderDataScene->isAmbientColourChanged)
441                 {
442                         __lightingParameters.SetAmbientColor(__renderDataScene->GetLightAmbientColour());
443                         __renderDataScene->isAmbientColourChanged = false;
444                 }
445
446                 if (__renderDataScene->isIntensityChanged)
447                 {
448                         __lightingParameters.SetAmbientIntensity(__renderDataScene->GetLightIntensity());
449                         __renderDataScene->isIntensityChanged = false;
450                 }
451
452                 if (__renderDataScene->isAttenuationChanged)
453                 {
454                         __lightingParameters.SetAttenuation(__renderDataScene->GetLightAttenuation());
455
456                         for (PointLightsList::iterator it = __pointLights.begin(); it != __pointLights.end(); ++it)
457                         {
458                                 it->second->UpdateAttenuation();
459                         }
460
461                         for (SpotLightsList::iterator it = __spotLights.begin(); it != __spotLights.end(); ++it)
462                         {
463                                 it->second->UpdateAttenuation();
464                         }
465
466                         __renderDataScene->isAttenuationChanged = false;
467                 }
468                 __renderDataScene->isSomethingChanged = false;
469         }
470
471         if (__renderDataScene->LockUnitsLightContainer())
472         {
473                 do
474                 {
475                         const _Runtime::UnitLight *pLight = __renderDataScene->GetCurrentUnitLight<_Runtime::UnitLight>();
476                         updated = updated || pLight->isSomethingChanged;
477
478                         if (pLight->isSomethingChanged)
479                         {
480                                 string nameUnitLight = pLight->GetName();
481
482                                 switch (pLight->GetType())
483                                 {
484                                 case TYPE_UNIT_LIGHT_POINT:
485                                 {
486                                         const _Runtime::PointLight* pModelPointLight = static_cast<const _Runtime::PointLight*>(pLight);
487                                         PointLight *pPointLight = System::GetImpl(__pointLights[nameUnitLight]);
488
489                                         if (pModelPointLight->isPositionChanged)
490                                         {
491                                                 pPointLight->SetPosition(pModelPointLight->GetPosition());
492                                         }
493
494                                         if (pModelPointLight->isColourChanged)
495                                         {
496                                                 pPointLight->SetColor(pModelPointLight->GetColour());
497                                         }
498
499                                         if (pModelPointLight->isIntensityChanged)
500                                         {
501                                                 pPointLight->SetIntensity(pModelPointLight->GetIntensity());
502                                         }
503
504                                         if (pModelPointLight->isEnabledChanged)
505                                         {
506                                                 needShaderCompilation = true;
507                                                 pPointLight->SetEnabled(pModelPointLight->GetEnabled());
508                                         }
509
510                                 }
511                                 break;
512                                 case TYPE_UNIT_LIGHT_SPOT:
513                                 {
514                                         const _Runtime::SpotLight* pModelSpotLight = static_cast<const _Runtime::SpotLight*>(pLight);
515                                         SpotLight *pSpotLight = System::GetImpl(__spotLights[nameUnitLight]);
516
517                                         if (pModelSpotLight->isPositionChanged)
518                                         {
519                                                 pSpotLight->SetPosition(pModelSpotLight->GetPosition());
520                                         }
521
522                                         if (pModelSpotLight->isTargetChanged)
523                                         {
524                                                 pSpotLight->SetTarget(pModelSpotLight->GetTarget());
525                                         }
526
527                                         if (pModelSpotLight->isAngleOpeningChanged)
528                                         {
529                                                 pSpotLight->SetOpeningAngle(pModelSpotLight->GetAngleOpening());
530                                         }
531
532                                         if (pModelSpotLight->isAngleFadeOutChanged)
533                                         {
534                                                 pSpotLight->SetFadeOutAngle(pModelSpotLight->GetAngleFadeOut());
535                                         }
536
537                                         if (pModelSpotLight->isColourChanged)
538                                         {
539                                                 pSpotLight->SetColor(pModelSpotLight->GetColour());
540                                         }
541
542                                         if (pModelSpotLight->isIntensityChanged)
543                                         {
544                                                 pSpotLight->SetIntensity(pModelSpotLight->GetIntensity());
545                                         }
546
547                                         if (pModelSpotLight->isEnabledChanged)
548                                         {
549                                                 needShaderCompilation = true;
550                                                 pSpotLight->SetEnabled(pModelSpotLight->GetEnabled());
551                                         }
552                                 }
553                                 break;
554                                 case TYPE_UNIT_LIGHT_DIRECTIONAL:
555                                 {
556                                         const _Runtime::DirectionalLight* pModelDirectionalLight = static_cast<const _Runtime::DirectionalLight*>(pLight);
557                                         DirectionalLight *pDirectionalLight = System::GetImpl(__directionalLights[nameUnitLight]);
558
559                                         if (pModelDirectionalLight->isDirectionChanged)
560                                         {
561                                                 pDirectionalLight->SetDirection(pModelDirectionalLight->GetDirection());
562                                         }
563
564                                         if (pModelDirectionalLight->isColourChanged)
565                                         {
566                                                 pDirectionalLight->SetColor(pModelDirectionalLight->GetColour());
567                                         }
568
569                                         if (pModelDirectionalLight->isIntensityChanged)
570                                         {
571                                                 pDirectionalLight->SetIntensity(pModelDirectionalLight->GetIntensity());
572                                         }
573
574                                         if (pModelDirectionalLight->isEnabledChanged)
575                                         {
576                                                 needShaderCompilation = true;
577                                                 pDirectionalLight->SetEnabled(pModelDirectionalLight->GetEnabled());
578                                         }
579                                 }
580                                 break;
581                                 default:
582                                         break;
583                                 } // switch
584
585                                 __renderDataScene->ResetSignsCurrentUnitLight();
586
587                         } // if (flags != 0)
588                 }
589                 while (__renderDataScene->GoToNextUnitLight());
590
591                 if (updated)
592                 {
593                         if (needShaderCompilation)
594                         {
595                                 CreateShader();
596                         }
597
598                         std::vector<RendererObjectPtr>::size_type n = __objects.size();
599                         for (std::vector<RendererObjectPtr>::size_type i = 0; i < n; ++i)
600                         {
601                                 __objects[i]->GetMaterial()->TouchDrawables();
602                                 __objects[i]->InvalidateCache();
603                         }
604                 }
605         }
606
607         return;
608 }
609
610 void
611 EffectRenderer::CreateShader()
612 {
613         string __fragmentSource = EFFECT_FRAGMENT_SHADER_STR;
614
615
616         if (__pointLights.size() > 0)
617         {
618                 char buffer [30];
619                 string def_entry;
620                 string src_entry;
621
622                 string::size_type defpos = __fragmentSource.find(POINTLIGHT_DEFPOS_STR);
623                 string::size_type srcpos = __fragmentSource.find(POINTLIGHT_SRCPOS_STR);
624
625                 SysAssert(defpos != string::npos);
626                 SysAssert(srcpos != string::npos);
627
628                 int i = 0;
629
630                 for (PointLightsList::const_iterator it = __pointLights.begin(); it != __pointLights.end(); ++it)
631                 {
632                         if (!it->second->GetEnabled())
633                         {
634                                 continue;
635                         }
636
637                         def_entry = POINTLIGHT_DEF_STR;
638                         sprintf(buffer, "%d", i);
639                         replace(def_entry, "%n", buffer);
640                         __fragmentSource.insert(defpos, def_entry);
641                         defpos += def_entry.length();
642                         srcpos += def_entry.length();
643
644                         src_entry = it->second->IsBlack()?  POINTLIGHT_NOATTSRC_STR : POINTLIGHT_ATTSRC_STR;
645                         sprintf(buffer, "%d", i);
646                         replace(src_entry, "%n", buffer);
647                         __fragmentSource.insert(srcpos, src_entry);
648                         srcpos += src_entry.length();
649
650                         i++;
651                 }
652         }
653
654         if (__spotLights.size() > 0)
655         {
656                 char buffer [30];
657                 string def_entry;
658                 string src_entry;
659
660                 string::size_type defpos = __fragmentSource.find(SPOTLIGHT_DEFPOS_STR);
661                 string::size_type srcpos = __fragmentSource.find(SPOTLIGHT_SRCPOS_STR);
662
663                 SysAssert(defpos != string::npos);
664                 SysAssert(srcpos != string::npos);
665
666                 int i = 0;
667
668                 for (SpotLightsList::const_iterator it = __spotLights.begin(); it != __spotLights.end(); ++it)
669                 {
670                         if (!it->second->GetEnabled())
671                         {
672                                 continue;
673                         }
674
675                         def_entry = SPOTLIGHT_DEF_STR;
676                         sprintf(buffer, "%d", i);
677                         replace(def_entry, "%n", buffer);
678                         __fragmentSource.insert(defpos, def_entry);
679                         defpos += def_entry.length();
680                         srcpos += def_entry.length();
681
682                         src_entry = it->second->IsBlack()?  SPOTLIGHT_NOATTSRC_STR : SPOTLIGHT_ATTSRC_STR;
683                         sprintf(buffer, "%d", i);
684                         replace(src_entry, "%n", buffer);
685                         __fragmentSource.insert(srcpos, src_entry);
686                         srcpos += src_entry.length();
687
688                         i++;
689                 }
690         }
691
692         if (__directionalLights.size() > 0)
693         {
694                 char buffer [30];
695                 string def_entry;
696                 string src_entry;
697
698                 string::size_type defpos = __fragmentSource.find(DIRECTIOALLIGHT_DEFPOS_STR);
699                 string::size_type srcpos = __fragmentSource.find(DIRECTIOALLIGHT_SRCPOS_STR);
700
701                 SysAssert(defpos != string::npos);
702                 SysAssert(srcpos != string::npos);
703
704                 int i = 0;
705
706                 for (DirectionalLightsList::const_iterator it = __directionalLights.begin(); it != __directionalLights.end(); ++it)
707                 {
708                         if (!it->second->GetEnabled())
709                         {
710                                 continue;
711                         }
712
713                         def_entry = DIRECTIOALLIGHT_DEF_STR;
714                         sprintf(buffer, "%d", i);
715                         replace(def_entry, "%n", buffer);
716                         __fragmentSource.insert(defpos, def_entry);
717                         defpos += def_entry.length();
718                         srcpos += def_entry.length();
719
720                         src_entry = DIRECTIOALLIGHT_SRC_STR;
721                         sprintf(buffer, "%d", i);
722                         replace(src_entry, "%n", buffer);
723                         __fragmentSource.insert(srcpos, src_entry);
724                         srcpos += src_entry.length();
725
726                         i++;
727                 }
728         }
729
730         __program->GetShader(EngineModel::ShaderProperty::ShaderType::FRAGMENT).staticCast<StringShaderProperty>()->SetSource(__fragmentSource);
731         if (System::GetImpl(__program->GetCache()) != null)
732         {
733                 __program->GetCache()->Invalidate();
734         }
735
736         PRINT_DEBUG("Shader ", __fragmentSource);
737
738         return;
739 }
740
741 void
742 EffectRenderer::InitRObjectFromData(RenderDataSurfaceCollection::size_type index, RenderDataSurface &rdata)
743 {
744         SysAssertf(index < __objects.size(), "Effects. Renderer: index < __objects.size()");
745
746         __objects[index]->opacity->Set(1.0f - rdata.transparency);
747         __objects[index]->alphablend->Enable(rdata.transparency > 0.0f);
748
749         __objects[index]->GetMat()->AddProperty("Lib Effects Rendering Program",  __program);
750         __objects[index]->GetMat()->AddProperty(MAIN_TEX_STR, FindTexture(rdata.bitmapId));
751         __objects[index]->GetMat()->AddProperty(LIGHTING_AMBIENTCOLORI_STR, __lightingParameters.GetAmbientColorIHolder());
752
753         char buffer [30];
754
755         int i = 0;
756         for(PointLightsList::const_iterator it = __pointLights.begin(); it != __pointLights.end(); ++it)
757         {
758                 sprintf(buffer, "%d", i);
759
760                 __objects[index]->GetMat()->AddProperty((string(POINTLIGHT_STR) + buffer + POINTLIGHT_POSITION_STR).c_str(), (*it).second->GetPositionHolder());
761                 __objects[index]->GetMat()->AddProperty((string(POINTLIGHT_STR) + buffer + POINTLIGHT_COLORI_STR).c_str(), (*it).second->GetColorIHolder());
762                 __objects[index]->GetMat()->AddProperty((string(POINTLIGHT_STR) + buffer + POINTLIGHT_RK_STR).c_str(), (*it).second->GetRkHolder());
763
764                 i++;
765         }
766
767         i = 0;
768         for (DirectionalLightsList::const_iterator it = __directionalLights.begin(); it != __directionalLights.end(); ++it)
769         {
770                 sprintf(buffer, "%d", i);
771
772                 __objects[index]->GetMat()->AddProperty((string(DIRECTIOALLIGHT_STR) + buffer + DIRECTIOALLIGHT_DIRECTION_STR).c_str(), (*it).second->GetDirectionHolder());
773                 __objects[index]->GetMat()->AddProperty((string(DIRECTIOALLIGHT_STR) + buffer + DIRECTIOALLIGHTLIGHT_COLORI_STR).c_str(), (*it).second->GetColorIHolder());
774
775                 i++;
776         }
777
778         i = 0;
779         for (SpotLightsList::const_iterator it = __spotLights.begin(); it != __spotLights.end(); ++it)
780         {
781                 sprintf(buffer, "%d", i);
782
783                 __objects[index]->GetMat()->AddProperty((string(SPOTLIGHT_STR) + buffer + SPOTLIGHT_POSITION_STR).c_str(), (*it).second->GetPositionHolder());
784                 __objects[index]->GetMat()->AddProperty((string(SPOTLIGHT_STR) + buffer + SPOTLIGHT_DIRECTION_STR).c_str(), (*it).second->GetDirectionHolder());
785                 __objects[index]->GetMat()->AddProperty((string(SPOTLIGHT_STR) + buffer + SPOTLIGHT_K1_STR).c_str(), (*it).second->GetK1Holder());
786                 __objects[index]->GetMat()->AddProperty((string(SPOTLIGHT_STR) + buffer + SPOTLIGHT_K2_STR).c_str(), (*it).second->GetK2Holder());
787                 __objects[index]->GetMat()->AddProperty((string(SPOTLIGHT_STR) + buffer + SPOTLIGHT_COLORI_STR).c_str(), (*it).second->GetColorIHolder());
788                 __objects[index]->GetMat()->AddProperty((string(SPOTLIGHT_STR) + buffer + SPOTLIGHT_RK_STR).c_str(), (*it).second->GetRkHolder());
789
790                 i++;
791         }
792
793         RendererGeometryPtr geom(new (std::nothrow) RendererGeometry);
794         result r = GetLastResult();
795         SysTryReturnVoidResult(NID_UI_EFFECT, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
796         SysTryReturnVoidResult(NID_UI_EFFECT, System::GetImpl(geom) != null, E_OUT_OF_MEMORY, _UiEffectError::OUT_OF_MEMORY);
797
798         __objects[index]->setGeometry(geom);
799
800         __objects[index]->GetGeom()->SetVertData(rdata.vnt);
801         __objects[index]->GetGeom()->SetIndices(rdata.indices);
802
803         __objects[index]->modelMtr->Set(Math::Matrix4f(rdata.modelMtr[0], rdata.modelMtr[4], rdata.modelMtr[8], rdata.modelMtr[12],
804                                                                      rdata.modelMtr[1], rdata.modelMtr[5], rdata.modelMtr[9], rdata.modelMtr[13],
805                                                                      rdata.modelMtr[2], rdata.modelMtr[6], rdata.modelMtr[10], rdata.modelMtr[14],
806                                                                      rdata.modelMtr[3], rdata.modelMtr[7], rdata.modelMtr[11], rdata.modelMtr[15]));
807
808         Math::Matrix4f tmpNormalMtr(Math::Matrix4f::GetIdentity());
809         __objects[index]->normalMtr->Set(tmpNormalMtr.SetRotation(__objects[index]->modelMtr->Get().GetRotation().Inverse())); // ".transpose()" is omitted due to "column order" matrix representation in GLSL
810
811         __root->AddChild(__objects[index]);
812
813         return;
814 }
815
816 void
817 EffectRenderer::Update(void)
818 {
819
820         std::unique_ptr<int> x;
821
822         SysAssertf(__renderDataScene != null, _UiEffectError::INTERNAL_ERROR);
823         SysAssertf(__pRenderDataSurfaceCollection != null, _UiEffectError::INTERNAL_ERROR);
824         SysAssertf(__objects.size() == __pRenderDataSurfaceCollection->size(), _UiEffectError::INTERNAL_ERROR);
825
826         Tizen::Ui::Effects::_Runtime::RenderDataSurfaceCollection::size_type objcount = __pRenderDataSurfaceCollection->size();
827
828         for (RenderDataSurfaceCollection::size_type i = 0; i < objcount; ++i)
829         {
830                 UpdateRObject(i, *(*__pRenderDataSurfaceCollection)[i]);
831         }
832
833         UpdateLighting();
834
835         return;
836 }
837
838 void
839 EffectRenderer::UpdateRObject(RenderDataSurfaceCollection::size_type index, RenderDataSurface &rdata)
840 {
841         if (rdata.vertexDataChanged || rdata.indicesChanged)
842         {
843                 RendererGeometryPtr geometry = __objects[index]->GetGeom();
844
845                 if (rdata.vertexDataChanged)
846                 {
847                         geometry->InvalidateVertexData();
848                         rdata.vertexDataChanged = false;
849                 }
850
851                 if (rdata.indicesChanged)
852                 {
853                         geometry->InvalidateIndices();
854                         rdata.indicesChanged = false;
855                 }
856
857                 geometry->TouchDrawables();
858         }
859
860         if (rdata.modelMtrChanged)
861         {
862                 __objects[index]->modelMtr->Set(Math::Matrix4f(rdata.modelMtr[0], rdata.modelMtr[4], rdata.modelMtr[8], rdata.modelMtr[12],
863                                                                              rdata.modelMtr[1], rdata.modelMtr[5], rdata.modelMtr[9], rdata.modelMtr[13],
864                                                                              rdata.modelMtr[2], rdata.modelMtr[6], rdata.modelMtr[10], rdata.modelMtr[14],
865                                                                              rdata.modelMtr[3], rdata.modelMtr[7], rdata.modelMtr[11], rdata.modelMtr[15]));
866
867                 Math::Matrix4f tmpNormalMtr(Math::Matrix4f::GetIdentity());
868
869                 __objects[index]->normalMtr->Set(tmpNormalMtr.SetRotation(__objects[index]->modelMtr->Get().GetRotation().Inverse())); // ".transpose()" is omitted due to "column order" matrix representation in GLSL
870                 __objects[index]->InvalidateCache();
871                 rdata.modelMtrChanged = false;
872         }
873
874         if (rdata.bitmapIdChanged || rdata.transparencyChanged)
875         {
876                 PropertyHolderMaterialPtr material = __objects[index]->GetMat();
877
878                 if (rdata.bitmapIdChanged)
879                 {
880                         material->AddProperty(MAIN_TEX_STR,  FindTexture(rdata.bitmapId));
881                         rdata.bitmapIdChanged = false;
882                 }
883
884                 if (rdata.transparencyChanged)
885                 {
886                         __objects[index]->opacity->Set(1.0f - rdata.transparency);
887                         __objects[index]->alphablend->Enable(rdata.transparency > 0.0f);
888                         rdata.transparencyChanged = false;
889                 }
890
891                 material->TouchDrawables();
892         }
893
894         return;
895 }
896
897 void
898 EffectRenderer::Draw(void)
899 {
900         SysAssertf(__eglDisplay != EGL_NO_DISPLAY, _UiEffectError::INTERNAL_ERROR);
901         SysAssertf(surface != EGL_NO_SURFACE, _UiEffectError::INTERNAL_ERROR);
902         SysAssertf(__context != EGL_NO_CONTEXT, _UiEffectError::INTERNAL_ERROR);
903
904         MakeCurrent();
905         InitializeContext();
906         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
907         __renderer->Draw(*__root);
908         eglSwapBuffers(__eglDisplay, surface);
909
910         RestorePreviousContext();
911
912         return;
913 }
914
915 void
916 EffectRenderer::SetScreen(float screenLeft, float screenRight, float screenBottom, float screenTop, int displayWidth, int displayHeight)
917 {
918         SysAssertf(screenRight > screenLeft, _UiEffectError::INTERNAL_ERROR);
919         SysAssertf(screenTop < screenBottom, _UiEffectError::INTERNAL_ERROR);
920         SysAssertf(displayWidth > 0, _UiEffectError::INTERNAL_ERROR);
921         SysAssertf(displayHeight > 0, _UiEffectError::INTERNAL_ERROR);
922
923         __viewport.screenLeft = screenLeft;
924         __viewport.screenRight = screenRight;
925         __viewport.screenTop = screenTop;
926         __viewport.screenBottom = screenBottom;
927         __viewport.displayWidth = displayWidth;
928         __viewport.displayHeight = displayHeight;
929
930         __camera->SetViewport(Vector2f(0,0), Vector2f(displayWidth, displayHeight));
931
932         return;
933 }
934
935 void
936 EffectRenderer::TrackScreenSizeChanges(const Control& control)
937 {
938         if (__dimensionPreviousControl != control.GetSize())
939         {
940                 SetScreen(control);
941         }
942         return;
943 }
944
945 void
946 EffectRenderer::SetScreen(const Control& control)
947 {
948         Dimension logicalScreenSizeCurrent = control.GetSize();                         // not real but logical size of control
949         Dimension realScreenSize = _CoordinateSystemUtils::Transform(logicalScreenSizeCurrent);                 // real size of control
950         SetScreen(0, logicalScreenSizeCurrent.width, logicalScreenSizeCurrent.height, 0, realScreenSize.width, realScreenSize.height);
951         __dimensionPreviousControl = logicalScreenSizeCurrent;
952         return;
953 }
954
955 bool
956 EffectRenderer::SetWorld(float worldLeft, float worldRight, float worldBottom, float worldTop, float worldZ, float worldNearDist, float worldFarDist, float FOV_Y_deg, bool perspectiveProjection)
957 {
958         SysAssertf(fabs(worldLeft - worldRight) > std::numeric_limits<float>::epsilon(), _UiEffectError::INTERNAL_ERROR);
959         SysAssertf(fabs(worldTop - worldBottom) > std::numeric_limits<float>::epsilon(), _UiEffectError::INTERNAL_ERROR);
960         SysAssertf(FOV_Y_deg < 180.0f && FOV_Y_deg > 0.0f, _UiEffectError::INTERNAL_ERROR);
961         SysAssertf(worldNearDist > 0.0f && worldFarDist > 0.0f && worldNearDist < worldFarDist, _UiEffectError::INTERNAL_ERROR);
962
963         __viewport.worldLeft = worldLeft;
964         __viewport.worldRight = worldRight;
965         __viewport.worldTop = worldTop;
966         __viewport.worldBottom = worldBottom;
967         __viewport.worldZ = worldZ;
968         __viewport.worldNearDist = worldNearDist;
969         __viewport.worldFarDist = worldFarDist;
970
971         __FOV_Y_deg = FOV_Y_deg;
972         __perspectiveProjection = perspectiveProjection;
973
974         Math::Matrix4f tmpmat;
975
976         if (__perspectiveProjection)
977         {
978                 float cameraHeight = (__viewport.worldTop - __viewport.worldBottom) / 2 / tan(Math::F_Deg_2_Rad(__FOV_Y_deg)/2.0f) + __viewport.worldZ;
979
980                 tmpmat = Math::Matrix4f::CreatePerspectiveFovRH(Math::F_Deg_2_Rad(__FOV_Y_deg), (__viewport.worldRight - __viewport.worldLeft) / (__viewport.worldTop - __viewport.worldBottom), __viewport.worldNearDist, __viewport.worldFarDist);
981                 tmpmat.data[1].data[1] = -tmpmat.data[1].data[1];
982                 __camera->SetProj(tmpmat);
983
984                 tmpmat = Math::Matrix4f::GetIdentity();
985                 tmpmat.SetTranslation((__viewport.worldRight + __viewport.worldLeft) / 2, (__viewport.worldTop + __viewport.worldBottom) / 2, cameraHeight);
986                 __camera->SetWorld(tmpmat);
987         }
988         else
989         {
990                 tmpmat = Math::Matrix4f::GetIdentity();
991                 __camera->SetWorld(tmpmat);
992
993                 tmpmat = Math::Matrix4f::CreateOrthoRH(__viewport.worldLeft, __viewport.worldRight, __viewport.worldBottom, __viewport.worldTop, -__viewport.worldFarDist, __viewport.worldFarDist);
994                 __camera->SetProj(tmpmat);
995         }
996
997         return true;
998 }
999
1000 Tizen::Ui::Effects::_Utils::Vec3f
1001 EffectRenderer::TransformScreenToWorld(Tizen::Ui::Effects::_Utils::Vec2f p) const
1002 {
1003         return __viewport.TransformScreenToWorld(p);
1004 }
1005
1006 bool
1007 EffectRenderer::SetBitmap(long bitmapID, Tizen::Graphics::Bitmap &bitmap)
1008 {
1009         MemoryTexture2DPropertyPtr tex = FindTexture(bitmapID);
1010         Tizen::Graphics::_BitmapImpl* pBitmapImpl = Tizen::Graphics::_BitmapImpl::GetInstance(bitmap);
1011         BufferInfo bufferInfo;
1012
1013         SysTryReturn(NID_UI_EFFECT, pBitmapImpl != null, false, E_OPERATION_FAILED, "[E_OPERATION_FAILED] _BitmapImpl::GetInstance has returned null value");
1014
1015         PROFILER_EXPR(pBitmapImpl->LockFast(bufferInfo);, PROFLOG_Lock);
1016
1017         if (bufferInfo.pPixels == null || bufferInfo.width <= 0 || bufferInfo.height <= 0)
1018         {
1019                 bitmap.Unlock();
1020                 return false;
1021         }
1022
1023         PROFILER_EXPR(tex->SetData((void*) bufferInfo.pPixels, bufferInfo.width, bufferInfo.height);, PROFLOG_Setdata);
1024         PROFILER_EXPR(pBitmapImpl->UnlockFast();, PROFLOG_Unlock);
1025
1026         return true;
1027 }
1028
1029 bool
1030 EffectRenderer::SetBitmap(long bitmapID, const void* ptr, size_t width, size_t height)
1031 {
1032         //ptr = null is OK for texture memory allocation
1033         FindTexture(bitmapID)->SetData(ptr, width, height);
1034
1035         return true;
1036 }
1037
1038 void EffectRenderer::BuildCache()
1039 {
1040         MakeCurrent();
1041         __renderer->InternalCollectInfo(*__root);
1042         RestorePreviousContext();
1043 }
1044
1045 void EffectRenderer::ReleaseCache()
1046 {
1047         if (surface != EGL_NO_SURFACE)
1048         {
1049                 MakeCurrent();
1050                 Reset(__renderer);
1051                 RestorePreviousContext();
1052         }
1053 }
1054
1055 }}}} //Tizen::Ui::Effects::_Renderer