[dali_1.4.29] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / bloom-view / bloom-view-impl.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 "bloom-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <sstream>
23 #include <iomanip>
24 #include <dali/public-api/animation/constraint.h>
25 #include <dali/public-api/animation/constraints.h>
26 #include <dali/public-api/common/stage.h>
27 #include <dali/public-api/object/property-map.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30 #include <dali/public-api/render-tasks/render-task-list.h>
31 #include <dali/public-api/rendering/renderer.h>
32
33 // INTERNAL INCLUDES
34 #include <dali-toolkit/devel-api/controls/gaussian-blur-view/gaussian-blur-view.h>
35 #include <dali-toolkit/devel-api/controls/bloom-view/bloom-view.h>
36 #include <dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.h>
37 #include <dali-toolkit/internal/controls/control/control-renderers.h>
38
39 namespace Dali
40 {
41
42 namespace Toolkit
43 {
44
45 namespace Internal
46 {
47
48 namespace
49 {
50
51 using namespace Dali;
52
53 BaseHandle Create()
54 {
55   return Toolkit::BloomView::New();
56 }
57
58 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::BloomView, Toolkit::Control, Create )
59 DALI_TYPE_REGISTRATION_END()
60
61 // default parameters
62 const float BLOOM_THRESHOLD_DEFAULT = 0.25f;
63 const float BLOOM_BLUR_STRENGTH_DEFAULT = 1.0f;
64 const float BLOOM_INTENSITY_DEFAULT = 1.0f;
65 const float IMAGE_INTENSITY_DEFAULT = 1.0f;
66 const float BLOOM_SATURATION_DEFAULT = 1.0f;
67 const float IMAGE_SATURATION_DEFAULT = 1.0f;
68
69 // gaussian blur
70 const unsigned int BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_NUM_SAMPLES = 5;
71 const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_BELL_CURVE_WIDTH = 1.5f;
72 const Pixel::Format BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_RENDER_TARGET_PIXEL_FORMAT = Pixel::RGBA8888;
73 const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_FADE_IN = 1.0f;                                       // default, fully blurred
74 const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_WIDTH_SCALE = 0.5f;
75 const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_HEIGHT_SCALE = 0.5f;
76
77 const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
78
79 const char* const BLOOM_BLUR_STRENGTH_PROPERTY_NAME = "BlurStrengthProperty";
80 const char* const BLOOM_THRESHOLD_PROPERTY_NAME = "uBloomThreshold";
81 const char* const RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME = "uRecipOneMinusBloomThreshold";
82 const char* const BLOOM_INTENSITY_PROPERTY_NAME = "uBloomIntensity";
83 const char* const BLOOM_SATURATION_PROPERTY_NAME = "uBloomSaturation";
84 const char* const IMAGE_INTENSITY_PROPERTY_NAME = "uImageIntensity";
85 const char* const IMAGE_SATURATION_PROPERTY_NAME = "uImageSaturation";
86
87 ///////////////////////////////////////////////////////
88 //
89 // Bloom shaders
90 //
91
92 const char* const BLOOM_EXTRACT_FRAGMENT_SOURCE =
93   "varying mediump vec2 vTexCoord;\n"
94   "uniform sampler2D sTexture;\n"
95   "uniform lowp vec4 uColor;\n"
96   "uniform mediump float uBloomThreshold;\n"
97   "uniform mediump float uRecipOneMinusBloomThreshold;\n"
98   "void main()\n"
99   "{\n"
100   "  mediump vec4 col;\n"
101   "  col = texture2D(sTexture, vTexCoord);\n"
102   "  col = (col - uBloomThreshold) * uRecipOneMinusBloomThreshold;\n" // remove intensities lower than the thresold and remap intensities above the threshold to [0..1]
103   "  gl_FragColor = clamp(col, 0.0, 1.0);\n"
104   "}\n";
105
106 const char* const COMPOSITE_FRAGMENT_SOURCE =
107   "precision mediump float;\n"
108   "varying mediump vec2 vTexCoord;\n"
109   "uniform sampler2D sTexture;\n"
110   "uniform sampler2D sEffect;\n"
111   "uniform lowp vec4 uColor;\n"
112   "uniform float uBloomIntensity;\n"
113   "uniform float uImageIntensity;\n"
114   "uniform float uBloomSaturation;\n"
115   "uniform float uImageSaturation;\n"
116
117   "vec4 ChangeSaturation(vec4 col, float sat)\n"
118   "{\n"
119   "  float grey = dot(col.rgb, vec3(0.3, 0.6, 0.1));\n"
120   "  return mix(vec4(grey, grey, grey, 1.0), col, sat);\n"
121   "}\n"
122
123   "void main()\n"
124   "{\n"
125   "  mediump vec4 image;\n"
126   "  mediump vec4 bloom;\n"
127   "  image = texture2D(sTexture, vTexCoord);\n"
128   "  bloom = texture2D(sEffect, vTexCoord);\n"
129   "  image = ChangeSaturation(image, uImageSaturation) * uImageIntensity;\n"
130   "  bloom = ChangeSaturation(bloom, uBloomSaturation) * uBloomIntensity;\n"
131   "  image *= 1.0 - clamp(bloom, 0.0, 1.0);\n" // darken base where bloom is strong, to prevent excessive burn-out of result
132   "  gl_FragColor = image + bloom;\n"
133   "}\n";
134
135 } // namespace
136
137
138
139 BloomView::BloomView()
140 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
141   mBlurNumSamples(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_NUM_SAMPLES),
142   mBlurBellCurveWidth(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_BELL_CURVE_WIDTH),
143   mPixelFormat(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_RENDER_TARGET_PIXEL_FORMAT),
144   mDownsampleWidthScale(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_WIDTH_SCALE),
145   mDownsampleHeightScale(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_HEIGHT_SCALE),
146   mDownsampledWidth( 0.0f ),
147   mDownsampledHeight( 0.0f ),
148   mTargetSize(Vector2::ZERO),
149   mLastSize(Vector2::ZERO),
150   mChildrenRoot(Actor::New()),
151   mInternalRoot(Actor::New() ),
152   mBloomThresholdPropertyIndex(Property::INVALID_INDEX),
153   mBlurStrengthPropertyIndex(Property::INVALID_INDEX),
154   mBloomIntensityPropertyIndex(Property::INVALID_INDEX),
155   mBloomSaturationPropertyIndex(Property::INVALID_INDEX),
156   mImageIntensityPropertyIndex(Property::INVALID_INDEX),
157   mImageSaturationPropertyIndex(Property::INVALID_INDEX),
158   mActivated( false )
159 {
160 }
161
162 BloomView::BloomView( const unsigned int blurNumSamples, const float blurBellCurveWidth, const Pixel::Format renderTargetPixelFormat,
163                                     const float downsampleWidthScale, const float downsampleHeightScale)
164 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
165   mBlurNumSamples(blurNumSamples),
166   mBlurBellCurveWidth(blurBellCurveWidth),
167   mPixelFormat(renderTargetPixelFormat),
168   mDownsampleWidthScale(downsampleWidthScale),
169   mDownsampleHeightScale(downsampleHeightScale),
170   mDownsampledWidth( 0.0f ),
171   mDownsampledHeight( 0.0f ),
172   mTargetSize(Vector2::ZERO),
173   mLastSize(Vector2::ZERO),
174   mChildrenRoot(Actor::New()),
175   mInternalRoot(Actor::New()),
176   mBloomThresholdPropertyIndex(Property::INVALID_INDEX),
177   mBlurStrengthPropertyIndex(Property::INVALID_INDEX),
178   mBloomIntensityPropertyIndex(Property::INVALID_INDEX),
179   mBloomSaturationPropertyIndex(Property::INVALID_INDEX),
180   mImageIntensityPropertyIndex(Property::INVALID_INDEX),
181   mImageSaturationPropertyIndex(Property::INVALID_INDEX),
182   mActivated( false )
183 {
184 }
185
186 BloomView::~BloomView()
187 {
188 }
189
190 Toolkit::BloomView BloomView::New()
191 {
192   BloomView* impl = new BloomView();
193
194   Dali::Toolkit::BloomView handle = Dali::Toolkit::BloomView( *impl );
195
196   // Second-phase init of the implementation
197   // This can only be done after the CustomActor connection has been made...
198   impl->Initialize();
199
200   return handle;
201 }
202
203 Toolkit::BloomView BloomView::New(const unsigned int blurNumSamples, const float blurBellCurveWidth, const Pixel::Format renderTargetPixelFormat,
204                                                 const float downsampleWidthScale, const float downsampleHeightScale)
205 {
206   BloomView* impl = new BloomView( blurNumSamples, blurBellCurveWidth, renderTargetPixelFormat, downsampleWidthScale, downsampleHeightScale);
207
208   Dali::Toolkit::BloomView handle = Dali::Toolkit::BloomView( *impl );
209
210   // Second-phase init of the implementation
211   // This can only be done after the CustomActor connection has been made...
212   impl->Initialize();
213
214   return handle;
215 }
216
217 ///////////////////////////////////////////////////////////
218 //
219 // Private methods
220 //
221
222 void BloomView::OnInitialize()
223 {
224   // root actor to parent all user added actors, needed to allow us to set that subtree as exclusive for our child render task
225   mChildrenRoot.SetParentOrigin( ParentOrigin::CENTER );
226   mInternalRoot.SetParentOrigin( ParentOrigin::CENTER );
227
228   //////////////////////////////////////////////////////
229   // Create actors
230
231   // Create an image view for rendering from the scene texture to the bloom texture
232   mBloomExtractActor = Actor::New();
233   mBloomExtractActor.SetParentOrigin( ParentOrigin::CENTER );
234
235   // Create an image view for compositing the result (scene and bloom textures) to output
236   mCompositeActor = Actor::New();
237   mCompositeActor.SetParentOrigin( ParentOrigin::CENTER );
238
239   // Create an image view for holding final result, i.e. the blurred image. This will get rendered to screen later, via default / user render task
240   mTargetActor = Actor::New();
241   mTargetActor.SetParentOrigin( ParentOrigin::CENTER );
242
243   // Create the Gaussian Blur object + render tasks
244   // Note that we use mBloomExtractTarget as the source image and also re-use this as the gaussian blur final render target. This saves the gaussian blur code from creating it
245   // render targets etc internally, so we make better use of resources
246   // Note, this also internally creates the render tasks used by the Gaussian blur, this must occur after the bloom extraction and before the compositing
247   mGaussianBlurView = Dali::Toolkit::GaussianBlurView::New(mBlurNumSamples, mBlurBellCurveWidth, mPixelFormat, mDownsampleWidthScale, mDownsampleHeightScale, true);
248   mGaussianBlurView.SetParentOrigin( ParentOrigin::CENTER );
249
250
251   //////////////////////////////////////////////////////
252   // Create cameras for the renders corresponding to the (potentially downsampled) render targets' size
253   mRenderDownsampledCamera = CameraActor::New();
254   mRenderDownsampledCamera.SetParentOrigin(ParentOrigin::CENTER);
255   mRenderDownsampledCamera.SetInvertYAxis( true );
256
257   mRenderFullSizeCamera = CameraActor::New();
258   mRenderFullSizeCamera.SetParentOrigin(ParentOrigin::CENTER);
259   mRenderFullSizeCamera.SetInvertYAxis( true );
260
261
262   ////////////////////////////////
263   // Connect to actor tree
264   Self().Add( mChildrenRoot );
265   Self().Add( mInternalRoot );
266   mInternalRoot.Add( mBloomExtractActor );
267   mInternalRoot.Add( mGaussianBlurView );
268   mInternalRoot.Add( mCompositeActor );
269   mInternalRoot.Add( mTargetActor );
270   mInternalRoot.Add( mRenderDownsampledCamera );
271   mInternalRoot.Add( mRenderFullSizeCamera );
272
273   // bind properties for / set shader constants to defaults
274   SetupProperties();
275 }
276
277 void BloomView::OnSizeSet(const Vector3& targetSize)
278 {
279   mTargetSize = Vector2(targetSize);
280   mChildrenRoot.SetSize(targetSize);
281   mCompositeActor.SetSize(targetSize);
282   mTargetActor.SetSize(targetSize);
283
284   // Children render camera must move when GaussianBlurView object is
285   // resized. This is since we cannot change render target size - so we need
286   // to remap the child actors' rendering accordingly so they still exactly
287   // fill the render target. Note that this means the effective resolution of
288   // the child render changes as the GaussianBlurView object changes size,
289   // this is the trade off for not being able to modify render target size
290   // Change camera z position based on GaussianBlurView actor height
291   float cameraPosConstraintScale = 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f);
292   mRenderFullSizeCamera.SetZ( mTargetSize.height * cameraPosConstraintScale);
293
294   // if we have already activated the blur, need to update render target sizes now to reflect the new size of this actor
295   if(mActivated)
296   {
297     Deactivate();
298     Activate();
299   }
300
301   Control::OnSizeSet( targetSize );
302 }
303
304 void BloomView::OnChildAdd( Actor& child )
305 {
306   if( child != mChildrenRoot && child != mInternalRoot)
307   {
308     mChildrenRoot.Add( child );
309   }
310
311   Control::OnChildAdd( child );
312 }
313
314 void BloomView::OnChildRemove( Actor& child )
315 {
316   mChildrenRoot.Remove( child );
317
318   Control::OnChildRemove( child );
319 }
320
321 void BloomView::AllocateResources()
322 {
323   // size of render targets etc is based on the size of this actor, ignoring z
324   if(mTargetSize != mLastSize || !mActivated)
325   {
326     mLastSize = mTargetSize;
327
328     // get size of downsampled render targets
329     mDownsampledWidth = mTargetSize.width * mDownsampleWidthScale;
330     mDownsampledHeight = mTargetSize.height * mDownsampleHeightScale;
331
332
333     //////////////////////////////////////////////////////
334     // Create cameras
335
336     // Create and place a camera for the renders corresponding to the (potentially downsampled) render targets' size
337     mRenderDownsampledCamera.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
338     mRenderDownsampledCamera.SetNearClippingPlane(1.0f);
339     mRenderDownsampledCamera.SetAspectRatio(mDownsampledWidth / mDownsampledHeight);
340     mRenderDownsampledCamera.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
341
342     mRenderDownsampledCamera.SetPosition(0.0f, 0.0f, ((mDownsampledHeight * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
343
344     // Create and place a camera for the children render, corresponding to its render target size
345     mRenderFullSizeCamera.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
346     mRenderFullSizeCamera.SetNearClippingPlane(1.0f);
347     mRenderFullSizeCamera.SetAspectRatio(mTargetSize.width / mTargetSize.height);
348     mRenderFullSizeCamera.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
349
350     float cameraPosConstraintScale = 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f);
351     mRenderFullSizeCamera.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosConstraintScale);
352
353     //////////////////////////////////////////////////////
354     // Pass size change onto GaussianBlurView, so it matches
355     mGaussianBlurView.SetSize(mTargetSize);
356     GetImpl(mGaussianBlurView).AllocateResources();
357
358     mGaussianBlurView.SetVisible( true );
359
360     //////////////////////////////////////////////////////
361     // Create render targets
362
363     // create off screen buffer of new size to render our child actors to
364     mRenderTargetForRenderingChildren = FrameBuffer::New( mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE );
365     Texture textureForChildren = Texture::New( TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height) );
366     mRenderTargetForRenderingChildren.AttachColorTexture( textureForChildren );
367
368     mBloomExtractTarget = FrameBuffer::New( mDownsampledWidth, mDownsampledHeight, FrameBuffer::Attachment::NONE );
369     Texture texture = Texture::New( TextureType::TEXTURE_2D, mPixelFormat, unsigned(mDownsampledWidth), unsigned(mDownsampledHeight) );
370     mBloomExtractTarget.AttachColorTexture( texture );
371
372     FrameBuffer blurExtractTarget = FrameBuffer::New( mDownsampledWidth, mDownsampledHeight, FrameBuffer::Attachment::NONE );
373     texture = Texture::New( TextureType::TEXTURE_2D, mPixelFormat, unsigned(mDownsampledWidth), unsigned(mDownsampledHeight) );
374     blurExtractTarget.AttachColorTexture( texture );
375
376     mOutputRenderTarget = FrameBuffer::New( mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE );
377     Texture outputTexture = Texture::New( TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height) );
378     mOutputRenderTarget.AttachColorTexture( outputTexture );
379
380     //////////////////////////////////////////////////////
381     // Point actors and render tasks at new render targets
382
383     Renderer bloomRenderer = CreateRenderer( BASIC_VERTEX_SOURCE, BLOOM_EXTRACT_FRAGMENT_SOURCE );
384     SetRendererTexture( bloomRenderer, mRenderTargetForRenderingChildren );
385     mBloomExtractActor.AddRenderer( bloomRenderer );
386     mBloomExtractActor.SetSize( mDownsampledWidth, mDownsampledHeight ); // size needs to match render target
387
388     // set GaussianBlurView to blur our extracted bloom
389     mGaussianBlurView.SetUserImageAndOutputRenderTarget( mBloomExtractTarget.GetColorTexture(), blurExtractTarget );
390
391     // use the completed blur in the first buffer and composite with the original child actors render
392     Renderer compositeRenderer = CreateRenderer( BASIC_VERTEX_SOURCE, COMPOSITE_FRAGMENT_SOURCE );
393     SetRendererTexture( compositeRenderer, mRenderTargetForRenderingChildren );
394     TextureSet textureSet = compositeRenderer.GetTextures();
395     textureSet.SetTexture( 0u, mRenderTargetForRenderingChildren.GetColorTexture() );
396     textureSet.SetTexture( 1u, blurExtractTarget.GetColorTexture() );
397     mCompositeActor.AddRenderer( compositeRenderer );
398
399     // set up target actor for rendering result, i.e. the blurred image
400     Renderer targetRenderer = CreateRenderer( BASIC_VERTEX_SOURCE, BASIC_FRAGMENT_SOURCE );
401     SetRendererTexture( targetRenderer, mOutputRenderTarget );
402     mTargetActor.AddRenderer( targetRenderer );
403   }
404 }
405
406 void BloomView::CreateRenderTasks()
407 {
408   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
409
410   // create render task to render our child actors to offscreen buffer
411   mRenderChildrenTask = taskList.CreateTask();
412   mRenderChildrenTask.SetSourceActor( mChildrenRoot );
413   mRenderChildrenTask.SetExclusive(true);
414   mRenderChildrenTask.SetInputEnabled( false );
415   mRenderChildrenTask.SetClearEnabled( true );
416   mRenderChildrenTask.SetCameraActor(mRenderFullSizeCamera); // use camera that covers render target exactly
417   mRenderChildrenTask.SetFrameBuffer( mRenderTargetForRenderingChildren );
418
419   // Extract the bright part of the image and render to a new buffer. Downsampling also occurs at this stage to save pixel fill, if it is set up.
420   mBloomExtractTask = taskList.CreateTask();
421   mBloomExtractTask.SetSourceActor( mBloomExtractActor );
422   mBloomExtractTask.SetExclusive(true);
423   mBloomExtractTask.SetInputEnabled( false );
424   mBloomExtractTask.SetClearEnabled( true );
425   mBloomExtractTask.SetCameraActor(mRenderDownsampledCamera);
426   mBloomExtractTask.SetFrameBuffer( mBloomExtractTarget );
427
428   // GaussianBlurView tasks must be created here, so they are executed in the correct order with respect to BloomView tasks
429   GetImpl(mGaussianBlurView).CreateRenderTasks();
430
431   // Use an image view displaying the children render and composite it with the blurred bloom buffer, targeting the output
432   mCompositeTask = taskList.CreateTask();
433   mCompositeTask.SetSourceActor( mCompositeActor );
434   mCompositeTask.SetExclusive(true);
435   mCompositeTask.SetInputEnabled( false );
436   mCompositeTask.SetClearEnabled( true );
437   mCompositeTask.SetCameraActor(mRenderFullSizeCamera);
438   mCompositeTask.SetFrameBuffer( mOutputRenderTarget );
439 }
440
441 void BloomView::RemoveRenderTasks()
442 {
443   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
444
445   taskList.RemoveTask(mRenderChildrenTask);
446   taskList.RemoveTask(mBloomExtractTask);
447
448   GetImpl(mGaussianBlurView).RemoveRenderTasks();
449
450   taskList.RemoveTask(mCompositeTask);
451 }
452
453 void BloomView::Activate()
454 {
455   // make sure resources are allocated and start the render tasks processing
456   AllocateResources();
457   CreateRenderTasks();
458   mActivated = true;
459 }
460
461 void BloomView::Deactivate()
462 {
463   // stop render tasks processing
464   // Note: render target resources are automatically freed since we set the Image::Unused flag
465   RemoveRenderTasks();
466
467   mRenderTargetForRenderingChildren.Reset();
468   mBloomExtractTarget.Reset();
469   mOutputRenderTarget.Reset();
470
471   // Reset children
472   mBloomExtractActor.RemoveRenderer( 0u );
473   mTargetActor.RemoveRenderer( 0u );
474   mCompositeActor.RemoveRenderer( 0u );
475
476   mGaussianBlurView.SetVisible( false );
477
478   mActivated = false;
479 }
480
481 /**
482  * RecipOneMinusConstraint
483  *
484  * f(current, property) = property
485  */
486 struct RecipOneMinusConstraint
487 {
488   RecipOneMinusConstraint(){}
489
490   void operator()( float& current, const PropertyInputContainer& inputs )
491   {
492     current = 1.0f / ( 1.0f - inputs[0]->GetFloat() );
493   }
494 };
495
496 // create properties and constraints to tie internal shader etc settings to BloomView object. User can therefore animate / set them via BloomView object without knowing about
497 // internal implementation classes
498 void BloomView::SetupProperties()
499 {
500   CustomActor self = Self();
501
502
503   ///////////////////////////////////////////
504   // bloom threshold
505
506   // set defaults, makes sure properties are registered with shader
507   mBloomExtractActor.RegisterProperty( BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT );
508   mBloomExtractActor.RegisterProperty( RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME, 1.0f / (1.0f - BLOOM_THRESHOLD_DEFAULT) );
509
510   // Register a property that the user can control to change the bloom threshold
511   mBloomThresholdPropertyIndex = self.RegisterProperty(BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT);
512   Property::Index shaderBloomThresholdPropertyIndex = mBloomExtractActor.GetPropertyIndex(BLOOM_THRESHOLD_PROPERTY_NAME);
513   Constraint bloomThresholdConstraint = Constraint::New<float>( mBloomExtractActor, shaderBloomThresholdPropertyIndex, EqualToConstraint());
514   bloomThresholdConstraint.AddSource( Source(self, mBloomThresholdPropertyIndex) );
515   bloomThresholdConstraint.Apply();
516
517   // precalc 1.0 / (1.0 - threshold) on CPU to save shader insns, using constraint to tie to the normal threshold property
518   Property::Index shaderRecipOneMinusBloomThresholdPropertyIndex = mBloomExtractActor.GetPropertyIndex(RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME);
519   Constraint thresholdConstraint = Constraint::New<float>( mBloomExtractActor, shaderRecipOneMinusBloomThresholdPropertyIndex, RecipOneMinusConstraint());
520   thresholdConstraint.AddSource( LocalSource(shaderBloomThresholdPropertyIndex) );
521   thresholdConstraint.Apply();
522
523
524   ////////////////////////////////////////////
525   // bloom strength
526
527   // Register a property that the user can control to fade the blur in / out via internal GaussianBlurView object
528   mBlurStrengthPropertyIndex = self.RegisterProperty(BLOOM_BLUR_STRENGTH_PROPERTY_NAME, BLOOM_BLUR_STRENGTH_DEFAULT);
529   Constraint blurStrengthConstraint = Constraint::New<float>( mGaussianBlurView, mGaussianBlurView.GetBlurStrengthPropertyIndex(), EqualToConstraint());
530   blurStrengthConstraint.AddSource( Source(self, mBlurStrengthPropertyIndex) );
531   blurStrengthConstraint.Apply();
532
533
534   ////////////////////////////////////////////
535   // bloom intensity
536
537   // Register a property that the user can control to fade the bloom intensity via internally hidden shader
538   mBloomIntensityPropertyIndex = self.RegisterProperty(BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT);
539   mCompositeActor.RegisterProperty( BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT );
540   Property::Index shaderBloomIntensityPropertyIndex = mCompositeActor.GetPropertyIndex(BLOOM_INTENSITY_PROPERTY_NAME);
541   Constraint bloomIntensityConstraint = Constraint::New<float>( mCompositeActor, shaderBloomIntensityPropertyIndex, EqualToConstraint());
542   bloomIntensityConstraint.AddSource( Source(self, mBloomIntensityPropertyIndex) );
543   bloomIntensityConstraint.Apply();
544
545
546   ////////////////////////////////////////////
547   // bloom saturation
548
549   // Register a property that the user can control to fade the bloom saturation via internally hidden shader
550   mBloomSaturationPropertyIndex = self.RegisterProperty(BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT);
551   mCompositeActor.RegisterProperty( BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT );
552   Property::Index shaderBloomSaturationPropertyIndex = mCompositeActor.GetPropertyIndex(BLOOM_SATURATION_PROPERTY_NAME);
553   Constraint bloomSaturationConstraint = Constraint::New<float>( mCompositeActor, shaderBloomSaturationPropertyIndex, EqualToConstraint());
554   bloomSaturationConstraint.AddSource( Source(self, mBloomSaturationPropertyIndex) );
555   bloomSaturationConstraint.Apply();
556
557
558   ////////////////////////////////////////////
559   // image intensity
560
561   // Register a property that the user can control to fade the image intensity via internally hidden shader
562   mImageIntensityPropertyIndex = self.RegisterProperty(IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT);
563   mCompositeActor.RegisterProperty( IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT );
564   Property::Index shaderImageIntensityPropertyIndex = mCompositeActor.GetPropertyIndex(IMAGE_INTENSITY_PROPERTY_NAME);
565   Constraint imageIntensityConstraint = Constraint::New<float>( mCompositeActor, shaderImageIntensityPropertyIndex, EqualToConstraint());
566   imageIntensityConstraint.AddSource( Source(self, mImageIntensityPropertyIndex) );
567   imageIntensityConstraint.Apply();
568
569
570   ////////////////////////////////////////////
571   // image saturation
572
573   // Register a property that the user can control to fade the image saturation via internally hidden shader
574   mImageSaturationPropertyIndex = self.RegisterProperty(IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT);
575   mCompositeActor.RegisterProperty( IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT );
576   Property::Index shaderImageSaturationPropertyIndex = mCompositeActor.GetPropertyIndex(IMAGE_SATURATION_PROPERTY_NAME);
577   Constraint imageSaturationConstraint = Constraint::New<float>( mCompositeActor, shaderImageSaturationPropertyIndex, EqualToConstraint());
578   imageSaturationConstraint.AddSource( Source(self, mImageSaturationPropertyIndex) );
579   imageSaturationConstraint.Apply();
580 }
581
582 } // namespace Internal
583
584 } // namespace Toolkit
585
586 } // namespace Dali