From: Paul Wisbey Date: Wed, 3 Aug 2016 16:00:27 +0000 (-0700) Subject: Merge "Geometry Batching" into devel/master X-Git-Tag: dali_1.2.0~4 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=901499a7ec86ca342c4e0fdec62a6e4eeeee5c5f;hp=c5651d9850075a3d2d96444883ee8e23844a5f3e Merge "Geometry Batching" into devel/master --- 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 d7664ae..f4677a7 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