Enable to use GPU masking in image visual 26/275226/16
authorseungho <sbsh.baek@samsung.com>
Wed, 18 May 2022 12:08:22 +0000 (21:08 +0900)
committerseungho <sbsh.baek@samsung.com>
Fri, 27 May 2022 12:53:06 +0000 (21:53 +0900)
Change-Id: I37673b02dfa6764a1ebf87a68193c839a6b6212d
Signed-off-by: seungho <sbsh.baek@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h
dali-toolkit/public-api/visuals/image-visual-properties.h

index b36457f..3f4fdba 100644 (file)
@@ -1593,7 +1593,7 @@ int UtcDaliImageVisualSetInvalidRemoteImage(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
-int UtcDaliImageVisualAlphaMask(void)
+int UtcDaliImageVisualAlphaMask01(void)
 {
   ToolkitTestApplication application;
   tet_infoline("Request image visual with a Property::Map containing an Alpha mask");
 {
   ToolkitTestApplication application;
   tet_infoline("Request image visual with a Property::Map containing an Alpha mask");
@@ -1647,7 +1647,127 @@ int UtcDaliImageVisualAlphaMask(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
-int UtcDaliImageVisualSynchronousLoadAlphaMask(void)
+int UtcDaliImageVisualAlphaMask02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU");
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK(factory);
+
+  Property::Map propertyMap;
+  propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+  propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME);
+  propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+  propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+  Visual::Base visual = factory.CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  Property::Map testMap;
+  visual.CreatePropertyMap(testMap);
+  DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION);
+  DALI_TEST_EQUALS(*testMap.Find(DevelImageVisual::Property::MASKING_TYPE), Property::Value(DevelImageVisual::MaskingType::MASKING_ON_RENDERING), TEST_LOCATION);
+
+  // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+  // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  DummyControl      actor     = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+  actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
+
+  application.GetScene().Add(actor);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+  Renderer renderer = actor.GetRendererAt(0u);
+  TextureSet textures = renderer.GetTextures();
+  DALI_TEST_CHECK(textures);
+  DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+  dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliImageVisualAlphaMask03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with fail case");
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK(factory);
+
+  Property::Map propertyMap;
+  propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+  propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME);
+  propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "dummy_path");
+  propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+  Visual::Base visual = factory.CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  Property::Map testMap;
+  visual.CreatePropertyMap(testMap);
+
+  // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+  // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  DummyControl      actor     = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+  actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
+
+  application.GetScene().Add(actor);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+  Renderer renderer = actor.GetRendererAt(0u);
+  TextureSet textures = renderer.GetTextures();
+  DALI_TEST_CHECK(textures);
+  DALI_TEST_EQUALS(textures.GetTextureCount(), 1u, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+  dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliImageVisualSynchronousLoadAlphaMask01(void)
 {
   ToolkitTestApplication application;
   tet_infoline("Request image visual with a Property::Map containing an Alpha mask with synchronous loading");
 {
   ToolkitTestApplication application;
   tet_infoline("Request image visual with a Property::Map containing an Alpha mask with synchronous loading");
@@ -1700,6 +1820,65 @@ int UtcDaliImageVisualSynchronousLoadAlphaMask(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
+int UtcDaliImageVisualSynchronousLoadAlphaMask02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with synchronous loading");
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK(factory);
+
+  Property::Map propertyMap;
+  propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+  propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME);
+  propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+  propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true);
+  propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+  Visual::Base visual = factory.CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  Property::Map testMap;
+  visual.CreatePropertyMap(testMap);
+  DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION);
+
+  // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+  // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  DummyControl      actor     = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+  actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
+
+  application.GetScene().Add(actor);
+
+  // Do not wait for any EventThreadTrigger in synchronous alpha mask.
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+  Renderer renderer = actor.GetRendererAt(0u);
+  TextureSet textures = renderer.GetTextures();
+  DALI_TEST_CHECK(textures);
+  DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+  dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliImageVisualRemoteAlphaMask(void)
 {
   ToolkitTestApplication application;
 int UtcDaliImageVisualRemoteAlphaMask(void)
 {
   ToolkitTestApplication application;
index cac3b47..445ad65 100644 (file)
@@ -402,39 +402,36 @@ TextureSet TextureManager::LoadTexture(
       if(!textureSet) // big image, no atlasing or atlasing failed
       {
         atlasingStatus = false;
       if(!textureSet) // big image, no atlasing or atlasing failed
       {
         atlasingStatus = false;
-        if(!maskInfo || !maskInfo->mAlphaMaskUrl.IsValid())
-        {
-          textureId = RequestLoad(
-            url,
-            desiredSize,
-            fittingMode,
-            samplingMode,
-            UseAtlas::NO_ATLAS,
-            textureObserver,
-            orientationCorrection,
-            reloadPolicy,
-            preMultiplyOnLoad,
-            synchronousLoading);
-        }
-        else
+
+        TextureId alphaMaskId        = INVALID_TEXTURE_ID;
+        float     contentScaleFactor = 1.0f;
+        bool      cropToMask         = false;
+        if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
         {
           maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, maskInfo->mPreappliedMasking ? StorageType::KEEP_PIXEL_BUFFER : StorageType::KEEP_TEXTURE, synchronousLoading);
         {
           maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, maskInfo->mPreappliedMasking ? StorageType::KEEP_PIXEL_BUFFER : StorageType::KEEP_TEXTURE, synchronousLoading);
-          textureId              = RequestLoad(
-            url,
-            maskInfo->mAlphaMaskId,
-            maskInfo->mContentScaleFactor,
-            desiredSize,
-            fittingMode,
-            samplingMode,
-            UseAtlas::NO_ATLAS,
-            maskInfo->mCropToMask,
-            textureObserver,
-            orientationCorrection,
-            reloadPolicy,
-            preMultiplyOnLoad,
-            synchronousLoading);
+          alphaMaskId            = maskInfo->mAlphaMaskId;
+          if(maskInfo && maskInfo->mPreappliedMasking)
+          {
+            contentScaleFactor = maskInfo->mContentScaleFactor;
+            cropToMask         = maskInfo->mCropToMask;
+          }
         }
 
         }
 
+        textureId = RequestLoad(
+          url,
+          alphaMaskId,
+          contentScaleFactor,
+          desiredSize,
+          fittingMode,
+          samplingMode,
+          UseAtlas::NO_ATLAS,
+          cropToMask,
+          textureObserver,
+          orientationCorrection,
+          reloadPolicy,
+          preMultiplyOnLoad,
+          synchronousLoading);
+
         TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
         if(loadState == TextureManager::LoadState::UPLOADED)
         {
         TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
         if(loadState == TextureManager::LoadState::UPLOADED)
         {
@@ -667,19 +664,31 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
       }
       else // For the image loading.
       {
       }
       else // For the image loading.
       {
+        Texture maskTexture;
         if(maskTextureId != INVALID_TEXTURE_ID)
         {
           TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId);
           if(maskCacheIndex != INVALID_CACHE_INDEX)
           {
         if(maskTextureId != INVALID_TEXTURE_ID)
         {
           TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId);
           if(maskCacheIndex != INVALID_CACHE_INDEX)
           {
-            Devel::PixelBuffer maskPixelBuffer = mTextureCacheManager[maskCacheIndex].pixelBuffer;
-            if(maskPixelBuffer)
+            if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_TEXTURE)
             {
             {
-              pixelBuffer.ApplyMask(maskPixelBuffer, contentScale, cropToMask);
+              TextureSet maskTextures = mTextureCacheManager[maskCacheIndex].textureSet;
+              if(maskTextures && maskTextures.GetTextureCount())
+              {
+                maskTexture = maskTextures.GetTexture(0u);
+              }
             }
             }
-            else
+            else if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_PIXEL_BUFFER)
             {
             {
-              DALI_LOG_ERROR("Mask image cached invalid pixel buffer!\n");
+              Devel::PixelBuffer maskPixelBuffer = mTextureCacheManager[maskCacheIndex].pixelBuffer;
+              if(maskPixelBuffer)
+              {
+                pixelBuffer.ApplyMask(maskPixelBuffer, contentScale, cropToMask);
+              }
+              else
+              {
+                DALI_LOG_ERROR("Mask image cached invalid pixel buffer!\n");
+              }
             }
           }
           else
             }
           }
           else
@@ -691,6 +700,10 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
 
         // Upload texture
         UploadTexture(pixelBuffer, textureInfo);
 
         // Upload texture
         UploadTexture(pixelBuffer, textureInfo);
+        if(maskTexture && textureInfo.textureSet)
+        {
+          textureInfo.textureSet.SetTexture(1u, maskTexture);
+        }
       }
     }
   }
       }
     }
   }
index 72f44cf..a334e2f 100644 (file)
@@ -83,7 +83,6 @@ static constexpr Vector4  FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 static constexpr auto     LOOP_FOREVER = -1;
 static constexpr auto     FIRST_LOOP   = 0u;
 
 static constexpr auto     LOOP_FOREVER = -1;
 static constexpr auto     FIRST_LOOP   = 0u;
 
-const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio");
 constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u;
 
 #if defined(DEBUG_ENABLED)
 constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u;
 
 #if defined(DEBUG_ENABLED)
index e3aa797..44c9fac 100644 (file)
@@ -51,7 +51,7 @@ namespace Internal
 {
 namespace
 {
 {
 namespace
 {
-const int CUSTOM_PROPERTY_COUNT(9); // wrap, pixel area, atlas, pixalign, + border/corner
+const int CUSTOM_PROPERTY_COUNT(12); // ltr, wrap, pixel area, atlas, pixalign, crop to mask, mask texture ratio + border/corner
 
 // fitting modes
 DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE)
 
 // fitting modes
 DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE)
@@ -99,6 +99,8 @@ const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 const float PIXEL_ALIGN_ON  = 1.0f;
 const float PIXEL_ALIGN_OFF = 0.0f;
 
 const float PIXEL_ALIGN_ON  = 1.0f;
 const float PIXEL_ALIGN_OFF = 0.0f;
 
+constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u;
+
 Geometry CreateGeometry(VisualFactoryCache& factoryCache, ImageDimensions gridSize)
 {
   Geometry geometry;
 Geometry CreateGeometry(VisualFactoryCache& factoryCache, ImageDimensions gridSize)
 {
   Geometry geometry;
@@ -274,6 +276,10 @@ void ImageVisual::DoSetProperties(const Property::Map& propertyMap)
       {
         DoSetProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, keyValue.second);
       }
       {
         DoSetProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, keyValue.second);
       }
+      else if(keyValue.first == MASKING_TYPE_NAME)
+      {
+        DoSetProperty(Toolkit::DevelImageVisual::Property::MASKING_TYPE, keyValue.second);
+      }
       else if(keyValue.first == LOAD_POLICY_NAME)
       {
         DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second);
       else if(keyValue.first == LOAD_POLICY_NAME)
       {
         DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second);
@@ -426,6 +432,17 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va
       break;
     }
 
       break;
     }
 
+    case Toolkit::DevelImageVisual::Property::MASKING_TYPE:
+    {
+      int maskingType = 0;
+      if(value.Get(maskingType))
+      {
+        AllocateMaskData();
+        mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false;
+      }
+      break;
+    }
+
     case Toolkit::ImageVisual::Property::RELEASE_POLICY:
     {
       int releasePolicy = 0;
     case Toolkit::ImageVisual::Property::RELEASE_POLICY:
     {
       int releasePolicy = 0;
@@ -481,11 +498,9 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize)
     auto textureSet = mImpl->mRenderer.GetTextures();
     if(textureSet && textureSet.GetTextureCount())
     {
     auto textureSet = mImpl->mRenderer.GetTextures();
     if(textureSet && textureSet.GetTextureCount())
     {
-      auto texture = textureSet.GetTexture(0);
-      if(texture)
+      if(mTextureSize != Vector2::ZERO)
       {
       {
-        naturalSize.x = texture.GetWidth();
-        naturalSize.y = texture.GetHeight();
+        naturalSize = mTextureSize;
         return;
       }
     }
         return;
       }
     }
@@ -574,6 +589,11 @@ void ImageVisual::OnInitialize()
   mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
 
   EnablePreMultipliedAlpha(IsPreMultipliedAlphaEnabled());
   mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
 
   EnablePreMultipliedAlpha(IsPreMultipliedAlphaEnabled());
+
+  if(mMaskingData)
+  {
+    mImpl->mRenderer.RegisterProperty(CROP_TO_MASK_NAME, static_cast<float>(mMaskingData->mCropToMask));
+  }
 }
 
 void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, TextureManager::ReloadPolicy forceReload)
 }
 
 void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, TextureManager::ReloadPolicy forceReload)
@@ -661,6 +681,8 @@ void ImageVisual::InitializeRenderer()
   if(mTextures)
   {
     mImpl->mRenderer.SetTextures(mTextures);
   if(mTextures)
   {
     mImpl->mRenderer.SetTextures(mTextures);
+    ComputeTextureSize();
+    CheckMaskTexture();
     if(DevelTexture::IsNative(mTextures.GetTexture(0)))
     {
       UpdateShader();
     if(DevelTexture::IsNative(mTextures.GetTexture(0)))
     {
       UpdateShader();
@@ -745,6 +767,7 @@ void ImageVisual::DoSetOffScene(Actor& actor)
 
     TextureSet textureSet = TextureSet::New();
     mImpl->mRenderer.SetTextures(textureSet);
 
     TextureSet textureSet = TextureSet::New();
     mImpl->mRenderer.SetTextures(textureSet);
+    ComputeTextureSize();
 
     mLoadState = TextureManager::LoadState::NOT_STARTED;
   }
 
     mLoadState = TextureManager::LoadState::NOT_STARTED;
   }
@@ -780,6 +803,7 @@ void ImageVisual::DoCreatePropertyMap(Property::Map& map) const
     map.Insert(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl());
     map.Insert(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor);
     map.Insert(Toolkit::ImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask);
     map.Insert(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl());
     map.Insert(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor);
     map.Insert(Toolkit::ImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask);
+    map.Insert(Toolkit::DevelImageVisual::Property::MASKING_TYPE, mMaskingData->mPreappliedMasking ? DevelImageVisual::MaskingType::MASKING_ON_LOADING : DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
   }
 
   map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
   }
 
   map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
@@ -879,6 +903,8 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn
       sampler.SetWrapMode(mWrapModeU, mWrapModeV);
       textureInformation.textureSet.SetSampler(0u, sampler);
       mImpl->mRenderer.SetTextures(textureInformation.textureSet);
       sampler.SetWrapMode(mWrapModeU, mWrapModeV);
       textureInformation.textureSet.SetSampler(0u, sampler);
       mImpl->mRenderer.SetTextures(textureInformation.textureSet);
+      ComputeTextureSize();
+      CheckMaskTexture();
     }
 
     if(actor)
     }
 
     if(actor)
@@ -967,6 +993,60 @@ void ImageVisual::RemoveTexture()
   }
 }
 
   }
 }
 
+void ImageVisual::ComputeTextureSize()
+{
+  if(mImpl->mRenderer)
+  {
+    auto textureSet = mImpl->mRenderer.GetTextures();
+    if(textureSet && textureSet.GetTextureCount())
+    {
+      auto texture = textureSet.GetTexture(0);
+      if(texture)
+      {
+        mTextureSize.x = texture.GetWidth();
+        mTextureSize.y = texture.GetHeight();
+        if(textureSet.GetTextureCount() > 1u && mMaskingData && !mMaskingData->mPreappliedMasking && mMaskingData->mCropToMask)
+        {
+          Texture maskTexture = textureSet.GetTexture(1);
+          if(maskTexture)
+          {
+            mTextureSize.x = std::min(static_cast<uint32_t>(mTextureSize.x * mMaskingData->mContentScaleFactor), maskTexture.GetWidth());
+            mTextureSize.y = std::min(static_cast<uint32_t>(mTextureSize.y * mMaskingData->mContentScaleFactor), maskTexture.GetHeight());
+          }
+        }
+      }
+    }
+  }
+}
+
+Vector2 ImageVisual::ComputeMaskTextureRatio()
+{
+  Vector2 maskTextureRatio;
+  if(mImpl->mRenderer)
+  {
+    auto textureSet = mImpl->mRenderer.GetTextures();
+    if(textureSet && textureSet.GetTextureCount())
+    {
+      auto texture = textureSet.GetTexture(0);
+      if(texture)
+      {
+        if(textureSet.GetTextureCount() > 1u && mMaskingData && !mMaskingData->mPreappliedMasking && mMaskingData->mCropToMask)
+        {
+          Texture maskTexture = textureSet.GetTexture(1);
+          if(maskTexture)
+          {
+            float textureWidth  = std::max(static_cast<float>(texture.GetWidth() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1);
+            float textureHeight = std::max(static_cast<float>(texture.GetHeight() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1);
+            maskTextureRatio    = Vector2(std::min(static_cast<float>(maskTexture.GetWidth()), textureWidth) / textureWidth,
+                                       std::min(static_cast<float>(maskTexture.GetHeight()), textureHeight) / textureHeight);
+          }
+        }
+      }
+    }
+  }
+  return maskTextureRatio;
+}
+
 Shader ImageVisual::GenerateShader() const
 {
   Shader shader;
 Shader ImageVisual::GenerateShader() const
 {
   Shader shader;
@@ -977,6 +1057,7 @@ Shader ImageVisual::GenerateShader() const
 
   if(useStandardShader)
   {
 
   if(useStandardShader)
   {
+    bool   requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false;
     // Create and cache the standard shader
     shader = mImageVisualShaderFactory.GetShader(
       mFactoryCache,
     // Create and cache the standard shader
     shader = mImageVisualShaderFactory.GetShader(
       mFactoryCache,
@@ -985,7 +1066,8 @@ Shader ImageVisual::GenerateShader() const
         .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE)
         .EnableRoundedCorner(IsRoundedCornerRequired())
         .EnableBorderline(IsBorderlineRequired())
         .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE)
         .EnableRoundedCorner(IsRoundedCornerRequired())
         .EnableBorderline(IsBorderlineRequired())
-        .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture()));
+        .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture())
+        .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering));
   }
   else
   {
   }
   else
   {
@@ -1047,6 +1129,29 @@ Shader ImageVisual::GenerateShader() const
   return shader;
 }
 
   return shader;
 }
 
+void ImageVisual::CheckMaskTexture()
+{
+  if(mMaskingData && !mMaskingData->mPreappliedMasking)
+  {
+    bool maskLoadFailed = true;
+    TextureSet textures = mImpl->mRenderer.GetTextures();
+    if(textures && textures.GetTextureCount() >= TEXTURE_COUNT_FOR_GPU_ALPHA_MASK)
+    {
+      if(mMaskingData->mCropToMask)
+      {
+        mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, ComputeMaskTextureRatio());
+      }
+      maskLoadFailed = false;
+    }
+
+    if(mMaskingData->mMaskImageLoadingFailed != maskLoadFailed)
+    {
+      mMaskingData->mMaskImageLoadingFailed = maskLoadFailed;
+      UpdateShader();
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index 0cbc3ba..17d5a6e 100644 (file)
@@ -299,12 +299,29 @@ private:
   void RemoveTexture();
 
   /**
   void RemoveTexture();
 
   /**
+   * @brief Compute texture size
+   */
+  void ComputeTextureSize();
+
+  /**
+   * @brief Compute mask texture ratio
+   * @return The Mask Texture Ratio
+   */
+  Vector2 ComputeMaskTextureRatio();
+
+  /**
    * Helper method to set individual values by index key.
    * @param[in] index The index key of the value
    * @param[in] value The value
    */
   void DoSetProperty(Property::Index index, const Property::Value& value);
 
    * Helper method to set individual values by index key.
    * @param[in] index The index key of the value
    * @param[in] value The value
    */
   void DoSetProperty(Property::Index index, const Property::Value& value);
 
+  /**
+   * @brief Check whether the mask texture is loaded or not.
+   * If MaskingType is MASKING_ON_LOADING and mask texture is failed to load, update shader.
+   */
+  void CheckMaskTexture();
+
 private:
   Vector4                            mPixelArea;
   WeakHandle<Actor>                  mPlacementActor;
 private:
   Vector4                            mPixelArea;
   WeakHandle<Actor>                  mPlacementActor;
@@ -314,6 +331,7 @@ private:
   Dali::ImageDimensions     mDesiredSize;
   TextureManager::TextureId mTextureId;
   TextureSet                mTextures;
   Dali::ImageDimensions     mDesiredSize;
   TextureManager::TextureId mTextureId;
   TextureSet                mTextures;
+  Vector2                   mTextureSize;
 
   ImageVisualShaderFactory& mImageVisualShaderFactory;
 
 
   ImageVisualShaderFactory& mImageVisualShaderFactory;
 
index 6b48a2d..c79c9a6 100644 (file)
@@ -123,6 +123,7 @@ const char* const IMAGE_DESIRED_HEIGHT("desiredHeight");
 const char* const ALPHA_MASK_URL("alphaMaskUrl");
 const char* const REDRAW_IN_SCALING_DOWN_NAME("redrawInScalingDown");
 const char* const MASKING_TYPE_NAME("maskingType");
 const char* const ALPHA_MASK_URL("alphaMaskUrl");
 const char* const REDRAW_IN_SCALING_DOWN_NAME("redrawInScalingDown");
 const char* const MASKING_TYPE_NAME("maskingType");
+const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio");
 
 // Text visual
 const char* const TEXT_PROPERTY("text");
 
 // Text visual
 const char* const TEXT_PROPERTY("text");
index e736132..b65292f 100644 (file)
@@ -107,6 +107,7 @@ extern const char* const IMAGE_DESIRED_HEIGHT;
 extern const char* const ALPHA_MASK_URL;
 extern const char* const REDRAW_IN_SCALING_DOWN_NAME;
 extern const char* const MASKING_TYPE_NAME;
 extern const char* const ALPHA_MASK_URL;
 extern const char* const REDRAW_IN_SCALING_DOWN_NAME;
 extern const char* const MASKING_TYPE_NAME;
+extern const char* const MASK_TEXTURE_RATIO_NAME;
 
 // Text visual
 extern const char* const TEXT_PROPERTY;
 
 // Text visual
 extern const char* const TEXT_PROPERTY;
index b0b28d4..29b9409 100644 (file)
@@ -226,7 +226,7 @@ enum
    * @details Name "cropToMask", type Property::BOOLEAN, True if the image should
    * be cropped to match the mask size, or false if the image should remain the same size.
    * @SINCE_1_2.60
    * @details Name "cropToMask", type Property::BOOLEAN, True if the image should
    * be cropped to match the mask size, or false if the image should remain the same size.
    * @SINCE_1_2.60
-   * @note Optional.
+   * @note Optional, Default true
    * @note If this is false, then the mask is scaled to fit the image before being applied.
    */
   CROP_TO_MASK,
    * @note If this is false, then the mask is scaled to fit the image before being applied.
    */
   CROP_TO_MASK,