Fix ImageView issue 32/199432/5
authorHeeyong Song <heeyong.song@samsung.com>
Mon, 11 Feb 2019 09:12:32 +0000 (18:12 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Mon, 25 Feb 2019 04:42:53 +0000 (04:42 +0000)
Fix the issue that ImageView::Property::PRE_MULTIPLIED_ALPHA didn't work

Change-Id: Iaffb788b5202c95e9b109c3a27270ddcb678ca79

automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h

index 7d1ea16..20686c6 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 
 #include <test-native-image.h>
@@ -353,7 +354,7 @@ int UtcDaliImageViewSetGetProperty03(void)
   Property::Value value = renderer.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
   bool enable;
   DALI_TEST_CHECK( value.Get( enable ) );
-  DALI_TEST_CHECK( !enable );
+  DALI_TEST_CHECK( enable );
 
   // pre-multiplied alpha blending
   imageView.SetProperty( Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA, true );
@@ -376,6 +377,205 @@ int UtcDaliImageViewSetGetProperty03(void)
   END_TEST;
 }
 
+int UtcDaliImageViewPreMultipliedAlphaPng(void)
+{
+  ToolkitTestApplication application;
+
+  // Set up trace debug
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable( true );
+
+  Property::Map imageMap;
+  imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA;
+  imageMap[ ImageVisual::Property::RELEASE_POLICY] = ImageVisual::ReleasePolicy::NEVER;   // To keep the texture cache
+
+  ImageView imageView1 = ImageView::New();
+  imageView1.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView1 );
+
+  Property::Value value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  bool enable;
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );    // Default value is true
+
+  // loading started, this waits for the loader thread for max 30 seconds
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );    // Keep true
+
+  // conventional alpha blending
+  Renderer renderer1 = imageView1.GetRendererAt( 0 );
+  value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );
+
+  int srcFactorRgb    = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  int destFactorRgb   = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  int srcFactorAlpha  = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  int destFactorAlpha = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );  // A new texture should be generated.
+  textureTrace.Reset();
+
+  // Disable pre-multiplied alpha blending
+  imageView1.SetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA, false );
+
+  // Reload the image
+  Property::Map attributes;
+  DevelControl::DoAction( imageView1, ImageView::Property::IMAGE, DevelImageVisual::Action::RELOAD, attributes );
+
+  // loading started, this waits for the loader thread for max 30 seconds
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  // conventional alpha blending
+  value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  srcFactorRgb    = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  destFactorRgb   = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  srcFactorAlpha  = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  destFactorAlpha = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );  // A new texture should be generated.
+  textureTrace.Reset();
+
+  // Make a new ImageView using the same image
+  ImageView imageView2 = ImageView::New();
+  imageView2.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView2 );
+
+  application.SendNotification();
+  application.Render();
+
+  Renderer renderer2 = imageView2.GetRendererAt( 0 );
+  value = renderer2.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );
+
+  srcFactorRgb    = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  destFactorRgb   = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  srcFactorAlpha  = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  destFactorAlpha = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION ); // The cached texture should be used.
+
+  END_TEST;
+}
+
+int UtcDaliImageViewPreMultipliedAlphaJpg(void)
+{
+  ToolkitTestApplication application;
+
+  // Set up trace debug
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable( true );
+
+  Property::Map imageMap;
+  imageMap[ ImageVisual::Property::URL ] = gImage_600_RGB;
+  imageMap[ ImageVisual::Property::RELEASE_POLICY] = ImageVisual::ReleasePolicy::NEVER;   // To keep the texture cache
+
+  ImageView imageView1 = ImageView::New();
+  imageView1.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView1 );
+
+  Property::Value value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  bool enable;
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );    // Default value is true
+
+  // loading started, this waits for the loader thread for max 30 seconds
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );    // Should be false after loading
+
+  // conventional alpha blending
+  Renderer renderer1 = imageView1.GetRendererAt( 0 );
+  value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  int srcFactorRgb    = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  int destFactorRgb   = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  int srcFactorAlpha  = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  int destFactorAlpha = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );  // A new texture should be generated.
+  textureTrace.Reset();
+
+  ImageView imageView2 = ImageView::New();
+  imageView2.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  // Disable pre-multiplied alpha blending
+  imageView2.SetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA, false );
+
+  Stage::GetCurrent().Add( imageView2 );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView2.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  // conventional alpha blending
+  Renderer renderer2 = imageView2.GetRendererAt( 0 );
+  value = renderer2.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  srcFactorRgb    = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  destFactorRgb   = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  srcFactorAlpha  = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  destFactorAlpha = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION ); // The cached texture should be used.
+
+  END_TEST;
+}
+
 int UtcDaliImageViewPixelArea(void)
 {
   // Test pixel area property
index 4e259e1..aee2e2f 100644 (file)
@@ -3294,7 +3294,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
 
   VisualFactory factory = VisualFactory::Get();
 
-  // image visual, test default value ( false )
+  // image visual, test default value ( true )
   {
     Visual::Base imageVisual = factory.CreateVisual(
           Property::Map()
@@ -3307,7 +3307,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
 
     // test values
     DALI_TEST_CHECK( value );
-    DALI_TEST_EQUALS( value->Get<bool>(), false, TEST_LOCATION );
+    DALI_TEST_EQUALS( value->Get<bool>(), true, TEST_LOCATION );
   }
 
   // image visual, override premultiplied
@@ -3316,7 +3316,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
           Property::Map()
           .Add( Toolkit::Visual::Property::TYPE, Visual::IMAGE )
           .Add( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME )
-          .Add( Visual::Property::PREMULTIPLIED_ALPHA, true ) );
+          .Add( Visual::Property::PREMULTIPLIED_ALPHA, false ) );
 
     Dali::Property::Map visualMap;
     imageVisual.CreatePropertyMap( visualMap );
@@ -3324,7 +3324,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
 
     // test values
     DALI_TEST_CHECK( value );
-    DALI_TEST_EQUALS( value->Get<bool>(), true, TEST_LOCATION);
+    DALI_TEST_EQUALS( value->Get<bool>(), false, TEST_LOCATION);
   }
 
   // svg visual ( premultiplied alpha by default is true )
index fad510b..77d06b7 100644 (file)
@@ -187,6 +187,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
   mLoading( false ),
   mOrientationCorrection( true )
 {
+  EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() );
 }
 
 ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image )
@@ -211,6 +212,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFac
   mLoading( false ),
   mOrientationCorrection( true )
 {
+  EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() );
 }
 
 ImageVisual::~ImageVisual()
@@ -683,7 +685,7 @@ void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& t
     atlasUploadObserver = this;
   }
 
-  auto preMultiplyOnLoad = mFactoryCache.GetPreMultiplyOnLoad() && !mImpl->mCustomShader
+  auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader
     ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
     : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
index 6ae1d8e..e1b162c 100755 (executable)
@@ -291,7 +291,7 @@ void NPatchVisual::LoadImages()
 {
   if( NPatchLoader::UNINITIALIZED_ID == mId && mImageUrl.IsLocalResource() )
   {
-    bool preMultiplyOnLoad = mFactoryCache.GetPreMultiplyOnLoad() && !mImpl->mCustomShader ? true : false;
+    bool preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader ? true : false;
 
     mId = mLoader.Load( mImageUrl.GetUrl(), mBorder, preMultiplyOnLoad );
 
@@ -434,6 +434,7 @@ NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
   mBorder(),
   mAuxiliaryImageAlpha( 0.0f )
 {
+  EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() );
 }
 
 NPatchVisual::~NPatchVisual()
index 5e9910d..3a32ddc 100644 (file)
@@ -344,7 +344,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
 {
   // First check if the requested Texture is cached.
   const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas,
-                                                maskTextureId, preMultiplyOnLoad );
+                                                maskTextureId );
 
   TextureManager::TextureId textureId = INVALID_TEXTURE_ID;
 
@@ -978,8 +978,7 @@ TextureManager::TextureHash TextureManager::GenerateHash(
   const FittingMode::Type        fittingMode,
   const Dali::SamplingMode::Type samplingMode,
   const UseAtlas                 useAtlas,
-  TextureId                      maskTextureId,
-  TextureManager::MultiplyOnLoad preMultiplyOnLoad)
+  TextureId                      maskTextureId )
 {
   std::string hashTarget( url );
   const size_t urlLength = hashTarget.length();
@@ -1039,22 +1038,6 @@ TextureManager::TextureHash TextureManager::GenerateHash(
     }
   }
 
-  auto premultipliedIndex = hashTarget.length();
-  hashTarget.resize( premultipliedIndex + 1 );
-  switch( preMultiplyOnLoad )
-  {
-    case TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD:
-    {
-      hashTarget[ premultipliedIndex ] = 't';
-      break;
-    }
-    case TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY:
-    {
-      hashTarget[ premultipliedIndex ] = 'f';
-      break;
-    }
-  }
-
   return Dali::CalculateHash( hashTarget );
 }
 
@@ -1079,21 +1062,24 @@ int TextureManager::FindCachedTexture(
     {
       // We have a match, now we check all the original parameters in case of a hash collision.
       TextureInfo& textureInfo( mTextureInfoContainer[i] );
-      auto multiplyOnLoad = textureInfo.preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD :
-        TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
       if( ( url == textureInfo.url.GetUrl() ) &&
           ( useAtlas == textureInfo.useAtlas ) &&
           ( maskTextureId == textureInfo.maskTextureId ) &&
           ( size == textureInfo.desiredSize ) &&
-          ( preMultiplyOnLoad ==  multiplyOnLoad ) &&
           ( ( size.GetWidth() == 0 && size.GetHeight() == 0 ) ||
             ( fittingMode == textureInfo.fittingMode &&
               samplingMode == textureInfo.samplingMode ) ) )
       {
-        // The found Texture is a match.
-        cacheIndex = i;
-        break;
+        // 1. If preMultiplyOnLoad is MULTIPLY_ON_LOAD, then textureInfo.preMultiplyOnLoad should be true. The premultiplication result can be different.
+        // 2. If preMultiplyOnLoad is LOAD_WITHOUT_MULTIPLY, then textureInfo.preMultiplied should be false.
+        if( ( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD && textureInfo.preMultiplyOnLoad )
+            || ( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY && !textureInfo.preMultiplied ) )
+        {
+          // The found Texture is a match.
+          cacheIndex = i;
+          break;
+        }
       }
     }
   }
index 502cf11..c64b781 100755 (executable)
@@ -665,8 +665,8 @@ private:
   TextureHash GenerateHash( const std::string& url, const ImageDimensions size,
                             const FittingMode::Type fittingMode,
                             const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
-                            TextureId maskTextureId,
-                            MultiplyOnLoad preMultiplyOnLoad);
+                            TextureId maskTextureId );
+
   /**
    * @brief Looks up a cached texture by its hash.
    * If found, the given parameters are used to check there is no hash-collision.