From: Xiangyin Ma Date: Mon, 14 Sep 2015 16:38:02 +0000 (+0100) Subject: (Control base)Use RendererFactory&ControlRenderer to handle background X-Git-Tag: dali_1.1.3~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=4ac30f392a3277a566a03176ea066841c6784b61 (Control base)Use RendererFactory&ControlRenderer to handle background Change-Id: I19eb9bd4b94bc8e924c77155691bab4ebc553ad6 --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp index 722f0a8..f77f903 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp @@ -396,17 +396,21 @@ int UtcDaliControlBackgroundImage(void) Image image = ResourceImage::New("TestImage"); control.SetBackgroundImage( image ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::WHITE, TEST_LOCATION ); + DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); control.SetBackgroundColor( Color::GREEN ); DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::GREEN, TEST_LOCATION ); + control.SetBackgroundColor( Color::RED ); + DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION ); + control.ClearBackground(); DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); control.SetBackgroundColor( Color::YELLOW ); control.SetBackgroundImage( image ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::YELLOW, TEST_LOCATION ); + // The background can be either an image or a color, not both + DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); END_TEST; } @@ -418,32 +422,33 @@ int UtcDaliControlBackgroundProperties(void) DALI_TEST_CHECK( control.GetChildCount() == 0 ); DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); - DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), Color::TRANSPARENT, TEST_LOCATION ); - DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND_IMAGE ).Get< Property::Map >().Empty() ); + DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() ); - control.SetProperty( Control::Property::BACKGROUND_COLOR, Color::RED ); - DALI_TEST_CHECK( control.GetChildCount() > 0 ); + Property::Map colorMap; + colorMap["color"] = Color::RED; + control.SetProperty( Control::Property::BACKGROUND, colorMap ); DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION ); - DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), Color::RED, TEST_LOCATION ); + DALI_TEST_CHECK( control.GetChildCount() > 0 ); + Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND ); + Property::Map* resultMap = propValue.GetMap(); + DALI_TEST_CHECK( resultMap->Find( "color" ) ); + DALI_TEST_CHECK( resultMap->Find( "color" )->Get() == Color::RED ); Property::Map imageMap; imageMap[ "filename" ] = "TestImage"; - control.SetProperty( Control::Property::BACKGROUND_IMAGE, imageMap ); + control.SetProperty( Control::Property::BACKGROUND, imageMap ); DALI_TEST_CHECK( control.GetChildCount() > 0 ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION ); - DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), Color::RED, TEST_LOCATION ); - - Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND_IMAGE ); - Property::Map* resultMap = propValue.GetMap(); + DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); + propValue = control.GetProperty( Control::Property::BACKGROUND ); + resultMap = propValue.GetMap(); DALI_TEST_CHECK( resultMap->Find( "filename" ) ); DALI_TEST_CHECK( resultMap->Find( "filename" )->Get< std::string>() == "TestImage" ); Property::Map emptyMap; - control.SetProperty( Control::Property::BACKGROUND_IMAGE, emptyMap ); + control.SetProperty( Control::Property::BACKGROUND, emptyMap ); DALI_TEST_CHECK( control.GetChildCount() == 0 ); DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); - DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), Color::TRANSPARENT, TEST_LOCATION ); - DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND_IMAGE ).Get< Property::Map >().Empty() ); + DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() ); END_TEST; } diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp index 1c654dd..a49de61 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp @@ -94,10 +94,10 @@ int UtcDaliRendererFactoryCopyAndAssignment(void) END_TEST; } -int UtcDaliRendererFactoryGetColorRenderer(void) +int UtcDaliRendererFactoryGetColorRenderer1(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliRendererFactoryGetColorRenderer" ); + tet_infoline( "UtcDaliRendererFactoryGetColorRenderer1: Request color renderer with a Property::Map" ); RendererFactory factory = RendererFactory::Get(); DALI_TEST_CHECK( factory ); @@ -130,6 +130,38 @@ int UtcDaliRendererFactoryGetColorRenderer(void) END_TEST; } +int UtcDaliRendererFactoryGetColorRenderer2(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactoryGetColorRenderer2: Request color renderer with a Vector4" ); + + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f ); + ControlRenderer controlRenderer = factory.GetControlRenderer(testColor); + DALI_TEST_CHECK( controlRenderer ); + + Actor actor = Actor::New(); + actor.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( actor ); + controlRenderer.SetSize(Vector2(200.f, 200.f)); + controlRenderer.SetOnStage( actor ); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + + application.SendNotification(); + application.Render(0); + + Vector4 actualValue(Vector4::ZERO); + DALI_TEST_CHECK( gl.GetUniformValue( "uBlendColor", actualValue ) ); + DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION ); + + END_TEST; +} + int UtcDaliRendererFactoryGetLinearGradientRenderer(void) { ToolkitTestApplication application; @@ -234,10 +266,10 @@ int UtcDaliRendererFactoryGetRadialGradientRenderer(void) END_TEST; } -int UtcDaliRendererFactoryGetImageRenderer(void) +int UtcDaliRendererFactoryGetImageRenderer1(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliRendererFactoryGetImageRenderer" ); + tet_infoline( "UtcDaliRendererFactoryGetImageRenderer1: Request image renderer with a Property::Map" ); RendererFactory factory = RendererFactory::Get(); DALI_TEST_CHECK( factory ); @@ -281,3 +313,143 @@ int UtcDaliRendererFactoryGetImageRenderer(void) END_TEST; } + +int UtcDaliRendererFactoryGetImageRenderer2(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactoryGetImageRenderer2: Request image renderer with an image handle" ); + + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME); + ControlRenderer controlRenderer = factory.GetControlRenderer( image ); + + Actor actor = Actor::New(); + actor.SetSize( 200.f, 200.f ); + Stage::GetCurrent().Add( actor ); + controlRenderer.SetSize( Vector2(200.f, 200.f) ); + controlRenderer.SetOnStage( actor ); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + application.SendNotification(); + application.Render(); + + Integration::ResourceRequest* request = application.GetPlatform().GetRequest(); + if(request) + { + application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD))); + } + + application.Render(); + application.SendNotification(); + + DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc)); + + int textureUnit = -1; + DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); + DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliRendererFactoryResetRenderer1(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactoryResetRenderer1" ); + + Actor actor = Actor::New(); + actor.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( actor ); + + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + ControlRenderer controlRenderer = factory.GetControlRenderer( Color::RED ); + DALI_TEST_CHECK( controlRenderer ); + controlRenderer.SetSize(Vector2(200.f, 200.f)); + controlRenderer.SetOnStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + application.SendNotification(); + application.Render(0); + Vector4 actualValue(Vector4::ZERO); + DALI_TEST_CHECK( gl.GetUniformValue( "uBlendColor", actualValue ) ); + DALI_TEST_EQUALS( actualValue, Color::RED, TEST_LOCATION ); + + bool isNewRenderer = factory.ResetRenderer( controlRenderer, Color::GREEN ); + DALI_TEST_CHECK( !isNewRenderer ); + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK( gl.GetUniformValue( "uBlendColor", actualValue ) ); + DALI_TEST_EQUALS( actualValue, Color::GREEN, TEST_LOCATION ); + + Image bufferImage = CreateBufferImage( 100, 200, Vector4( 1.f, 1.f, 1.f, 1.f ) ); + isNewRenderer = factory.ResetRenderer( controlRenderer, bufferImage ); + DALI_TEST_CHECK( isNewRenderer ); + + Actor actor2 = Actor::New(); + actor2.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( actor2 ); + controlRenderer.SetSize(Vector2(200.f, 200.f)); + controlRenderer.SetOnStage( actor2 ); + application.SendNotification(); + application.Render(0); + Image samplerImage = actor2.GetRendererAt(0u).GetMaterial().GetSamplerAt(0u).GetImage(); + DALI_TEST_CHECK( BufferImage::DownCast( samplerImage ) ); + + END_TEST; +} + +int UtcDaliRendererFactoryResetRenderer2(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactoryResetRenderer2" ); + + Actor actor = Actor::New(); + actor.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( actor ); + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + Image resourceImage = ResourceImage::New(TEST_IMAGE_FILE_NAME); + ControlRenderer controlRenderer = factory.GetControlRenderer( resourceImage ); + DALI_TEST_CHECK( controlRenderer ); + controlRenderer.SetSize(Vector2(200.f, 200.f)); + controlRenderer.SetOnStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + application.SendNotification(); + application.Render(0); + Image samplerImage = actor.GetRendererAt(0u).GetMaterial().GetSamplerAt(0u).GetImage(); + DALI_TEST_CHECK( ResourceImage::DownCast( samplerImage ) ); + + Image bufferImage = CreateBufferImage( 100, 200, Vector4( 1.f, 1.f, 1.f, 1.f ) ); + bool isNewRenderer = factory.ResetRenderer( controlRenderer, bufferImage ); + DALI_TEST_CHECK( !isNewRenderer ); + application.SendNotification(); + application.Render(0); + samplerImage = actor.GetRendererAt(0u).GetMaterial().GetSamplerAt(0u).GetImage(); + DALI_TEST_CHECK( BufferImage::DownCast( samplerImage ) ); + + isNewRenderer = factory.ResetRenderer( controlRenderer, Color::RED ); + DALI_TEST_CHECK( isNewRenderer ); + + Actor actor2 = Actor::New(); + actor2.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( actor2 ); + controlRenderer.SetSize(Vector2(200.f, 200.f)); + controlRenderer.SetOnStage( actor2 ); + TestGlAbstraction& gl = application.GetGlAbstraction(); + application.SendNotification(); + application.Render(0); + Vector4 actualValue(Vector4::ZERO); + DALI_TEST_CHECK( gl.GetUniformValue( "uBlendColor", actualValue ) ); + DALI_TEST_EQUALS( actualValue, Color::RED, TEST_LOCATION ); + + END_TEST; +} diff --git a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp index f64ab9f..f836e8c 100644 --- a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp +++ b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp @@ -87,6 +87,26 @@ ControlRenderer RendererFactory::GetControlRenderer( const Property::Map& proper return GetImplementation( *this ).GetControlRenderer( propertyMap ); } +ControlRenderer RendererFactory::GetControlRenderer( const Vector4& color ) +{ + return GetImplementation( *this ).GetControlRenderer( color ); +} + +bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Vector4& color ) +{ + return GetImplementation( *this ).ResetRenderer( renderer, color ); +} + +ControlRenderer RendererFactory::GetControlRenderer( const Image& image ) +{ + return GetImplementation( *this ).GetControlRenderer( image ); +} + +bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Image& image ) +{ + return GetImplementation( *this ).ResetRenderer( renderer, image ); +} + } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h index 3c3cec7..4a30888 100644 --- a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h +++ b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h @@ -25,6 +25,8 @@ namespace Dali { +class Image; +class Vector4; namespace Toolkit { @@ -84,13 +86,50 @@ public: RendererFactory& operator=( const RendererFactory& handle ); /** - * Request the control renderer + * @brief Request the control renderer + * * @param[in] propertyMap The map contains the properties required by the control renderer * Depends on the content of the map, different kind of renderer would be returned. - * @return the pointer pointing to control renderer + * @return The pointer pointing to control renderer */ ControlRenderer GetControlRenderer( const Property::Map& propertyMap ); + /** + * @brief Request the control renderer to render the given color + * + * @param[in] color The color to be rendered + * @return The pointer pointing to the control renderer + */ + ControlRenderer GetControlRenderer( const Vector4& color ); + + /** + * @brief Request the current control renderer to render the given color + * + * if the current renderer is a handle to an internal color renderer, set this color to it, + * else the renderer would be a handle to a newly created internal color renderer. + * + * @return Whether a new internal control renderer is created. + */ + bool ResetRenderer( ControlRenderer& renderer, const Vector4& color ); + + /** + * @brief Request the control renderer to render the image. + * + * @param[in] image The image to be rendered. + * @return The pointer pointing to the control renderer + */ + ControlRenderer GetControlRenderer( const Image& image ); + + /** + * @brief Request the current control renderer to render the given image + * + * if the current renderer is a handle to an internal image renderer, set this image to it, + * else the renderer would be a handle to a newly created internal image renderer. + * + * @return Whether a new internal control renderer is created. + */ + bool ResetRenderer( ControlRenderer& renderer, const Image& image ); + private: explicit DALI_INTERNAL RendererFactory(Internal::RendererFactory *impl); diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp b/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp index 01ebca9..7b3ae1c 100644 --- a/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp @@ -66,7 +66,8 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( } ColorRenderer::ColorRenderer() -: ControlRenderer() +: ControlRenderer(), + mBlendColorIndex( Property::INVALID_INDEX ) { } @@ -76,19 +77,7 @@ ColorRenderer::~ColorRenderer() void ColorRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) { - mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); - if( !(mImpl->mGeometry) ) - { - mImpl->mGeometry = RendererFactoryCache::CreateQuadGeometry(); - factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry ); - } - - mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::COLOR_SHADER ); - if( !(mImpl->mShader) ) - { - mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - factoryCache.SaveShader( RendererFactoryCache::COLOR_SHADER, mImpl->mShader ); - } + Initialize( factoryCache ); Property::Value* color = propertyMap.Find( COLOR_NAME ); if( !( color && color->Get(mBlendColor) ) ) @@ -118,13 +107,44 @@ void ColorRenderer::SetOffset( const Vector2& offset ) void ColorRenderer::DoSetOnStage( Actor& actor ) { - (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBlendColor ); + mBlendColorIndex = (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBlendColor ); if( mBlendColor.a < 1.f ) { (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON ); } } +void ColorRenderer::Initialize( RendererFactoryCache& factoryCache) +{ + mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); + if( !(mImpl->mGeometry) ) + { + mImpl->mGeometry = RendererFactoryCache::CreateQuadGeometry(); + factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry ); + } + + mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::COLOR_SHADER ); + if( !(mImpl->mShader) ) + { + mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); + factoryCache.SaveShader( RendererFactoryCache::COLOR_SHADER, mImpl->mShader ); + } +} + +void ColorRenderer::SetColor(const Vector4& color) +{ + mBlendColor = color; + + if( mImpl->mIsOnStage ) + { + (mImpl->mRenderer).SetProperty( mBlendColorIndex, color ); + if( color.a < 1.f && (mImpl->mRenderer).GetMaterial().GetBlendMode() != BlendingMode::ON) + { + (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON ); + } + } +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.h b/dali-toolkit/internal/controls/renderers/color/color-renderer.h index d7cc1e5..5f5dd27 100644 --- a/dali-toolkit/internal/controls/renderers/color/color-renderer.h +++ b/dali-toolkit/internal/controls/renderers/color/color-renderer.h @@ -81,6 +81,21 @@ protected: */ virtual void DoSetOnStage( Actor& actor ); +public: + + /** + * Request the geometry and shader from the cache, if not available, create and save to the cache for sharing. + * + * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object + */ + void Initialize( RendererFactoryCache& factoryCache ); + + /** + * Set the color for rendering. + * @param[in] color The color to be rendered. + */ + void SetColor( const Vector4& color ); + private: // Undefined @@ -92,6 +107,7 @@ private: private: Vector4 mBlendColor; + Property::Index mBlendColorIndex; }; diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp index cfe4e21..3a2da25 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp @@ -36,7 +36,6 @@ namespace Internal namespace { - const char * const IMAGE_URL_NAME("image-url"); const char * const IMAGE_FITTING_MODE("image-fitting-mode"); const char * const IMAGE_SAMPLING_MODE("image-sampling-mode"); @@ -91,24 +90,7 @@ ImageRenderer::~ImageRenderer() void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) { - mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); - if( !(mImpl->mGeometry) ) - { - mImpl->mGeometry = factoryCache.CreateQuadGeometry(); - factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry ); - } - - mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER ); - if( !mImpl->mShader ) - { - mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader ); - } - - mDesiredSize = ImageDimensions(); - mFittingMode = FittingMode::DEFAULT; - mSamplingMode = SamplingMode::DEFAULT; - mImageUrl.clear(); + Initialize(factoryCache); Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME ); if( imageURLValue ) @@ -251,6 +233,28 @@ void ImageRenderer::DoSetOffStage( Actor& actor ) ControlRenderer::SetOffStage( actor ); } +void ImageRenderer::Initialize( RendererFactoryCache& factoryCache ) +{ + mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); + if( !(mImpl->mGeometry) ) + { + mImpl->mGeometry = factoryCache.CreateQuadGeometry(); + factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry ); + } + + mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER ); + if( !mImpl->mShader ) + { + mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); + factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader ); + } + + mDesiredSize = ImageDimensions(); + mFittingMode = FittingMode::DEFAULT; + mSamplingMode = SamplingMode::DEFAULT; + mImageUrl.clear(); +} + void ImageRenderer::SetImage( const std::string& imageUrl ) { SetImage( imageUrl, 0, 0, Dali::FittingMode::DEFAULT, Dali::SamplingMode::DEFAULT ); diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.h b/dali-toolkit/internal/controls/renderers/image/image-renderer.h index fbebfc4..e3a60a0 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.h +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.h @@ -83,6 +83,7 @@ public: ~ImageRenderer(); public: // from ControlRenderer + /** * @copydoc ControlRenderer::Initialize */ @@ -117,6 +118,13 @@ protected: public: /** + * Request the geometry and shader from the cache, if not available, create and save to the cache for sharing. + * + * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object + */ + void Initialize( RendererFactoryCache& factoryCache ); + + /** * @brief Sets the image of this renderer to the resource at imageUrl * The renderer will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage * diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp index 91d5ed3..1320436 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp @@ -19,6 +19,7 @@ // EXTERNAL INCLUDES #include +#include #include #include #include @@ -107,6 +108,64 @@ Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Property::Ma return Toolkit::ControlRenderer(rendererPtr); } +Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Vector4& color ) +{ + ColorRenderer* rendererPtr = new ColorRenderer(); + + if( !mFactoryCache ) + { + mFactoryCache = new RendererFactoryCache(); + } + rendererPtr->Initialize( *( mFactoryCache.Get() ) ); + + rendererPtr->SetColor(color); + + return Toolkit::ControlRenderer(rendererPtr); +} + +bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Vector4& color ) +{ + ColorRenderer* rendererPtr = dynamic_cast(&GetImplementation(renderer)); + if( rendererPtr ) + { + rendererPtr->SetColor(color); + return false; + } + else + { + renderer = GetControlRenderer(color); + return true; + } +} + +Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Image& image ) +{ + ImageRenderer* rendererPtr = new ImageRenderer(); + if( !mFactoryCache ) + { + mFactoryCache = new RendererFactoryCache(); + } + rendererPtr->Initialize( *( mFactoryCache.Get() ) ); + rendererPtr->SetImage( image ); + + return Toolkit::ControlRenderer(rendererPtr); +} + +bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Image& image ) +{ + ImageRenderer* rendererPtr = dynamic_cast(&GetImplementation(renderer)); + if( rendererPtr ) + { + rendererPtr->SetImage(image); + return false; + } + else + { + renderer = GetControlRenderer(image); + return true; + } +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h index 44af828..93cbc3c 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h @@ -50,10 +50,30 @@ public: RendererFactory(); /** - * @copydoc Toolkit::RenderFactory::GetControlRenderer + * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Property::Map& ) */ Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap ); + /** + * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Vector4& ) + */ + Toolkit::ControlRenderer GetControlRenderer( const Vector4& color ); + + /** + * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, const Vector4& ) + */ + bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Vector4& color ); + + /** + * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Image& ) + */ + Toolkit::ControlRenderer GetControlRenderer( const Image& image ); + + /** + * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, const Image& ) + */ + bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Image& image ); + protected: /** diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index b4b9cdb..af2f4ca 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -22,7 +22,6 @@ #include // for strcmp #include #include -#include #include #include #include @@ -34,11 +33,14 @@ // INTERNAL INCLUDES #include +#include #include #include #include #include #include +#include +#include namespace Dali { @@ -162,127 +164,96 @@ TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &Do DALI_TYPE_REGISTRATION_END() + +const char * const BACKGROUND_COLOR_NAME("color"); + /** * Structure which holds information about the background of a control */ struct Background { - Actor actor; ///< Background actor - Vector4 color; ///< The color of the actor. + //ToDo: remove this actor and apply the Renderer on the Control + // when the implementation of Actor::RemoveRenderer(Renderer&) is in place. + Actor actor; ///< Background actor + ControlRenderer controlRenderer; ///< The control renderer to render the background + // The background can either be an image or a solid color. + Image image; ///< The background image + Vector4 color; ///< The background color /** * Constructor */ Background() : actor(), - color( Color::WHITE ) + controlRenderer(), + image(), + color( Color::TRANSPARENT ) { } }; -unsigned int gQuadIndex[6] = { 0, 2, 1, 1, 2, 3 }; +//ToDo: skip this actor creation and apply the Renderer on the Control +// when the implementation of Actor::RemoveRenderer(Renderer&) is in place. +Actor CreateBackgroundActor() +{ + // Create the actor + Actor actor = Actor::New(); + actor.SetSize( Vector3::ONE ); + actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION ); + actor.SetColorMode( USE_PARENT_COLOR ); -Vector2 gQuad[] = { - Vector2( -0.5f, -0.5f ), - Vector2( 0.5f, -0.5f ), - Vector2( -0.5f, 0.5f ), - Vector2( 0.5f, 0.5f ) -}; + //Constraint scale of the background actor to the size of the control + Constraint constraint = Constraint::New( actor, + Actor::Property::SCALE, + EqualToConstraint() ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.Apply(); + return actor; +} + +/** + * @brief Create the background actor for the control. + * + * @param[in] actor The parent actor of the background + * @param[in] color The background color + */ +void CreateBackground( Background& background, const Vector4& color ) +{ + background.actor = CreateBackgroundActor(); -const char* VERTEX_SHADER_COLOR = DALI_COMPOSE_SHADER( - attribute mediump vec2 aPosition;\n - uniform mediump mat4 uMvpMatrix;\n - void main()\n - {\n - gl_Position = uMvpMatrix * vec4( aPosition, 0.0, 1.0 );\n - }\n -); + background.image.Reset(); + background.color = color; -const char* FRAGMENT_SHADER_COLOR = DALI_COMPOSE_SHADER( - uniform lowp vec4 uBackgroundColor;\n - uniform lowp vec4 uColor;\n - void main()\n - {\n - gl_FragColor = uBackgroundColor * uColor;\n - }\n -); + // Create the control renderer + RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); + background.controlRenderer = rendererFactory.GetControlRenderer(color); + // ToDo: Call SetOnStage at Control::OnStageConnection and call SetOffStage at Control::OnStageDisconnection; + // Currently Actor::RemoveRenderer doesnot work yet. + background.controlRenderer.SetOnStage( background.actor ); +} /** * @brief Create the background actor for the control. * * @param[in] actor The parent actor of the background - * @param[in] color The background color - * @param[in] image If a valid image is supplied this will be the texture used by the background - * - * @return An actor which will render the background - * + * @param[in] image The background image */ -Actor CreateBackground( Actor parent, const Vector4& color, Image image = Image() ) +void CreateBackground( Background& background, const Image& image ) { - if( !image ) - { - PropertyBuffer vertexBuffer; - Shader shader; - Material material; - - Property::Map vertexFormat; - vertexFormat["aPosition"] = Property::VECTOR2; - - //Create a vertex buffer for vertex positions - vertexBuffer = PropertyBuffer::New( vertexFormat, 4u ); - vertexBuffer.SetData( gQuad ); - - shader = Shader::New( VERTEX_SHADER_COLOR, FRAGMENT_SHADER_COLOR ); - material = Material::New( shader ); - - //Create the index buffer - Property::Map indexFormat; - indexFormat["indices"] = Property::INTEGER; - PropertyBuffer indexBuffer = PropertyBuffer::New( indexFormat, 6u ); - indexBuffer.SetData(gQuadIndex); - - //Create the geometry - Geometry mesh = Geometry::New(); - mesh.AddVertexBuffer( vertexBuffer ); - mesh.SetIndexBuffer( indexBuffer ); - - //Add uniforms to the shader - shader.RegisterProperty( "uBackgroundColor", color ); - - //Create the renderer - Renderer renderer = Renderer::New( mesh, material ); - renderer.SetDepthIndex( parent.GetHierarchyDepth() + BACKGROUND_DEPTH_INDEX ); - - //Create the actor - Actor meshActor = Actor::New(); - meshActor.SetSize( Vector3::ONE ); - meshActor.AddRenderer( renderer ); - meshActor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION ); - meshActor.SetColorMode( USE_PARENT_COLOR ); - - //Constraint scale of the mesh actor to the size of the control - Constraint constraint = Constraint::New( meshActor, - Actor::Property::SCALE, - EqualToConstraint() ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.Apply(); - - return meshActor; - } - else - { - ImageActor imageActor = ImageActor::New( image ); - imageActor.SetColor( color ); - imageActor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION ); - imageActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR ); - imageActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); - imageActor.SetSortModifier( parent.GetHierarchyDepth() + BACKGROUND_DEPTH_INDEX ); - - return imageActor; - } + background.actor = CreateBackgroundActor(); + background.color = Color::TRANSPARENT; + background.image = image; + + // Create the control renderer + RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); + background.controlRenderer = rendererFactory.GetControlRenderer(image); + + // ToDo: Call SetOnStage at Control::OnStageConnection and call SetOffStage at Control::OnStageDisconnection; + // Currently Actor::RemoveRenderer doesnot work yet. + background.controlRenderer.SetOnStage( background.actor ); } } // unnamed namespace @@ -379,25 +350,28 @@ public: controlImpl.SetStyleName( value.Get< std::string >() ); break; } - - case Toolkit::Control::Property::BACKGROUND_COLOR: - { - controlImpl.SetBackgroundColor( value.Get< Vector4 >() ); - break; - } - - case Toolkit::Control::Property::BACKGROUND_IMAGE: + case Toolkit::Control::Property::BACKGROUND: { Image image = Scripting::NewImage( value ); if ( image ) { controlImpl.SetBackgroundImage( image ); + break; } - else + const Property::Map* map = value.GetMap(); + if( map ) { - // An empty map means the background is no longer required - controlImpl.ClearBackground(); + const Property::Value* colorValue = map->Find( BACKGROUND_COLOR_NAME ); + Vector4 color; + if( colorValue && colorValue->Get(color)) + { + controlImpl.SetBackgroundColor( color ); + break; + } } + + // The background is neither an valid image nor a valid color, so it is no longer required + controlImpl.ClearBackground(); break; } @@ -441,35 +415,20 @@ public: break; } - case Toolkit::Control::Property::BACKGROUND_COLOR: - { - value = controlImpl.GetBackgroundColor(); - break; - } - - case Toolkit::Control::Property::BACKGROUND_IMAGE: + case Toolkit::Control::Property::BACKGROUND: { Property::Map map; Background* back = controlImpl.mImpl->mBackground; - if ( back && back->actor ) + if ( back && back->actor) { - if( back->actor.GetRendererCount() > 0 && back->actor.GetRendererAt(0).GetMaterial().GetNumberOfSamplers() > 0 ) + if( back->image ) { - Image image = back->actor.GetRendererAt(0).GetMaterial().GetSamplerAt(0).GetImage(); - if ( image ) - { - Scripting::CreatePropertyMap( image, map ); - } + Scripting::CreatePropertyMap( back->image, map ); } else { - ImageActor imageActor = ImageActor::DownCast( back->actor ); - if ( imageActor ) - { - Image image = imageActor.GetImage(); - Scripting::CreatePropertyMap( image, map ); - } + map[BACKGROUND_COLOR_NAME] = back->color; } } @@ -513,14 +472,12 @@ public: static PropertyRegistration PROPERTY_1; static PropertyRegistration PROPERTY_2; static PropertyRegistration PROPERTY_3; - static PropertyRegistration PROPERTY_4; }; // Properties registered without macro to use specific member variables. -PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "style-name", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "background-color", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "background-image", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "key-input-focus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "style-name", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "background", Toolkit::Control::Property::BACKGROUND, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "key-input-focus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); Toolkit::Control Control::New() { @@ -566,30 +523,28 @@ void Control::SetBackgroundColor( const Vector4& color ) { Background& background( mImpl->GetBackground() ); - if ( background.actor ) + // The background renderer exits and it is a color renderer, we continue to use the current renderer + if ( background.actor && (!background.image) + && (!Toolkit::RendererFactory::Get().ResetRenderer( background.controlRenderer, color ) )) { - if( background.actor.GetRendererCount() > 0 ) - { - Shader shader = background.actor.GetRendererAt(0).GetMaterial().GetShader(); - shader.SetProperty( shader.GetPropertyIndex("uBackgroundColor"), color ); - } - else - { - background.actor.SetColor( color ); - } + background.color = color; } else { - // Create Mesh Actor - Actor actor = CreateBackground(Self(), color ); - background.actor = actor; + // TODO: Apply the new renderer directly, as Actor::RemoveRenderer is not working yet, we create a new actor + if( background.actor ) + { + mImpl->mAddRemoveBackgroundChild = true; + Self().Remove( background.actor ); + mImpl->mAddRemoveBackgroundChild = false; + } + // Create background actor + CreateBackground(background, color ); mImpl->mAddRemoveBackgroundChild = true; // The actor does not need to be inserted to guarantee order. - Self().Add( actor ); + Self().Add( background.actor ); mImpl->mAddRemoveBackgroundChild = false; } - - background.color = color; } Vector4 Control::GetBackgroundColor() const @@ -605,23 +560,28 @@ void Control::SetBackgroundImage( Image image ) { Background& background( mImpl->GetBackground() ); - if ( background.actor ) - { - // Remove Current actor, unset AFTER removal - mImpl->mAddRemoveBackgroundChild = true; - Self().Remove( background.actor ); - mImpl->mAddRemoveBackgroundChild = false; - background.actor.Reset(); - } - - Actor actor = CreateBackground(Self(), background.color, image); - - // Set the background actor before adding so that we do not inform derived classes - background.actor = actor; - mImpl->mAddRemoveBackgroundChild = true; - // The actor does not need to be inserted to guarantee order. - Self().Add( actor ); - mImpl->mAddRemoveBackgroundChild = false; + // The background renderer exits and it is an image renderer, we continue to use the current renderer + if( background.actor && background.image + && (! Toolkit::RendererFactory::Get().ResetRenderer( background.controlRenderer, image ) ) ) + { + background.image = image; + } + else + { + // TODO: Apply the new renderer directly, as Actor::RemoveRenderer is not working yet, we create a new actor + if( background.actor ) + { + mImpl->mAddRemoveBackgroundChild = true; + Self().Remove( background.actor ); + mImpl->mAddRemoveBackgroundChild = false; + } + // Create background actor + CreateBackground(background, image); + mImpl->mAddRemoveBackgroundChild = true; + // The actor does not need to be inserted to guarantee order. + Self().Add( background.actor ); + mImpl->mAddRemoveBackgroundChild = false; + } } void Control::ClearBackground() @@ -968,25 +928,9 @@ void Control::OnStageConnection( int depth ) } } - if( mImpl->mBackground ) + if( mImpl->mBackground && mImpl->mBackground->controlRenderer) { - if(mImpl->mBackground->actor.GetRendererCount() > 0 ) - { - Renderer backgroundRenderer = mImpl->mBackground->actor.GetRendererAt( 0 ); - if(backgroundRenderer) - { - backgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth ); - } - } - else - { - - ImageActor imageActor = ImageActor::DownCast( mImpl->mBackground->actor ); - if ( imageActor ) - { - imageActor.SetSortModifier( BACKGROUND_DEPTH_INDEX+depth ); - } - } + mImpl->mBackground->controlRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth ); } } diff --git a/dali-toolkit/public-api/controls/control.h b/dali-toolkit/public-api/controls/control.h index 35587f9..74f7fa8 100644 --- a/dali-toolkit/public-api/controls/control.h +++ b/dali-toolkit/public-api/controls/control.h @@ -89,8 +89,7 @@ public: enum { STYLE_NAME = PROPERTY_START_INDEX, ///< name "style-name", @see SetStyleName, type std::string - BACKGROUND_COLOR, ///< name "background-color", @see SetBackgroundColor, type Vector4 - BACKGROUND_IMAGE, ///< name "background-image", @see SetBackgroundImage, type Map + BACKGROUND, ///< name "background", @see SetBackgroundImage, type Map KEY_INPUT_FOCUS, ///< name "key-input-focus", @see SetKeyInputFocus, type bool }; }; @@ -271,6 +270,8 @@ public: /** * @brief Retrieves the background color of the control. * + * @deprecated DALi 1.1.3 API removed. + * * @return The background color of the control. */ Vector4 GetBackgroundColor() const;