Geometry Batching 36/59336/36
authoradam.b <adam.b@samsung.com>
Mon, 25 Jul 2016 14:55:33 +0000 (15:55 +0100)
committerTom Robinson <tom.robinson@samsung.com>
Tue, 2 Aug 2016 18:29:10 +0000 (11:29 -0700)
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

16 files changed:
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/dali-toolkit.h
dali-toolkit/internal/file.list
dali-toolkit/internal/visuals/image/batch-image-visual.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/image/batch-image-visual.h [new file with mode: 0644]
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/visual-factory-cache.cpp
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/public-api/file.list
dali-toolkit/public-api/visuals/batch-image-visual-properties.h [new file with mode: 0644]
dali-toolkit/public-api/visuals/visual-properties.h

index b6080c3..ef801bb 100644 (file)
@@ -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)
   //  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
   //  </svg>
   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<int>() == Visual::BATCH_IMAGE );
+
+  value = resultMap.Find( BatchImageVisual::Property::URL, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<std::string>() == TEST_IMAGE_FILE_NAME );
+
+  value = resultMap.Find( BatchImageVisual::Property::DESIRED_WIDTH, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<int>() == 20 );
+
+  value = resultMap.Find( BatchImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<int>() == 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;
+}
index f332a7f..4a32341 100644 (file)
@@ -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>(), (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;
+}
index 5a9d08d..4c641ae 100644 (file)
@@ -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 <dali-toolkit/public-api/text/rendering-backend.h>
 
+#include <dali-toolkit/public-api/visuals/batch-image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/border-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/gradient-visual-properties.h>
@@ -73,4 +74,4 @@
 #include <dali-toolkit/public-api/enums.h>
 #include <dali-toolkit/public-api/toolkit-property-index-ranges.h>
 
-#endif // __DALI_TOOLKIT_H__
+#endif // DALI_TOOLKIT_H
index 2c22b61..1954782 100644 (file)
@@ -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 (file)
index 0000000..8eca47e
--- /dev/null
@@ -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 <cstring> // for strncasecmp
+#include <dali/public-api/images/resource-image.h>
+#include <dali/public-api/images/native-image.h>
+#include <dali/integration-api/debug.h>
+#include <dali/devel-api/adaptor-framework/bitmap-loader.h>
+#include <dali/public-api/images/pixel-data.h>
+#include <dali/public-api/rendering/texture.h>
+#include <dali/public-api/rendering/texture-set.h>
+#include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali/public-api/rendering/texture-set.h>
+
+// INTERNAL HEADER
+#include <dali-toolkit/public-api/visuals/batch-image-visual-properties.h>
+#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
+
+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<int>& 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 (file)
index 0000000..750e28f
--- /dev/null
@@ -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 <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/images/resource-image.h>
+
+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<int>& 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
index 70347ff..e7ad66e 100644 (file)
@@ -490,7 +490,6 @@ void ImageVisual::InitializeRenderer( const Image& image )
   }
 }
 
-
 void ImageVisual::DoSetOnStage( Actor& actor )
 {
   if( !mImageUrl.empty() )
index 10bce2b..9d0c964 100644 (file)
@@ -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;
 }
 
index 2622a82..da15492 100644 (file)
@@ -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:
 
index aef0fc8..404f2ec 100644 (file)
@@ -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
index 488be15..2c2210a 100644 (file)
@@ -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:
 
   /**
index 5775130..2c79c27 100644 (file)
@@ -41,6 +41,7 @@
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
+#include <dali-toolkit/internal/visuals/image/batch-image-visual.h>
 
 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 )
index a224124..b68f27c 100644 (file)
@@ -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
index 7eb3cfc..205dca8 100755 (executable)
@@ -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 (file)
index 0000000..25def11
--- /dev/null
@@ -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 <dali-toolkit/public-api/visuals/visual-properties.h>
+
+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
index 4952ebb..f8d4b70 100644 (file)
@@ -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