From: adam.b Date: Mon, 25 Jul 2016 14:55:33 +0000 (+0100) Subject: Geometry Batching X-Git-Tag: dali_1.2.0~4^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=f29b744f4c9d27aeb355319712313876bb236bca;hp=-c Geometry Batching Toolkit support for the geometry batching feature. It provides simple batching for ImageView objects. Turning on batching is done same way as for other Actors, by setting the property BATCHING_ENABLED on the ImageView. Change-Id: Ib283b6c2f7053a017dc2e87725a9d3047c9ed801 --- f29b744f4c9d27aeb355319712313876bb236bca diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index b6080c3..ef801bb 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -177,7 +177,7 @@ int UtcDaliVisualSize(void) gradientVisual.GetNaturalSize(naturalSize); DALI_TEST_EQUALS( naturalSize, Vector2::ZERO,TEST_LOCATION ); - //svg visual + // svg visual Visual::Base svgVisual = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions() ); svgVisual.SetSize( visualSize ); DALI_TEST_EQUALS( svgVisual.GetSize(), visualSize, TEST_LOCATION ); @@ -187,6 +187,17 @@ int UtcDaliVisualSize(void) // // DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 100.f), TEST_LOCATION ); + + // Batch Image visual + propertyMap.Clear(); + propertyMap.Insert( Visual::Property::TYPE, Visual::BATCH_IMAGE ); + propertyMap.Insert( BatchImageVisual::Property::URL, TEST_IMAGE_FILE_NAME ); + Visual::Base batchImageVisual = factory.CreateVisual( propertyMap ); + batchImageVisual.SetSize( visualSize ); + DALI_TEST_EQUALS( batchImageVisual.GetSize(), visualSize, TEST_LOCATION ); + batchImageVisual.GetNaturalSize( naturalSize ); + DALI_TEST_EQUALS( naturalSize, Vector2( 80.0f, 160.0f ), TEST_LOCATION ); + END_TEST; } @@ -777,3 +788,68 @@ int UtcDaliVisualGetPropertyMap9(void) END_TEST; } + +int UtcDaliVisualGetPropertyMapBatchImageVisual(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualGetPropertyMapBatchImageVisual:" ); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert( Visual::Property::TYPE, Visual::BATCH_IMAGE ); + propertyMap.Insert( BatchImageVisual::Property::URL, TEST_IMAGE_FILE_NAME ); + propertyMap.Insert( BatchImageVisual::Property::DESIRED_WIDTH, 20 ); + propertyMap.Insert( BatchImageVisual::Property::DESIRED_HEIGHT, 30 ); + + Visual::Base batchImageVisual = factory.CreateVisual( propertyMap ); + DALI_TEST_CHECK( batchImageVisual ); + + Property::Map resultMap; + batchImageVisual.CreatePropertyMap( resultMap ); + + // Check the property values from the returned map from visual + Property::Value* value = resultMap.Find( Visual::Property::TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == Visual::BATCH_IMAGE ); + + value = resultMap.Find( BatchImageVisual::Property::URL, Property::STRING ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == TEST_IMAGE_FILE_NAME ); + + value = resultMap.Find( BatchImageVisual::Property::DESIRED_WIDTH, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == 20 ); + + value = resultMap.Find( BatchImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == 30 ); + + END_TEST; +} + +int UtcDaliVisualGetPropertyMapBatchImageVisualNoAtlas(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualGetPropertyMapBatchImageVisualNoAtlas:" ); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert( Visual::Property::TYPE, Visual::BATCH_IMAGE ); + propertyMap.Insert( BatchImageVisual::Property::URL, TEST_IMAGE_FILE_NAME ); + + // Set the desired size to be larger than the atlas limit of 1024x1024. + propertyMap.Insert( BatchImageVisual::Property::DESIRED_WIDTH, 2048 ); + propertyMap.Insert( BatchImageVisual::Property::DESIRED_HEIGHT, 2048 ); + + // Create the visual. + Visual::Base batchImageVisual = factory.CreateVisual( propertyMap ); + + DALI_TEST_CHECK( batchImageVisual ); + + Actor actor = Actor::New(); + batchImageVisual.SetOnStage( actor ); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp index f332a7f..4a32341 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp @@ -1511,3 +1511,109 @@ int UtcDaliVisualFactoryGetPrimitiveVisualN1(void) END_TEST; } + +int UtcDaliVisualFactoryGetBatchImageVisual1(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualFactoryGetBatchImageVisual1: Request a Batch Image visual with a Property::Map" ); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + propertyMap.Insert( Visual::Property::TYPE, Visual::BATCH_IMAGE ); + propertyMap.Insert( BatchImageVisual::Property::URL, TEST_IMAGE_FILE_NAME ); + + Visual::Base visual = factory.CreateVisual( propertyMap ); + DALI_TEST_CHECK( visual ); + + Actor actor = Actor::New(); + + actor.SetSize( 200.0f, 200.0f ); + Stage::GetCurrent().Add( actor ); + visual.SetSize( Vector2( 200.0f, 200.0f ) ); + + // Test SetOnStage(). + visual.SetOnStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + application.SendNotification(); + application.Render(); + + // Test SetOffStage(). + visual.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + + END_TEST; +} + +int UtcDaliVisualFactoryGetBatchImageVisual2(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualFactoryGetBatchImageVisual2: Request Batch Image visual from an Image Visual with batchingEnabled set" ); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + // Create a normal Image Visual. + propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE ); + // Instruct the factory to change Image Visuals to Batch-Image Visuals. + propertyMap.Insert( Visual::Property::BATCHING_ENABLED, true ); + + // Properties for the Batch-Image Visual. + propertyMap.Insert( BatchImageVisual::Property::URL, TEST_IMAGE_FILE_NAME ); + + Visual::Base visual = factory.CreateVisual( propertyMap ); + DALI_TEST_CHECK( visual ); + + // Check that a Batch-Image visual was created instead of an Image visual. + Property::Map resultMap; + visual.CreatePropertyMap( resultMap ); + + Property::Value* value = resultMap.Find( Visual::Property::TYPE, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), (int)Visual::BATCH_IMAGE, TEST_LOCATION ); + + Actor actor = Actor::New(); + + actor.SetSize( 200.0f, 200.0f ); + Stage::GetCurrent().Add( actor ); + visual.SetSize( Vector2( 200.0f, 200.0f ) ); + + // Test SetOnStage(). + visual.SetOnStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + application.SendNotification(); + application.Render(); + + // Test SetOffStage(). + visual.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + + END_TEST; +} + +int UtcDaliVisualFactoryGetBatchImageVisual3(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualFactoryGetBatchImageVisual3: Create an ImageView that uses a batched visual internally" ); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + // Create a property-map that enables batching. + Property::Map propertyMap; + propertyMap.Insert( Dali::Toolkit::BatchImageVisual::Property::URL, TEST_IMAGE_FILE_NAME ); + propertyMap.Insert( Visual::Property::BATCHING_ENABLED, true ); + + // Create an ImageView, passing the property-map in to instruct it to use batching. + Toolkit::ImageView imageView = Toolkit::ImageView::New(); + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, propertyMap ); + + imageView.SetSize( 200.0f, 200.0f ); + Stage::GetCurrent().Add( imageView ); + + END_TEST; +} diff --git a/dali-toolkit/dali-toolkit.h b/dali-toolkit/dali-toolkit.h index 5a9d08d..4c641ae 100644 --- a/dali-toolkit/dali-toolkit.h +++ b/dali-toolkit/dali-toolkit.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_H__ -#define __DALI_TOOLKIT_H__ +#ifndef DALI_TOOLKIT_H +#define DALI_TOOLKIT_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -61,6 +61,7 @@ #include +#include #include #include #include @@ -73,4 +74,4 @@ #include #include -#endif // __DALI_TOOLKIT_H__ +#endif // DALI_TOOLKIT_H diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 2c22b61..1954782 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -29,6 +29,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/visuals/svg/svg-visual.cpp \ $(toolkit_src_dir)/visuals/mesh/mesh-visual.cpp \ $(toolkit_src_dir)/visuals/primitive/primitive-visual.cpp \ + $(toolkit_src_dir)/visuals/image/batch-image-visual.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 \ diff --git a/dali-toolkit/internal/visuals/image/batch-image-visual.cpp b/dali-toolkit/internal/visuals/image/batch-image-visual.cpp new file mode 100644 index 0000000..8eca47e --- /dev/null +++ b/dali-toolkit/internal/visuals/image/batch-image-visual.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2016 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 "batch-image-visual.h" + +// EXTERNAL HEADER +#include // for strncasecmp +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// INTERNAL HEADER +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ +const char HTTP_URL[] = "http://"; +const char HTTPS_URL[] = "https://"; + +// Properties: +const char * const DESIRED_WIDTH( "desiredWidth" ); +const char * const DESIRED_HEIGHT( "desiredHeight" ); + +const Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f ); + +// The shader used for batched rendering. It uses interleaved data for +// attributes. Limitation is that all batched renderers will share same set of uniforms. +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + attribute mediump vec2 aTexCoord;\n + uniform mediump mat4 uMvpMatrix;\n + varying mediump vec2 vTexCoord;\n + \n + void main()\n + {\n + vTexCoord = aTexCoord;\n + gl_Position = uMvpMatrix * vec4( aPosition, 0.0, 1.0 );\n + }\n +); + +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + uniform lowp float uAlphaBlending; // Set to 1.0 for conventional alpha blending; if pre-multiplied alpha blending, set to 0.0 + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * vec4( uColor.rgb*max( uAlphaBlending, uColor.a ), uColor.a );\n + }\n +); + +} //unnamed namespace + +BatchImageVisual::BatchImageVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ) + : Visual::Base( factoryCache ), + mAtlasManager( atlasManager ), + mDesiredSize() +{ +} + +BatchImageVisual::~BatchImageVisual() +{ +} + +void BatchImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) +{ + std::string oldImageUrl = mImageUrl; + Property::Value* imageURLValue = propertyMap.Find( Dali::Toolkit::BatchImageVisual::Property::URL, Dali::Toolkit::Internal::IMAGE_URL_NAME ); + + if( imageURLValue ) + { + imageURLValue->Get( mImageUrl ); + + int desiredWidth = 0; + Property::Value* desiredWidthValue = propertyMap.Find( Dali::Toolkit::BatchImageVisual::Property::DESIRED_WIDTH, DESIRED_WIDTH ); + if( desiredWidthValue ) + { + desiredWidthValue->Get( desiredWidth ); + } + + int desiredHeight = 0; + Property::Value* desiredHeightValue = propertyMap.Find( Dali::Toolkit::BatchImageVisual::Property::DESIRED_HEIGHT, DESIRED_HEIGHT ); + if( desiredHeightValue ) + { + desiredHeightValue->Get( desiredHeight ); + } + + mDesiredSize = ImageDimensions( desiredWidth, desiredHeight ); + } + + // Remove old renderer if exit. + if( mImpl->mRenderer ) + { + if( actor ) // Remove old renderer from actor. + { + actor.RemoveRenderer( mImpl->mRenderer ); + } + if( !oldImageUrl.empty() ) // Clean old renderer from cache. + { + CleanCache( oldImageUrl ); + } + } + + // If actor is on stage, create new renderer and apply to actor. + if( actor && actor.OnStage() ) + { + SetOnStage( actor ); + } +} + +void BatchImageVisual::SetSize( const Vector2& size ) +{ + Visual::Base::SetSize( size ); +} + +void BatchImageVisual::GetNaturalSize( Vector2& naturalSize ) const +{ + if( mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0 ) + { + naturalSize.x = mDesiredSize.GetWidth(); + naturalSize.y = mDesiredSize.GetHeight(); + return; + } + else if( !mImageUrl.empty() ) + { + ImageDimensions dimentions = ResourceImage::GetImageSize( mImageUrl ); + naturalSize.x = dimentions.GetWidth(); + naturalSize.y = dimentions.GetHeight(); + return; + } + + naturalSize = Vector2::ZERO; +} + +void BatchImageVisual::SetClipRect( const Rect& clipRect ) +{ + Visual::Base::SetClipRect( clipRect ); +} + +void BatchImageVisual::InitializeRenderer( const std::string& imageUrl ) +{ + if( imageUrl.empty() ) + { + return; + } + + mImageUrl = imageUrl; + mImpl->mRenderer.Reset(); + mAtlasRect = FULL_TEXTURE_RECT; + + if( !mImpl->mCustomShader && + ( strncasecmp( imageUrl.c_str(),HTTP_URL, sizeof( HTTP_URL ) -1 ) != 0 ) && // Ignore remote images + ( strncasecmp( imageUrl.c_str(), HTTPS_URL, sizeof( HTTPS_URL ) -1 ) != 0 ) ) + { + if( !mImpl->mRenderer ) + { + TextureSet textureSet = mAtlasManager.Add( + mAtlasRect, + imageUrl, + mDesiredSize ); + + // If image doesn't fit the atlas, create new texture set with texture that + // is used as whole. + if( !textureSet ) + { + BitmapLoader loader = BitmapLoader::New( imageUrl, mDesiredSize ); + loader.Load(); + Dali::PixelData pixelData = loader.GetPixelData(); + Texture texture = Texture::New( TextureType::TEXTURE_2D, + pixelData.GetPixelFormat(), + pixelData.GetWidth(), + pixelData.GetHeight() ); + texture.Upload( pixelData ); + textureSet = TextureSet::New(); + textureSet.SetTexture( 0, texture ); + mAtlasRect = FULL_TEXTURE_RECT; + } + + Geometry geometry = mFactoryCache.CreateBatchQuadGeometry( mAtlasRect ); + Shader shader( GetBatchShader( mFactoryCache ) ); + mImpl->mRenderer = Renderer::New( geometry, shader ); + mImpl->mRenderer.SetTextures( textureSet ); + + // Turn batching on, to send message it must be on stage. + mImpl->mRenderer.SetProperty( Dali::Renderer::Property::BATCHING_ENABLED, true ); + } + mImpl->mFlags |= Impl::IS_FROM_CACHE; + } +} + +void BatchImageVisual::DoSetOnStage( Actor& actor ) +{ + if( !mImageUrl.empty() ) + { + InitializeRenderer( mImageUrl ); + } + // Turn batching on, to send message it must be on stage + mImpl->mRenderer.SetProperty( Dali::Renderer::Property::BATCHING_ENABLED, true ); +} + +void BatchImageVisual::DoSetOffStage( Actor& actor ) +{ + actor.RemoveRenderer( mImpl->mRenderer ); + + // If we own the image then make sure we release it when we go off stage + if( !mImageUrl.empty() ) + { + CleanCache( mImageUrl ); + } + else + { + mImpl->mRenderer.Reset(); + } +} + +void BatchImageVisual::DoCreatePropertyMap( Property::Map& map ) const +{ + map.Clear(); + map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::BATCH_IMAGE ); + + if( !mImageUrl.empty() ) + { + map.Insert( Toolkit::BatchImageVisual::Property::URL, mImageUrl ); + map.Insert( Toolkit::BatchImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth() ); + map.Insert( Toolkit::BatchImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight() ); + } +} + +Shader BatchImageVisual::GetBatchShader( VisualFactoryCache& factoryCache ) +{ + Shader shader = factoryCache.GetShader( VisualFactoryCache::BATCH_IMAGE_SHADER ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); + factoryCache.SaveShader( VisualFactoryCache::BATCH_IMAGE_SHADER, shader ); + } + return shader; +} + +void BatchImageVisual::CleanCache(const std::string& url) +{ + TextureSet textureSet = mImpl->mRenderer.GetTextures(); + mImpl->mRenderer.Reset(); + if( mFactoryCache.CleanRendererCache( url ) ) + { + mAtlasManager.Remove( textureSet, mAtlasRect ); + } +} + + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/visuals/image/batch-image-visual.h b/dali-toolkit/internal/visuals/image/batch-image-visual.h new file mode 100644 index 0000000..750e28f --- /dev/null +++ b/dali-toolkit/internal/visuals/image/batch-image-visual.h @@ -0,0 +1,125 @@ +#ifndef DALI_TOOLKIT_INTERNAL_BATCH_IMAGE_VISUAL_H +#define DALI_TOOLKIT_INTERNAL_BATCH_IMAGE_VISUAL_H + +/* + * Copyright (c) 2016 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 HEADER +#include +#include + +// EXTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ + +class BatchImageVisual: public Visual::Base, public ConnectionTracker +{ +public: + + /** + * @brief Constructor. + * + * @param[in] factoryCache The VisualFactoryCache object + * @param[in] atlasManager The atlasManager object + */ + BatchImageVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ); + + /** + * @brief A reference counted object may only be deleted by calling Unreference(). + */ + ~BatchImageVisual(); + +public: // from Visual + + /** + * @copydoc Visual::Base::SetSize + */ + virtual void SetSize( const Vector2& size ); + + /** + * @copydoc Visual::Base::GetNaturalSize + */ + virtual void GetNaturalSize( Vector2& naturalSize ) const; + + /** + * @copydoc Visual::Base::SetClipRect + */ + virtual void SetClipRect( const Rect& clipRect ); + + /** + * @copydoc Visual::Base::CreatePropertyMap + */ + virtual void DoCreatePropertyMap( Property::Map& map ) const; + +protected: + + /** + * @copydoc Visua::Base::DoInitialize + */ + virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap ); + + /** + * @copydoc Visual::Base::DoSetOnStage + */ + virtual void DoSetOnStage( Actor& actor ); + + /** + * @copydoc Visual::Base::DoSetOffStage + */ + virtual void DoSetOffStage( Actor& actor ); + +private: + + /** + * Get the batch image rendering shader. + * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + */ + static Shader GetBatchShader( VisualFactoryCache& factoryCache ); + + /** + * @brief Initializes the Dali::Renderer from an image url string + * + * @param[in] imageUrl The image url string to intialize this ImageVisual from + */ + void InitializeRenderer( const std::string& imageUrl ); + + /** + * Clean the Visual from cache, and remove the image from atlas if it is not used anymore + */ + void CleanCache( const std::string& url ); + +private: + + ImageAtlasManager& mAtlasManager; + Vector4 mAtlasRect; + std::string mImageUrl; + Dali::ImageDimensions mDesiredSize; +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_INTERNAL_BATCH_IMAGE_VISUAL_H diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 70347ff..e7ad66e 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -490,7 +490,6 @@ void ImageVisual::InitializeRenderer( const Image& image ) } } - void ImageVisual::DoSetOnStage( Actor& actor ) { if( !mImageUrl.empty() ) diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index 10bce2b..9d0c964 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -122,6 +122,7 @@ void Base::SetOnStage( Actor& actor ) mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled()); mImpl->mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex ); actor.AddRenderer( mImpl->mRenderer ); + mImpl->mFlags |= Impl::IS_ON_STAGE; } diff --git a/dali-toolkit/internal/visuals/visual-base-impl.h b/dali-toolkit/internal/visuals/visual-base-impl.h index 2622a82..da15492 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.h +++ b/dali-toolkit/internal/visuals/visual-base-impl.h @@ -182,7 +182,7 @@ protected: * @param[in] actor The Actor the visual is applied to if, empty if the visual has not been applied to any Actor * @param[in] propertyMap The properties for the requested Visual object. */ - virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap ) {}; + virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap ) {} protected: diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.cpp b/dali-toolkit/internal/visuals/visual-factory-cache.cpp index aef0fc8..404f2ec 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-cache.cpp @@ -266,6 +266,49 @@ Geometry VisualFactoryCache::CreateGridGeometry( Uint16Pair gridSize ) return geometry; } +Geometry VisualFactoryCache::CreateBatchQuadGeometry( Vector4 texCoords ) +{ + const float halfWidth = 0.5f; + const float halfHeight = 0.5f; + struct QuadVertex { + QuadVertex( const Vector2& vertexPosition, const Vector2& vertexTexCoords ) + : position( vertexPosition ), + texCoords( vertexTexCoords ) + {} + Vector2 position; + Vector2 texCoords; + }; + + // special case, when texture takes whole space + if( texCoords == Vector4::ZERO ) + { + texCoords = Vector4(0.0f, 0.0f, 1.0f, 1.0f); + } + + QuadVertex quadVertexData[6] = + { + QuadVertex( Vector2(-halfWidth, -halfHeight ), Vector2(texCoords.x, texCoords.y) ), + QuadVertex( Vector2( halfWidth, -halfHeight ), Vector2(texCoords.z, texCoords.y) ), + QuadVertex( Vector2(-halfWidth, halfHeight ), Vector2(texCoords.x, texCoords.w) ), + QuadVertex( Vector2( halfWidth, -halfHeight ), Vector2(texCoords.z, texCoords.y) ), + QuadVertex( Vector2(-halfWidth, halfHeight ), Vector2(texCoords.x, texCoords.w) ), + QuadVertex( Vector2( halfWidth, halfHeight ), Vector2(texCoords.z, texCoords.w) ), + }; + + Property::Map vertexFormat; + vertexFormat[ "aPosition" ] = Property::VECTOR2; + vertexFormat[ "aTexCoord" ] = Property::VECTOR2; + PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat ); + vertexBuffer.SetData( quadVertexData, 6 ); + + // create geometry as normal, single quad + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer( vertexBuffer ); + geometry.SetType( Geometry::TRIANGLES ); + + return geometry; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index 488be15..2c2210a 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -59,6 +59,7 @@ public: GRADIENT_SHADER_RADIAL_USER_SPACE, GRADIENT_SHADER_RADIAL_BOUNDING_BOX, IMAGE_SHADER, + BATCH_IMAGE_SHADER, NINE_PATCH_SHADER, SVG_SHADER, SHADER_TYPE_MAX = SVG_SHADER @@ -122,6 +123,13 @@ public: */ static Geometry CreateGridGeometry( Uint16Pair gridSize ); + /** + * Create the batchable geometry + * @param[in] texCoords The texture atlas rect coordinates + * @return The created batchable geometry + */ + static Geometry CreateBatchQuadGeometry( Vector4 texCoords ); + public: /** diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.cpp b/dali-toolkit/internal/visuals/visual-factory-impl.cpp index 5775130..2c79c27 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@ -41,6 +41,7 @@ #include #include #include +#include namespace { @@ -67,9 +68,11 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, IMAGE ) DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, MESH ) DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, PRIMITIVE ) DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, DEBUG ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, BATCH_IMAGE ) DALI_ENUM_TO_STRING_TABLE_END( VISUAL_TYPE ) const char * const VISUAL_TYPE( "visualType" ); +const char * const BATCHING_ENABLED( "batchingEnabled" ); BaseHandle Create() { @@ -109,12 +112,27 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property Visual::Base* visualPtr = NULL; Property::Value* typeValue = propertyMap.Find( Toolkit::Visual::Property::TYPE, VISUAL_TYPE ); - Toolkit::Visual::Type visualType = Toolkit::Visual::IMAGE; // Default to IMAGE type + Toolkit::Visual::Type visualType = Toolkit::Visual::IMAGE; // Default to IMAGE type. if( typeValue ) { Scripting::GetEnumerationProperty( *typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, visualType ); } + // If the type is IMAGE, either from a default or the TYPE value in the property-map, change it to a BatchImage if required. + if( visualType == Toolkit::Visual::IMAGE ) + { + bool batchingEnabled( false ); + Property::Value* value = propertyMap.Find( Toolkit::Visual::Property::BATCHING_ENABLED, BATCHING_ENABLED ); + if( value ) + { + value->Get( batchingEnabled ); + if( batchingEnabled ) + { + visualType = Toolkit::Visual::BATCH_IMAGE; + } + } + } + switch( visualType ) { case Toolkit::Visual::BORDER: @@ -187,6 +205,13 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property visualPtr = new DebugVisual( *( mFactoryCache.Get() ) ); break; } + + case Toolkit::Visual::BATCH_IMAGE: + { + CreateAtlasManager(); + visualPtr = new BatchImageVisual( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) ); + break; + } } if( visualPtr ) diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index a224124..b68f27c 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -36,7 +36,7 @@ const char * const CUSTOM_SUBDIVIDE_GRID_Y( "subdivideGridY" ); const char * const CUSTOM_SHADER_HINTS( "hints" ); // Image visual -const char * const IMAGE_URL_NAME("url"); +const char * const IMAGE_URL_NAME( "url" ); const char * const ATLAS_RECT_UNIFORM_NAME ( "uAtlasRect" ); } // namespace Internal diff --git a/dali-toolkit/public-api/file.list b/dali-toolkit/public-api/file.list index 7eb3cfc..205dca8 100755 --- a/dali-toolkit/public-api/file.list +++ b/dali-toolkit/public-api/file.list @@ -124,6 +124,7 @@ public_api_video_view_header_files = \ $(public_api_src_dir)/controls/video-view/video-view.h public_api_visuals_header_files = \ + $(public_api_src_dir)/visuals/batch-image-visual-properties.h \ $(public_api_src_dir)/visuals/border-visual-properties.h \ $(public_api_src_dir)/visuals/color-visual-properties.h \ $(public_api_src_dir)/visuals/gradient-visual-properties.h \ diff --git a/dali-toolkit/public-api/visuals/batch-image-visual-properties.h b/dali-toolkit/public-api/visuals/batch-image-visual-properties.h new file mode 100644 index 0000000..25def11 --- /dev/null +++ b/dali-toolkit/public-api/visuals/batch-image-visual-properties.h @@ -0,0 +1,71 @@ +#ifndef DALI_TOOLKIT_BATCH_IMAGE_VISUAL_PROPERTIES_H +#define DALI_TOOLKIT_BATCH_IMAGE_VISUAL_PROPERTIES_H + +/* + * Copyright (c) 2016 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 BatchImageVisual +{ + +namespace Property +{ + +enum +{ + /** + * @brief The URL of the image. + * @details Name "url", type Property::STRING. + * @SINCE_1_1.46 + * @note Mandatory. + */ + URL = VISUAL_PROPERTY_START_INDEX, + + /** + * @brief The image width. + * @details Name "desiredWidth", type Property::INTEGER. + * @SINCE_1_1.46 + * @note Optional. If not specified, the actual image width is used. + */ + DESIRED_WIDTH, + + /** + * @brief The image height. + * @details Name "desiredHeight", type Property::INTEGER. + * @SINCE_1_1.46 + * @note Optional. If not specified, the actual image height is used. + */ + DESIRED_HEIGHT, +}; + +} // namespace Property + +} // namespace BatchImageVisual + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_BATCH_IMAGE_VISUAL_PROPERTIES_H diff --git a/dali-toolkit/public-api/visuals/visual-properties.h b/dali-toolkit/public-api/visuals/visual-properties.h index 4952ebb..f8d4b70 100644 --- a/dali-toolkit/public-api/visuals/visual-properties.h +++ b/dali-toolkit/public-api/visuals/visual-properties.h @@ -43,6 +43,7 @@ enum Type MESH, ///< Renders a mesh using an "obj" file, optionally with textures provided by an "mtl" file. @SINCE_1_1.45 PRIMITIVE, ///< Renders a simple 3D shape, such as a cube or sphere. @SINCE_1_1.45 DEBUG, ///< Renders a simple wire-frame outlining a quad. @SINCE_1_1.45 + BATCH_IMAGE, ///< Renders an image in the geometry batching mode @SINCE_1_1.46 }; namespace Property @@ -67,7 +68,15 @@ enum * @note Will override the existing shaders. * @see Shader::Property */ - SHADER + SHADER, + + /** + * @brief This enables Image visuals to automatically be converted to Batch-Image visuals. + * @details Name "batchingEnabled", type Boolean. + * @SINCE_1_1.46 + * @note Optional. + */ + BATCHING_ENABLED, }; } // namespace Property