[Tizen] Fix gpu masking error
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / image / image-visual.cpp
index 44c9fac..6b639dd 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/actors/layer.h>
+#include <dali/public-api/rendering/decorated-visual-renderer.h>
 #include <cstring> // for strlen()
 
 // INTERNAL HEADERS
@@ -51,7 +52,7 @@ namespace Internal
 {
 namespace
 {
-const int CUSTOM_PROPERTY_COUNT(12); // ltr, wrap, pixel area, atlas, pixalign, crop to mask, mask texture ratio + border/corner
+const int CUSTOM_PROPERTY_COUNT(7); // ltr, wrap, pixel area, atlas, pixalign, crop to mask, mask texture ratio
 
 // fitting modes
 DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE)
@@ -179,18 +180,6 @@ ImageVisual::~ImageVisual()
 {
   if(Stage::IsInstalled())
   {
-    if(mMaskingData)
-    {
-      // TextureManager could have been deleted before the actor that contains this
-      // ImageVisual is destroyed (e.g. due to stage shutdown). Ensure the stage
-      // is still valid before accessing texture manager.
-      if(mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
-      {
-        TextureManager& textureManager = mFactoryCache.GetTextureManager();
-        textureManager.Remove(mMaskingData->mAlphaMaskId, this);
-      }
-    }
-
     if(mImageUrl.IsValid())
     {
       // Decrease reference count of External Resources :
@@ -329,7 +318,7 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va
 
     case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
     {
-      float desiredWidth = 0.0f;
+      int32_t desiredWidth = 0;
       if(value.Get(desiredWidth))
       {
         mDesiredSize.SetWidth(desiredWidth);
@@ -343,7 +332,7 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va
 
     case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
     {
-      float desiredHeight = 0.0f;
+      int32_t desiredHeight = 0;
       if(value.Get(desiredHeight))
       {
         mDesiredSize.SetHeight(desiredHeight);
@@ -438,7 +427,16 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va
       if(value.Get(maskingType))
       {
         AllocateMaskData();
-        mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false;
+        if(mImageUrl.IsValid() && mImageUrl.GetProtocolType() == VisualUrl::TEXTURE)
+        {
+          // For external textures, only gpu masking is available.
+          // Therefore, MASKING_TYPE is set to MASKING_ON_RENDERING forcelly.
+          mMaskingData->mPreappliedMasking = false;
+        }
+        else
+        {
+          mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false;
+        }
       }
       break;
     }
@@ -475,6 +473,10 @@ void ImageVisual::AllocateMaskData()
   if(!mMaskingData)
   {
     mMaskingData.reset(new TextureManager::MaskingData());
+    if(mImageUrl.IsValid() && mImageUrl.GetProtocolType() == VisualUrl::TEXTURE)
+    {
+      mMaskingData->mPreappliedMasking = false;
+    }
   }
 }
 
@@ -536,6 +538,11 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize)
         {
           imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
         }
+        else
+        {
+          imageSize = mPlacementActorSize;
+        }
+
         mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize);
         Texture brokenImage = mImpl->mRenderer.GetTextures().GetTexture(0);
         naturalSize.x       = brokenImage.GetWidth();
@@ -582,7 +589,7 @@ void ImageVisual::OnInitialize()
   Shader shader = GenerateShader();
 
   // Create the renderer
-  mImpl->mRenderer = VisualRenderer::New(geometry, shader);
+  mImpl->mRenderer = DecoratedVisualRenderer::New(geometry, shader);
   mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
 
   //Register transform properties
@@ -617,7 +624,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te
   bool synchronousLoading = IsSynchronousLoadingRequired();
   bool loadingStatus;
 
-  textures = textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, mWrapModeU, mWrapModeV, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad);
+  textures = textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad);
 
   if(textures)
   {
@@ -631,6 +638,12 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te
     }
 
     EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
+    if(!atlasing)
+    {
+      Sampler sampler = Sampler::New();
+      sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+      textures.SetSampler(0u, sampler);
+    }
   }
   else if(synchronousLoading)
   {
@@ -675,6 +688,12 @@ void ImageVisual::InitializeRenderer()
     else
     {
       mTextures = mFactoryCache.GetTextureManager().GetTextureSet(mTextureId);
+      if(!(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) && mTextures)
+      {
+        Sampler sampler = Sampler::New();
+        sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+        mTextures.SetSampler(0u, sampler);
+      }
     }
   }
 
@@ -683,7 +702,19 @@ void ImageVisual::InitializeRenderer()
     mImpl->mRenderer.SetTextures(mTextures);
     ComputeTextureSize();
     CheckMaskTexture();
-    if(DevelTexture::IsNative(mTextures.GetTexture(0)))
+
+    bool needToUpdateShader = DevelTexture::IsNative(mTextures.GetTexture(0));
+
+    if(mTextures.GetTextureCount() == 3)
+    {
+      if(mTextures.GetTexture(0).GetPixelFormat() == Pixel::L8 && mTextures.GetTexture(1).GetPixelFormat() == Pixel::CHROMINANCE_U && mTextures.GetTexture(2).GetPixelFormat() == Pixel::CHROMINANCE_V)
+      {
+        mNeedYuvToRgb      = true;
+        needToUpdateShader = true;
+      }
+    }
+
+    if(needToUpdateShader)
     {
       UpdateShader();
     }
@@ -744,8 +775,10 @@ void ImageVisual::DoSetOnScene(Actor& actor)
     Vector2 imageSize = Vector2::ZERO;
     if(actor)
     {
-      imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+      imageSize  = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+      mPlacementActorSize = imageSize;
     }
+
     mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize);
     actor.AddRenderer(mImpl->mRenderer);
     mPlacementActor.Reset();
@@ -892,19 +925,38 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn
       Vector2 imageSize = Vector2::ZERO;
       if(actor)
       {
-        imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+        imageSize  = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+        mPlacementActorSize = imageSize;
+      }
+      else
+      {
+        imageSize = mPlacementActorSize;
       }
+
       mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize);
       textureInformation.textureSet = mImpl->mRenderer.GetTextures();
     }
     else
     {
-      Sampler sampler = Sampler::New();
-      sampler.SetWrapMode(mWrapModeU, mWrapModeV);
-      textureInformation.textureSet.SetSampler(0u, sampler);
+      if(!textureInformation.useAtlasing)
+      {
+        Sampler sampler = Sampler::New();
+        sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+        textureInformation.textureSet.SetSampler(0u, sampler);
+      }
+
       mImpl->mRenderer.SetTextures(textureInformation.textureSet);
       ComputeTextureSize();
       CheckMaskTexture();
+
+      if(textureInformation.textureSet.GetTextureCount() == 3)
+      {
+        if(textureInformation.textureSet.GetTexture(0).GetPixelFormat() == Pixel::L8 && textureInformation.textureSet.GetTexture(1).GetPixelFormat() == Pixel::CHROMINANCE_U && textureInformation.textureSet.GetTexture(2).GetPixelFormat() == Pixel::CHROMINANCE_V)
+        {
+          mNeedYuvToRgb = true;
+          UpdateShader();
+        }
+      }
     }
 
     if(actor)
@@ -1057,7 +1109,7 @@ Shader ImageVisual::GenerateShader() const
 
   if(useStandardShader)
   {
-    bool   requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false;
+    bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false;
     // Create and cache the standard shader
     shader = mImageVisualShaderFactory.GetShader(
       mFactoryCache,
@@ -1067,7 +1119,8 @@ Shader ImageVisual::GenerateShader() const
         .EnableRoundedCorner(IsRoundedCornerRequired())
         .EnableBorderline(IsBorderlineRequired())
         .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture())
-        .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering));
+        .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering)
+        .EnableYuvToRgb(mNeedYuvToRgb));
   }
   else
   {
@@ -1133,10 +1186,11 @@ void ImageVisual::CheckMaskTexture()
 {
   if(mMaskingData && !mMaskingData->mPreappliedMasking)
   {
-    bool maskLoadFailed = true;
-    TextureSet textures = mImpl->mRenderer.GetTextures();
+    bool       maskLoadFailed = true;
+    TextureSet textures       = mImpl->mRenderer.GetTextures();
     if(textures && textures.GetTextureCount() >= TEXTURE_COUNT_FOR_GPU_ALPHA_MASK)
     {
+      mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, Vector2::ONE);
       if(mMaskingData->mCropToMask)
       {
         mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, ComputeMaskTextureRatio());