From c560f95435d40fd3980cd5f92da65c9f28f440e7 Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Wed, 26 Aug 2015 14:23:53 +0100 Subject: [PATCH] ControlRenderer & RendererFactory for Toolkit Controls 1. example of getting a ColorRenderer: Property::Map propertyMap; propertyMap.Insert("renderer-type", "color-renderer"); propertyMap.Insert("blend-color", Color::MAGENTA); Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); Internal::ControlRendererPtr renderer = rendererFactory.GetControlRenderer(propertyMap); 2. example of getting a GradientRenderer: Property::Map propertyMap; propertyMap.Insert("renderer-type", "gradient-renderer"); propertyMap.Insert("gradient-center", Vector2(0.5f, 0.5f)); propertyMap.Insert("gradient-radius", 0.5f); Property::Array stopOffsets; stopOffsets.PushBack( 0.0f ); stopOffsets.PushBack( 1.f ); propertyMap.Insert("gradient-stop-offset", stopOffsets); Property::Array stopColors; stopColors.PushBack( Color::RED ); stopColors.PushBack( Color::GREEN ); propertyMap.Insert("gradient-stop-color", stopColors); Change-Id: I82348ed6fb428e186ceec216efd8e1b235a5e3ee Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); Internal::ControlRendererPtr renderer = rendererFactory.GetControlRenderer(propertyMap); --- automated-tests/src/dali-toolkit/CMakeLists.txt | 1 + .../src/dali-toolkit/utc-Dali-RendererFactory.cpp | 216 ++++++++++++++ build/tizen/dali-toolkit/Makefile.am | 2 + .../controls/renderer-factory/control-renderer.cpp | 75 +++++ .../controls/renderer-factory/control-renderer.h | 102 +++++++ .../controls/renderer-factory/renderer-factory.cpp | 92 ++++++ .../controls/renderer-factory/renderer-factory.h | 104 +++++++ dali-toolkit/devel-api/file.list | 6 + .../controls/renderers/color/color-renderer.cpp | 133 +++++++++ .../controls/renderers/color/color-renderer.h | 103 +++++++ .../renderers/control-renderer-data-impl.h | 52 ++++ .../controls/renderers/control-renderer-impl.cpp | 88 ++++++ .../controls/renderers/control-renderer-impl.h | 138 +++++++++ .../renderers/gradient/gradient-renderer.cpp | 321 +++++++++++++++++++++ .../renderers/gradient/gradient-renderer.h | 148 ++++++++++ .../controls/renderers/gradient/gradient.cpp | 195 +++++++++++++ .../controls/renderers/gradient/gradient.h | 173 +++++++++++ .../renderers/gradient/linear-gradient.cpp | 66 +++++ .../controls/renderers/gradient/linear-gradient.h | 85 ++++++ .../renderers/gradient/radial-gradient.cpp | 64 ++++ .../controls/renderers/gradient/radial-gradient.h | 85 ++++++ .../controls/renderers/renderer-factory-cache.cpp | 115 ++++++++ .../controls/renderers/renderer-factory-cache.h | 127 ++++++++ .../controls/renderers/renderer-factory-impl.cpp | 109 +++++++ .../controls/renderers/renderer-factory-impl.h | 93 ++++++ dali-toolkit/internal/file.list | 8 + 26 files changed, 2701 insertions(+) create mode 100644 automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp create mode 100644 dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp create mode 100644 dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h create mode 100644 dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp create mode 100644 dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h create mode 100644 dali-toolkit/internal/controls/renderers/color/color-renderer.cpp create mode 100644 dali-toolkit/internal/controls/renderers/color/color-renderer.h create mode 100644 dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h create mode 100644 dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp create mode 100644 dali-toolkit/internal/controls/renderers/control-renderer-impl.h create mode 100644 dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp create mode 100644 dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h create mode 100644 dali-toolkit/internal/controls/renderers/gradient/gradient.cpp create mode 100644 dali-toolkit/internal/controls/renderers/gradient/gradient.h create mode 100644 dali-toolkit/internal/controls/renderers/gradient/linear-gradient.cpp create mode 100644 dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h create mode 100644 dali-toolkit/internal/controls/renderers/gradient/radial-gradient.cpp create mode 100644 dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h create mode 100644 dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp create mode 100644 dali-toolkit/internal/controls/renderers/renderer-factory-cache.h create mode 100644 dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp create mode 100644 dali-toolkit/internal/controls/renderers/renderer-factory-impl.h diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 446bb36..b1a7c71 100644 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -49,6 +49,7 @@ SET(TC_SOURCES utc-Dali-SuperBlurView.cpp utc-Dali-Toolkit.cpp utc-Dali-Model3dView.cpp + utc-Dali-RendererFactory.cpp ) # Append list of test harness files (Won't get parsed for test cases) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp new file mode 100644 index 0000000..8da2c94 --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +void dali_renderer_factory_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void dali_renderer_factory_cleanup(void) +{ + test_return_value = TET_PASS; +} + +int UtcDaliRendererFactoryGet(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactory" ); + + //Register type + TypeInfo type; + type = TypeRegistry::Get().GetTypeInfo( "RendererFactory" ); + DALI_TEST_CHECK( type ); + BaseHandle handle = type.CreateInstance(); + DALI_TEST_CHECK( handle ); + + RendererFactory factory; + factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + RendererFactory newFactory = RendererFactory::Get(); + DALI_TEST_CHECK( newFactory ); + + // Check that renderer factory is a singleton + DALI_TEST_CHECK(factory == newFactory); + + RendererFactory newFactory2(factory); + DALI_TEST_CHECK(factory == newFactory2); + + END_TEST; +} + +int UtcDaliRendererFactoryGetColorRenderer(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactoryGetColorRenderer" ); + + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f ); + propertyMap.Insert("renderer-type", "color-renderer"); + propertyMap.Insert("blend-color", testColor); + + ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap); + 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 ); + + Stage::GetCurrent().Remove( actor ); + controlRenderer.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + + END_TEST; +} + +int UtcDaliRendererFactoryGetLinearGradientRenderer(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRendererFactoryGetRadialGradientRenderer"); + + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + propertyMap.Insert("renderer-type", "gradient-renderer"); + + Vector2 start(-1.f, -1.f); + Vector2 end(1.f, 1.f); + propertyMap.Insert("gradient-start-position", start); + propertyMap.Insert("gradient-end-position", end); + propertyMap.Insert("gradient-spread-method", "repeat"); + + Property::Array stopOffsets; + stopOffsets.PushBack( 0.2f ); + stopOffsets.PushBack( 0.8f ); + propertyMap.Insert("gradient-stop-offset", stopOffsets); + + Property::Array stopColors; + stopColors.PushBack( Color::RED ); + stopColors.PushBack( Color::GREEN ); + propertyMap.Insert("gradient-stop-color", stopColors); + + ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap); + DALI_TEST_CHECK( controlRenderer ); + + Actor actor = Actor::New(); + Vector2 size(200.f, 200.f); + actor.SetSize(size); + Stage::GetCurrent().Add( actor ); + controlRenderer.SetOnStage( actor ); + controlRenderer.SetSize(size); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + // A lookup texture is generated and pass to shader as sampler + DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + + application.SendNotification(); + application.Render(0); + + Stage::GetCurrent().Remove( actor ); + controlRenderer.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + + END_TEST; +} + +int UtcDaliRendererFactoryGetRadialGradientRenderer(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRendererFactoryGetRadialGradientRenderer"); + + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + propertyMap.Insert("renderer-type", "gradient-renderer"); + + Vector2 center(100.f, 100.f); + float radius = 100.f; + propertyMap.Insert("gradient-units", "user-space"); + propertyMap.Insert("gradient-center", center); + propertyMap.Insert("gradient-radius", radius); + + Property::Array stopOffsets; + stopOffsets.PushBack( 0.0f ); + stopOffsets.PushBack( 1.f ); + propertyMap.Insert("gradient-stop-offset", stopOffsets); + + Property::Array stopColors; + stopColors.PushBack( Color::RED ); + stopColors.PushBack( Color::GREEN ); + propertyMap.Insert("gradient-stop-color", stopColors); + + ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap); + DALI_TEST_CHECK( controlRenderer ); + + Actor actor = Actor::New(); + Vector2 size(200.f, 200.f); + actor.SetSize(size); + Stage::GetCurrent().Add( actor ); + controlRenderer.SetSize(size); + controlRenderer.SetOnStage( actor ); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + // A lookup texture is generated and pass to shader as sampler + DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + application.SendNotification(); + application.Render(0); + + Matrix3 alignMatrix( radius, 0.f, 0.f, 0.f, radius, 0.f, center.x, center.y, 1.f ); + alignMatrix.Invert(); + + Matrix3 actualValue( Matrix3::IDENTITY ); + DALI_TEST_CHECK( gl.GetUniformValue( "uAlignmentMatrix", actualValue ) ); + DALI_TEST_EQUALS( actualValue, alignMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + Stage::GetCurrent().Remove( actor ); + controlRenderer.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + + END_TEST; +} diff --git a/build/tizen/dali-toolkit/Makefile.am b/build/tizen/dali-toolkit/Makefile.am index bd24d22..75d8ca4 100644 --- a/build/tizen/dali-toolkit/Makefile.am +++ b/build/tizen/dali-toolkit/Makefile.am @@ -88,6 +88,7 @@ develapibloomviewdir = $(develapicontrolsdir)/bloom-view develapibubbleemitterdir = $(develapicontrolsdir)/bubble-effect develapieffectsviewdir = $(develapicontrolsdir)/effects-view develapimagnifierdir = $(develapicontrolsdir)/magnifier +develapirendererfactorydir = $(develapicontrolsdir)/renderer-factory develapipopupdir = $(develapicontrolsdir)/popup develapisliderdir = $(develapicontrolsdir)/slider develapishadowviewdir = $(develapicontrolsdir)/shadow-view @@ -108,6 +109,7 @@ develapieffectsview_HEADERS = $(devel_api_effects_view_header_files) develapifocusmanager_HEADERS = $(devel_api_focus_manager_header_files) develapimagnifier_HEADERS = $(devel_api_magnifier_header_files) develapipopup_HEADERS = $(devel_api_popup_header_files) +develapirendererfactory_HEADERS = $(devel_api_renderer_factory_header_files) develapiscripting_HEADERS = $(devel_api_scripting_header_files) develapishadowview_HEADERS = $(devel_api_shadow_view_header_files) develapishadereffects_HEADERS = $(devel_api_shader_effects_header_files) diff --git a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp new file mode 100644 index 0000000..2c8aa07 --- /dev/null +++ b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp @@ -0,0 +1,75 @@ + /* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "control-renderer.h" + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +ControlRenderer::ControlRenderer() +{ +} + +ControlRenderer::~ControlRenderer() +{ +} + +ControlRenderer::ControlRenderer(Internal::ControlRenderer *impl) +: BaseHandle(impl) +{ +} + +void ControlRenderer::SetSize( const Vector2& size ) +{ + GetImplementation( *this ).SetSize(size); +} + +void ControlRenderer::SetClipRect( const Rect& clipRect ) +{ + GetImplementation( *this ).SetClipRect(clipRect); +} + +void ControlRenderer::SetOffset( const Vector2& offset ) +{ + GetImplementation( *this ).SetOffset(offset); +} + +void ControlRenderer::SetDepthIndex( float index ) +{ + GetImplementation( *this ).SetDepthIndex(index); +} + +void ControlRenderer::SetOnStage( Actor& actor ) +{ + GetImplementation( *this ).SetOnStage(actor); +} + +void ControlRenderer::SetOffStage( Actor& actor ) +{ + GetImplementation( *this ).SetOffStage(actor); +} + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h new file mode 100644 index 0000000..57626d4 --- /dev/null +++ b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h @@ -0,0 +1,102 @@ +#ifndef __DALI_TOOLKIT_CONTROL_RENDERER_H__ +#define __DALI_TOOLKIT_CONTROL_RENDERER_H__ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal DALI_INTERNAL +{ +class ControlRenderer; +} + +/** + * ControlRenderer provides renderer for rendering the controls. A control may have multiple ControlRenders. + * ControlRenderers reuses geometry, shader etc. across controls and manages the renderer and material to exist only when control is on-stage. + * It also responds to actor size and color change, and provides the clipping at the renderer level. + * Note: The control renderer responds to the the Actor::COLOR by blending it with the 'Multiply' operator. + */ +class DALI_IMPORT_API ControlRenderer : public BaseHandle +{ +public: + + ControlRenderer(); + ControlRenderer(Internal::ControlRenderer *impl); + ~ControlRenderer(); + + /** + * Set the size of the painting area. + * + * @param[in] size The size of the painting area. + */ + void SetSize( const Vector2& size ); + + /** + * Set the clip rectangular of this renderer. + * The contents of the renderer will not be visible outside this rectangular. + * + * @param [in] clipRect The clipping rectangular. + */ + void SetClipRect( const Rect& clipRect ); + + /** + * Reposition this renderer with a 2D offset. + * + * @param[in] offset The offset to reposition the renderer. + */ + void SetOffset( const Vector2& offset ); + + /** + * Set the depth index of this renderer. + * Depth-index controls draw-order for overlapping renderers. + * Renderer with higher depth indices are rendered in front of other renderer with smaller values + * + * @param[in] depthIndex The depth index of this renderer. + */ + void SetDepthIndex( float index ); + + /** + * Renderer only exists when control is on stage. + * This function should be called when the control put on stage. + * + * @param[in] actor The actor applying this renderer. + */ + void SetOnStage( Actor& actor ); + + /** + * Renderer is destroyed when control is off stage. + * This function should be called when the control removes from stage + * + * @param[in] actor The actor applying this renderer. + */ + void SetOffStage( Actor& actor ); + +}; + +} // namespace Toolkit + +} // namespace Dali + +#endif /*__DALI_TOOLKIT_CONTROL_RENDERER_H__*/ diff --git a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp new file mode 100644 index 0000000..f64ab9f --- /dev/null +++ b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp @@ -0,0 +1,92 @@ + /* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "renderer-factory.h" + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include + + +namespace Dali +{ + +namespace Toolkit +{ + +RendererFactory RendererFactory::Get() +{ + RendererFactory factory; + + // Check whether the RendererFactory is already created + SingletonService singletonService( SingletonService::Get() ); + if( singletonService ) + { + BaseHandle handle = singletonService.GetSingleton( typeid(RendererFactory) ); + if( handle ) + { + //If so, downcast the handle of singleton to RendererFactory + factory = RendererFactory( dynamic_cast(handle.GetObjectPtr()) ); + } + + if( !factory ) + { + // If not, create the RendererFactory and register it as a singleton + factory = RendererFactory( new Internal::RendererFactory() ); + singletonService.Register( typeid(RendererFactory), factory ); + + } + } + + return factory; +} + +RendererFactory::RendererFactory() +{ +} + +RendererFactory::~RendererFactory() +{ +} + +RendererFactory::RendererFactory( const RendererFactory& handle ) +: BaseHandle( handle ) +{ +} + +RendererFactory& RendererFactory::operator=( const RendererFactory& handle ) +{ + BaseHandle::operator=( handle ); + return *this; +} + +RendererFactory::RendererFactory(Internal::RendererFactory *impl) +: BaseHandle(impl) +{ +} + +ControlRenderer RendererFactory::GetControlRenderer( const Property::Map& propertyMap ) +{ + return GetImplementation( *this ).GetControlRenderer( propertyMap ); +} + +} // 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 new file mode 100644 index 0000000..3c3cec7 --- /dev/null +++ b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h @@ -0,0 +1,104 @@ +#ifndef __DALI_TOOLKIT_RENDERER_FACTORY_H__ +#define __DALI_TOOLKIT_RENDERER_FACTORY_H__ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include + +// INTERNAK INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal DALI_INTERNAL +{ +class RendererFactory; +} + +/** + * RendererFactory is a singleton object that provides and shares renderers for controls + * + * The renderer type is required in the property map for requesting a control renderer. + * + * | %Property Name | Type | + * |---------------------------|------------------| + * | renderer-type | STRING | + */ +class DALI_IMPORT_API RendererFactory : public BaseHandle +{ +public: + + /** + * @brief Create or retrieve RendererFactory singleton. + * + * @return A handle to the RendererFactory control. + */ + static RendererFactory Get(); + + /** + * @brief Create a RendererFactory handle. + * + * Calling member functions with an uninitialised handle is not allowed. + */ + RendererFactory(); + + /** + * @brief Destructor + * + * This is non-virtual since derived Handle types must not contain data or virtual methods. + */ + ~RendererFactory(); + + /** + * @brief This copy constructor is required for (smart) pointer semantics. + * + * @param[in] handle A reference to the copied handle. + */ + RendererFactory( const RendererFactory& handle ); + + /** + * @brief This assignment operator is required for (smart) pointer semantics. + * + * @param [in] handle A reference to the copied handle. + * @return A reference to this. + */ + RendererFactory& operator=( const RendererFactory& handle ); + + /** + * 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 + */ + ControlRenderer GetControlRenderer( const Property::Map& propertyMap ); + +private: + + explicit DALI_INTERNAL RendererFactory(Internal::RendererFactory *impl); + +}; + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_RENDERER_FACTORY_H__ */ diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 9668fcd..bf62a04 100755 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -10,6 +10,8 @@ devel_api_src_files = \ $(devel_api_src_dir)/controls/magnifier/magnifier.cpp \ $(devel_api_src_dir)/controls/popup/confirmation-popup.cpp \ $(devel_api_src_dir)/controls/popup/popup.cpp \ + $(devel_api_src_dir)/controls/renderer-factory/renderer-factory.cpp \ + $(devel_api_src_dir)/controls/renderer-factory/control-renderer.cpp \ $(devel_api_src_dir)/controls/shadow-view/shadow-view.cpp \ $(devel_api_src_dir)/controls/slider/slider.cpp \ $(devel_api_src_dir)/controls/super-blur-view/super-blur-view.cpp \ @@ -47,6 +49,10 @@ devel_api_popup_header_files = \ $(devel_api_src_dir)/controls/popup/confirmation-popup.h \ $(devel_api_src_dir)/controls/popup/popup.h +devel_api_renderer_factory_header_files = \ + $(devel_api_src_dir)/controls/renderer-factory/renderer-factory.h \ + $(devel_api_src_dir)/controls/renderer-factory/control-renderer.h + devel_api_shadow_view_header_files = \ $(devel_api_src_dir)/controls/shadow-view/shadow-view.h diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp b/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp new file mode 100644 index 0000000..ab3306a --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "color-renderer.h" + +// EXTERNAL INCLUDES +#include + +//INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ +const char * const COLOR_NAME("blend-color"); +const char * const COLOR_UNIFORM_NAME("uBlendColor"); + + +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + \n + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n + vertexPosition.xyz *= uSize;\n + gl_Position = uMvpMatrix * vertexPosition;\n + }\n +); + +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + uniform lowp vec4 uColor;\n + uniform lowp vec4 uBlendColor;\n + \n + void main()\n + {\n + gl_FragColor = uBlendColor*uColor;\n + }\n +); +} + +ColorRenderer::ColorRenderer() +: ControlRenderer() +{ +} + +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 ); + } + + Property::Value* color = propertyMap.Find( COLOR_NAME ); + if( !( color && color->Get(mBlendColor) ) ) + { + DALI_LOG_ERROR( "Fail to provide a color to the ColorRenderer object" ); + } +} + +void ColorRenderer::SetSize( const Vector2& size ) +{ + ControlRenderer::SetSize( size ); + + // ToDo: renderer responds to the size change +} + +void ColorRenderer::SetClipRect( const Rect& clipRect ) +{ + ControlRenderer::SetClipRect( clipRect ); + + //ToDo: renderer responds to the clipRect change +} + +void ColorRenderer::SetOffset( const Vector2& offset ) +{ + //ToDo: renderer applies the offset +} + +void ColorRenderer::SetOnStage( Actor& actor ) +{ + ControlRenderer::SetOnStage(actor); + (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBlendColor ); + if( mBlendColor.a < 1.f ) + { + (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON ); + } +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.h b/dali-toolkit/internal/controls/renderers/color/color-renderer.h new file mode 100644 index 0000000..48c9778 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/color/color-renderer.h @@ -0,0 +1,103 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_COLOR_RENDERER_H__ +#define __DALI_TOOLKIT_INTERNAL_COLOR_RENDERER_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * The renderer which renders a solid color to the control's quad + * + * The following properties are required for create a ColorRender + * + * | %Property Name | Type | + * |------------------|-------------| + * | blend-color | VECTOR4 | + */ +class ColorRenderer: public ControlRenderer +{ +public: + + /** + * @brief Constructor. + */ + ColorRenderer(); + + /** + * @brief A reference counted object may only be deleted by calling Unreference(). + */ + virtual ~ColorRenderer(); + +public: // from ControlRenderer + + /** + * @copydoc ControlRenderer::Initialize + */ + virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); + + /** + * @copydoc ControlRenderer::SetSize + */ + virtual void SetSize( const Vector2& size ); + + /** + * @copydoc ControlRenderer::SetClipRect + */ + virtual void SetClipRect( const Rect& clipRect ); + + /** + * @copydoc ControlRenderer::SetOffset + */ + virtual void SetOffset( const Vector2& offset ); + + /** + * @copydoc ControlRenderer::SetOnStage + */ + virtual void SetOnStage( Actor& actor ); + +private: + + // Undefined + ColorRenderer( const ColorRenderer& colorRenderer ); + + // Undefined + ColorRenderer& operator=( const ColorRenderer& colorRenderer ); + +private: + + Vector4 mBlendColor; + +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_INTERNAL_COLOR_RENDERER_H__ */ diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h new file mode 100644 index 0000000..ce0bbcb --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h @@ -0,0 +1,52 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__ +#define __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +struct Internal::ControlRenderer::Impl +{ + Geometry mGeometry; + Shader mShader; + Renderer mRenderer; + + Vector2 mSize; + Vector2 mOffset; + Rect mClipRect; + float mDepthIndex; +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__ */ diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp b/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp new file mode 100644 index 0000000..115a6a2 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "control-renderer-impl.h" + +// EXTERNAL HEADER +#include + +//INTERNAL HEARDER +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +ControlRenderer::ControlRenderer() +: mImpl( new Impl() ) +{ +} + +ControlRenderer::~ControlRenderer() +{ + delete mImpl; +} + +void ControlRenderer::SetSize( const Vector2& size ) +{ + mImpl->mSize = size; +} + +void ControlRenderer::SetClipRect( const Rect& clipRect ) +{ + mImpl->mClipRect = clipRect; +} + +void ControlRenderer::SetOffset( const Vector2& offset ) +{ + mImpl->mOffset = offset; +} + +void ControlRenderer::SetDepthIndex( float index ) +{ + mImpl->mDepthIndex = index; + if( mImpl->mRenderer ) + { + mImpl->mRenderer.SetDepthIndex( mImpl->mDepthIndex ); + } +} + +void ControlRenderer::SetOnStage( Actor& actor ) +{ + Material material = Material::New( mImpl->mShader ); + mImpl->mRenderer = Renderer::New( mImpl->mGeometry, material ); + mImpl->mRenderer.SetDepthIndex( mImpl->mDepthIndex ); + actor.AddRenderer( mImpl->mRenderer ); +} + +void ControlRenderer::SetOffStage( Actor& actor ) +{ + actor.RemoveRenderer( mImpl->mRenderer ); + mImpl->mRenderer.Reset(); +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h new file mode 100644 index 0000000..cfa2da7 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h @@ -0,0 +1,138 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H__ +#define __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +// EXTERNAL INCLUDES +#include + +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +class RendererFactoryCache; + +/** + * Base class for all Control rendering logic. A control may have multiple control renderers. + * + * Note: The control renderer responds to the the Actor::COLOR by blending it with the 'Multiply' operator. + */ +class ControlRenderer : public BaseObject +{ +public: + + /** + * Initialisation of the renderer, this API should only called by the RendererFactory: + * request the geometry and shader from the cache, if not available, create and save to the cache for sharing; + * record the property values. + * + * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object + * @param[in] propertyMap The properties for the requested ControlRenderer object. + */ + virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) = 0; + + /** + * @copydoc Toolkit::ControlRenderer::SetSize + */ + virtual void SetSize( const Vector2& size ); + + /** + * @copydoc Toolkit::ControlRenderer::SetCipRect + */ + virtual void SetClipRect( const Rect& clipRect ); + + /** + * @copydoc Toolkit::ControlRenderer::SetOffset + */ + virtual void SetOffset( const Vector2& offset ); + + /** + * @copydoc Toolkit::ControlRenderer::SetDepthIndex + */ + void SetDepthIndex( float index ); + + /** + * @copydoc Toolkit::ControlRenderer::SetOnStage + */ + virtual void SetOnStage( Actor& actor ); + + /** + * @copydoc Toolkit::ControlRenderer::SetOffStage + */ + void SetOffStage( Actor& actor ); + +protected: + + /** + * @brief Constructor. + */ + ControlRenderer(); + + /** + * @brief A reference counted object may only be deleted by calling Unreference(). + */ + virtual ~ControlRenderer(); + +private: + + // Undefined + ControlRenderer( const ControlRenderer& renderer ); + + // Undefined + ControlRenderer& operator=( const ControlRenderer& renderer ); + +protected: + + struct Impl; + Impl* mImpl; +}; + +} // namespace Internal + +inline const Internal::ControlRenderer& GetImplementation(const Toolkit::ControlRenderer& renderer) +{ + DALI_ASSERT_ALWAYS( renderer && "ControlRenderer handle is empty" ); + + const BaseObject& handle = renderer.GetBaseObject(); + + return static_cast(handle); +} + +inline Internal::ControlRenderer& GetImplementation(Toolkit::ControlRenderer& renderer) +{ + DALI_ASSERT_ALWAYS( renderer && "ControlRenderer handle is empty" ); + + BaseObject& handle = renderer.GetBaseObject(); + + return static_cast(handle); +} + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H___ */ diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp new file mode 100644 index 0000000..9ba7369 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "gradient-renderer.h" + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +//INTERNAL INCLUDES +#include +#include +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ +// properties: linear gradient +const char * const GRADIENT_START_POSITION_NAME("gradient-start-position"); // Property::VECTOR2 +const char * const GRADIENT_END_POSITION_NAME("gradient-end-position"); // Property::VECTOR2 + +// properties: radial gradient +const char * const GRADIENT_CENTER_NAME("gradient-center"); // Property::VECTOR2 +const char * const GRADIENT_RADIUS_NAME("gradient-radius"); // Property::FLOAT + +// properties: linear&radial gradient +const char * const GRADIENT_STOP_OFFSET_NAME("gradient-stop-offset"); // Property::Array FLOAT +const char * const GRADIENT_STOP_COLOR_NAME("gradient-stop-color"); // Property::Array VECTOR4 +const char * const GRADIENT_UNITS_NAME("gradient-units"); // Property::String "userSpaceOnUse | objectBoundingBox" +const char * const GRADIENT_SPREAD_METHOD_NAME("gradient-spread-method"); // Property::String "pad | reflect | repeat" + +// string values +const char * const UNIT_USER_SPACE("user-space"); +const char * const SPREAD_REFLECT("reflect"); +const char * const SPREAD_REPEAT("repeat"); + +// uniform names +const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" ); +const char * const UNIFORM_TEXTULRE_NAME("sTexture"); + + +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + uniform mediump mat3 uAlignmentMatrix;\n + varying mediump vec2 vTexCoord;\n + \n + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n + vertexPosition.xyz *= uSize;\n + gl_Position = uMvpMatrix * vertexPosition;\n + \n + vTexCoord = (uAlignmentMatrix*vertexPosition.xyw).xy;\n + }\n +); + +const char* FRAGMENT_SHADER_LINEAR = DALI_COMPOSE_SHADER( + uniform sampler2D sTexture;\n // sampler1D? + uniform lowp vec4 uColor;\n + varying mediump vec2 vTexCoord;\n + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vec2( vTexCoord.y, 0.5 ) ) * uColor;\n + }\n +); + +const char* FRAGMENT_SHADER_RADIAL = DALI_COMPOSE_SHADER( + uniform sampler2D sTexture;\n // sampler1D? + uniform lowp vec4 uColor;\n + varying mediump vec2 vTexCoord;\n + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vec2( length(vTexCoord), 0.5 ) ) * uColor;\n + }\n +); + +Sampler::WrapMode GetWrapMode( Gradient::SpreadMethod spread ) +{ + switch(spread) + { + case Gradient::REPEAT: + { + return Sampler::REPEAT; + } + case Gradient::REFLECT: + { + return Sampler::MIRRORED_REPEAT; + } + case Gradient::PAD: + default: + { + return Sampler::CLAMP_TO_EDGE; + } + } +} + +} + + +GradientRenderer::GradientRenderer() +:mGradientTransformIndex( Property::INVALID_INDEX ) +{ +} + +GradientRenderer::~GradientRenderer() +{ +} + +void GradientRenderer::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 ); + } + + Type gradientType; + if( propertyMap.Find( GRADIENT_RADIUS_NAME )) + { + mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::GRADIENT_SHADER_RADIAL ); + if( !(mImpl->mShader) ) + { + mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RADIAL ); + factoryCache.SaveShader( RendererFactoryCache::GRADIENT_SHADER_RADIAL, mImpl->mShader ); + } + gradientType = RADIAL; + } + else + { + mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::GRADIENT_SHADER_LINEAR ); + if( !(mImpl->mShader) ) + { + mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_LINEAR ); + factoryCache.SaveShader( RendererFactoryCache::GRADIENT_SHADER_LINEAR, mImpl->mShader ); + } + gradientType = LINEAR; + } + + if( NewGradient(gradientType, propertyMap) ) + { + mGradientTransform = mGradient->GetAlignmentTransform(); + } + else + { + DALI_LOG_ERROR( "Fail to provide valid properties to create a GradientRenderer object" ); + } +} + +void GradientRenderer::SetSize( const Vector2& size ) +{ + ControlRenderer::SetSize( size ); + + if( mGradient->GetGradientUnits() == Gradient::OBJECT_BOUNDING_BOX ) + { + // Apply scaling + Matrix3 scaling( 1.f/(size.x+Math::MACHINE_EPSILON_100), 0.f, 0.f, + 0.f, 1.f/(size.y+Math::MACHINE_EPSILON_100), 0.f, 0.5f, 0.5f, 1.f ); + Matrix3::Multiply( mGradientTransform, scaling, mGradient->GetAlignmentTransform() ); + + if( mImpl->mRenderer ) + { + (mImpl->mRenderer).SetProperty( mGradientTransformIndex, mGradientTransform ); + } + } +} + +void GradientRenderer::SetClipRect( const Rect& clipRect ) +{ + ControlRenderer::SetClipRect( clipRect ); + + //ToDo: renderer responds to the clipRect change +} + +void GradientRenderer::SetOffset( const Vector2& offset ) +{ + //ToDo: renderer applies the offset +} + +void GradientRenderer::SetOnStage( Actor& actor ) +{ + ControlRenderer::SetOnStage(actor); + + mGradientTransformIndex = (mImpl->mRenderer).RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform ); + + Dali::BufferImage lookupTexture = mGradient->GenerateLookupTexture(); + Sampler sampler = Sampler::New( lookupTexture, UNIFORM_TEXTULRE_NAME ); + Sampler::WrapMode wrap = GetWrapMode( mGradient->GetSpreadMethod() ); + sampler.SetWrapMode( wrap, wrap ); + ((mImpl->mRenderer).GetMaterial()).AddSampler( sampler ); +} + +bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& propertyMap) +{ + if( gradientType==LINEAR ) + { + Property::Value* startPositionValue = propertyMap.Find( GRADIENT_START_POSITION_NAME ); + Property::Value* endPositionValue = propertyMap.Find( GRADIENT_END_POSITION_NAME ); + Vector2 startPosition; + Vector2 endPosition; + + if( startPositionValue && startPositionValue->Get(startPosition) + && endPositionValue && endPositionValue->Get( endPosition ) ) + { + mGradient = new LinearGradient( startPosition, endPosition ); + } + else + { + return false; + } + } + else // type==RADIAL + { + Property::Value* centerValue = propertyMap.Find( GRADIENT_CENTER_NAME ); + Property::Value* radiusValue = propertyMap.Find( GRADIENT_RADIUS_NAME ); + Vector2 center; + float radius; + if( centerValue && centerValue->Get(center) + && radiusValue && radiusValue->Get(radius) ) + { + mGradient = new RadialGradient( center, radius ); + } + else + { + return false; + } + } + + unsigned int numValidStop = 0u; + Property::Value* stopOffsetValue = propertyMap.Find( GRADIENT_STOP_OFFSET_NAME ); + Property::Value* stopColorValue = propertyMap.Find( GRADIENT_STOP_COLOR_NAME ); + if( stopOffsetValue && stopColorValue ) + { + Property::Array* offsetArray = stopOffsetValue->GetArray(); + Property::Array* colorArray = stopColorValue->GetArray(); + if( offsetArray && colorArray ) + { + unsigned int numStop = offsetArray->Count() < colorArray->Count() ? + offsetArray->Count() : colorArray->Count(); + float offset; + Vector4 color; + for( unsigned int i=0; iGetElementAt(i)).Get(offset) + && (colorArray->GetElementAt(i)).Get(color) ) + { + mGradient->AddStop( offset, color); + numValidStop++; + } + } + } + } + if( numValidStop < 1u ) // no valid stop + { + return false; + } + + Property::Value* unitsValue = propertyMap.Find( GRADIENT_UNITS_NAME ); + std::string units; + // The default unit is OBJECT_BOUNDING_BOX. + // Only need to set new units if 'user-space' + if( unitsValue && unitsValue->Get( units ) && units == UNIT_USER_SPACE ) + { + mGradient->SetGradientUnits( Gradient::USER_SPACE_ON_USE ); + } + + Property::Value* spread = propertyMap.Find( GRADIENT_SPREAD_METHOD_NAME ); + std::string stringValue ; + // The default spread method is PAD. + // Only need to set new spread if 'reflect' or 'repeat" + if( spread && spread->Get( stringValue )) + { + if( stringValue == SPREAD_REFLECT ) + { + mGradient->SetSpreadMethod( Gradient::REFLECT ); + } + else if( stringValue == SPREAD_REPEAT ) + { + mGradient->SetSpreadMethod( Gradient::REPEAT ); + } + } + + return true; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h new file mode 100644 index 0000000..257c14e --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h @@ -0,0 +1,148 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__ +#define __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +class Vector2; + +namespace Toolkit +{ + +namespace Internal +{ + +class Gradient; + +/** + * The renderer which renders smooth transition of colors to the control's quad. + * It supports two types of gradients: linear and radial. + * + * The following properties are essential for create a LINEAR GradientRender + * + * | %Property Name | Type | + * |---------------------------|------------------| + * | gradient-start-position | VECTOR2 | + * | gradient-end-position | VECTOR2 | + * | gradient-stop-offset | ARRAY of FLOAT | + * | gradient-stop-color | ARRAY of VECTOR4 | + * + * The following properties are essential for create a RADIAL GradientRender + * + * | %Property Name | Type | + * |---------------------------|------------------| + * | gradient-center | VECTOR2 | + * | gradient-radius | FLOAT | + * | gradient-stop-offset | ARRAY of FLOAT | + * | gradient-stop-color | ARRAY of VECTOR4 | + * + * The following properties are optional for both LINEAR and RADIAL GradientRender. + * + * | %Property Name | Type | + * |---------------------------|------------------| + * | gradient-units | STRING | + * | gradient-spread-method | STRING | + * + * Valid values for gradient-units are 'user-space' and 'object-bounding-box'. + * Valid values for gradient-spread-method are 'pad', 'repeat' and 'reflect.' + * If not provided, 'objectBoundingBox' is used as default gradient units, and 'pad' is used as default spread method. + */ +class GradientRenderer: public ControlRenderer +{ +public: + + /** + * @brief Constructor. + */ + GradientRenderer(); + + /** + * @brief A reference counted object may only be deleted by calling Unreference(). + */ + ~GradientRenderer(); + +public: // from ControlRenderer + + /** + * @copydoc ControlRenderer::Initialize + */ + virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); + + /** + * @copydoc ControlRenderer::SetSize + */ + virtual void SetSize( const Vector2& size ); + + /** + * @copydoc ControlRenderer::SetClipRect + */ + virtual void SetClipRect( const Rect& clipRect ); + + /** + * @copydoc ControlRenderer::SetOffset + */ + virtual void SetOffset( const Vector2& offset ); + + /** + * @copydoc ControlRenderer::SetOnStage + */ + virtual void SetOnStage( Actor& actor ); + +private: + + /** + * Types of the gradient + */ + enum Type + { + LINEAR, + RADIAL + }; + + /** + * New a gradient object with the given property map. + * + * @return True if the property map provides valid properties to create a gradient. Otherwise, returns false. + */ + bool NewGradient(Type gradientType, const Property::Map& propertyMap); + + // Undefined + GradientRenderer( const GradientRenderer& gradientRenderer ); + + // Undefined + GradientRenderer& operator=( const GradientRenderer& gradientRenderer ); + +private: + + Matrix3 mGradientTransform; + Property::Index mGradientTransformIndex; + IntrusivePtr mGradient; +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__ */ diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient.cpp new file mode 100644 index 0000000..920fddd --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "gradient.h" + +#include // std::sort +#include + +namespace +{ +// The maximum width of the lookup texture ( it is a 1-dimension texture with the height as 1 ) +const unsigned int MAXIMUM_TEXTURE_RESOLUTION(128u); +} + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +Gradient::Gradient() +: mGradientUnits( OBJECT_BOUNDING_BOX ), + mSpreadMethod( PAD ) +{} + +Gradient::~Gradient() +{} + +void Gradient::AddStop( float offset, const Vector4& color ) +{ + // the offset is clamped to the range [0.0, 1.0] + mGradientStops.PushBack( GradientStop( Clamp( offset, 0.f, 1.f ), color) ); +} + +void Gradient::SetGradientUnits( GradientUnits gradientUnits ) +{ + mGradientUnits = gradientUnits; +} + +Gradient::GradientUnits Gradient::GetGradientUnits() const +{ + return mGradientUnits; +} + +void Gradient::SetSpreadMethod( SpreadMethod spread ) +{ + mSpreadMethod = spread; +} + +Gradient::SpreadMethod Gradient::GetSpreadMethod() const +{ + return mSpreadMethod; +} + +const Matrix3& Gradient::GetAlignmentTransform() const +{ + return mAlignmentTransform; +} + +/** + * Following the SVG gradient. + * + * Not only the spread method decides the texture wrap mode: + * PAD-->GL_CLAMP_TO_EDGE; REPEAT-->GL_REPEAT; REFLECT-->GL_MIRROR_REPEAT + * + * If the stops have not covered the whole zero to one range, + * the REPEAT spread behaves different from the two others in the lookup texture generation. + */ +BufferImage Gradient::GenerateLookupTexture() +{ + std::sort( mGradientStops.Begin(), mGradientStops.End() ); + + unsigned int numStops = mGradientStops.Count(); + + /** + * If the stops have not covered the whole zero to one range, + * for PAD and REFLECT, use the color of the first stop to fill the range [0.0, first stop offset) + * and use the color of the last stop to fill the range (last stop offset, 1.0] + * for REPEAT, mix the two color of the first and last stop to fill the remainder + */ + bool tempFirstStop = false; + if( mGradientStops[0].mOffset > 0.f ) + { + tempFirstStop = true; + Vector4 firstStopColor( mGradientStops[0].mStopColor ); // If spread method is PAD or REFLECT + if( mSpreadMethod == REPEAT ) + { + firstStopColor = ( mGradientStops[0].mStopColor * (1.f-mGradientStops[numStops-1].mOffset) + + mGradientStops[numStops-1].mStopColor * mGradientStops[0].mOffset ) + / ( mGradientStops[0].mOffset+1.f-mGradientStops[numStops-1].mOffset); + } + + mGradientStops.Insert( mGradientStops.Begin(), GradientStop(0.f, firstStopColor) ); + numStops++; + } + + bool tempLastStop = false; + if( mGradientStops[numStops-1].mOffset < 1.f ) + { + tempLastStop = true; + Vector4 lastStopColor( mGradientStops[numStops-1].mStopColor ); // If spread method is PAD or REFLECT + if( mSpreadMethod == REPEAT ) + { + lastStopColor = mGradientStops[0].mStopColor; + } + mGradientStops.PushBack( GradientStop(1.f, lastStopColor) ); + numStops++; + } + + /** + * Generate the pixels with the color transit from one stop to next. + */ + unsigned int resolution = EstimateTextureResolution(); + BufferImage texture = BufferImage::New( resolution, 1 ); + PixelBuffer* pixels = texture.GetBuffer(); + int segmentStart = 0; + int segmentEnd = 0; + int k = 0; + float length = static_cast(resolution); + for( unsigned int i=0; i(segmentEnd-segmentStart); + + for( int j = segmentStart; j(j-segmentStart)/segmentWidth; + Vector4 currentColor = mGradientStops[i].mStopColor * (1.f-ratio) + mGradientStops[i+1].mStopColor * ratio; + pixels[k*4] = static_cast( 255.f * Clamp( currentColor.r, 0.f, 1.f ) ); + pixels[k*4+1] = static_cast( 255.f * Clamp( currentColor.g, 0.f, 1.f ) ); + pixels[k*4+2] = static_cast( 255.f * Clamp( currentColor.b, 0.f, 1.f ) ); + pixels[k*4+3] = static_cast( 255.f * Clamp( currentColor.a, 0.f, 1.f ) ); + k++; + } + segmentStart = segmentEnd; + } + + // remove the stops added temporarily for generating the pixels, as the spread method might get changed later + if( tempLastStop ) + { + mGradientStops.Erase( mGradientStops.Begin()+numStops-1 ); + } + if( tempFirstStop ) + { + mGradientStops.Erase( mGradientStops.Begin()); + } + + return texture; +} + +unsigned int Gradient::EstimateTextureResolution() +{ + float minInterval = 1.0; + for( unsigned int i=0, numStops = mGradientStops.Count(); i minInterval ? minInterval:interval; + } + // Use at least three pixels for each segment between two stops + unsigned int resolution = static_cast(3.f/(minInterval+Math::MACHINE_EPSILON_100)+0.5f); + // Clamp the resolution to handle the overlapping stops + if( resolution > MAXIMUM_TEXTURE_RESOLUTION ) + { + return MAXIMUM_TEXTURE_RESOLUTION; + } + + return resolution; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient.h b/dali-toolkit/internal/controls/renderers/gradient/gradient.h new file mode 100644 index 0000000..82b58cb --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient.h @@ -0,0 +1,173 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_GRADIENT_H__ +#define __DALI_TOOLKIT_INTERNAL_GRADIENT_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +//EXTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali +{ + +class Vector4; + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * Gradients consist of continuously smooth color transitions along a vector from one color to another, + * possibly followed by additional transitions along the same vector to other colors. + */ +class Gradient : public RefObject +{ +public: + /** + * Defines the coordinate system of the attributes + * (start and end position for linear gradient, circle center and radius for radial gradient) + */ + enum GradientUnits + { + USER_SPACE_ON_USE, + OBJECT_BOUNDING_BOX + }; + + /** + * Indicates what happens if the gradient starts or ends inside the bounds of the object being painted by the gradient. + */ + enum SpreadMethod + { + PAD, // use the terminal colors of the gradient to fill the remainder of the target region + REPEAT, // reflect the gradient pattern start-to-end, end-to-start, start-to-end, etc. continuously until the target rectangle is filled + REFLECT // repeat the gradient pattern start-to-end, start-to-end, start-to-end, etc. continuously until the target region is filled + }; + + /** + * The stop node tells the gradient what color it should be at certain position. + */ + struct GradientStop + { + GradientStop( float offset, const Vector4& color ) + : mOffset( offset ), mStopColor( color ) + {} + + bool operator<(const GradientStop& rhs) const + { + return mOffset < rhs.mOffset; + } + + float mOffset; // A value ranging from 0 to 1 to indicate where the gradient stop is placed. + Vector4 mStopColor; // The color to use at this gradient stop + }; + +public: + + /** + * Add a gradient stop. + * + * @param[in] offset The position to place the stop. + * @param[in] color The color to use at this stop. + */ + void AddStop(float offset, const Vector4& color); + + /** + * Set the coordinate system used by the gradient attributes. + * @param[in] gradientUnits The the attributes are defined using the current user coordinate system or the bounding box of the shape. + */ + void SetGradientUnits( GradientUnits gradientUnits ); + + /** + * Get the coordinate system used by the gradient attributes. + * @return USER_SPACE_ON_USE or OBJECT_BOUNDING_BOX + */ + GradientUnits GetGradientUnits() const; + + /** + * Indicates what happens if the gradient starts or ends inside the bounds of the target rectangle. + * If not specified, the effect is as if a value of 'pad' were specified + * + * @param[in] spread The method to fill the remainder of target region which is outside the gradient bounds + */ + void SetSpreadMethod( SpreadMethod spread ); + + /** + * Get the filling method for the the remainder of target region which is outside the gradient boun. + * @return PAD, REFLECT or REPEAT + */ + SpreadMethod GetSpreadMethod() const; + + /** + * Get the transformation matrix to align the vertices with the gradient line/circle + * @ return the aligning transformation matrix + */ + const Matrix3& GetAlignmentTransform() const; + + /** + * Generate the lookup texture with the gradient stops. + * @return the lookup texture which transit smoothly between stops. + */ + BufferImage GenerateLookupTexture(); + +private: + + /** + * Estimate the resolution of the lookup texture. + * Note: Only call this function after the gradient stops are sorted in order. + */ + unsigned int EstimateTextureResolution(); + +protected: + + /** + * Construct a new Gradient object + * Called in the constructor of subclasses + */ + Gradient(); + + /** + * @brief A reference counted object may only be deleted by calling Unreference(). + */ + virtual ~Gradient(); + + // Undefined + Gradient( const Gradient& gradient ); + + // Undefined + Gradient& operator=( const Gradient& handle ); + +protected: + + Vector mGradientStops; + Matrix3 mAlignmentTransform; + GradientUnits mGradientUnits; + SpreadMethod mSpreadMethod; + +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__ */ diff --git a/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.cpp b/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.cpp new file mode 100644 index 0000000..d1453a6 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "linear-gradient.h" + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +LinearGradient::LinearGradient( const Vector2& startPosition, const Vector2& endPosition ) +: Gradient() +{ + SetStartAndEndPosition( startPosition, endPosition ); +} + +LinearGradient::~LinearGradient() +{} + +void LinearGradient::SetStartAndEndPosition( const Vector2& startPosition, const Vector2& endPosition ) +{ + mStartPosition = startPosition; + mEndPosition = endPosition; + + // Calculate the transform aligning to the gradient line + float dx = mEndPosition.x - mStartPosition.x; + float dy = mEndPosition.y - mStartPosition.y; + Matrix3 alignMatrix( dy, -dx, 0.f, dx, dy, 0.f, mStartPosition.x, mStartPosition.y, 1.f ); + alignMatrix.Invert(); + + mAlignmentTransform = alignMatrix; +} + +const Vector2& LinearGradient::GetStartPosition() const +{ + return mStartPosition; +} + +const Vector2& LinearGradient::GetEndPosition() const +{ + return mEndPosition; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h b/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h new file mode 100644 index 0000000..df7fade --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h @@ -0,0 +1,85 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_LINEAR_GRADIENT_H__ +#define __DALI_TOOLKIT_INTERNAL_LINEAR_GRADIENT_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * Linear gradients change color evenly along a straight line. + * The gradient is defined by an axis (the gradient line) at any specified angles. + */ +class LinearGradient : public Gradient +{ +public: + + /** + * Constructor. + * @param[in] startPosition The starting point onto which the 0% gradient stops are mapped. + * @param[in] endPosition The ending point r onto which the 100% gradient stops are mapped. + */ + LinearGradient( const Vector2& startPosition, const Vector2& endPosition ); + + /** + * Destructor. + */ + virtual ~LinearGradient(); + + /** + * Set the starting and ending points of the vector onto which the gradient stops are mapped. + * @param[in] startPosition The starting point of the gradient vector. + * @param[in] endPosition The ending point of the gradient vector. + */ + void SetStartAndEndPosition( const Vector2& startPosition, const Vector2& endPosition ); + + /** + * Get the stating point of the gradient vector. + * @return The stating point of the gradient vector. + */ + const Vector2& GetStartPosition() const; + + /** + * Get the ending point of the gradient vector. + * @return The ending point of the gradient vector. + */ + const Vector2& GetEndPosition() const; + +private: + + Vector2 mStartPosition; + Vector2 mEndPosition; +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_INTERNAL_LINEAR_GRADIENT_H__ */ diff --git a/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.cpp b/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.cpp new file mode 100644 index 0000000..e986612 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "radial-gradient.h" + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +RadialGradient::RadialGradient( const Vector2& center, float radius ) +: Gradient() +{ + SetCenterAndRadius( center, radius ); +} + +RadialGradient::~RadialGradient() +{} + +void RadialGradient::SetCenterAndRadius( const Vector2& center, float radius ) +{ + mCenter = center; + mRadius = radius; + + // Calculate the transform aligning to the circle + Matrix3 alignMatrix( mRadius, 0.f, 0.f, 0.f, mRadius, 0.f, mCenter.x, mCenter.y, 1.f ); + alignMatrix.Invert(); + + mAlignmentTransform = alignMatrix; +} + +const Vector2& RadialGradient::GetCenter() const +{ + return mCenter; +} + +float RadialGradient::GetRadius() const +{ + return mRadius; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h b/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h new file mode 100644 index 0000000..3e90f5f --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h @@ -0,0 +1,85 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_RADIAL_GRADIENT_H__ +#define __DALI_TOOLKIT_INTERNAL_RADIAL_GRADIENT_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * Radial gradients change color circularly. + * The color transition starts from the center of the circle and distribute outwardly. + */ +class RadialGradient : public Gradient +{ +public: + + /** + * Contructor. + * @param[in] center The center of the gradient circle onto which the 0% gradient stop is mapped. + * @param[in] radius The radius of the outmost circle onto which the 100% gradient stop is mapped. + */ + RadialGradient( const Vector2& center, float radius ); + + /** + * Destructor. + */ + virtual ~RadialGradient(); + + /** + * Set the center and radius of the outermost circle for the radial gradient. + * @param[in] center The center of the gradient circle onto which the 0% gradient stop is mapped. + * @param[in] radius The radius of the outmost circle onto which the 100% gradient stop is mapped. + */ + void SetCenterAndRadius( const Vector2& center, float radius ); + + /** + * Get the center of the gradient circle. + * @return The center of the gradient circle. + */ + const Vector2& GetCenter() const; + + /** + * Get the radius of the outmost gradient circle. + * @return The radius of the outmost gradient circle. + */ + float GetRadius() const; + +private: + + Vector2 mCenter; + float mRadius; +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_INTERNAL_RADIAL_GRADIENT_H__ */ diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp new file mode 100644 index 0000000..462e29c --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp @@ -0,0 +1,115 @@ + /* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// CLASS HEADER +#include "renderer-factory-cache.h" + +// Internal HEADER +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +RendererFactoryCache::RendererFactoryCache() +{ +} + +RendererFactoryCache::~RendererFactoryCache() +{ + for( int i=0; i<= SHADER_TYPE_MAX; i++) + { + if(mShader[i]) + { + mShader[i].Reset(); + } + } + + for( int i=0; i<= GEOMETRY_TYPE_MAX; i++) + { + if(mGeometry[i]) + { + mGeometry[i].Reset(); + } + } +} + + +Geometry RendererFactoryCache::GetGeometry( GeometryType type ) +{ + return mGeometry[type]; +} + +void RendererFactoryCache::SaveGeometry( GeometryType type, Geometry geometry) +{ + mGeometry[type] = geometry; +} + +Shader RendererFactoryCache::GetShader( ShaderType type ) +{ + return mShader[type]; +} + +void RendererFactoryCache::SaveShader( ShaderType type, Shader shader ) +{ + mShader[type] = shader; +} + +Geometry RendererFactoryCache::CreateQuadGeometry() +{ + const float halfWidth = 0.5f; + const float halfHeight = 0.5f; + struct QuadVertex { Vector2 position;}; + QuadVertex quadVertexData[4] = + { + { Vector2(-halfWidth, -halfHeight) }, + { Vector2( halfWidth, -halfHeight) }, + { Vector2(-halfWidth, halfHeight) }, + { Vector2( halfWidth, halfHeight) } + }; + + Property::Map quadVertexFormat; + quadVertexFormat["aPosition"] = Property::VECTOR2; + PropertyBuffer quadVertices = PropertyBuffer::New( quadVertexFormat, 4 ); + quadVertices.SetData(quadVertexData); + + // Create indices + //TODO: replace with triangle strip when Geometry supports it + unsigned int indexData[6] = { 0, 3, 1, 0, 2, 3 }; + Property::Map indexFormat; + indexFormat["indices"] = Property::INTEGER; + PropertyBuffer indices = PropertyBuffer::New( indexFormat, 6 ); + indices.SetData(indexData); + + // Create the geometry object + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer( quadVertices ); + geometry.SetIndexBuffer( indices ); + + return geometry; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h new file mode 100644 index 0000000..4797c54 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h @@ -0,0 +1,127 @@ +#ifndef __DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__ +#define __DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// EXTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * Caches shaders and geometries. Owned by RenderFactory. + */ +class RendererFactoryCache : public RefObject +{ +public: + + /** + * Type of shader for caching. + */ + enum ShaderType + { + COLOR_SHADER, + BORDER_SHADER, + GRADIENT_SHADER_LINEAR, + GRADIENT_SHADER_RADIAL, + IMAGE_SHADER, + N_PATCH_SHADER, + SVG_SHADER, + SHADER_TYPE_MAX = SVG_SHADER + }; + + /** + * Type of geometry for caching. + */ + enum GeometryType + { + QUAD_GEOMETRY, + NINE_PATCH_GEOMETRY, + GEOMETRY_TYPE_MAX = NINE_PATCH_GEOMETRY + }; + +public: + + /** + * @brief Constructor + */ + RendererFactoryCache(); + + /** + * Request geometry of the given type. + * @return The geometry of the required type if it exist in the cache. Otherwise, an empty handle is returned. + */ + Geometry GetGeometry( GeometryType type ); + + /** + * Cache the geometry of the give type. + * @param[in] type The geometry type. + * @param[in] geometry The geometry for caching. + */ + void SaveGeometry( GeometryType type, Geometry geometry); + + /** + * Request shader of the given type. + * @return The shader of the required type if it exist in the cache. Otherwise, an empty handle is returned. + */ + Shader GetShader( ShaderType type ); + + /** + * Cache the geometry of the give type. + * @param[in] type The geometry type. + * @param[in] geometry The geometry for caching. + */ + void SaveShader( ShaderType type, Shader shader ); + + /* + * Greate the quad geometry. + * Quad geometry is shared by multiple kind of Renderer, so implement it in the factory-cache. + */ + static Geometry CreateQuadGeometry(); + +protected: + + /** + * A reference counted object may only be deleted by calling Unreference() + */ + virtual ~RendererFactoryCache(); + +private: + + // ToDo: test whether using the WeakHandle could improve the performance + // With WeakHandle, the resource would be released automatically when no control is using it + + Geometry mGeometry[GEOMETRY_TYPE_MAX+1]; + Shader mShader[SHADER_TYPE_MAX+1]; +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /*__DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__ */ diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp new file mode 100644 index 0000000..8cf01dd --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp @@ -0,0 +1,109 @@ + /* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// CLASS HEADER +#include "renderer-factory-impl.h" + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +// Internal HEADER +#include +#include +#include + +namespace +{ +const char * const RENDERER_TYPE_NAME( "renderer-type" ); +const char * const COLOR_RENDERER("color-renderer"); +const char * const GRADIENT_RENDERER("gradient-renderer"); +} + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ + +BaseHandle Create() +{ + BaseHandle handle = Toolkit::RendererFactory::Get(); + + return handle; +} + +DALI_TYPE_REGISTRATION_BEGIN_CREATE( Toolkit::RendererFactory, Dali::BaseHandle, Create, true ) +DALI_TYPE_REGISTRATION_END() + +} // namespace + +RendererFactory::RendererFactory() +{ +} + +RendererFactory::~RendererFactory() +{ +} + +Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Property::Map& propertyMap ) +{ + ControlRenderer* rendererPtr = NULL; + + Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME ); + std::string typeValue ; + if( type && type->Get( typeValue )) + { + if( typeValue == COLOR_RENDERER ) + { + rendererPtr = new ColorRenderer(); + } + else if( typeValue == GRADIENT_RENDERER ) + { + rendererPtr = new GradientRenderer(); + } + } + + if( rendererPtr ) + { + if( !mFactoryCache ) + { + mFactoryCache = new RendererFactoryCache(); + } + rendererPtr->Initialize( *( mFactoryCache.Get() ), propertyMap ); + } + else + { + DALI_LOG_ERROR( "Renderer type unknown" ); + } + + return Toolkit::ControlRenderer(rendererPtr); +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h new file mode 100644 index 0000000..c153c53 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h @@ -0,0 +1,93 @@ +#ifndef __DALI_TOOLKIT_RENDERER_FACTORY_IMPL_H__ +#define __DALI_TOOLKIT_RENDERER_FACTORY_IMPL_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +class RendererFactoryCache; +typedef IntrusivePtr RendererFactoryCachePtr; + +/** + * @copydoc Toolkit::RendererFactory + */ +class RendererFactory : public BaseObject +{ + +public: + + /** + * @brief Constructor + */ + RendererFactory(); + + /** + * @copydoc Toolkit::RenderFactory::GetControlRenderer + */ + Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap ); + +protected: + + /** + * A reference counted object may only be deleted by calling Unreference() + */ + virtual ~RendererFactory(); + +private: + + RendererFactoryCachePtr mFactoryCache; +}; + +} // namespace Internal + +inline const Internal::RendererFactory& GetImplementation(const Toolkit::RendererFactory& factory) +{ + DALI_ASSERT_ALWAYS( factory && "RendererFactory handle is empty" ); + + const BaseObject& handle = factory.GetBaseObject(); + + return static_cast(handle); +} + +inline Internal::RendererFactory& GetImplementation(Toolkit::RendererFactory& factory) +{ + DALI_ASSERT_ALWAYS( factory && "RendererFactory handle is empty" ); + + BaseObject& handle = factory.GetBaseObject(); + + return static_cast(handle); +} + +} // namespace Toolkit + +} // namespace Dali + +#endif /* __DALI_TOOLKIT_RENDERER_FACTORY_IMPL_H__ */ diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 0b0517c..a01c7f2 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -12,6 +12,14 @@ toolkit_src_files = \ $(toolkit_src_dir)/builder/json-parser-impl.cpp \ $(toolkit_src_dir)/builder/tree-node-manipulator.cpp \ $(toolkit_src_dir)/builder/replacement.cpp \ + $(toolkit_src_dir)/controls/renderers/control-renderer-impl.cpp \ + $(toolkit_src_dir)/controls/renderers/renderer-factory-cache.cpp \ + $(toolkit_src_dir)/controls/renderers/renderer-factory-impl.cpp \ + $(toolkit_src_dir)/controls/renderers/color/color-renderer.cpp \ + $(toolkit_src_dir)/controls/renderers/gradient/gradient.cpp \ + $(toolkit_src_dir)/controls/renderers/gradient/linear-gradient.cpp \ + $(toolkit_src_dir)/controls/renderers/gradient/radial-gradient.cpp \ + $(toolkit_src_dir)/controls/renderers/gradient/gradient-renderer.cpp \ $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \ $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \ $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \ -- 2.7.4