Fix npatch visual auxiliary bug
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / npatch / npatch-visual.cpp
index e87e244..f95a796 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/integration-api/debug.h>
-#include <dali/devel-api/common/stage.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/utility/npatch-helper.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
 #include <dali-toolkit/internal/visuals/npatch-loader.h>
 #include <dali-toolkit/internal/visuals/rendering-addon.h>
@@ -45,90 +47,9 @@ namespace Internal
 {
 namespace
 {
-/**
- * @brief Creates the geometry formed from the vertices and indices
- *
- * @param[in]  vertices             The vertices to generate the geometry from
- * @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 short>& indices)
-{
-  Property::Map vertexFormat;
-  vertexFormat["aPosition"] = Property::VECTOR2;
-  VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat);
-  if(vertices.Size() > 0)
-  {
-    vertexBuffer.SetData(&vertices[0], vertices.Size());
-  }
-
-  // Create the geometry object
-  Geometry geometry = Geometry::New();
-  geometry.AddVertexBuffer(vertexBuffer);
-  if(indices.Size() > 0)
-  {
-    geometry.SetIndexBuffer(&indices[0], indices.Size());
-  }
-
-  return geometry;
-}
-
-/**
- * @brief Adds the indices to form a quad composed off two triangles where the indices are organised in a grid
- *
- * @param[out] indices     The indices to add to
- * @param[in]  rowIdx      The row index to start the quad
- * @param[in]  nextRowIdx  The index to the next row
- */
-void AddQuadIndices(Vector<unsigned short>& indices, unsigned int rowIdx, unsigned int nextRowIdx)
-{
-  indices.PushBack(rowIdx);
-  indices.PushBack(nextRowIdx + 1);
-  indices.PushBack(rowIdx + 1);
-
-  indices.PushBack(rowIdx);
-  indices.PushBack(nextRowIdx);
-  indices.PushBack(nextRowIdx + 1);
-}
-
-void AddVertex(Vector<Vector2>& vertices, unsigned int x, unsigned int y)
-{
-  vertices.PushBack(Vector2(x, y));
-}
-
-void RegisterStretchProperties(Renderer& renderer, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent)
-{
-  uint16_t     prevEnd     = 0;
-  uint16_t     prevFix     = 0;
-  uint16_t     prevStretch = 0;
-  unsigned int i           = 1;
-  for(NPatchUtility::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i)
-  {
-    uint16_t start = it->GetX();
-    uint16_t end   = it->GetY();
-
-    uint16_t fix     = prevFix + start - prevEnd;
-    uint16_t stretch = prevStretch + end - start;
-
-    std::stringstream uniform;
-    uniform << uniformName << "[" << i << "]";
-    renderer.RegisterProperty(uniform.str(), Vector2(fix, stretch));
-
-    prevEnd     = end;
-    prevFix     = fix;
-    prevStretch = stretch;
-  }
-
-  {
-    prevFix += imageExtent - prevEnd;
-    std::stringstream uniform;
-    uniform << uniformName << "[" << i << "]";
-    renderer.RegisterProperty(uniform.str(), Vector2(prevFix, prevStretch));
-  }
+const int CUSTOM_PROPERTY_COUNT(5); // fixed(3),stretch,aux
 }
 
-} //unnamed namespace
-
 /////////////////NPatchVisual////////////////
 
 NPatchVisualPtr NPatchVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties)
@@ -165,11 +86,29 @@ void NPatchVisual::LoadImages()
     }
   }
 
-  if(!mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && (mAuxiliaryUrl.IsLocalResource() || mAuxiliaryUrl.IsBufferResource()))
+  if(mAuxiliaryTextureId == TextureManager::INVALID_TEXTURE_ID && mAuxiliaryUrl.IsValid() && (mAuxiliaryUrl.IsLocalResource() || mAuxiliaryUrl.IsBufferResource()))
   {
+    auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader
+                               ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+                               : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+    TextureManager::MaskingDataPointer maskingDataPtr       = nullptr;
+    ImageAtlasManagerPtr               imageAtlasManagerPtr = nullptr;
+
+    bool atlasing      = false;
+    auto atlasRect     = Vector4::ZERO;
+    auto atlasRectSize = Dali::ImageDimensions();
+
+    bool loadingStatus = false;
+
     // Load the auxiliary image
-    auto preMultiplyOnLoading = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
-    mAuxiliaryPixelBuffer     = textureManager.LoadPixelBuffer(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, synchronousLoading, this, true, preMultiplyOnLoading);
+    mAuxiliaryTextureSet = textureManager.LoadTexture(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, maskingDataPtr, synchronousLoading, mAuxiliaryTextureId, atlasRect, atlasRectSize, atlasing, loadingStatus, WrapMode::DEFAULT, WrapMode::DEFAULT, this, nullptr, imageAtlasManagerPtr, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad);
+
+    // If synchronousLoading is true, we can check the auxiliaryResource's status now.
+    if(synchronousLoading)
+    {
+      mAuxiliaryResourceStatus = (mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u) ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED;
+    }
   }
 }
 
@@ -198,10 +137,10 @@ void NPatchVisual::GetNaturalSize(Vector2& naturalSize)
     }
   }
 
-  if(mAuxiliaryPixelBuffer)
+  if(mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u)
   {
-    naturalSize.x = std::max(naturalSize.x, float(mAuxiliaryPixelBuffer.GetWidth()));
-    naturalSize.y = std::max(naturalSize.y, float(mAuxiliaryPixelBuffer.GetHeight()));
+    naturalSize.x = std::max(naturalSize.x, float(mAuxiliaryTextureSet.GetTexture(0u).GetWidth()));
+    naturalSize.y = std::max(naturalSize.y, float(mAuxiliaryTextureSet.GetTexture(0u).GetHeight()));
   }
 }
 
@@ -272,40 +211,39 @@ void NPatchVisual::DoSetOnScene(Actor& actor)
   // load when first go on stage
   LoadImages();
 
+  // Set mPlacementActor now, because some case, LoadImages can use this information in LoadComplete API.
+  // at this case, we try to SetResouce to mPlaceActor twice. so, we should avoid that case.
+  mPlacementActor = actor;
+
   const NPatchData* data;
-  if(mLoader.GetNPatchData(mId, data))
+  if(mImpl->mRenderer && mLoader.GetNPatchData(mId, data) && data->GetLoadingState() != NPatchData::LoadingState::LOADING)
   {
-    Geometry geometry = CreateGeometry();
-    Shader   shader   = CreateShader();
-
-    mImpl->mRenderer.SetGeometry(geometry);
-    mImpl->mRenderer.SetShader(shader);
-
-    mPlacementActor = actor;
-    if(data->GetLoadingState() != NPatchData::LoadingState::LOADING)
+    // If mAuxiliaryUrl need to be loaded, we should wait it until LoadComplete called.
+    if(!mAuxiliaryUrl.IsValid() || mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::PREPARING)
     {
-      if(RenderingAddOn::Get().IsValid())
-      {
-        RenderingAddOn::Get().SubmitRenderTask(mImpl->mRenderer, data->GetRenderingMap());
-      }
-
-      ApplyTextureAndUniforms();
-      actor.AddRenderer(mImpl->mRenderer);
-      mPlacementActor.Reset();
-
-      // npatch loaded and ready to display
-      ResourceReady(Toolkit::Visual::ResourceStatus::READY);
+      SetResource();
     }
   }
 }
 
 void NPatchVisual::DoSetOffScene(Actor& actor)
 {
-  if((mId != NPatchData::INVALID_NPATCH_DATA_ID) && mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED)
+  if(mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED)
   {
-    mLoader.Remove(mId, this);
-    mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
-    mId                    = NPatchData::INVALID_NPATCH_DATA_ID;
+    if(mId != NPatchData::INVALID_NPATCH_DATA_ID)
+    {
+      mLoader.Remove(mId, this);
+      mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
+      mId                    = NPatchData::INVALID_NPATCH_DATA_ID;
+    }
+    if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
+    {
+      TextureManager& textureManager = mFactoryCache.GetTextureManager();
+      textureManager.Remove(mAuxiliaryTextureId, this);
+      mAuxiliaryTextureId      = TextureManager::INVALID_TEXTURE_ID;
+      mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
+      mAuxiliaryTextureSet.Reset();
+    }
   }
 
   actor.RemoveRenderer(mImpl->mRenderer);
@@ -316,7 +254,7 @@ void NPatchVisual::OnSetTransform()
 {
   if(mImpl->mRenderer)
   {
-    mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+    mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
   }
 }
 
@@ -355,6 +293,9 @@ NPatchVisual::NPatchVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFa
   mImageUrl(),
   mAuxiliaryUrl(),
   mId(NPatchData::INVALID_NPATCH_DATA_ID),
+  mAuxiliaryTextureSet(),
+  mAuxiliaryTextureId(TextureManager::INVALID_TEXTURE_ID),
+  mAuxiliaryResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
   mBorderOnly(false),
   mBorder(),
   mAuxiliaryImageAlpha(0.0f),
@@ -365,10 +306,23 @@ NPatchVisual::NPatchVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFa
 
 NPatchVisual::~NPatchVisual()
 {
-  if(Stage::IsInstalled() && (mId != NPatchData::INVALID_NPATCH_DATA_ID) && (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER))
+  if(Stage::IsInstalled())
   {
-    mLoader.Remove(mId, this);
-    mId = NPatchData::INVALID_NPATCH_DATA_ID;
+    if(mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER)
+    {
+      if(mId != NPatchData::INVALID_NPATCH_DATA_ID)
+      {
+        mLoader.Remove(mId, this);
+        mId = NPatchData::INVALID_NPATCH_DATA_ID;
+      }
+      if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
+      {
+        TextureManager& textureManager = mFactoryCache.GetTextureManager();
+        textureManager.Remove(mAuxiliaryTextureId, this);
+        mAuxiliaryTextureId = TextureManager::INVALID_TEXTURE_ID;
+        mAuxiliaryTextureSet.Reset();
+      }
+    }
   }
 }
 
@@ -378,16 +332,13 @@ void NPatchVisual::OnInitialize()
   Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
   Shader   shader   = mImageVisualShaderFactory.GetShader(
     mFactoryCache,
-    TextureAtlas::DISABLED,
-    DefaultTextureWrapMode::APPLY,
-    RoundedCorner::DISABLED,
-    Borderline::DISABLED
-  );
+    ImageVisualShaderFeature::FeatureBuilder());
 
-  mImpl->mRenderer = Renderer::New(geometry, shader);
+  mImpl->mRenderer = VisualRenderer::New(geometry, shader);
+  mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
 
   //Register transform properties
-  mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+  mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
 }
 
 Geometry NPatchVisual::CreateGeometry()
@@ -424,12 +375,12 @@ Geometry NPatchVisual::CreateGeometry()
       Uint16Pair gridSize(2 * data->GetStretchPixelsX().Size() + 1, 2 * data->GetStretchPixelsY().Size() + 1);
       if(!data->GetRenderingMap())
       {
-        geometry = !mBorderOnly ? CreateGridGeometry(gridSize) : CreateBorderGeometry(gridSize);
+        geometry = !mBorderOnly ? NPatchHelper::CreateGridGeometry(gridSize) : NPatchHelper::CreateBorderGeometry(gridSize);
       }
       else
       {
         uint32_t elementCount[2];
-        geometry = !mBorderOnly ? RenderingAddOn::Get().CreateGeometryGrid(data->GetRenderingMap(), gridSize, elementCount) : CreateBorderGeometry(gridSize);
+        geometry = !mBorderOnly ? RenderingAddOn::Get().CreateGeometryGrid(data->GetRenderingMap(), gridSize, elementCount) : NPatchHelper::CreateBorderGeometry(gridSize);
         if(mImpl->mRenderer)
         {
           RenderingAddOn::Get().SubmitRenderTask(mImpl->mRenderer, data->GetRenderingMap());
@@ -454,10 +405,10 @@ Shader NPatchVisual::CreateShader()
   NPatchUtility::StretchRanges::SizeType xStretchCount = 0;
   NPatchUtility::StretchRanges::SizeType yStretchCount = 0;
 
-  auto fragmentShader = mAuxiliaryPixelBuffer ? SHADER_NPATCH_VISUAL_MASK_SHADER_FRAG
-                                              : SHADER_NPATCH_VISUAL_SHADER_FRAG;
-  auto shaderType     = mAuxiliaryPixelBuffer ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
-                                              : VisualFactoryCache::NINE_PATCH_SHADER;
+  auto fragmentShader = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? SHADER_NPATCH_VISUAL_MASK_SHADER_FRAG
+                                                                                           : SHADER_NPATCH_VISUAL_SHADER_FRAG;
+  auto shaderType = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
+                                                                                       : VisualFactoryCache::NINE_PATCH_SHADER;
 
   // ask loader for the regions
   if(mLoader.GetNPatchData(mId, data))
@@ -533,78 +484,41 @@ void NPatchVisual::ApplyTextureAndUniforms()
   if(mLoader.GetNPatchData(mId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
   {
     textureSet = data->GetTextures();
+    NPatchHelper::ApplyTextureAndUniforms(mImpl->mRenderer, data);
 
-    if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1)
-    {
-      //special case for 9 patch
-      Uint16Pair stretchX = data->GetStretchPixelsX()[0];
-      Uint16Pair stretchY = data->GetStretchPixelsY()[0];
-
-      uint16_t stretchWidth  = (stretchX.GetY() >= stretchX.GetX()) ? stretchX.GetY() - stretchX.GetX() : 0;
-      uint16_t stretchHeight = (stretchY.GetY() >= stretchY.GetX()) ? stretchY.GetY() - stretchY.GetX() : 0;
-
-      mImpl->mRenderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
-      mImpl->mRenderer.RegisterProperty("uFixed[1]", Vector2(stretchX.GetX(), stretchY.GetX()));
-      mImpl->mRenderer.RegisterProperty("uFixed[2]", Vector2(data->GetCroppedWidth() - stretchWidth, data->GetCroppedHeight() - stretchHeight));
-      mImpl->mRenderer.RegisterProperty("uStretchTotal", Vector2(stretchWidth, stretchHeight));
-    }
-    else
+    if(mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY)
     {
-      mImpl->mRenderer.RegisterProperty("uNinePatchFactorsX[0]", Vector2::ZERO);
-      mImpl->mRenderer.RegisterProperty("uNinePatchFactorsY[0]", Vector2::ZERO);
-
-      RegisterStretchProperties(mImpl->mRenderer, "uNinePatchFactorsX", data->GetStretchPixelsX(), data->GetCroppedWidth());
-      RegisterStretchProperties(mImpl->mRenderer, "uNinePatchFactorsY", data->GetStretchPixelsY(), data->GetCroppedHeight());
+      DALI_ASSERT_ALWAYS(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID);
+      DALI_ASSERT_ALWAYS(mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u);
+
+      // TODO : This code exist due to the texture cache manager hold TextureSet, not Texture.
+      // If we call textureSet.SetTexture(1, texture) directly, the cached TextureSet also be changed.
+      // We should make pass utc-Dali-VisualFactory.cpp UtcDaliNPatchVisualAuxiliaryImage02().
+      TextureSet tempTextureSet = TextureSet::New();
+      tempTextureSet.SetTexture(0, textureSet.GetTexture(0));
+      tempTextureSet.SetTexture(1, mAuxiliaryTextureSet.GetTexture(0));
+      textureSet = tempTextureSet;
+
+      mImpl->mRenderer.RegisterProperty(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA,
+                                        AUXILIARY_IMAGE_ALPHA_NAME,
+                                        mAuxiliaryImageAlpha);
     }
+    mImpl->mRenderer.SetTextures(textureSet);
   }
   else
   {
     DALI_LOG_ERROR("The N patch image '%s' is not a valid N patch image\n", mImageUrl.GetUrl().c_str());
-    textureSet = TextureSet::New();
-
-    Actor actor = mPlacementActor.GetHandle();
+    Actor   actor     = mPlacementActor.GetHandle();
     Vector2 imageSize = Vector2::ZERO;
     if(actor)
     {
       imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
     }
-    mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize);
-    Texture croppedImage = mImpl->mRenderer.GetTextures().GetTexture(0);
-    textureSet.SetTexture(0u, croppedImage);
-    mImpl->mRenderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
-    mImpl->mRenderer.RegisterProperty("uFixed[1]", Vector2::ZERO);
-    mImpl->mRenderer.RegisterProperty("uFixed[2]", Vector2::ZERO);
-    mImpl->mRenderer.RegisterProperty("uStretchTotal", Vector2(croppedImage.GetWidth(), croppedImage.GetHeight()));
+    mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize, false);
   }
 
-  if(mAuxiliaryPixelBuffer)
-  {
-    // If the auxiliary image is smaller than the un-stretched NPatch, use CPU resizing to enlarge it to the
-    // same size as the unstretched NPatch. This will give slightly higher quality results than just relying
-    // on GL interpolation alone.
-    if(mAuxiliaryPixelBuffer.GetWidth() < data->GetCroppedWidth() &&
-       mAuxiliaryPixelBuffer.GetHeight() < data->GetCroppedHeight())
-    {
-      mAuxiliaryPixelBuffer.Resize(data->GetCroppedWidth(), data->GetCroppedHeight());
-    }
-
-    // Note, this resets mAuxiliaryPixelBuffer handle
-    auto auxiliaryPixelData = Devel::PixelBuffer::Convert(mAuxiliaryPixelBuffer);
-
-    auto texture = Texture::New(TextureType::TEXTURE_2D,
-                                auxiliaryPixelData.GetPixelFormat(),
-                                auxiliaryPixelData.GetWidth(),
-                                auxiliaryPixelData.GetHeight());
-    texture.Upload(auxiliaryPixelData);
-    textureSet.SetTexture(1, texture);
-    mImpl->mRenderer.RegisterProperty(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA,
-                                      AUXILIARY_IMAGE_ALPHA_NAME,
-                                      mAuxiliaryImageAlpha);
-  }
-  mImpl->mRenderer.SetTextures(textureSet);
-
   // Register transform properties
-  mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+  mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
 }
 
 Geometry NPatchVisual::GetNinePatchGeometry(VisualFactoryCache::GeometryType subType)
@@ -614,148 +528,17 @@ Geometry NPatchVisual::GetNinePatchGeometry(VisualFactoryCache::GeometryType sub
   {
     if(DALI_LIKELY(VisualFactoryCache::NINE_PATCH_GEOMETRY == subType))
     {
-      geometry = CreateGridGeometry(Uint16Pair(3, 3));
+      geometry = NPatchHelper::CreateGridGeometry(Uint16Pair(3, 3));
     }
     else if(VisualFactoryCache::NINE_PATCH_BORDER_GEOMETRY == subType)
     {
-      geometry = CreateBorderGeometry(Uint16Pair(3, 3));
+      geometry = NPatchHelper::CreateBorderGeometry(Uint16Pair(3, 3));
     }
     mFactoryCache.SaveGeometry(subType, geometry);
   }
   return geometry;
 }
 
-Geometry NPatchVisual::CreateGridGeometry(Uint16Pair gridSize)
-{
-  uint16_t gridWidth  = gridSize.GetWidth();
-  uint16_t gridHeight = gridSize.GetHeight();
-
-  // Create vertices
-  Vector<Vector2> vertices;
-  vertices.Reserve((gridWidth + 1) * (gridHeight + 1));
-
-  for(int y = 0; y < gridHeight + 1; ++y)
-  {
-    for(int x = 0; x < gridWidth + 1; ++x)
-    {
-      AddVertex(vertices, x, y);
-    }
-  }
-
-  // Create indices
-  Vector<unsigned short> indices;
-  indices.Reserve(gridWidth * gridHeight * 6);
-
-  unsigned int rowIdx     = 0;
-  unsigned int nextRowIdx = gridWidth + 1;
-  for(int y = 0; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx)
-  {
-    for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
-    {
-      AddQuadIndices(indices, rowIdx, nextRowIdx);
-    }
-  }
-
-  return GenerateGeometry(vertices, indices);
-}
-
-Geometry NPatchVisual::CreateBorderGeometry(Uint16Pair gridSize)
-{
-  uint16_t gridWidth  = gridSize.GetWidth();
-  uint16_t gridHeight = gridSize.GetHeight();
-
-  // Create vertices
-  Vector<Vector2> vertices;
-  vertices.Reserve((gridWidth + 1) * (gridHeight + 1));
-
-  //top
-  int y = 0;
-  for(; y < 2; ++y)
-  {
-    for(int x = 0; x < gridWidth + 1; ++x)
-    {
-      AddVertex(vertices, x, y);
-    }
-  }
-
-  for(; y < gridHeight - 1; ++y)
-  {
-    //left
-    AddVertex(vertices, 0, y);
-    AddVertex(vertices, 1, y);
-
-    //right
-    AddVertex(vertices, gridWidth - 1, y);
-    AddVertex(vertices, gridWidth, y);
-  }
-
-  //bottom
-  for(; y < gridHeight + 1; ++y)
-  {
-    for(int x = 0; x < gridWidth + 1; ++x)
-    {
-      AddVertex(vertices, x, y);
-    }
-  }
-
-  // Create indices
-  Vector<unsigned short> indices;
-  indices.Reserve(gridWidth * gridHeight * 6);
-
-  //top
-  unsigned int rowIdx     = 0;
-  unsigned int nextRowIdx = gridWidth + 1;
-  for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
-  {
-    AddQuadIndices(indices, rowIdx, nextRowIdx);
-  }
-
-  if(gridHeight > 2)
-  {
-    rowIdx     = gridWidth + 1;
-    nextRowIdx = (gridWidth + 1) * 2;
-
-    unsigned increment = gridWidth - 1;
-    if(gridHeight > 3)
-    {
-      increment = 2;
-      //second row left
-      AddQuadIndices(indices, rowIdx, nextRowIdx);
-
-      rowIdx     = gridWidth * 2;
-      nextRowIdx = (gridWidth + 1) * 2 + 2;
-      //second row right
-      AddQuadIndices(indices, rowIdx, nextRowIdx);
-
-      //left and right
-      rowIdx     = nextRowIdx - 2;
-      nextRowIdx = rowIdx + 4;
-      for(int y = 2; y < 2 * (gridHeight - 3); ++y, rowIdx += 2, nextRowIdx += 2)
-      {
-        AddQuadIndices(indices, rowIdx, nextRowIdx);
-      }
-    }
-
-    //second row left
-    AddQuadIndices(indices, rowIdx, nextRowIdx);
-
-    rowIdx += increment;
-    nextRowIdx += gridWidth - 1;
-    //second row right
-    AddQuadIndices(indices, rowIdx, nextRowIdx);
-  }
-
-  //bottom
-  rowIdx     = nextRowIdx - gridWidth + 1;
-  nextRowIdx = rowIdx + gridWidth + 1;
-  for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
-  {
-    AddQuadIndices(indices, rowIdx, nextRowIdx);
-  }
-
-  return GenerateGeometry(vertices, indices);
-}
-
 void NPatchVisual::SetResource()
 {
   const NPatchData* data;
@@ -767,45 +550,73 @@ void NPatchVisual::SetResource()
     mImpl->mRenderer.SetGeometry(geometry);
     mImpl->mRenderer.SetShader(shader);
 
+    if(RenderingAddOn::Get().IsValid())
+    {
+      RenderingAddOn::Get().SubmitRenderTask(mImpl->mRenderer, data->GetRenderingMap());
+    }
     Actor actor = mPlacementActor.GetHandle();
     if(actor)
     {
       ApplyTextureAndUniforms();
       actor.AddRenderer(mImpl->mRenderer);
       mPlacementActor.Reset();
+    }
 
-      // npatch loaded and ready to display
+    // npatch loaded and ready to display
+    if(data->GetLoadingState() != NPatchData::LoadingState::LOAD_COMPLETE)
+    {
+      ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
+    }
+    else
+    {
       ResourceReady(Toolkit::Visual::ResourceStatus::READY);
     }
   }
 }
 
-void NPatchVisual::UploadComplete(bool loadSuccess, int32_t textureId, TextureSet textureSet, bool useAtlasing, const Vector4& atlasRect, bool preMultiplied)
+void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
 {
-  EnablePreMultipliedAlpha(preMultiplied);
-  if(!loadSuccess)
+  if(textureInformation.url.length() > 0) // For the Url.
   {
-    // Image loaded and ready to display
-    ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
+    if(DALI_UNLIKELY(mId == NPatchData::INVALID_NPATCH_DATA_ID))
+    {
+      // Special case when mLoader.Load call LoadComplete function before mId setup.
+      // We can overwrite mId.
+      mId = static_cast<NPatchData::NPatchDataId>(textureInformation.textureId);
+    }
+    if(loadSuccess)
+    {
+      EnablePreMultipliedAlpha(textureInformation.preMultiplied);
+    }
   }
-
-  if(mAuxiliaryPixelBuffer || !mAuxiliaryUrl.IsValid())
+  else // For the AuxiliaryUrl
   {
-    SetResource();
+    if(DALI_UNLIKELY(mAuxiliaryTextureId == TextureManager::INVALID_TEXTURE_ID))
+    {
+      // Special case when TextureManager.LoadTexture call LoadComplete function before mAuxiliaryTextureId setup.
+      // We can overwrite mAuxiliaryTextureId.
+      mAuxiliaryTextureId = textureInformation.textureId;
+    }
+    if(loadSuccess)
+    {
+      mAuxiliaryTextureSet     = textureInformation.textureSet;
+      mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::READY;
+    }
+    else
+    {
+      mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
+    }
   }
-}
 
-void NPatchVisual::LoadComplete(bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied)
-{
-  if(loadSuccess && url.GetUrl() == mAuxiliaryUrl.GetUrl())
+  // If auxiliaryUrl didn't required OR auxiliaryUrl load done.
+  if(!mAuxiliaryUrl.IsValid() || mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::PREPARING)
   {
-    mAuxiliaryPixelBuffer = pixelBuffer;
-    SetResource();
-  }
-  else
-  {
-    // Image loaded and ready to display
-    ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
+    const NPatchData* data;
+    // and.. If Url loading done.
+    if(mImpl->mRenderer && mLoader.GetNPatchData(mId, data) && data->GetLoadingState() != NPatchData::LoadingState::LOADING)
+    {
+      SetResource();
+    }
   }
 }