From 397218b6cdd85915f5fe00fa9d3615dfa3867422 Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Fri, 4 Dec 2015 17:26:30 +0000 Subject: [PATCH 1/1] Stop using ImageActor in GaussianBlur, Bloom & SuperBlur Change-Id: Id5dfa5523914f99a98c222bb02c1f0f90ffaa5da --- .../src/dali-toolkit/utc-Dali-SuperBlurView.cpp | 12 +- .../controls/super-blur-view/super-blur-view.h | 2 +- .../controls/bloom-view/bloom-view-impl.cpp | 129 +++++++++------- .../internal/controls/bloom-view/bloom-view-impl.h | 13 +- .../gaussian-blur-view/gaussian-blur-view-impl.cpp | 99 ++++++------ .../gaussian-blur-view/gaussian-blur-view-impl.h | 14 +- .../controls/renderers/image/image-renderer.cpp | 11 +- .../super-blur-view/super-blur-view-impl.cpp | 171 +++++++++++++++------ .../super-blur-view/super-blur-view-impl.h | 37 ++++- .../gaussian-blur-view/gaussian-blur-view.h | 2 - .../public-api/controls/image-view/image-view.cpp | 2 +- 11 files changed, 311 insertions(+), 181 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-SuperBlurView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-SuperBlurView.cpp index de9a7d5..97592d7 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-SuperBlurView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-SuperBlurView.cpp @@ -146,13 +146,17 @@ int UtcDaliSuperBlurViewSetImage(void) tet_infoline(" UtcDaliSuperBlurViewSetImage "); SuperBlurView blurView = SuperBlurView::New( BLUR_LEVELS ); - // create image actors for the original image and each blurred image - DALI_TEST_CHECK( blurView.GetChildCount() == BLUR_LEVELS+1 ); + blurView.SetSize( 100.f, 100.f ); Image inputImage = CreateSolidColorImage( application, Color::GREEN, 50, 50 ); blurView.SetImage( inputImage ); // start multiple guassian blur call, each guassian blur creates two render tasks - DALI_TEST_CHECK( Stage::GetCurrent().GetRenderTaskList().GetTaskCount() == BLUR_LEVELS*2 + 1); + DALI_TEST_CHECK( Stage::GetCurrent().GetRenderTaskList().GetTaskCount() == 1+BLUR_LEVELS*2); + + // create image actors for the original image and each blurred image + Stage::GetCurrent().Add( blurView ); + Wait(application); + DALI_TEST_EQUALS(blurView.GetRendererCount(), BLUR_LEVELS+1, TEST_LOCATION ); END_TEST; } @@ -212,7 +216,7 @@ int UtcDaliSuperBlurViewGetBlurredImage(void) DALI_TEST_EQUALS( image2.GetHeight(), 25u, TEST_LOCATION ); Image image3 = blurView.GetBlurredImage( 3 ); - DALI_TEST_CHECK( FrameBufferImage::DownCast( image2 ) ); + DALI_TEST_CHECK( FrameBufferImage::DownCast( image3 ) ); END_TEST; } diff --git a/dali-toolkit/devel-api/controls/super-blur-view/super-blur-view.h b/dali-toolkit/devel-api/controls/super-blur-view/super-blur-view.h index ab9ec44..f63ddd5 100644 --- a/dali-toolkit/devel-api/controls/super-blur-view/super-blur-view.h +++ b/dali-toolkit/devel-api/controls/super-blur-view/super-blur-view.h @@ -44,7 +44,7 @@ class SuperBlurView; * Stage::GetCurrent().Add(blurView);\n * * // Set the input image - * Image image = Image::New(...);\n + * ResourceImage image = ResourceImage::New(...);\n * blurView.SetImage(image);\n * * // animate the strength of the blur - this can fade between no blur and full blur. .\n diff --git a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp index eab906c..3c6dca4 100644 --- a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp +++ b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp @@ -24,9 +24,11 @@ #include #include #include +#include #include #include #include +#include // INTERNAL INCLUDES #include @@ -81,23 +83,33 @@ const char* const BLOOM_SATURATION_PROPERTY_NAME = "uBloomSaturation"; const char* const IMAGE_INTENSITY_PROPERTY_NAME = "uImageIntensity"; const char* const IMAGE_SATURATION_PROPERTY_NAME = "uImageSaturation"; +const char* const EFFECT_IMAGE_NAME( "sEffect" ); + /////////////////////////////////////////////////////// // // Bloom shaders // const char* const BLOOM_EXTRACT_FRAGMENT_SOURCE = - "uniform float uBloomThreshold;\n" - "uniform float uRecipOneMinusBloomThreshold;\n" + "varying mediump vec2 vTexCoord;\n" + "uniform sampler2D sTexture;\n" + "uniform lowp vec4 uColor;\n" + "uniform mediump float uBloomThreshold;\n" + "uniform mediump float uRecipOneMinusBloomThreshold;\n" "void main()\n" "{\n" " mediump vec4 col;\n" - " col = texture2D(sTexture, vec2(vTexCoord.x, vTexCoord.y));\n" + " col = texture2D(sTexture, vTexCoord);\n" " col = (col - uBloomThreshold) * uRecipOneMinusBloomThreshold;\n" // remove intensities lower than the thresold and remap intensities above the threshold to [0..1] " gl_FragColor = clamp(col, 0.0, 1.0);\n" "}\n"; const char* const COMPOSITE_FRAGMENT_SOURCE = + "precision mediump float;\n" + "varying mediump vec2 vTexCoord;\n" + "uniform sampler2D sTexture;\n" + "uniform sampler2D sEffect;\n" + "uniform lowp vec4 uColor;\n" "uniform float uBloomIntensity;\n" "uniform float uImageIntensity;\n" "uniform float uBloomSaturation;\n" @@ -113,8 +125,8 @@ const char* const COMPOSITE_FRAGMENT_SOURCE = "{\n" " mediump vec4 image;\n" " mediump vec4 bloom;\n" - " image = texture2D(sTexture, vec2(vTexCoord.x, vTexCoord.y));\n" - " bloom = texture2D(sEffect, vec2(vTexCoord.x, vTexCoord.y));\n" + " image = texture2D(sTexture, vTexCoord);\n" + " bloom = texture2D(sEffect, vTexCoord);\n" " image = ChangeSaturation(image, uImageSaturation) * uImageIntensity;\n" " bloom = ChangeSaturation(bloom, uBloomSaturation) * uBloomIntensity;\n" " image *= 1.0 - clamp(bloom, 0.0, 1.0);\n" // darken base where bloom is strong, to prevent excessive burn-out of result @@ -143,6 +155,7 @@ BloomView::BloomView() , mBloomSaturationPropertyIndex(Property::INVALID_INDEX) , mImageIntensityPropertyIndex(Property::INVALID_INDEX) , mImageSaturationPropertyIndex(Property::INVALID_INDEX) + , mActivated( false ) { } @@ -165,6 +178,7 @@ BloomView::BloomView( const unsigned int blurNumSamples, const float blurBellCur , mBloomSaturationPropertyIndex(Property::INVALID_INDEX) , mImageIntensityPropertyIndex(Property::INVALID_INDEX) , mImageSaturationPropertyIndex(Property::INVALID_INDEX) + , mActivated( false ) { } @@ -228,34 +242,32 @@ void BloomView::OnInitialize() mChildrenRoot.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); ////////////////////////////////////////////////////// - // Create shaders - - // Create shader used for extracting the bright parts of an image - mBloomExtractShader = ShaderEffect::New( "", BLOOM_EXTRACT_FRAGMENT_SOURCE ); - - // Create shader used to composite bloom and original image to output render target - mCompositeShader = ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ); - - - ////////////////////////////////////////////////////// // Create actors // Create an ImageActor for rendering from the scene texture to the bloom texture - mBloomExtractImageActor = ImageActor::New(); + mBloomExtractImageActor = Toolkit::ImageView::New(); mBloomExtractImageActor.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - mBloomExtractImageActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME - mBloomExtractImageActor.SetShaderEffect( mBloomExtractShader ); + + // Create shader used for extracting the bright parts of an image + Property::Map customShader; + customShader[ "fragmentShader" ] = BLOOM_EXTRACT_FRAGMENT_SOURCE; + Property::Map rendererMap; + rendererMap.Insert( "rendererType", "imageRenderer" ); + rendererMap.Insert( "shader", customShader ); + mBloomExtractImageActor.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); // Create an ImageActor for compositing the result (scene and bloom textures) to output - mCompositeImageActor = ImageActor::New(); + mCompositeImageActor = Toolkit::ImageView::New(); mCompositeImageActor.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - mCompositeImageActor.SetShaderEffect( mCompositeShader ); - mCompositeImageActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME + + // Create shader used to composite bloom and original image to output render target + customShader[ "fragmentShader" ] = COMPOSITE_FRAGMENT_SOURCE; + rendererMap[ "shader" ] = customShader; + mCompositeImageActor.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );; // Create an ImageActor for holding final result, i.e. the blurred image. This will get rendered to screen later, via default / user render task - mTargetImageActor = ImageActor::New(); + mTargetImageActor = Toolkit::ImageView::New(); mTargetImageActor.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - mTargetImageActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME // Create the Gaussian Blur object + render tasks @@ -270,9 +282,11 @@ void BloomView::OnInitialize() // Create cameras for the renders corresponding to the (potentially downsampled) render targets' size mRenderDownsampledCamera = CameraActor::New(); mRenderDownsampledCamera.SetParentOrigin(ParentOrigin::CENTER); + mRenderDownsampledCamera.SetInvertYAxis( true ); mRenderFullSizeCamera = CameraActor::New(); mRenderFullSizeCamera.SetParentOrigin(ParentOrigin::CENTER); + mRenderFullSizeCamera.SetInvertYAxis( true ); //////////////////////////////// @@ -306,10 +320,11 @@ void BloomView::OnSizeSet(const Vector3& targetSize) float cameraPosConstraintScale = 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f); mRenderFullSizeCamera.SetZ( mTargetSize.height * cameraPosConstraintScale); - // if we are already on stage, need to update render target sizes now to reflect the new size of this actor - if(Self().OnStage()) + // if we have already activated the blur, need to update render target sizes now to reflect the new size of this actor + if(mActivated) { - AllocateResources(); + Deactivate(); + Activate(); } } @@ -359,6 +374,7 @@ void BloomView::AllocateResources() // create off screen buffer of new size to render our child actors to mRenderTargetForRenderingChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED ); mBloomExtractTarget = FrameBufferImage::New( mDownsampledWidth, mDownsampledHeight, mPixelFormat, Dali::Image::UNUSED ); + FrameBufferImage mBlurExtractTarget = FrameBufferImage::New( mDownsampledWidth, mDownsampledHeight, mPixelFormat, Dali::Image::UNUSED ); mOutputRenderTarget = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED); @@ -369,11 +385,20 @@ void BloomView::AllocateResources() mBloomExtractImageActor.SetSize(mDownsampledWidth, mDownsampledHeight); // size needs to match render target // set GaussianBlurView to blur our extracted bloom - mGaussianBlurView.SetUserImageAndOutputRenderTarget(mBloomExtractTarget, mBloomExtractTarget); + mGaussianBlurView.SetUserImageAndOutputRenderTarget(mBloomExtractTarget, mBlurExtractTarget); // use the completed blur in the first buffer and composite with the original child actors render mCompositeImageActor.SetImage( mRenderTargetForRenderingChildren ); - mCompositeShader.SetEffectImage( mBloomExtractTarget ); + Material material = mCompositeImageActor.GetRendererAt(0).GetMaterial(); + int textureIndex = material.GetTextureIndex( EFFECT_IMAGE_NAME ); + if( textureIndex == -1 ) + { + material.AddTexture( mBlurExtractTarget, EFFECT_IMAGE_NAME ); + } + else + { + material.SetTextureImage( textureIndex, mBlurExtractTarget ); + } // set up target actor for rendering result, i.e. the blurred image mTargetImageActor.SetImage(mOutputRenderTarget); @@ -390,6 +415,8 @@ void BloomView::CreateRenderTasks() mRenderChildrenTask.SetExclusive(true); mRenderChildrenTask.SetInputEnabled( false ); mRenderChildrenTask.SetClearEnabled( true ); + mRenderChildrenTask.SetCameraActor(mRenderFullSizeCamera); // use camera that covers render target exactly + mRenderChildrenTask.SetTargetFrameBuffer( mRenderTargetForRenderingChildren ); // 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. mBloomExtractTask = taskList.CreateTask(); @@ -397,6 +424,8 @@ void BloomView::CreateRenderTasks() mBloomExtractTask.SetExclusive(true); mBloomExtractTask.SetInputEnabled( false ); mBloomExtractTask.SetClearEnabled( true ); + mBloomExtractTask.SetCameraActor(mRenderDownsampledCamera); + mBloomExtractTask.SetTargetFrameBuffer( mBloomExtractTarget ); // GaussianBlurView tasks must be created here, so they are executed in the correct order with respect to BloomView tasks GetImpl(mGaussianBlurView).CreateRenderTasks(); @@ -407,13 +436,7 @@ void BloomView::CreateRenderTasks() mCompositeTask.SetExclusive(true); mCompositeTask.SetInputEnabled( false ); mCompositeTask.SetClearEnabled( true ); - - mRenderChildrenTask.SetCameraActor(mRenderFullSizeCamera); // use camera that covers render target exactly - mBloomExtractTask.SetCameraActor(mRenderDownsampledCamera); mCompositeTask.SetCameraActor(mRenderFullSizeCamera); - - mRenderChildrenTask.SetTargetFrameBuffer( mRenderTargetForRenderingChildren ); - mBloomExtractTask.SetTargetFrameBuffer( mBloomExtractTarget ); mCompositeTask.SetTargetFrameBuffer( mOutputRenderTarget ); } @@ -434,6 +457,7 @@ void BloomView::Activate() // make sure resources are allocated and start the render tasks processing AllocateResources(); CreateRenderTasks(); + mActivated = true; } void BloomView::Deactivate() @@ -441,6 +465,7 @@ void BloomView::Deactivate() // stop render tasks processing // Note: render target resources are automatically freed since we set the Image::Unused flag RemoveRenderTasks(); + mActivated = false; } /** @@ -469,19 +494,19 @@ void BloomView::SetupProperties() // bloom threshold // set defaults, makes sure properties are registered with shader - mBloomExtractShader.SetUniform( BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT ); - mBloomExtractShader.SetUniform( RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME, 1.0f / (1.0f - BLOOM_THRESHOLD_DEFAULT) ); + mBloomExtractImageActor.RegisterProperty( BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT ); + mBloomExtractImageActor.RegisterProperty( RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME, 1.0f / (1.0f - BLOOM_THRESHOLD_DEFAULT) ); // Register a property that the user can control to change the bloom threshold mBloomThresholdPropertyIndex = self.RegisterProperty(BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT); - Property::Index shaderBloomThresholdPropertyIndex = mBloomExtractShader.GetPropertyIndex(BLOOM_THRESHOLD_PROPERTY_NAME); - Constraint bloomThresholdConstraint = Constraint::New( mBloomExtractShader, shaderBloomThresholdPropertyIndex, EqualToConstraint()); + Property::Index shaderBloomThresholdPropertyIndex = mBloomExtractImageActor.GetPropertyIndex(BLOOM_THRESHOLD_PROPERTY_NAME); + Constraint bloomThresholdConstraint = Constraint::New( mBloomExtractImageActor, shaderBloomThresholdPropertyIndex, EqualToConstraint()); bloomThresholdConstraint.AddSource( Source(self, mBloomThresholdPropertyIndex) ); bloomThresholdConstraint.Apply(); // precalc 1.0 / (1.0 - threshold) on CPU to save shader insns, using constraint to tie to the normal threshold property - Property::Index shaderRecipOneMinusBloomThresholdPropertyIndex = mBloomExtractShader.GetPropertyIndex(RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME); - Constraint thresholdConstraint = Constraint::New( mBloomExtractShader, shaderRecipOneMinusBloomThresholdPropertyIndex, RecipOneMinusConstraint()); + Property::Index shaderRecipOneMinusBloomThresholdPropertyIndex = mBloomExtractImageActor.GetPropertyIndex(RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME); + Constraint thresholdConstraint = Constraint::New( mBloomExtractImageActor, shaderRecipOneMinusBloomThresholdPropertyIndex, RecipOneMinusConstraint()); thresholdConstraint.AddSource( LocalSource(shaderBloomThresholdPropertyIndex) ); thresholdConstraint.Apply(); @@ -501,9 +526,9 @@ void BloomView::SetupProperties() // Register a property that the user can control to fade the bloom intensity via internally hidden shader mBloomIntensityPropertyIndex = self.RegisterProperty(BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT); - mCompositeShader.SetUniform( BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT ); - Property::Index shaderBloomIntensityPropertyIndex = mCompositeShader.GetPropertyIndex(BLOOM_INTENSITY_PROPERTY_NAME); - Constraint bloomIntensityConstraint = Constraint::New( mCompositeShader, shaderBloomIntensityPropertyIndex, EqualToConstraint()); + mCompositeImageActor.RegisterProperty( BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT ); + Property::Index shaderBloomIntensityPropertyIndex = mCompositeImageActor.GetPropertyIndex(BLOOM_INTENSITY_PROPERTY_NAME); + Constraint bloomIntensityConstraint = Constraint::New( mCompositeImageActor, shaderBloomIntensityPropertyIndex, EqualToConstraint()); bloomIntensityConstraint.AddSource( Source(self, mBloomIntensityPropertyIndex) ); bloomIntensityConstraint.Apply(); @@ -513,9 +538,9 @@ void BloomView::SetupProperties() // Register a property that the user can control to fade the bloom saturation via internally hidden shader mBloomSaturationPropertyIndex = self.RegisterProperty(BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT); - mCompositeShader.SetUniform( BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT ); - Property::Index shaderBloomSaturationPropertyIndex = mCompositeShader.GetPropertyIndex(BLOOM_SATURATION_PROPERTY_NAME); - Constraint bloomSaturationConstraint = Constraint::New( mCompositeShader, shaderBloomSaturationPropertyIndex, EqualToConstraint()); + mCompositeImageActor.RegisterProperty( BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT ); + Property::Index shaderBloomSaturationPropertyIndex = mCompositeImageActor.GetPropertyIndex(BLOOM_SATURATION_PROPERTY_NAME); + Constraint bloomSaturationConstraint = Constraint::New( mCompositeImageActor, shaderBloomSaturationPropertyIndex, EqualToConstraint()); bloomSaturationConstraint.AddSource( Source(self, mBloomSaturationPropertyIndex) ); bloomSaturationConstraint.Apply(); @@ -525,9 +550,9 @@ void BloomView::SetupProperties() // Register a property that the user can control to fade the image intensity via internally hidden shader mImageIntensityPropertyIndex = self.RegisterProperty(IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT); - mCompositeShader.SetUniform( IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT ); - Property::Index shaderImageIntensityPropertyIndex = mCompositeShader.GetPropertyIndex(IMAGE_INTENSITY_PROPERTY_NAME); - Constraint imageIntensityConstraint = Constraint::New( mCompositeShader, shaderImageIntensityPropertyIndex, EqualToConstraint()); + mCompositeImageActor.RegisterProperty( IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT ); + Property::Index shaderImageIntensityPropertyIndex = mCompositeImageActor.GetPropertyIndex(IMAGE_INTENSITY_PROPERTY_NAME); + Constraint imageIntensityConstraint = Constraint::New( mCompositeImageActor, shaderImageIntensityPropertyIndex, EqualToConstraint()); imageIntensityConstraint.AddSource( Source(self, mImageIntensityPropertyIndex) ); imageIntensityConstraint.Apply(); @@ -537,9 +562,9 @@ void BloomView::SetupProperties() // Register a property that the user can control to fade the image saturation via internally hidden shader mImageSaturationPropertyIndex = self.RegisterProperty(IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT); - mCompositeShader.SetUniform( IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT ); - Property::Index shaderImageSaturationPropertyIndex = mCompositeShader.GetPropertyIndex(IMAGE_SATURATION_PROPERTY_NAME); - Constraint imageSaturationConstraint = Constraint::New( mCompositeShader, shaderImageSaturationPropertyIndex, EqualToConstraint()); + mCompositeImageActor.RegisterProperty( IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT ); + Property::Index shaderImageSaturationPropertyIndex = mCompositeImageActor.GetPropertyIndex(IMAGE_SATURATION_PROPERTY_NAME); + Constraint imageSaturationConstraint = Constraint::New( mCompositeImageActor, shaderImageSaturationPropertyIndex, EqualToConstraint()); imageSaturationConstraint.AddSource( Source(self, mImageSaturationPropertyIndex) ); imageSaturationConstraint.Apply(); } diff --git a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.h b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.h index 2da9293..207ce92 100644 --- a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.h +++ b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.h @@ -24,11 +24,11 @@ #include #include #include -#include // INTERNAL INCLUDES #include #include +#include #include namespace Dali @@ -132,8 +132,7 @@ private: // for extracting bright parts of image to an offscreen target FrameBufferImage mBloomExtractTarget; // for rendering bright parts of image into separate texture, also used as target for gaussian blur RenderTask mBloomExtractTask; - ShaderEffect mBloomExtractShader; - ImageActor mBloomExtractImageActor; + Toolkit::ImageView mBloomExtractImageActor; ///////////////////////////////////////////////////////////// // for blurring extracted bloom @@ -142,13 +141,13 @@ private: ///////////////////////////////////////////////////////////// // for compositing bloom and children renders to offscreen target RenderTask mCompositeTask; - ShaderEffect mCompositeShader; - ImageActor mCompositeImageActor; + + Toolkit::ImageView mCompositeImageActor; ///////////////////////////////////////////////////////////// // for holding blurred result FrameBufferImage mOutputRenderTarget; - ImageActor mTargetImageActor; + Toolkit::ImageView mTargetImageActor; ///////////////////////////////////////////////////////////// // Properties for setting by user, e.g. by animations @@ -159,6 +158,8 @@ private: Property::Index mImageIntensityPropertyIndex; Property::Index mImageSaturationPropertyIndex; + bool mActivated:1; + private: // Undefined copy constructor. diff --git a/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp b/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp index ddbb242..df03aaf 100644 --- a/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp +++ b/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -98,17 +99,19 @@ const float GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_HEIGHT_SCALE = 0.5f; const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f; const char* const GAUSSIAN_BLUR_FRAGMENT_SOURCE = + "varying mediump vec2 vTexCoord;\n" + "uniform sampler2D sTexture;\n" + "uniform lowp vec4 uColor;\n" "uniform mediump vec2 uSampleOffsets[NUM_SAMPLES];\n" "uniform mediump float uSampleWeights[NUM_SAMPLES];\n" "void main()\n" "{\n" - " mediump vec4 col;\n" - " col = texture2D(sTexture, vec2(vTexCoord.x, vTexCoord.y) + uSampleOffsets[0]) * uSampleWeights[0]; \n" - " for (int i=1; i( mImageActorComposite, Actor::Property::COLOR_ALPHA, EqualToConstraint()); @@ -292,14 +291,13 @@ void GaussianBlurView::OnInitialize() blurStrengthConstraint.Apply(); // Create an ImageActor for holding final result, i.e. the blurred image. This will get rendered to screen later, via default / user render task - mTargetActor = ImageActor::New(); + mTargetActor = Toolkit::ImageView::New(); mTargetActor.SetParentOrigin(ParentOrigin::CENTER); - mTargetActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME - ////////////////////////////////////////////////////// // Create cameras for the renders corresponding to the view size mRenderFullSizeCamera = CameraActor::New(); + mRenderFullSizeCamera.SetInvertYAxis( true ); mRenderFullSizeCamera.SetParentOrigin(ParentOrigin::CENTER); @@ -314,6 +312,7 @@ void GaussianBlurView::OnInitialize() ////////////////////////////////////////////////////// // Create camera for the renders corresponding to the (potentially downsampled) render targets' size mRenderDownsampledCamera = CameraActor::New(); + mRenderDownsampledCamera.SetInvertYAxis( true ); mRenderDownsampledCamera.SetParentOrigin(ParentOrigin::CENTER); @@ -346,10 +345,11 @@ void GaussianBlurView::OnSizeSet(const Vector3& targetSize) } - // if we are already on stage, need to update render target sizes now to reflect the new size of this actor - if(Self().OnStage()) + // if we have already activated the blur, need to update render target sizes now to reflect the new size of this actor + if(mActivated) { - AllocateResources(); + Deactivate(); + Activate(); } } @@ -387,13 +387,13 @@ void GaussianBlurView::AllocateResources() mRenderFullSizeCamera.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosConstraintScale); // create offscreen buffer of new size to render our child actors to - mRenderTargetForRenderingChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED ); + mRenderTargetForRenderingChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat ); // Set ImageActor for performing a horizontal blur on the texture mImageActorHorizBlur.SetImage( mRenderTargetForRenderingChildren ); // Create offscreen buffer for vert blur pass - mRenderTarget1 = FrameBufferImage::New( mDownsampledWidth, mDownsampledHeight, mPixelFormat, Dali::Image::UNUSED ); + mRenderTarget1 = FrameBufferImage::New( mDownsampledWidth, mDownsampledHeight, mPixelFormat ); // use the completed blur in the first buffer and composite with the original child actors render mImageActorComposite.SetImage( mRenderTarget1 ); @@ -403,7 +403,7 @@ void GaussianBlurView::AllocateResources() } // Create offscreen buffer for horiz blur pass - mRenderTarget2 = FrameBufferImage::New( mDownsampledWidth, mDownsampledHeight, mPixelFormat, Dali::Image::UNUSED ); + mRenderTarget2 = FrameBufferImage::New( mDownsampledWidth, mDownsampledHeight, mPixelFormat ); // size needs to match render target mImageActorHorizBlur.SetSize(mDownsampledWidth, mDownsampledHeight); @@ -442,6 +442,8 @@ void GaussianBlurView::CreateRenderTasks() mHorizBlurTask.SetInputEnabled( false ); mHorizBlurTask.SetClearEnabled( true ); mHorizBlurTask.SetClearColor( mBackgroundColor ); + mHorizBlurTask.SetCameraActor(mRenderDownsampledCamera); + mHorizBlurTask.SetTargetFrameBuffer( mRenderTarget2 ); if( mRenderOnce && mBlurUserImage ) { mHorizBlurTask.SetRefreshRate(RenderTask::REFRESH_ONCE); @@ -454,6 +456,15 @@ void GaussianBlurView::CreateRenderTasks() mVertBlurTask.SetInputEnabled( false ); mVertBlurTask.SetClearEnabled( true ); mVertBlurTask.SetClearColor( mBackgroundColor ); + mVertBlurTask.SetCameraActor(mRenderDownsampledCamera); + if(mUserOutputRenderTarget) + { + mVertBlurTask.SetTargetFrameBuffer( mUserOutputRenderTarget ); + } + else + { + mVertBlurTask.SetTargetFrameBuffer( mRenderTarget1 ); + } if( mRenderOnce && mBlurUserImage ) { mVertBlurTask.SetRefreshRate(RenderTask::REFRESH_ONCE); @@ -471,19 +482,6 @@ void GaussianBlurView::CreateRenderTasks() mCompositeTask.SetCameraActor(mRenderFullSizeCamera); mCompositeTask.SetTargetFrameBuffer( mRenderTargetForRenderingChildren ); } - - mHorizBlurTask.SetCameraActor(mRenderDownsampledCamera); - mVertBlurTask.SetCameraActor(mRenderDownsampledCamera); - - mHorizBlurTask.SetTargetFrameBuffer( mRenderTarget2 ); - if(mUserOutputRenderTarget) - { - mVertBlurTask.SetTargetFrameBuffer( mUserOutputRenderTarget ); - } - else - { - mVertBlurTask.SetTargetFrameBuffer( mRenderTarget1 ); - } } void GaussianBlurView::RemoveRenderTasks() @@ -501,6 +499,7 @@ void GaussianBlurView::Activate() // make sure resources are allocated and start the render tasks processing AllocateResources(); CreateRenderTasks(); + mActivated = true; } void GaussianBlurView::ActivateOnce() @@ -515,7 +514,11 @@ void GaussianBlurView::Deactivate() // stop render tasks processing // Note: render target resources are automatically freed since we set the Image::Unused flag RemoveRenderTasks(); + mRenderTargetForRenderingChildren.Reset(); + mRenderTarget1.Reset(); + mRenderTarget2.Reset(); mRenderOnce = false; + mActivated = false; } void GaussianBlurView::SetBlurBellCurveWidth(float blurBellCurveWidth) @@ -574,11 +577,11 @@ void GaussianBlurView::SetShaderConstants() Vector2 yAxis(0.0f, 1.0f); for (i = 0; i < mNumSamples; ++i ) { - mHorizBlurShader.SetUniform( GetSampleOffsetsPropertyName( i ), uvOffsets[ i ] * xAxis ); - mHorizBlurShader.SetUniform( GetSampleWeightsPropertyName( i ), weights[ i ] ); + mImageActorHorizBlur.RegisterProperty( GetSampleOffsetsPropertyName( i ), uvOffsets[ i ] * xAxis ); + mImageActorHorizBlur.RegisterProperty( GetSampleWeightsPropertyName( i ), weights[ i ] ); - mVertBlurShader.SetUniform( GetSampleOffsetsPropertyName( i ), uvOffsets[ i ] * yAxis ); - mVertBlurShader.SetUniform( GetSampleWeightsPropertyName( i ), weights[ i ] ); + mImageActorVertBlur.RegisterProperty( GetSampleOffsetsPropertyName( i ), uvOffsets[ i ] * yAxis ); + mImageActorVertBlur.RegisterProperty( GetSampleWeightsPropertyName( i ), weights[ i ] ); } delete[] uvOffsets; diff --git a/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.h b/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.h index 0afa61c..7f38489 100644 --- a/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.h +++ b/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.h @@ -25,6 +25,7 @@ // INTERNAL INCLUDES #include #include +#include namespace Dali { @@ -153,23 +154,20 @@ private: FrameBufferImage mRenderTarget1; FrameBufferImage mRenderTarget2; - ShaderEffect mHorizBlurShader; - ShaderEffect mVertBlurShader; - - ImageActor mImageActorHorizBlur; - ImageActor mImageActorVertBlur; + Toolkit::ImageView mImageActorHorizBlur; + Toolkit::ImageView mImageActorVertBlur; RenderTask mHorizBlurTask; RenderTask mVertBlurTask; ///////////////////////////////////////////////////////////// // for compositing blur and children renders to offscreen target - ImageActor mImageActorComposite; + Toolkit::ImageView mImageActorComposite; RenderTask mCompositeTask; ///////////////////////////////////////////////////////////// // for holding blurred result - ImageActor mTargetActor; + Toolkit::ImageView mTargetActor; ///////////////////////////////////////////////////////////// // for animating fade in / out of blur, hiding internal implementation but allowing user to set via GaussianBlurView interface @@ -181,6 +179,8 @@ private: FrameBufferImage mUserOutputRenderTarget; Dali::Toolkit::GaussianBlurView::GaussianBlurViewSignal mFinishedSignal; ///< Signal emitted when blur has completed. + + bool mActivated:1; private: // Undefined copy constructor. diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp index 1453b73..da77f95 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp @@ -474,14 +474,13 @@ void ImageRenderer::InitializeRenderer( const Image& image ) { mImpl->mFlags &= ~Impl::IS_FROM_CACHE; - if( !image ) + mImpl->mRenderer = CreateRenderer(); + + if( image ) { - return; + ApplyImageToSampler( image ); } - mImpl->mRenderer = CreateRenderer(); - ApplyImageToSampler( image ); - // default shader or custom shader with the default image vertex shader if( !mImpl->mCustomShader || mImpl->mCustomShader->mVertexShader.empty() ) { @@ -497,7 +496,7 @@ void ImageRenderer::DoSetOnStage( Actor& actor ) { InitializeRenderer( mImageUrl ); } - else if( mImage ) + else { InitializeRenderer( mImage ); } diff --git a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp index cd36331..8251b69 100644 --- a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp +++ b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include #include #include @@ -37,10 +39,24 @@ const unsigned int GAUSSIAN_BLUR_DEFAULT_NUM_SAMPLES = 11; const unsigned int GAUSSIAN_BLUR_NUM_SAMPLES_INCREMENTATION = 10; const float GAUSSIAN_BLUR_BELL_CURVE_WIDTH = 4.5f; const float GAUSSIAN_BLUR_BELL_CURVE_WIDTH_INCREMENTATION = 5.f; -const Pixel::Format GAUSSIAN_BLUR_RENDER_TARGET_PIXEL_FORMAT = Pixel::RGB888; +const Pixel::Format GAUSSIAN_BLUR_RENDER_TARGET_PIXEL_FORMAT = Pixel::RGBA8888; const float GAUSSIAN_BLUR_DOWNSAMPLE_WIDTH_SCALE = 0.5f; const float GAUSSIAN_BLUR_DOWNSAMPLE_HEIGHT_SCALE = 0.5f; +const char* ALPHA_UNIFORM_NAME( "uAlpha" ); +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + uniform lowp float uAlpha;\n + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n + gl_FragColor.a *= uAlpha; + }\n +); + /** * The constraint is used to blend the group of blurred images continuously with a unified blur strength property value which ranges from zero to one. */ @@ -56,17 +72,17 @@ struct ActorOpacityConstraint void operator()( float& current, const PropertyInputContainer& inputs ) { float blurStrength = inputs[0]->GetFloat(); - if(blurStrength <= mRange.x) + if(blurStrength < mRange.x) { - current = 1.f; + current = 0.f; } else if(blurStrength > mRange.y) { - current = 0.f; + current = 1.f; } else { - current = ( mRange.y - blurStrength) / ( mRange.y - mRange.x ); + current = ( blurStrength - mRange.x) / ( mRange.y - mRange.x ); } } @@ -105,15 +121,15 @@ DALI_TYPE_REGISTRATION_END() SuperBlurView::SuperBlurView( unsigned int blurLevels ) : Control( ControlBehaviour( DISABLE_SIZE_NEGOTIATION ) ), - mBlurLevels( blurLevels ), + mTargetSize( Vector2::ZERO ), mBlurStrengthPropertyIndex(Property::INVALID_INDEX), - mResourcesCleared( true ), - mTargetSize( Vector2::ZERO ) + mBlurLevels( blurLevels ), + mResourcesCleared( true ) { DALI_ASSERT_ALWAYS( mBlurLevels > 0 && " Minimal blur level is one, otherwise no blur is needed" ); - mGaussianBlurView.assign( blurLevels, NULL ); + mGaussianBlurView.assign( blurLevels, Toolkit::GaussianBlurView() ); mBlurredImage.assign( blurLevels, FrameBufferImage() ); - mImageActors.assign( blurLevels + 1, ImageActor() ); + mRenderers.assign( blurLevels+1, Toolkit::ControlRenderer() ); } SuperBlurView::~SuperBlurView() @@ -139,50 +155,49 @@ void SuperBlurView::OnInitialize() { mBlurStrengthPropertyIndex = Self().RegisterProperty( "blurStrength", 0.f ); - DALI_ASSERT_ALWAYS( mImageActors.size() == mBlurLevels+1 && "must synchronize the ImageActor group if blur levels got changed " ); - for(unsigned int i=0; i<=mBlurLevels;i++) - { - mImageActors[i] = ImageActor::New( ); - mImageActors[i].SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); - mImageActors[i].SetParentOrigin( ParentOrigin::CENTER ); - mImageActors[i].SetZ(-static_cast(i)*0.01f); - mImageActors[i].SetColorMode( USE_OWN_MULTIPLY_PARENT_ALPHA ); - Self().Add( mImageActors[i] ); - } + Property::Map rendererMap; + rendererMap.Insert( "rendererType", "imageRenderer"); + + Property::Map shaderMap; + std::stringstream verterShaderString; + shaderMap[ "fragmentShader" ] = FRAGMENT_SHADER; + rendererMap.Insert( "shader", shaderMap ); - for(unsigned int i=0; i < mBlurLevels; i++) + Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); + for(unsigned int i=0; i<=mBlurLevels; i++) { - Constraint constraint = Constraint::New( mImageActors[i], Actor::Property::COLOR_ALPHA, ActorOpacityConstraint(mBlurLevels, i) ); - constraint.AddSource( ParentSource( mBlurStrengthPropertyIndex ) ); - constraint.Apply(); + mRenderers[i] = rendererFactory.GetControlRenderer( rendererMap ); + mRenderers[i].SetDepthIndex(i); } - - Self().SetSize(Stage::GetCurrent().GetSize()); } void SuperBlurView::SetImage(Image inputImage) { - DALI_ASSERT_ALWAYS( mImageActors.size() == mBlurLevels+1 && "must synchronize the ImageActor group if blur levels got changed " ); - DALI_ASSERT_ALWAYS( mBlurredImage.size() == mBlurLevels && "must synchronize the blurred image group if blur levels got changed " ); + if( mTargetSize == Vector2::ZERO || mInputImage == inputImage) + { + return; + } ClearBlurResource(); - mImageActors[0].SetImage( inputImage ); - - for(unsigned int i=1; i<=mBlurLevels;i++) - { - mImageActors[i].SetImage( mBlurredImage[i-1] ); - } + mInputImage = inputImage; + Actor self = Self(); + Toolkit::RendererFactory::Get().ResetRenderer( mRenderers[0], self, mInputImage ); BlurImage( 0, inputImage); for(unsigned int i=1; i(i+1); - mBlurredImage[i] = FrameBufferImage::New( mTargetSize.width/std::pow(2.f,exponent) , mTargetSize.height/std::pow(2.f,exponent), + float exponent = static_cast(i); + mBlurredImage[i-1] = FrameBufferImage::New( mTargetSize.width/std::pow(2.f,exponent) , mTargetSize.height/std::pow(2.f,exponent), GAUSSIAN_BLUR_RENDER_TARGET_PIXEL_FORMAT, Dali::Image::NEVER ); + rendererFactory.ResetRenderer( mRenderers[i], self, mBlurredImage[i-1] ); + } + + if( mInputImage ) + { + SetImage( mInputImage ); + } + + if( self.OnStage() ) + { + for(unsigned int i=0; i<=mBlurLevels;i++) + { + mRenderers[i].SetOnStage( self ); + } } } } +void SuperBlurView::OnStageConnection( int depth ) +{ + Control::OnStageConnection( depth ); + + if( mTargetSize == Vector2::ZERO ) + { + return; + } + + Actor self = Self(); + mRenderers[0].SetOnStage( self ); + for(unsigned int i=1; i<=mBlurLevels;i++) + { + mRenderers[i].SetOnStage( self ); + + Renderer renderer = self.GetRendererAt( i ); + Property::Index index = renderer.RegisterProperty( ALPHA_UNIFORM_NAME, 0.f ); + Constraint constraint = Constraint::New( renderer, index, ActorOpacityConstraint(mBlurLevels, i-1) ); + constraint.AddSource( Source( self, mBlurStrengthPropertyIndex ) ); + constraint.Apply(); + } +} + +void SuperBlurView::OnStageDisconnection( ) +{ + if( mTargetSize == Vector2::ZERO ) + { + return; + } + + Actor self = Self(); + for(unsigned int i=0; i #include #include +#include namespace Dali { @@ -53,6 +54,12 @@ public: void SetImage(Image inputImage); /** + * Get the image for blurring. + * @return The image for blurring. + */ + Image GetImage(); + + /** * @copydoc Dali::Toolkit::SuperBlurView::GetBlurStrengthPropertyIndex */ Property::Index GetBlurStrengthPropertyIndex() const; @@ -119,6 +126,21 @@ private: // from Control */ virtual void OnSizeSet(const Vector3& targetSize); + /** + * @copydoc CustomActorImpl::OnStageConnection() + */ + virtual void OnStageConnection( int depth ); + + /** + * @copydoc CustomActorImpl::OnStageDisconnection() + */ + virtual void OnStageDisconnection(); + + /** + * @copydoc CustomActorImpl::GetNaturalSize() + */ + virtual Vector3 GetNaturalSize(); + private: /** @@ -140,18 +162,17 @@ private: void ClearBlurResource(); private: - - unsigned int mBlurLevels; - - Property::Index mBlurStrengthPropertyIndex; - std::vector mGaussianBlurView; std::vector mBlurredImage; - std::vector mImageActors; - bool mResourcesCleared; - + std::vector mRenderers; + Image mInputImage; Vector2 mTargetSize; + Toolkit::SuperBlurView::SuperBlurViewSignal mBlurFinishedSignal; ///< Signal emitted when blur has completed. + + Property::Index mBlurStrengthPropertyIndex; + unsigned int mBlurLevels; + bool mResourcesCleared; }; } diff --git a/dali-toolkit/public-api/controls/gaussian-blur-view/gaussian-blur-view.h b/dali-toolkit/public-api/controls/gaussian-blur-view/gaussian-blur-view.h index 10f05a9..7ffdaca 100644 --- a/dali-toolkit/public-api/controls/gaussian-blur-view/gaussian-blur-view.h +++ b/dali-toolkit/public-api/controls/gaussian-blur-view/gaussian-blur-view.h @@ -20,11 +20,9 @@ // EXTERNAL INCLUDES #include -#include #include #include #include -#include // INTERNAL INCLUDES #include diff --git a/dali-toolkit/public-api/controls/image-view/image-view.cpp b/dali-toolkit/public-api/controls/image-view/image-view.cpp index 6408c19..3333289 100644 --- a/dali-toolkit/public-api/controls/image-view/image-view.cpp +++ b/dali-toolkit/public-api/controls/image-view/image-view.cpp @@ -62,7 +62,7 @@ ImageView ImageView::New( Image image ) { ImageView imageView = Internal::ImageView::New(); imageView.SetImage( image ); - return ImageView( imageView ); + return imageView; } ImageView ImageView::New( const std::string& url ) -- 2.7.4