Merge "Moved TextureSet::SetImage() to separate devel-api module" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / renderers / npatch / npatch-renderer.cpp
index 64a1763..677d5ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * 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.
 #include <dali/integration-api/platform-abstraction.h>
 #include <dali/public-api/images/buffer-image.h>
 #include <dali/public-api/images/resource-image.h>
+#include <dali/devel-api/images/texture-set-image.h>
 
 // INTERNAL IINCLUDES
 #include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
+#include <dali-toolkit/internal/controls/renderers/renderer-string-constants.h>
 #include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
 
@@ -41,13 +43,7 @@ namespace Internal
 
 namespace
 {
-const char * const RENDERER_TYPE("renderer-type");
-const char * const RENDERER_TYPE_VALUE("n-patch-renderer");
-
-const char * const IMAGE_URL_NAME("image-url");
-const char * const BORDER_ONLY("border-only");
-
-std::string TEXTURE_UNIFORM_NAME = "sTexture";
+const char * const BORDER_ONLY("borderOnly");
 
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
@@ -123,28 +119,24 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
  * @param[in]  indices              The indices to generate the geometry from
  * @return The geometry formed from the vertices and indices
  */
-Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned int >& indices )
+Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned short >& indices )
 {
   Property::Map vertexFormat;
   vertexFormat[ "aPosition" ] = Property::VECTOR2;
-  PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat, vertices.Size() );
+  PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat );
   if( vertices.Size() > 0 )
   {
-    vertexPropertyBuffer.SetData( &vertices[ 0 ] );
+    vertexPropertyBuffer.SetData( &vertices[ 0 ], vertices.Size() );
   }
 
-  Property::Map indexFormat;
-  indexFormat[ "indices" ] = Property::INTEGER;
-  PropertyBuffer indexPropertyBuffer = PropertyBuffer::New( indexFormat, indices.Size() );
+  // Create the geometry object
+  Geometry geometry = Geometry::New();
+  geometry.AddVertexBuffer( vertexPropertyBuffer );
   if( indices.Size() > 0 )
   {
-    indexPropertyBuffer.SetData( &indices[ 0 ] );
+    geometry.SetIndexBuffer( &indices[ 0 ], indices.Size() );
   }
 
-  // Create the geometry object
-  Geometry geometry = Geometry::New();
-  geometry.AddVertexBuffer( vertexPropertyBuffer );
-  geometry.SetIndexBuffer( indexPropertyBuffer );
 
   return geometry;
 }
@@ -156,7 +148,7 @@ Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsi
  * @param[in]  rowIdx      The row index to start the quad
  * @param[in]  nextRowIdx  The index to the next row
  */
-void AddQuadIndices( Vector< unsigned int >& indices, unsigned int rowIdx, unsigned int nextRowIdx )
+void AddQuadIndices( Vector< unsigned short >& indices, unsigned int rowIdx, unsigned int nextRowIdx )
 {
   indices.PushBack( rowIdx );
   indices.PushBack( nextRowIdx + 1 );
@@ -172,7 +164,7 @@ void AddVertex( Vector< Vector2 >& vertices, unsigned int x, unsigned int y )
   vertices.PushBack( Vector2( x, y ) );
 }
 
-void RegisterStretchProperties( Material& material, const char * uniformName, const NinePatchImage::StretchRanges& stretchPixels, uint16_t imageExtent)
+void RegisterStretchProperties( Renderer& renderer, const char * uniformName, const NinePatchImage::StretchRanges& stretchPixels, uint16_t imageExtent)
 {
   uint16_t prevEnd = 0;
   uint16_t prevFix = 0;
@@ -188,7 +180,7 @@ void RegisterStretchProperties( Material& material, const char * uniformName, co
 
     std::stringstream uniform;
     uniform << uniformName << "[" << i << "]";
-    material.RegisterProperty( uniform.str(), Vector2( fix, stretch ) );
+    renderer.RegisterProperty( uniform.str(), Vector2( fix, stretch ) );
 
     prevEnd = end;
     prevFix = fix;
@@ -199,7 +191,7 @@ void RegisterStretchProperties( Material& material, const char * uniformName, co
     prevFix += imageExtent - prevEnd;
     std::stringstream uniform;
     uniform << uniformName << "[" << i << "]";
-    material.RegisterProperty( uniform.str(), Vector2( prevFix, prevStretch ) );
+    renderer.RegisterProperty( uniform.str(), Vector2( prevFix, prevStretch ) );
   }
 }
 
@@ -222,7 +214,7 @@ void NPatchRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMa
   Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
   if( imageURLValue )
   {
-    //Read the border-only property first since InitialiseFromImage relies on mBorderOnly to be properly set
+    //Read the borderOnly property first since InitialiseFromImage relies on mBorderOnly to be properly set
     Property::Value* borderOnlyValue = propertyMap.Find( BORDER_ONLY );
     if( borderOnlyValue )
     {
@@ -308,24 +300,53 @@ Geometry NPatchRenderer::CreateGeometry()
 Shader NPatchRenderer::CreateShader()
 {
   Shader shader;
-  if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+  if( !mImpl->mCustomShader )
   {
-    shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER );
-    if( !shader )
+    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
     {
-      shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER );
-      mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader );
+      shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER );
+      if( !shader )
+      {
+        shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER );
+        mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader );
+      }
+    }
+    else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+    {
+      std::stringstream vertexShader;
+      vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
+                   << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
+                   << VERTEX_SHADER;
+
+      shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER );
     }
   }
-  else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+  else
   {
-    std::stringstream vertexShader;
-    vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
-                 << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
-                 << VERTEX_SHADER;
+    const char* fragmentShader = FRAGMENT_SHADER;
+    Dali::Shader::ShaderHints hints = Dali::Shader::HINT_NONE;
+
+    if( !mImpl->mCustomShader->mFragmentShader.empty() )
+    {
+      fragmentShader = mImpl->mCustomShader->mFragmentShader.c_str();
+    }
+    hints = mImpl->mCustomShader->mHints;
 
-    shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER );
+    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+    {
+      shader = Shader::New( VERTEX_SHADER_3X3, fragmentShader, hints );
+    }
+    else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+    {
+      std::stringstream vertexShader;
+      vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
+                   << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
+                   << VERTEX_SHADER;
+
+      shader = Shader::New( vertexShader.str(), fragmentShader, hints );
+    }
   }
+
   return shader;
 }
 
@@ -340,8 +361,9 @@ void NPatchRenderer::InitializeRenderer()
     InitializeFromBrokenImage();
   }
 
-  Material material = Material::New( shader );
-  mImpl->mRenderer = Renderer::New( geometry, material );
+  TextureSet textureSet = TextureSet::New();
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+  mImpl->mRenderer.SetTextures( textureSet );
 }
 
 
@@ -372,12 +394,14 @@ void NPatchRenderer::DoSetOnStage( Actor& actor )
 void NPatchRenderer::DoSetOffStage( Actor& actor )
 {
   mCroppedImage.Reset();
+  actor.RemoveRenderer( mImpl->mRenderer );
+  mImpl->mRenderer.Reset();
 }
 
 void NPatchRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
-  map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+  map.Insert( RENDERER_TYPE, IMAGE_RENDERER );
   if( !mImageUrl.empty() )
   {
     map.Insert( IMAGE_URL_NAME, mImageUrl );
@@ -412,19 +436,15 @@ void NPatchRenderer::ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t
   if( gridChanged )
   {
     Shader shader = CreateShader();
-    Material material;
+    TextureSet textureSet;
     if( shader )
     {
-      material = mImpl->mRenderer.GetMaterial();
-      if( material )
+      textureSet = mImpl->mRenderer.GetTextures();
+      if( !textureSet )
       {
-        material.SetShader( shader );
+        InitializeFromBrokenImage();
       }
-    }
-
-    if( !material )
-    {
-      InitializeFromBrokenImage();
+      mImpl->mRenderer.SetShader( shader );
     }
   }
 }
@@ -512,18 +532,10 @@ void NPatchRenderer::InitializeFromBrokenImage()
 
 void NPatchRenderer::ApplyImageToSampler()
 {
-  Material material = mImpl->mRenderer.GetMaterial();
-  if( material )
+  TextureSet textureSet = mImpl->mRenderer.GetTextures();
+  if( textureSet )
   {
-    int index = material.GetTextureIndex( TEXTURE_UNIFORM_NAME );
-    if( index > -1 )
-    {
-      material.SetTextureImage( index, mCroppedImage );
-    }
-    else
-    {
-      material.AddTexture(  mCroppedImage, TEXTURE_UNIFORM_NAME );
-    }
+    TextureSetImage( textureSet, 0u, mCroppedImage );
 
     if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
     {
@@ -534,18 +546,18 @@ void NPatchRenderer::ApplyImageToSampler()
       uint16_t stretchWidth = stretchX.GetY() - stretchX.GetX();
       uint16_t stretchHeight = stretchY.GetY() - stretchY.GetX();
 
-      material.RegisterProperty( "uFixed[0]", Vector2::ZERO );
-      material.RegisterProperty( "uFixed[1]", Vector2( stretchX.GetX(), stretchY.GetX()) );
-      material.RegisterProperty( "uFixed[2]", Vector2( mImageSize.GetWidth() - stretchWidth, mImageSize.GetHeight() - stretchHeight ) );
-      material.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) );
+      mImpl->mRenderer.RegisterProperty( "uFixed[0]", Vector2::ZERO );
+      mImpl->mRenderer.RegisterProperty( "uFixed[1]", Vector2( stretchX.GetX(), stretchY.GetX()) );
+      mImpl->mRenderer.RegisterProperty( "uFixed[2]", Vector2( mImageSize.GetWidth() - stretchWidth, mImageSize.GetHeight() - stretchHeight ) );
+      mImpl->mRenderer.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) );
     }
     else
     {
-      material.RegisterProperty( "uNinePatchFactorsX[0]", Vector2::ZERO );
-      material.RegisterProperty( "uNinePatchFactorsY[0]", Vector2::ZERO );
+      mImpl->mRenderer.RegisterProperty( "uNinePatchFactorsX[0]", Vector2::ZERO );
+      mImpl->mRenderer.RegisterProperty( "uNinePatchFactorsY[0]", Vector2::ZERO );
 
-      RegisterStretchProperties( material, "uNinePatchFactorsX", mStretchPixelsX, mImageSize.GetWidth() );
-      RegisterStretchProperties( material, "uNinePatchFactorsY", mStretchPixelsY, mImageSize.GetHeight() );
+      RegisterStretchProperties( mImpl->mRenderer, "uNinePatchFactorsX", mStretchPixelsX, mImageSize.GetWidth() );
+      RegisterStretchProperties( mImpl->mRenderer, "uNinePatchFactorsY", mStretchPixelsY, mImageSize.GetHeight() );
     }
   }
 }
@@ -569,7 +581,7 @@ Geometry NPatchRenderer::CreateGeometry( Uint16Pair gridSize )
 
   // Create indices
   //TODO: compare performance with triangle strip when Geometry supports it
-  Vector< unsigned int > indices;
+  Vector< unsigned short > indices;
   indices.Reserve( gridWidth * gridHeight * 6 );
 
   unsigned int rowIdx     = 0;
@@ -626,7 +638,7 @@ Geometry NPatchRenderer::CreateGeometryBorder( Uint16Pair gridSize )
 
   // Create indices
   //TODO: compare performance with triangle strip when Geometry supports it
-  Vector< unsigned int > indices;
+  Vector< unsigned short > indices;
   indices.Reserve( gridWidth * gridHeight * 6 );
 
   //top